[bsp][stm32] update drv_eth

This commit is contained in:
SummerGift 2018-12-26 10:17:11 +08:00
parent a80b272048
commit 7279078005
3 changed files with 189 additions and 90 deletions

View File

@ -33,7 +33,7 @@ if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']):
src += ['drv_soft_i2c.c'] src += ['drv_soft_i2c.c']
if GetDepend('RT_USING_LWIP'): if GetDepend('RT_USING_LWIP'):
src += ['drv_emac.c'] src += ['drv_eth.c']
if GetDepend(['RT_USING_ADC']): if GetDepend(['RT_USING_ADC']):
src += Glob('drv_adc.c') src += Glob('drv_adc.c')
@ -43,13 +43,16 @@ if GetDepend('BSP_USING_SDRAM'):
if GetDepend('BSP_USING_ONCHIP_RTC'): if GetDepend('BSP_USING_ONCHIP_RTC'):
src += ['drv_rtc.c'] src += ['drv_rtc.c']
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F0']):
src += ['drv_flash/drv_flash_f0.c']
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F1']): if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F1']):
src += ['drv_flash/drv_flash_f1.c'] src += ['drv_flash/drv_flash_f1.c']
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F4']): if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F4']):
src += ['drv_flash/drv_flash_f4.c'] src += ['drv_flash/drv_flash_f4.c']
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F7']): if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F7']):
src += ['drv_flash/drv_flash_f7.c'] src += ['drv_flash/drv_flash_f7.c']

View File

