drv_eth.c 17.7 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-19     SummerGift   first version
S
SummerGift 已提交
9
 * 2018-12-25     zylx         fix some bugs
10 11 12 13 14 15
 */

#include "board.h"
#include "drv_config.h"
#include <netif/ethernetif.h>
#include "lwipopts.h"
S
SummerGift 已提交
16
#include "drv_eth.h"
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

/*
* Emac driver uses CubeMX tool to generate emac and phy's configuration,
* the configuration files can be found in CubeMX_Config floder.
*/

/* debug option */
//#define ETH_RX_DUMP
//#define ETH_TX_DUMP
//#define DRV_DEBUG
#define LOG_TAG             "drv.emac"
#include <drv_log.h>

#define MAX_ADDR_LEN 6

struct rt_stm32_eth
{
    /* inherit from ethernet device */
    struct eth_device parent;

S
SummerGift 已提交
37 38 39 40 41 42
    /* interface address info, hw address */
    rt_uint8_t  dev_addr[MAX_ADDR_LEN];
    /* ETH_Speed */
    uint32_t    ETH_Speed;
    /* ETH_Duplex_Mode */
    uint32_t    ETH_Mode;
43 44 45 46 47 48 49 50 51 52 53 54 55
};

static ETH_DMADescTypeDef *DMARxDscrTab, *DMATxDscrTab;
static rt_uint8_t *Rx_Buff, *Tx_Buff;
static rt_bool_t tx_is_waiting = RT_FALSE;
static  ETH_HandleTypeDef EthHandle;
static struct rt_stm32_eth stm32_eth_device;
static struct rt_semaphore tx_wait;

#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
{
S
SummerGift 已提交
56
    unsigned char *buf = (unsigned char *)ptr;
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
    int i, j;

    for (i = 0; i < buflen; i += 16)
    {
        rt_kprintf("%08X: ", i);

        for (j = 0; j < 16; j++)
            if (i + j < buflen)
                rt_kprintf("%02X ", buf[i + j]);
            else
                rt_kprintf("   ");
        rt_kprintf(" ");

        for (j = 0; j < 16; j++)
            if (i + j < buflen)
                rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
        rt_kprintf("\n");
    }
}
#endif

extern void phy_reset(void);
S
SummerGift 已提交
79
/* EMAC initialization function */
80 81 82 83 84 85
static rt_err_t rt_stm32_eth_init(rt_device_t dev)
{
    __HAL_RCC_ETH_CLK_ENABLE();

    phy_reset();

S
SummerGift 已提交
86
    /* ETHERNET Configuration */
87
    EthHandle.Instance = ETH;
S
SummerGift 已提交
88
    EthHandle.Init.MACAddr = (rt_uint8_t *)&stm32_eth_device.dev_addr[0];
89
    EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE;
90 91 92 93 94 95 96 97 98
    EthHandle.Init.Speed = ETH_SPEED_100M;
    EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
    EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
    EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
    EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;

    HAL_ETH_DeInit(&EthHandle);

    /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
99 100 101 102 103 104 105 106 107 108
    if (HAL_ETH_Init(&EthHandle) != HAL_OK)
    {
        LOG_E("eth hardware init failed");
        return -RT_ERROR;
    }
    else
    {
        LOG_D("eth hardware init success");
    }

109 110 111 112 113 114
    /* Initialize Tx Descriptors list: Chain Mode */
    HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, Tx_Buff, ETH_TXBUFNB);

    /* Initialize Rx Descriptors list: Chain Mode  */
    HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, Rx_Buff, ETH_RXBUFNB);

S
SummerGift 已提交
115 116 117 118
    /* ETH interrupt Init */
    HAL_NVIC_SetPriority(ETH_IRQn, 0x07, 0);
    HAL_NVIC_EnableIRQ(ETH_IRQn);

119 120 121 122 123 124 125
    /* Enable MAC and DMA transmission and reception */
    if (HAL_ETH_Start(&EthHandle) == HAL_OK)
    {
        LOG_D("emac hardware start");
    }
    else
    {
S
SummerGift 已提交
126 127
        LOG_E("emac hardware start faild");
        return -RT_ERROR;
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    }

    return RT_EOK;
}

