准备驱动移植适配Rust

This commit is contained in:
冯佳
2026-01-29 15:08:30 +08:00
parent e879b18602
commit 1bdeca55ea
68 changed files with 4371 additions and 4392 deletions

353
BSP/Src/bsp_eth.c Normal file
View File

@ -0,0 +1,353 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : bsp_eth.c
* @brief : Board support package Ethernet (LAN8720) driver implementation
******************************************************************************
*/
/* USER CODE END Header */
#include "bsp_eth.h"
/**
* @brief Ethernet configuration
*/
static bsp_eth_config_t eth_config;
static uint8_t eth_initialized = 0;
/**
* @brief Initialize Ethernet (LAN8720) module
* @param config: Pointer to Ethernet configuration structure
* @retval HAL status code
*/
hal_ret_t bsp_eth_init(const bsp_eth_config_t* config)
{
if (!config) {
return HAL_RET_INVALID_PARAM;
}
if (eth_initialized) {
return HAL_RET_OK;
}
/* Store configuration */
eth_config = *config;
/* Convert to HAL configuration */
hal_eth_config_t hal_config;
hal_config.enable = config->enable;
hal_config.instance = config->instance;
hal_config.mode = config->mode;
hal_config.speed = config->speed;
hal_config.phy_addr = config->phy_addr;
hal_config.mac_addr = config->mac_addr;
hal_config.auto_negotiation = config->auto_negotiation;
hal_config.interrupt_enable = config->interrupt_enable;
/* Initialize HAL Ethernet */
if (hal_eth_init(&hal_config) != HAL_RET_OK) {
return HAL_RET_INIT_ERROR;
}
/* Detect LAN8720 PHY */
uint8_t detected;
if (bsp_eth_detect_phy(&detected) != HAL_RET_OK) {
return HAL_RET_INIT_ERROR;
}
if (!detected) {
return HAL_RET_INIT_ERROR;
}
/* Configure PHY */
if (bsp_eth_configure_phy(config->mode, config->speed, config->auto_negotiation) != HAL_RET_OK) {
return HAL_RET_INIT_ERROR;
}
eth_initialized = 1;
return HAL_RET_OK;
}
/**
* @brief Deinitialize Ethernet (LAN8720) module
* @retval HAL status code
*/
hal_ret_t bsp_eth_deinit(void)
{
if (!eth_initialized) {
return HAL_RET_OK;
}
if (hal_eth_deinit(eth_config.instance) != HAL_RET_OK) {
return HAL_RET_DEINIT_ERROR;
}
eth_initialized = 0;
return HAL_RET_OK;
}
/**
* @brief Get Ethernet (LAN8720) status
* @param status: Pointer to Ethernet status structure
* @retval HAL status code
*/
hal_ret_t bsp_eth_get_status(bsp_eth_status_t* status)
{
if (!status) {
return HAL_RET_INVALID_PARAM;
}
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
/* Get HAL Ethernet status */
hal_eth_status_t hal_status;
if (hal_eth_get_status(eth_config.instance, &hal_status) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
/* Copy status */
status->link_up = hal_status.link_up;
status->duplex = hal_status.duplex;
status->speed = hal_status.speed;
status->rx_packets = hal_status.rx_packets;
status->tx_packets = hal_status.tx_packets;
status->rx_errors = hal_status.rx_errors;
status->tx_errors = hal_status.tx_errors;
/* Get PHY identifiers */
if (bsp_eth_read_phy_reg(LAN8720_REG_PID1, &status->phy_id1) != HAL_RET_OK) {
status->phy_id1 = 0;
}
if (bsp_eth_read_phy_reg(LAN8720_REG_PID2, &status->phy_id2) != HAL_RET_OK) {
status->phy_id2 = 0;
}
return HAL_RET_OK;
}
/**
* @brief Set Ethernet MAC address
* @param mac_addr: Pointer to MAC address structure
* @retval HAL status code
*/
hal_ret_t bsp_eth_set_mac_addr(const hal_eth_mac_addr_t* mac_addr)
{
if (!mac_addr) {
return HAL_RET_INVALID_PARAM;
}
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
if (hal_eth_set_mac_addr(eth_config.instance, mac_addr) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
eth_config.mac_addr = *mac_addr;
return HAL_RET_OK;
}
/**
* @brief Get Ethernet MAC address
* @param mac_addr: Pointer to MAC address structure
* @retval HAL status code
*/
hal_ret_t bsp_eth_get_mac_addr(hal_eth_mac_addr_t* mac_addr)
{
if (!mac_addr) {
return HAL_RET_INVALID_PARAM;
}
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
if (hal_eth_get_mac_addr(eth_config.instance, mac_addr) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
return HAL_RET_OK;
}
/**
* @brief Check Ethernet link status
* @param link_up: Pointer to store link up status
* @retval HAL status code
*/
hal_ret_t bsp_eth_check_link(uint8_t* link_up)
{
if (!link_up) {
return HAL_RET_INVALID_PARAM;
}
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
if (hal_eth_check_link(eth_config.instance, link_up) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
return HAL_RET_OK;
}
/**
* @brief Reset Ethernet PHY (LAN8720)
* @retval HAL status code
*/
hal_ret_t bsp_eth_reset_phy(void)
{
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
if (hal_eth_reset_phy(eth_config.instance, eth_config.phy_addr) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
return HAL_RET_OK;
}
/**
* @brief Read LAN8720 PHY register
* @param reg_addr: Register address
* @param value: Pointer to store register value
* @retval HAL status code
*/
hal_ret_t bsp_eth_read_phy_reg(uint16_t reg_addr, uint16_t* value)
{
if (!value) {
return HAL_RET_INVALID_PARAM;
}
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
if (hal_eth_read_phy_reg(eth_config.instance, eth_config.phy_addr, reg_addr, value) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
return HAL_RET_OK;
}
/**
* @brief Write LAN8720 PHY register
* @param reg_addr: Register address
* @param value: Register value
* @retval HAL status code
*/
hal_ret_t bsp_eth_write_phy_reg(uint16_t reg_addr, uint16_t value)
{
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
if (hal_eth_write_phy_reg(eth_config.instance, eth_config.phy_addr, reg_addr, value) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
return HAL_RET_OK;
}
/**
* @brief Detect LAN8720 PHY presence
* @param detected: Pointer to store detection result
* @retval HAL status code
*/
hal_ret_t bsp_eth_detect_phy(uint8_t* detected)
{
if (!detected) {
return HAL_RET_INVALID_PARAM;
}
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
/* Read PHY identifiers */
uint16_t id1, id2;
if (bsp_eth_read_phy_reg(LAN8720_REG_PID1, &id1) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
if (bsp_eth_read_phy_reg(LAN8720_REG_PID2, &id2) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
/* Check if this is a LAN8720 PHY */
if (id1 == LAN8720_PID1_VALUE && (id2 & 0xFFF0) == LAN8720_PID2_VALUE) {
*detected = 1;
} else {
*detected = 0;
}
return HAL_RET_OK;
}
/**
* @brief Configure LAN8720 PHY
* @param mode: Ethernet mode
* @param speed: Ethernet speed
* @param auto_neg: Auto-negotiation enable
* @retval HAL status code
*/
hal_ret_t bsp_eth_configure_phy(hal_eth_mode_t mode, hal_eth_speed_t speed, uint8_t auto_neg)
{
if (!eth_initialized) {
return HAL_RET_INIT_ERROR;
}
/* Read current BCR register */
uint16_t bcr;
if (bsp_eth_read_phy_reg(LAN8720_REG_BCR, &bcr) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
/* Clear relevant bits */
bcr &= ~(LAN8720_BCR_AUTO_NEG_EN | LAN8720_BCR_SPEED_SELECT | LAN8720_BCR_DUPLEX_MODE);
if (auto_neg) {
/* Enable auto-negotiation */
bcr |= LAN8720_BCR_AUTO_NEG_EN;
bcr |= LAN8720_BCR_RESTART_AN;
} else {
/* Manual configuration */
if (speed == HAL_ETH_SPEED_100MBPS) {
bcr |= LAN8720_BCR_SPEED_SELECT;
}
if (mode == HAL_ETH_MODE_FULLDUPLEX) {
bcr |= LAN8720_BCR_DUPLEX_MODE;
}
}
/* Write BCR register */
if (bsp_eth_write_phy_reg(LAN8720_REG_BCR, bcr) != HAL_RET_OK) {
return HAL_RET_ERROR;
}
/* Wait for configuration to complete */
if (auto_neg) {
uint32_t timeout = 1000;
uint16_t bsr;
while (timeout--) {
if (bsp_eth_read_phy_reg(LAN8720_REG_BSR, &bsr) == HAL_RET_OK) {
if (bsr & LAN8720_BSR_AUTO_NEG_COMPLETE) {
break;
}
}
HAL_Delay(1);
}
if (timeout == 0) {
return HAL_RET_TIMEOUT;
}
}
return HAL_RET_OK;
}