@ -6,12 +6,14 @@
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2018-11-19 SummerGift first version * 2018-11-19 SummerGift first version
* 2018-12-25 zylx fix some bugs
*/ */
#include "board.h" #include "board.h"
#include "drv_config.h" #include "drv_config.h"
#include <netif/ethernetif.h> #include <netif/ethernetif.h>
#include "lwipopts.h" #include "lwipopts.h"
#include "drv_eth.h"
/* /*
* Emac driver uses CubeMX tool to generate emac and phy's configuration, * Emac driver uses CubeMX tool to generate emac and phy's configuration,
@ -32,11 +34,12 @@ struct rt_stm32_eth
/* inherit from ethernet device */ /* inherit from ethernet device */
struct eth_device parent; struct eth_device parent;
/* interface address info. */ /* interface address info, hw address */
rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ rt_uint8_t dev_addr[MAX_ADDR_LEN];
/* ETH_Speed */
uint32_t ETH_Speed; /*!< @ref ETH_Speed */ uint32_t ETH_Speed;
uint32_t ETH_Mode; /*!< @ref ETH_Duplex_Mode */ /* ETH_Duplex_Mode */
uint32_t ETH_Mode;
}; };
static ETH_DMADescTypeDef *DMARxDscrTab, *DMATxDscrTab; static ETH_DMADescTypeDef *DMARxDscrTab, *DMATxDscrTab;
@ -50,7 +53,7 @@ static struct rt_semaphore tx_wait;
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen) static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
{ {
unsigned char *buf = (unsigned char*)ptr; unsigned char *buf = (unsigned char *)ptr;
int i, j; int i, j;
for (i = 0; i < buflen; i += 16) for (i = 0; i < buflen; i += 16)
@ -73,24 +76,22 @@ static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
#endif #endif
extern void phy_reset(void); extern void phy_reset(void);
/* EMAC initialization function */ /* EMAC initialization function */
static rt_err_t rt_stm32_eth_init(rt_device_t dev) static rt_err_t rt_stm32_eth_init(rt_device_t dev)
{ {
__HAL_RCC_ETH_CLK_ENABLE(); __HAL_RCC_ETH_CLK_ENABLE();
phy_reset(); phy_reset();
/* ETHERNET Configuration --------------------------------------------------*/ /* ETHERNET Configuration */
EthHandle.Instance = ETH; EthHandle.Instance = ETH;
EthHandle.Init.MACAddr = (rt_uint8_t*)&stm32_eth_device.dev_addr[0]; EthHandle.Init.MACAddr = (rt_uint8_t *)&stm32_eth_device.dev_addr[0];
EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
EthHandle.Init.Speed = ETH_SPEED_100M; EthHandle.Init.Speed = ETH_SPEED_100M;
EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX; EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE; EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE; EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
//EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
EthHandle.Init.PhyAddress = EXTERNAL_PHY_ADDRESS;
HAL_ETH_DeInit(&EthHandle); HAL_ETH_DeInit(&EthHandle);
@ -101,7 +102,8 @@ static rt_err_t rt_stm32_eth_init(rt_device_t dev)
} }
else else
{ {
LOG_D("emac hardware init faild"); LOG_E("emac hardware init faild");
return -RT_ERROR;
} }
/* Initialize Tx Descriptors list: Chain Mode */ /* Initialize Tx Descriptors list: Chain Mode */
@ -110,6 +112,10 @@ static rt_err_t rt_stm32_eth_init(rt_device_t dev)
/* Initialize Rx Descriptors list: Chain Mode */ /* Initialize Rx Descriptors list: Chain Mode */
HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, Rx_Buff, ETH_RXBUFNB); HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, Rx_Buff, ETH_RXBUFNB);
/* ETH interrupt Init */
HAL_NVIC_SetPriority(ETH_IRQn, 0x07, 0);
HAL_NVIC_EnableIRQ(ETH_IRQn);
/* Enable MAC and DMA transmission and reception */ /* Enable MAC and DMA transmission and reception */
if (HAL_ETH_Start(&EthHandle) == HAL_OK) if (HAL_ETH_Start(&EthHandle) == HAL_OK)
{ {
@ -117,13 +123,10 @@ static rt_err_t rt_stm32_eth_init(rt_device_t dev)
} }
else else
{ {
LOG_D("emac hardware start faild"); LOG_E("emac hardware start faild");
return -RT_ERROR;
} }
/* ETH interrupt Init */
HAL_NVIC_SetPriority(ETH_IRQn, 0x07, 0);
HAL_NVIC_EnableIRQ(ETH_IRQn);
return RT_EOK; return RT_EOK;
} }
@ -139,14 +142,14 @@ static rt_err_t rt_stm32_eth_close(rt_device_t dev)
return RT_EOK; return RT_EOK;
} }
static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{ {
LOG_D("emac read"); LOG_D("emac read");
rt_set_errno(-RT_ENOSYS); rt_set_errno(-RT_ENOSYS);
return 0; return 0;
} }
static rt_size_t rt_stm32_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) static rt_size_t rt_stm32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{ {
LOG_D("emac write"); LOG_D("emac write");
rt_set_errno(-RT_ENOSYS); rt_set_errno(-RT_ENOSYS);
@ -155,11 +158,11 @@ static rt_size_t rt_stm32_eth_write (rt_device_t dev, rt_off_t pos, const void*
static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args) static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
{ {
switch(cmd) switch (cmd)
{ {
case NIOCTL_GADDR: case NIOCTL_GADDR:
/* get mac address */ /* get mac address */
if(args) rt_memcpy(args, stm32_eth_device.dev_addr, 6); if (args) rt_memcpy(args, stm32_eth_device.dev_addr, 6);
else return -RT_ERROR; else return -RT_ERROR;
break; break;
@ -172,7 +175,7 @@ static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
/* ethernet device interface */ /* ethernet device interface */
/* transmit data*/ /* transmit data*/
rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p) rt_err_t rt_stm32_eth_tx(rt_device_t dev, struct pbuf *p)
{ {
rt_err_t ret = RT_ERROR; rt_err_t ret = RT_ERROR;
HAL_StatusTypeDef state; HAL_StatusTypeDef state;
@ -204,12 +207,12 @@ rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
} }
/* copy frame from pbufs to driver buffers */ /* copy frame from pbufs to driver buffers */
for(q = p; q != NULL; q = q->next) for (q = p; q != NULL; q = q->next)
{ {
/* Is this buffer available? If not, goto error */ /* Is this buffer available? If not, goto error */
if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
{ {
LOG_D("buffer not valid"); LOG_E("buffer not valid");
ret = ERR_USE; ret = ERR_USE;
goto error; goto error;
} }
@ -219,18 +222,18 @@ rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
payloadoffset = 0; payloadoffset = 0;
/* Check if the length of data to copy is bigger than Tx buffer size*/ /* Check if the length of data to copy is bigger than Tx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) while ((byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE)
{ {
/* Copy data to Tx buffer*/ /* Copy data to Tx buffer*/
memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) ); memcpy((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */ /* Point to next descriptor */
DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr); DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
/* Check if the buffer is available */ /* Check if the buffer is available */
if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
{ {
LOG_D("dma tx desc buffer is not valid"); LOG_E("dma tx desc buffer is not valid");
ret = ERR_USE; ret = ERR_USE;
goto error; goto error;
} }
@ -244,7 +247,7 @@ rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
} }
/* Copy the remaining bytes */ /* Copy the remaining bytes */
memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), byteslefttocopy ); memcpy((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)q->payload + payloadoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy; bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy; framelength = framelength + byteslefttocopy;
} }
@ -261,7 +264,7 @@ rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
state = HAL_ETH_TransmitFrame(&EthHandle, framelength); state = HAL_ETH_TransmitFrame(&EthHandle, framelength);
if (state != HAL_OK) if (state != HAL_OK)
{ {
LOG_D("eth transmit frame faild: %d", state); LOG_E("eth transmit frame faild: %d", state);
} }
ret = ERR_OK; ret = ERR_OK;
@ -324,16 +327,16 @@ struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
{ {
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc; dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
bufferoffset = 0; bufferoffset = 0;
for(q = p; q != NULL; q = q->next) for (q = p; q != NULL; q = q->next)
{ {
byteslefttocopy = q->len; byteslefttocopy = q->len;
payloadoffset = 0; payloadoffset = 0;
/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE ) while ((byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE)
{ {
/* Copy data to pbuf */ /* Copy data to pbuf */
memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset)); memcpy((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */ /* Point to next descriptor */
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr); dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
@ -344,7 +347,7 @@ struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
bufferoffset = 0; bufferoffset = 0;
} }
/* Copy remaining data in pbuf */ /* Copy remaining data in pbuf */
memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy); memcpy((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy; bufferoffset = bufferoffset + byteslefttocopy;
} }
} }
@ -399,41 +402,41 @@ void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{ {
rt_err_t result; rt_err_t result;
result = eth_device_ready(&(stm32_eth_device.parent)); result = eth_device_ready(&(stm32_eth_device.parent));
if( result != RT_EOK ) if (result != RT_EOK)
LOG_D("RX err = %d", result ); LOG_E("RX err = %d", result);
} }
void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
{ {
LOG_D("eth err"); LOG_E("eth err");
} }
/* PHY: LAN8720 */
static uint8_t phy_speed = 0; static uint8_t phy_speed = 0;
#define PHY_LINK_MASK (1<<0) #define PHY_LINK_MASK (1<<0)
#define PHY_100M_MASK (1<<1)
#define PHY_DUPLEX_MASK (1<<2)
static void phy_monitor_thread_entry(void *parameter) static void phy_monitor_thread_entry(void *parameter)
{ {
uint8_t phy_addr = 0xFF; uint8_t phy_addr = 0xFF;
uint8_t phy_speed_new = 0; uint8_t phy_speed_new = 0;
rt_uint32_t status = 0;
/* phy search */ /* phy search */
rt_uint32_t i, temp; rt_uint32_t i, temp;
for(i=0; i<=0x1F; i++) for (i = 0; i <= 0x1F; i++)
{ {
HAL_ETH_ReadPHYRegister(&EthHandle, 0x02, (uint32_t *)&temp); EthHandle.Init.PhyAddress = i;
if( temp != 0xFFFF ) HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ID1_REG, (uint32_t *)&temp);
if (temp != 0xFFFF)
{ {
phy_addr = i; phy_addr = i;
break; break;
} }
} }
if(phy_addr == 0xFF) if (phy_addr == 0xFF)
{ {
LOG_D("phy not probe!\r\n"); LOG_E("phy not probe!\r\n");
return; return;
} }
else else
@ -443,47 +446,49 @@ static void phy_monitor_thread_entry(void *parameter)
/* RESET PHY */ /* RESET PHY */
LOG_D("RESET PHY!"); LOG_D("RESET PHY!");
HAL_ETH_WritePHYRegister(&EthHandle, PHY_BCR, PHY_RESET); HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_RESET_MASK);
rt_thread_delay(RT_TICK_PER_SECOND * 2); rt_thread_mdelay(2000);
HAL_ETH_WritePHYRegister(&EthHandle, PHY_BCR, PHY_AUTONEGOTIATION); HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_AUTO_NEGOTIATION_MASK);
while(1) while (1)
{ {
rt_uint32_t status; HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BASIC_STATUS_REG, (uint32_t *)&status);
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BSR, (uint32_t *)&status); LOG_D("PHY BASIC STATUS REG:0x%04X\r\n", status);
LOG_D("LAN8720 status:0x%04X\r\n", status);
phy_speed_new = 0; phy_speed_new = 0;
if(status & (PHY_AUTONEGO_COMPLETE | PHY_LINKED_STATUS)) if (status & (PHY_AUTONEGO_COMPLETE_MASK | PHY_LINKED_STATUS_MASK))
{ {
rt_uint32_t SR; rt_uint32_t SR;
SR = HAL_ETH_ReadPHYRegister(&EthHandle, 31, (uint32_t *)&SR);
LOG_D("LAN8720 REG 31:0x%04X ", SR);
SR = (SR >> 2) & 0x07; /* LAN8720, REG31[4:2], Speed Indication. */
phy_speed_new = PHY_LINK_MASK; phy_speed_new = PHY_LINK_MASK;
if((SR & 0x03) == 2) SR = HAL_ETH_ReadPHYRegister(&EthHandle, PHY_Status_REG, (uint32_t *)&SR);
LOG_D("PHY Control/Status REG:0x%04X ", SR);
if (SR & PHY_100M_MASK)
{ {
phy_speed_new |= PHY_100M_MASK; phy_speed_new |= PHY_100M_MASK;
} }
else if (SR & PHY_10M_MASK)
if(SR & 0x04)
{ {
phy_speed_new |= PHY_DUPLEX_MASK; phy_speed_new |= PHY_10M_MASK;
}
if (SR & PHY_FULL_DUPLEX_MASK)
{
phy_speed_new |= PHY_FULL_DUPLEX_MASK;
} }
} }
/* linkchange */ /* linkchange */
if(phy_speed_new != phy_speed) if (phy_speed_new != phy_speed)
{ {
if(phy_speed_new & PHY_LINK_MASK) if (phy_speed_new & PHY_LINK_MASK)
{ {
LOG_D("link up "); LOG_D("link up ");
if(phy_speed_new & PHY_100M_MASK) if (phy_speed_new & PHY_100M_MASK)
{ {
LOG_D("100Mbps"); LOG_D("100Mbps");
stm32_eth_device.ETH_Speed = ETH_SPEED_100M; stm32_eth_device.ETH_Speed = ETH_SPEED_100M;
@ -494,7 +499,7 @@ static void phy_monitor_thread_entry(void *parameter)
LOG_D("10Mbps"); LOG_D("10Mbps");
} }
if(phy_speed_new & PHY_DUPLEX_MASK) if (phy_speed_new & PHY_FULL_DUPLEX_MASK)
{ {
LOG_D("full-duplex"); LOG_D("full-duplex");
stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX; stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX;
@ -504,54 +509,68 @@ static void phy_monitor_thread_entry(void *parameter)
LOG_D("half-duplex"); LOG_D("half-duplex");
stm32_eth_device.ETH_Mode = ETH_MODE_HALFDUPLEX; stm32_eth_device.ETH_Mode = ETH_MODE_HALFDUPLEX;
} }
rt_stm32_eth_init((rt_device_t)&stm32_eth_device);
/* send link up. */ if (rt_stm32_eth_init((rt_device_t)&stm32_eth_device) != RT_EOK)
eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE); {
break;
}
else
{
/* send link up. */
eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE);
}
} /* link up. */ } /* link up. */
else else
{ {
LOG_D("link down\r\n"); LOG_I("link down\r\n");
/* send link down. */ /* send link down. */
eth_device_linkchange(&stm32_eth_device.parent, RT_FALSE); eth_device_linkchange(&stm32_eth_device.parent, RT_FALSE);
} }
phy_speed = phy_speed_new; phy_speed = phy_speed_new;
} }
rt_thread_delay(RT_TICK_PER_SECOND); rt_thread_delay(RT_TICK_PER_SECOND);
} }
} }
/* Register the EMAC device */ /* Register the EMAC device */
static int rt_hw_stm32_eth_init(void) static int rt_hw_stm32_eth_init(void)
{ {
rt_err_t state = RT_EOK;
/* Prepare receive and send buffers */ /* Prepare receive and send buffers */
Rx_Buff = (rt_uint8_t *)rt_calloc(ETH_RXBUFNB, ETH_MAX_PACKET_SIZE); Rx_Buff = (rt_uint8_t *)rt_calloc(ETH_RXBUFNB, ETH_MAX_PACKET_SIZE);
if (Rx_Buff == RT_NULL) if (Rx_Buff == RT_NULL)
{ {
LOG_E("No memory"); LOG_E("No memory");
state = RT_ENOMEM;
goto __exit;
} }
Tx_Buff = (rt_uint8_t *)rt_calloc(ETH_TXBUFNB, ETH_MAX_PACKET_SIZE); Tx_Buff = (rt_uint8_t *)rt_calloc(ETH_TXBUFNB, ETH_MAX_PACKET_SIZE);
if (Rx_Buff == RT_NULL) if (Rx_Buff == RT_NULL)
{ {
LOG_E("No memory"); LOG_E("No memory");
state = RT_ENOMEM;
goto __exit;
} }
DMARxDscrTab = (ETH_DMADescTypeDef * )rt_calloc(ETH_RXBUFNB, sizeof(ETH_DMADescTypeDef)); DMARxDscrTab = (ETH_DMADescTypeDef *)rt_calloc(ETH_RXBUFNB, sizeof(ETH_DMADescTypeDef));
if (DMARxDscrTab == RT_NULL) if (DMARxDscrTab == RT_NULL)
{ {
LOG_E("No memory"); LOG_E("No memory");
state = RT_ENOMEM;
goto __exit;
} }
DMATxDscrTab = (ETH_DMADescTypeDef * )rt_calloc(ETH_TXBUFNB, sizeof(ETH_DMADescTypeDef)); DMATxDscrTab = (ETH_DMADescTypeDef *)rt_calloc(ETH_TXBUFNB, sizeof(ETH_DMADescTypeDef));
if (DMATxDscrTab == RT_NULL) if (DMATxDscrTab == RT_NULL)
{ {
LOG_E("No memory"); LOG_E("No memory");
state = RT_ENOMEM;
goto __exit;
} }
rt_err_t state;
stm32_eth_device.ETH_Speed = ETH_SPEED_100M; stm32_eth_device.ETH_Speed = ETH_SPEED_100M;
stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX; stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX;
@ -560,9 +579,9 @@ static int rt_hw_stm32_eth_init(void)
stm32_eth_device.dev_addr[1] = 0x80; stm32_eth_device.dev_addr[1] = 0x80;
stm32_eth_device.dev_addr[2] = 0xE1; stm32_eth_device.dev_addr[2] = 0xE1;
/* generate MAC addr from 96bit unique ID (only for test). */ /* generate MAC addr from 96bit unique ID (only for test). */
stm32_eth_device.dev_addr[3] = *(rt_uint8_t*)(UID_BASE + 4); stm32_eth_device.dev_addr[3] = *(rt_uint8_t *)(UID_BASE + 4);
stm32_eth_device.dev_addr[4] = *(rt_uint8_t*)(UID_BASE + 2); stm32_eth_device.dev_addr[4] = *(rt_uint8_t *)(UID_BASE + 2);
stm32_eth_device.dev_addr[5] = *(rt_uint8_t*)(UID_BASE + 0); stm32_eth_device.dev_addr[5] = *(rt_uint8_t *)(UID_BASE + 0);
stm32_eth_device.parent.parent.init = rt_stm32_eth_init; stm32_eth_device.parent.parent.init = rt_stm32_eth_init;
stm32_eth_device.parent.parent.open = rt_stm32_eth_open; stm32_eth_device.parent.parent.open = rt_stm32_eth_open;
@ -587,9 +606,10 @@ static int rt_hw_stm32_eth_init(void)
} }
else else
{ {
LOG_D("emac device init faild: %d", state); LOG_E("emac device init faild: %d", state);
return -RT_ERROR;
} }
/* start phy monitor */ /* start phy monitor */
rt_thread_t tid; rt_thread_t tid;
tid = rt_thread_create("phy", tid = rt_thread_create("phy",
@ -600,9 +620,32 @@ static int rt_hw_stm32_eth_init(void)
2); 2);
if (tid != RT_NULL) if (tid != RT_NULL)
{ {
rt_thread_startup(tid); rt_thread_startup(tid);
} }
__exit:
if (state != RT_EOK)
{
if (Rx_Buff)
{
rt_free(Rx_Buff);
}
if (Tx_Buff)
{
rt_free(Tx_Buff);
}
if (DMARxDscrTab)
{
rt_free(DMARxDscrTab);
}
if (DMATxDscrTab)
{
rt_free(DMATxDscrTab);
}
}
return state; return state;
} }
INIT_APP_EXPORT(rt_hw_stm32_eth_init); INIT_APP_EXPORT(rt_hw_stm32_eth_init);

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-25 zylx first version
*/
#ifndef __DRV_ETH_H__
#define __DRV_ETH_H__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <board.h>
/* The PHY basic control register */
#define PHY_BASIC_CONTROL_REG 0x00U
#define PHY_RESET_MASK (1<<15)
#define PHY_AUTO_NEGOTIATION_MASK (1<<12)
/* The PHY basic status register */
#define PHY_BASIC_STATUS_REG 0x01U
#define PHY_LINKED_STATUS_MASK (1<<2)
#define PHY_AUTONEGO_COMPLETE_MASK (1<<5)
/* The PHY ID one register */
#define PHY_ID1_REG 0x02U
/* The PHY ID two register */
#define PHY_ID2_REG 0x03U
/* The PHY auto-negotiate advertise register */
#define PHY_AUTONEG_ADVERTISE_REG 0x04U
#ifdef PHY_USING_LAN8720A
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x1DU
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_MSAK_REG 0x1EU
#define PHY_LINK_DOWN_MASK (1<<4)
#define PHY_AUTO_NEGO_COMPLETE_MASK (1<<6)
/* The PHY status register. */
#define PHY_Status_REG 0x1FU
#define PHY_10M_MASK (1<<2)
#define PHY_100M_MASK (1<<3)
#define PHY_FULL_DUPLEX_MASK (1<<4)
#endif /* PHY_USING_LAN8720A */
#endif /* __DRV_ETH_H__ */