static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
{
    LOG_D("emac open");
    return RT_EOK;
}

static rt_err_t rt_stm32_eth_close(rt_device_t dev)
{
    LOG_D("emac close");
    return RT_EOK;
}

S
SummerGift 已提交
145
static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
146 147 148 149 150 151
{
    LOG_D("emac read");
    rt_set_errno(-RT_ENOSYS);
    return 0;
}

S
SummerGift 已提交
152
static rt_size_t rt_stm32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
153 154 155 156 157 158 159 160
{
    LOG_D("emac write");
    rt_set_errno(-RT_ENOSYS);
    return 0;
}

static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
{
S
SummerGift 已提交
161
    switch (cmd)
162 163 164
    {
    case NIOCTL_GADDR:
        /* get mac address */
S
SummerGift 已提交
165
        if (args) rt_memcpy(args, stm32_eth_device.dev_addr, 6);
166 167 168 169 170 171 172 173 174 175 176 177
        else return -RT_ERROR;
        break;

    default :
        break;
    }

    return RT_EOK;
}

/* ethernet device interface */
/* transmit data*/
S
SummerGift 已提交
178
rt_err_t rt_stm32_eth_tx(rt_device_t dev, struct pbuf *p)
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
{
    rt_err_t ret = RT_ERROR;
    HAL_StatusTypeDef state;
    struct pbuf *q;
    uint8_t *buffer = (uint8_t *)(EthHandle.TxDesc->Buffer1Addr);
    __IO ETH_DMADescTypeDef *DmaTxDesc;
    uint32_t framelength = 0;
    uint32_t bufferoffset = 0;
    uint32_t byteslefttocopy = 0;
    uint32_t payloadoffset = 0;

    DmaTxDesc = EthHandle.TxDesc;
    bufferoffset = 0;

    /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
    while ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
    {
        rt_err_t result;
        rt_uint32_t level;

        level = rt_hw_interrupt_disable();
        tx_is_waiting = RT_TRUE;
        rt_hw_interrupt_enable(level);

        /* it's own bit set, wait it */
        result = rt_sem_take(&tx_wait, RT_WAITING_FOREVER);
        if (result == RT_EOK) break;
        if (result == -RT_ERROR) return -RT_ERROR;
    }

    /* copy frame from pbufs to driver buffers */
S
SummerGift 已提交
210
    for (q = p; q != NULL; q = q->next)
211 212
    {
        /* Is this buffer available? If not, goto error */
S
SummerGift 已提交
213
        if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
214
        {
S
SummerGift 已提交
215
            LOG_E("buffer not valid");
216 217 218 219 220 221 222 223 224
            ret = ERR_USE;
            goto error;
        }

        /* Get bytes in current lwIP buffer */
        byteslefttocopy = q->len;
        payloadoffset = 0;

        /* Check if the length of data to copy is bigger than Tx buffer size*/
S
SummerGift 已提交
225
        while ((byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE)
226 227
        {
            /* Copy data to Tx buffer*/
S
SummerGift 已提交
228
            memcpy((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset));
229 230 231 232 233

            /* Point to next descriptor */
            DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);

            /* Check if the buffer is available */
S
SummerGift 已提交
234
            if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
235
            {
S
SummerGift 已提交
236
                LOG_E("dma tx desc buffer is not valid");
237 238 239 240 241 242 243 244 245 246 247 248 249
                ret = ERR_USE;
                goto error;
            }

            buffer = (uint8_t *)(DmaTxDesc->Buffer1Addr);

            byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
            payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
            framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
            bufferoffset = 0;
        }

        /* Copy the remaining bytes */
S
SummerGift 已提交
250
        memcpy((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)q->payload + payloadoffset), byteslefttocopy);
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
        bufferoffset = bufferoffset + byteslefttocopy;
        framelength = framelength + byteslefttocopy;
    }

#ifdef ETH_TX_DUMP
    dump_hex(buffer, p->tot_len);
#endif

    /* Prepare transmit descriptors to give to DMA */
    /* TODO Optimize data send speed*/
    LOG_D("transmit frame lenth :%d", framelength);

    state = HAL_ETH_TransmitFrame(&EthHandle, framelength);
    if (state != HAL_OK)
    {
S
SummerGift 已提交
266
        LOG_E("eth transmit frame faild: %d", state);
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
    }

    ret = ERR_OK;

error:

    /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
    if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
    {
        /* Clear TUS ETHERNET DMA flag */
        EthHandle.Instance->DMASR = ETH_DMASR_TUS;

        /* Resume DMA transmission*/
        EthHandle.Instance->DMATPDR = 0;
    }

    return ret;
}

/* receive data*/
struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
{

    struct pbuf *p = NULL;
    struct pbuf *q = NULL;
    HAL_StatusTypeDef state;
    uint16_t len = 0;
    uint8_t *buffer;
    __IO ETH_DMADescTypeDef *dmarxdesc;
    uint32_t bufferoffset = 0;
    uint32_t payloadoffset = 0;
    uint32_t byteslefttocopy = 0;
    uint32_t i = 0;

    /* Get received frame */
    state = HAL_ETH_GetReceivedFrame_IT(&EthHandle);
    if (state != HAL_OK)
    {
        LOG_D("receive frame faild");
        return NULL;
    }

    /* Obtain the size of the packet and put it into the "len" variable. */
    len = EthHandle.RxFrameInfos.length;
    buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer;

    LOG_D("receive frame len : %d", len);

    if (len > 0)
    {
        /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
        p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
    }

#ifdef ETH_RX_DUMP
    dump_hex(buffer, p->tot_len);
#endif

    if (p != NULL)
    {
        dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
        bufferoffset = 0;
S
SummerGift 已提交
329
        for (q = p; q != NULL; q = q->next)
330 331 332 333 334
        {
            byteslefttocopy = q->len;
            payloadoffset = 0;

            /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
S
SummerGift 已提交
335
            while ((byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE)
336 337
            {
                /* Copy data to pbuf */
S
SummerGift 已提交
338
                memcpy((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
339 340 341 342 343 344 345 346 347 348

                /* Point to next descriptor */
                dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
                buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);

                byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
                payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
                bufferoffset = 0;
            }
            /* Copy remaining data in pbuf */
S
SummerGift 已提交
349
            memcpy((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), byteslefttocopy);
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
            bufferoffset = bufferoffset + byteslefttocopy;
        }
    }

    /* Release descriptors to DMA */
    /* Point to first descriptor */
    dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
    /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
    for (i = 0; i < EthHandle.RxFrameInfos.SegCount; i++)
    {
        dmarxdesc->Status |= ETH_DMARXDESC_OWN;
        dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
    }

    /* Clear Segment_Count */
    EthHandle.RxFrameInfos.SegCount = 0;

    /* When Rx Buffer unavailable flag is set: clear it and resume reception */
    if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
    {
        /* Clear RBUS ETHERNET DMA flag */
        EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
        /* Resume DMA reception */
        EthHandle.Instance->DMARPDR = 0;
    }

    return p;
}

/* interrupt service routine */
void ETH_IRQHandler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

    HAL_ETH_IRQHandler(&EthHandle);

    /* leave interrupt */
    rt_interrupt_leave();
}

void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
{
    if (tx_is_waiting == RT_TRUE)
    {
        tx_is_waiting = RT_FALSE;
        rt_sem_release(&tx_wait);
    }
}

void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
    rt_err_t result;
    result = eth_device_ready(&(stm32_eth_device.parent));
S
SummerGift 已提交
404 405
    if (result != RT_EOK)
        LOG_E("RX err = %d", result);
406 407 408 409
}

void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
{
S
SummerGift 已提交
410
    LOG_E("eth err");
411 412 413 414 415 416 417 418
}

static uint8_t phy_speed = 0;
#define PHY_LINK_MASK       (1<<0)
static void phy_monitor_thread_entry(void *parameter)
{
    uint8_t phy_addr = 0xFF;
    uint8_t phy_speed_new = 0;
S
SummerGift 已提交
419
    rt_uint32_t status = 0;
420 421 422

    /* phy search */
    rt_uint32_t i, temp;
S
SummerGift 已提交
423
    for (i = 0; i <= 0x1F; i++)
424
    {
S
SummerGift 已提交
425
        EthHandle.Init.PhyAddress = i;
426

S
SummerGift 已提交
427 428
        HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ID1_REG, (uint32_t *)&temp);

429
        if (temp != 0xFFFF && temp != 0x00)
430 431 432 433 434 435
        {
            phy_addr = i;
            break;
        }
    }

S
SummerGift 已提交
436
    if (phy_addr == 0xFF)
437
    {
S
SummerGift 已提交
438
        LOG_E("phy not probe!\r\n");
439 440 441 442 443 444 445 446 447
        return;
    }
    else
    {
        LOG_D("found a phy, address:0x%02X\r\n", phy_addr);
    }

    /* RESET PHY */
    LOG_D("RESET PHY!");
S
SummerGift 已提交
448 449 450
    HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_RESET_MASK);
    rt_thread_mdelay(2000);
    HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_AUTO_NEGOTIATION_MASK);
451

S
SummerGift 已提交
452
    while (1)
453
    {
S
SummerGift 已提交
454 455
        HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BASIC_STATUS_REG, (uint32_t *)&status);
        LOG_D("PHY BASIC STATUS REG:0x%04X\r\n", status);
456 457 458

        phy_speed_new = 0;

S
SummerGift 已提交
459
        if (status & (PHY_AUTONEGO_COMPLETE_MASK | PHY_LINKED_STATUS_MASK))
460 461 462 463 464
        {
            rt_uint32_t SR;

            phy_speed_new = PHY_LINK_MASK;

S
SummerGift 已提交
465 466 467 468
            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)
469 470 471
            {
                phy_speed_new |= PHY_100M_MASK;
            }
S
SummerGift 已提交
472 473 474 475
            else if (SR & PHY_10M_MASK)
            {
                phy_speed_new |= PHY_10M_MASK;
            }
476

S
SummerGift 已提交
477
            if (SR & PHY_FULL_DUPLEX_MASK)
478
            {
S
SummerGift 已提交
479
                phy_speed_new |= PHY_FULL_DUPLEX_MASK;
480 481 482 483
            }
        }

        /* linkchange */
S
SummerGift 已提交
484
        if (phy_speed_new != phy_speed)
485
        {
S
SummerGift 已提交
486
            if (phy_speed_new & PHY_LINK_MASK)
487 488 489
            {
                LOG_D("link up ");

S
SummerGift 已提交
490
                if (phy_speed_new & PHY_100M_MASK)
491 492 493 494 495 496 497 498 499 500
                {
                    LOG_D("100Mbps");
                    stm32_eth_device.ETH_Speed = ETH_SPEED_100M;
                }
                else
                {
                    stm32_eth_device.ETH_Speed = ETH_SPEED_10M;
                    LOG_D("10Mbps");
                }

S
SummerGift 已提交
501
                if (phy_speed_new & PHY_FULL_DUPLEX_MASK)
502 503 504 505 506 507 508 509 510 511
                {
                    LOG_D("full-duplex");
                    stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX;
                }
                else
                {
                    LOG_D("half-duplex");
                    stm32_eth_device.ETH_Mode = ETH_MODE_HALFDUPLEX;
                }

512 513 514
                /* send link up. */
                eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE);

515 516 517
            } /* link up. */
            else
            {
S
SummerGift 已提交
518
                LOG_I("link down\r\n");
519 520
                /* send link down. */
                eth_device_linkchange(&stm32_eth_device.parent, RT_FALSE);
S
SummerGift 已提交
521
            }
522
            phy_speed = phy_speed_new;
S
SummerGift 已提交
523
        }
524 525

        rt_thread_delay(RT_TICK_PER_SECOND);
S
SummerGift 已提交
526
    }
527 528 529 530 531
}

/* Register the EMAC device */
static int rt_hw_stm32_eth_init(void)
{
S
SummerGift 已提交
532 533
    rt_err_t state = RT_EOK;

534 535 536 537 538
    /* Prepare receive and send buffers */
    Rx_Buff = (rt_uint8_t *)rt_calloc(ETH_RXBUFNB, ETH_MAX_PACKET_SIZE);
    if (Rx_Buff == RT_NULL)
    {
        LOG_E("No memory");
S
SummerGift 已提交
539
        state = -RT_ENOMEM;
S
SummerGift 已提交
540
        goto __exit;
541
    }
S
SummerGift 已提交
542

543 544 545 546
    Tx_Buff = (rt_uint8_t *)rt_calloc(ETH_TXBUFNB, ETH_MAX_PACKET_SIZE);
    if (Rx_Buff == RT_NULL)
    {
        LOG_E("No memory");
S
SummerGift 已提交
547
        state = -RT_ENOMEM;
S
SummerGift 已提交
548
        goto __exit;
549
    }
S
SummerGift 已提交
550 551

    DMARxDscrTab = (ETH_DMADescTypeDef *)rt_calloc(ETH_RXBUFNB, sizeof(ETH_DMADescTypeDef));
552 553 554
    if (DMARxDscrTab == RT_NULL)
    {
        LOG_E("No memory");
S
SummerGift 已提交
555
        state = -RT_ENOMEM;
S
SummerGift 已提交
556
        goto __exit;
557
    }
S
SummerGift 已提交
558 559

    DMATxDscrTab = (ETH_DMADescTypeDef *)rt_calloc(ETH_TXBUFNB, sizeof(ETH_DMADescTypeDef));
560 561 562
    if (DMATxDscrTab == RT_NULL)
    {
        LOG_E("No memory");
S
SummerGift 已提交
563
        state = -RT_ENOMEM;
S
SummerGift 已提交
564
        goto __exit;
565 566 567 568 569 570 571 572 573 574
    }

    stm32_eth_device.ETH_Speed = ETH_SPEED_100M;
    stm32_eth_device.ETH_Mode  = ETH_MODE_FULLDUPLEX;

    /* OUI 00-80-E1 STMICROELECTRONICS. */
    stm32_eth_device.dev_addr[0] = 0x00;
    stm32_eth_device.dev_addr[1] = 0x80;
    stm32_eth_device.dev_addr[2] = 0xE1;
    /* generate MAC addr from 96bit unique ID (only for test). */
S
SummerGift 已提交
575 576 577
    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[5] = *(rt_uint8_t *)(UID_BASE + 0);
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601

    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.close      = rt_stm32_eth_close;
    stm32_eth_device.parent.parent.read       = rt_stm32_eth_read;
    stm32_eth_device.parent.parent.write      = rt_stm32_eth_write;
    stm32_eth_device.parent.parent.control    = rt_stm32_eth_control;
    stm32_eth_device.parent.parent.user_data  = RT_NULL;

    stm32_eth_device.parent.eth_rx     = rt_stm32_eth_rx;
    stm32_eth_device.parent.eth_tx     = rt_stm32_eth_tx;

    /* init tx semaphore */
    rt_sem_init(&tx_wait, "tx_wait", 0, RT_IPC_FLAG_FIFO);
    LOG_D("initialize tx wait semaphore");

    /* register eth device */
    state = eth_device_init(&(stm32_eth_device.parent), "e0");
    if (RT_EOK == state)
    {
        LOG_D("emac device init success");
    }
    else
    {
S
SummerGift 已提交
602
        LOG_E("emac device init faild: %d", state);
S
SummerGift 已提交
603 604
        state = -RT_ERROR;
        goto __exit;
605
    }
S
SummerGift 已提交
606

607 608 609 610 611 612 613 614 615 616
    /* start phy monitor */
    rt_thread_t tid;
    tid = rt_thread_create("phy",
                           phy_monitor_thread_entry,
                           RT_NULL,
                           1024,
                           RT_THREAD_PRIORITY_MAX - 2,
                           2);
    if (tid != RT_NULL)
    {
S
SummerGift 已提交
617
        rt_thread_startup(tid);
618
    }
S
SummerGift 已提交
619 620 621 622
    else
    {
        state = -RT_ERROR;
    }
S
SummerGift 已提交
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
__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);
        }
    }

647 648 649
    return state;
}
INIT_APP_EXPORT(rt_hw_stm32_eth_init);