123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733 |
- /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-1-20 bluebear233 first version
- */
- #include <rtthread.h>
- #ifdef RT_USING_LWIP
- #include "NuMicro.h"
- #include "drv_emac.h"
- #include <netif/ethernetif.h>
- #include <netif/etharp.h>
- #include <lwip/icmp.h>
- #include "lwipopts.h"
- #define ETH_DEBUG
- //#define ETH_RX_DUMP
- //#define ETH_TX_DUMP
- #ifdef ETH_DEBUG
- #define ETH_TRACE rt_kprintf
- #else
- #define ETH_TRACE(...)
- #endif /* ETH_DEBUG */
- #if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
- static void packet_dump(const char * msg, const struct pbuf* p)
- {
- rt_uint32_t i;
- rt_uint8_t *ptr = p->payload;
- ETH_TRACE("%s %d byte\n", msg, p->tot_len);
- for(i=0; i<p->tot_len; i++)
- {
- if( (i%8) == 0 )
- {
- ETH_TRACE(" ");
- }
- if( (i%16) == 0 )
- {
- ETH_TRACE("\r\n");
- }
- ETH_TRACE("%02x ",*ptr);
- ptr++;
- }
- ETH_TRACE("\n\n");
- }
- #endif /* dump */
- #define ETH_TRIGGER_RX() EMAC->RXST = 0
- #define ETH_TRIGGER_TX() EMAC->TXST = 0
- #define ETH_ENABLE_TX() EMAC->CTL |= EMAC_CTL_TXON
- #define ETH_ENABLE_RX() EMAC->CTL |= EMAC_CTL_RXON
- #define ETH_DISABLE_TX() EMAC->CTL &= ~EMAC_CTL_TXON
- #define ETH_DISABLE_RX() EMAC->CTL &= ~EMAC_CTL_RXON
- #define EMAC_DMARXDESC_CRCEIF_Msk (1ul << 17)
- #define ETH_TID_STACK 256
- static rt_uint8_t volatile phy_speed = 0;
- static rt_uint8_t eth_addr[6];
- static struct eth_device eth;
- static struct rt_semaphore eth_sem;
- static struct rt_thread eth_tid;
- static rt_uint32_t eth_stack[ETH_TID_STACK / 4];
- static struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
- static struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
- static struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
- static rt_uint32_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
- static rt_uint32_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
- static void mdio_write(rt_uint8_t addr, rt_uint8_t reg, rt_uint16_t val)
- {
- EMAC->MIIMDAT = val;
- EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
- while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
- }
- static rt_uint16_t mdio_read(rt_uint8_t addr, rt_uint8_t reg)
- {
- EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
- while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
- return EMAC->MIIMDAT;
- }
- static void init_tx_desc(void)
- {
- rt_uint32_t i;
- cur_tx_desc_ptr = fin_tx_desc_ptr = &tx_desc[0];
- for(i = 0; i < TX_DESCRIPTOR_NUM; i++)
- {
- tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN;
- tx_desc[i].buf = (rt_uint8_t*)tx_buf[i];
- tx_desc[i].status2 = 0;
- tx_desc[i].next = &tx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
- }
- EMAC->TXDSA = (unsigned int)&tx_desc[0];
- return;
- }
- static void init_rx_desc(void)
- {
- rt_uint32_t i;
- cur_rx_desc_ptr = &rx_desc[0];
- for(i = 0; i < RX_DESCRIPTOR_NUM; i++)
- {
- rx_desc[i].status1 = OWNERSHIP_EMAC;
- rx_desc[i].buf = (rt_uint8_t*)rx_buf[i];
- rx_desc[i].status2 = 0;
- rx_desc[i].next = &rx_desc[(i + 1) % RX_DESCRIPTOR_NUM];
- }
- EMAC->RXDSA = (unsigned int)&rx_desc[0];
- return;
- }
- static void add_mac_addr(const rt_uint8_t *addr)
- {
- rt_uint32_t *EMAC_CAMxM;
- rt_uint32_t *EMAC_CAMxL;
- rt_uint8_t index = 0;
- rt_uint8_t mac[6];
- for(; index < 13; index ++)
- {
- EMAC_CAMxM = (rt_uint32_t *)((rt_uint32_t)&EMAC->CAM0M + (index * 8));
- EMAC_CAMxL = (rt_uint32_t *)((rt_uint32_t)&EMAC->CAM0L + (index * 8));
- mac[0] = (*EMAC_CAMxM >> 24) & 0xff;
- mac[1] = (*EMAC_CAMxM >> 16) & 0xff;
- mac[2] = (*EMAC_CAMxM >> 8) & 0xff;
- mac[3] = (*EMAC_CAMxM) & 0xff;
- mac[4] = (*EMAC_CAMxL >> 24) & 0xff;
- mac[5] = (*EMAC_CAMxL >> 16) & 0xff;
- if(memcmp(mac, addr, sizeof(mac)) == 0)
- {
- return;
- }
- if(*EMAC_CAMxM == 0 && *EMAC_CAMxL == 0)
- {
- break;
- }
- }
- RT_ASSERT(index < 13)
- *EMAC_CAMxM = (addr[0] << 24) |
- (addr[1] << 16) |
- (addr[2] << 8) |
- addr[3];
- *EMAC_CAMxL = (addr[4] << 24) |
- (addr[5] << 16);
- EMAC->CAMEN |= (1 << index);
- }
- void EMAC_init()
- {
- // Reset MAC
- EMAC->CTL = EMAC_CTL_RST_Msk;
- while(EMAC->CTL & EMAC_CTL_RST_Msk);
- init_tx_desc();
- init_rx_desc();
- EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk | EMAC_CAMCTL_ABP_Msk;
- add_mac_addr(eth_addr);
- EMAC->CTL |= EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk | EMAC_CTL_RMIIEN_Msk;
- EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
- EMAC_INTEN_RXGDIEN_Msk |
- EMAC_INTEN_RDUIEN_Msk |
- EMAC_INTEN_RXBEIEN_Msk |
- EMAC_INTEN_TXIEN_Msk |
- EMAC_INTEN_TXBEIEN_Msk;
- /* Limit the max receive frame length to 1514 + 4 */
- EMAC->MRFL = PACKET_BUFFER_SIZE;
- EMAC->RXST = 0; // trigger Rx
- }
- void EMAC_Reinit(void)
- {
- rt_uint32_t EMAC_CAMxM[13];
- rt_uint32_t EMAC_CAMxL[13];
- rt_uint32_t EMAC_CAMEN;
- EMAC_CAMEN = EMAC->CAMEN;
- for(rt_uint8_t index = 0 ; index < 13; index ++)
- {
- rt_uint32_t *CAMxM = (rt_uint32_t *)((rt_uint32_t)&EMAC->CAM0M + (index * 8));
- rt_uint32_t *CAMxL = (rt_uint32_t *)((rt_uint32_t)&EMAC->CAM0L + (index * 8));
- EMAC_CAMxM[index] = *CAMxM;
- EMAC_CAMxL[index] = *CAMxL;
- }
- EMAC_init();
- for(rt_uint8_t index = 0 ; index < 13; index ++)
- {
- rt_uint32_t *CAMxM = (rt_uint32_t *)((rt_uint32_t)&EMAC->CAM0M + (index * 8));
- rt_uint32_t *CAMxL = (rt_uint32_t *)((rt_uint32_t)&EMAC->CAM0L + (index * 8));
- *CAMxM = EMAC_CAMxM[index];
- *CAMxL = EMAC_CAMxL[index];
- }
- EMAC->CAMEN = EMAC_CAMEN;
- phy_speed = 0;
- }
- void ETH_halt(void)
- {
- EMAC->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk);
- }
- __inline static rt_uint8_t *emac_get_tx_buf(void)
- {
- if(cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC)
- {
- return(RT_NULL);
- }
- else
- {
- return(cur_tx_desc_ptr->buf);
- }
- }
- __inline static void ETH_trigger_tx(rt_uint16_t length)
- {
- struct eth_descriptor volatile *desc;
-
- cur_tx_desc_ptr->status2 = (unsigned int)length;
- desc = cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr
- cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC;
- cur_tx_desc_ptr = desc;
- }
- #if LWIP_IPV4 && LWIP_IGMP
- static err_t igmp_mac_filter( struct netif *netif, const ip4_addr_t *ip4_addr, u8_t action )
- {
- rt_uint8_t mac[6];
- const uint8_t *p = (const uint8_t *)ip4_addr;
- mac[0] = 0x01;
- mac[1] = 0x00;
- mac[2] = 0x5E;
- mac[3] = *(p+1) & 0x7F;
- mac[4] = *(p+2);
- mac[5] = *(p+3);
- add_mac_addr(mac);
- if(1)
- {
- rt_kprintf("%s %s %s ", __FUNCTION__, (action==NETIF_ADD_MAC_FILTER)?"add":"del", ip4addr_ntoa(ip4_addr));
- rt_kprintf("%02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- }
- return 0;
- }
- #endif /* LWIP_IPV4 && LWIP_IGMP */
- /*
- * M480 EMAC Driver for RT-Thread
- * Change Logs:
- * Date Author Notes
- * 2017-12-31 Bluebear233 first implementation
- */
- void EMAC_RX_IRQHandler(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
-
- unsigned int status = EMAC->INTSTS;
- if(status & EMAC_INTSTS_RDUIF_Msk)
- {
- EMAC->INTEN &= ~(EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk);
- eth_device_ready(ð);
- }
- else if(status & EMAC_INTSTS_RXGDIF_Msk)
- {
- EMAC->INTEN &= ~EMAC_INTEN_RXGDIEN_Msk;
- eth_device_ready(ð);
- }
- if(status & EMAC_INTSTS_RXBEIF_Msk)
- {
- ETH_TRACE("Reinit Rx EMAC\n");
- EMAC->INTSTS = EMAC_INTSTS_RXBEIF_Msk;
- EMAC_Reinit();
- }
- /* leave interrupt */
- rt_interrupt_leave();
- }
- void EMAC_TX_IRQHandler(void)
- {
- rt_interrupt_enter();
- unsigned int status = EMAC->INTSTS;
- if(status & EMAC_INTSTS_TXCPIF_Msk)
- {
- EMAC->INTEN &= ~EMAC_INTEN_TXCPIEN_Msk;
- rt_sem_release(ð_sem);
- }
- if(status & EMAC_INTSTS_TXBEIF_Msk)
- {
- ETH_TRACE("Reinit Tx EMAC\n");
- EMAC->INTSTS = EMAC_INTSTS_TXBEIF_Msk;
- EMAC_Reinit();
- }
- rt_interrupt_leave();
- }
- #define PHY_LINK_MASK (1<<0)
- #define PHY_10FULL_MASK (1<<1)
- #define PHY_100FULL_MASK (1<<2)
- #define PHY_10HALF_MASK (1<<3)
- #define PHY_100HALF_MASK (1<<4)
- #define PHY_ANLPA_DR100_TX_FULL (1UL << 8UL)
- #define PHY_ANLPA_DR100_TX_HALF (1UL << 7UL)
- #define PHY_ANLPA_DR10_TX_FULL (1UL << 6UL)
- #define PHY_ANLPA_DR10_TX_HALF (1UL << 5UL)
- void eth_entry(void *param)
- {
- uint8_t phy_addr = 0xFF;
- uint8_t phy_speed_new = 0;
- /* phy search */
- {
- rt_uint32_t i;
- rt_uint16_t temp;
- for(i=0; i<=0x1F; i++)
- {
- temp = mdio_read(i, 0x02);
- if( temp != 0xFFFF )
- {
- phy_addr = i;
- break;
- }
- }
- } /* phy search */
- if(phy_addr == 0xFF)
- {
- ETH_TRACE("phy not probe!\n");
- return;
- }
- else
- {
- ETH_TRACE("found a phy, address:0x%02X\n", phy_addr);
- }
- /* RESET PHY */
- mdio_write(phy_addr, MII_BMCR, BMCR_RESET);
- while (1)
- {
- rt_thread_delay(RT_TICK_PER_SECOND);
- rt_uint16_t reg = mdio_read(phy_addr, MII_BMCR);
- if ((reg & BMCR_RESET) == 0)
- {
- break;
- }
- }
- mdio_write(phy_addr, MII_ADVERTISE, ADVERTISE_CSMA |
- ADVERTISE_10HALF |
- ADVERTISE_10FULL |
- ADVERTISE_100HALF |
- ADVERTISE_100FULL);
- {
- uint16_t reg = mdio_read(phy_addr, MII_BMCR);
- mdio_write(phy_addr, MII_BMCR, reg | BMCR_ANRESTART);
- }
- while(1)
- {
- uint16_t status = mdio_read(phy_addr, MII_BMSR);
- phy_speed_new = 0;
- if((status & (BMSR_ANEGCAPABLE | BMSR_LSTATUS)) == (BMSR_ANEGCAPABLE | BMSR_LSTATUS))
- {
- phy_speed_new = PHY_LINK_MASK;
- status = mdio_read(phy_addr, MII_LPA);
- if(status & PHY_ANLPA_DR100_TX_FULL)
- {
- phy_speed_new |= PHY_100FULL_MASK;
- }
- else if(status & PHY_ANLPA_DR100_TX_HALF)
- {
- phy_speed_new |= PHY_100HALF_MASK;
- }
- else if(status & PHY_ANLPA_DR10_TX_FULL)
- {
- phy_speed_new |= PHY_10FULL_MASK;
- }
- else if(status & PHY_ANLPA_DR10_TX_HALF)
- {
- phy_speed_new |= PHY_10HALF_MASK;
- }
- }
- /* linkchange */
- if(phy_speed_new != phy_speed)
- {
- if(phy_speed_new & PHY_LINK_MASK)
- {
- ETH_TRACE("link up ");
- if(phy_speed_new & PHY_100FULL_MASK)
- {
- ETH_TRACE("100Mbps full-duplex\n");
- EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- }
- else if(phy_speed_new & PHY_100HALF_MASK)
- {
- ETH_TRACE("100Mbps half-duplex\n");
- EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
- }
- else if(phy_speed_new & PHY_10FULL_MASK)
- {
- ETH_TRACE("10Mbps full-duplex\n");
- EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
- }
- else
- {
- ETH_TRACE("10Mbps half-duplex\n");
- EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- }
- /* send link up. */
- eth_device_linkchange(ð, RT_TRUE);
- } /* link up. */
- else
- {
- ETH_TRACE("link down\r\n");
- /* send link down. */
- eth_device_linkchange(ð, RT_FALSE);
- } /* link down. */
- phy_speed = phy_speed_new;
- } /* linkchange */
- rt_thread_delay(RT_TICK_PER_SECOND);
- } /* while(1) */
- }
- static rt_err_t rt_m480_emac_init(rt_device_t dev)
- {
- /* Unlock protected registers */
- SYS_UnlockReg();
- CLK_EnableModuleClock(EMAC_MODULE);
- // Configure MDC clock rate to HCLK / (127 + 1) = 1.5 MHz if system is running at 192 MHz
- CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
- // Configure RMII pins
- // SYS->GPA_MFPL |= SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
- SYS->GPA_MFPL |= SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
- SYS->GPC_MFPL |= SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
- SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
- SYS->GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
- SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
- SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
- SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
- SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN;
- // Enable high slew rate on all RMII TX output pins
- PE->SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos) |
- (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN11_Pos) |
- (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN12_Pos);
- /* Lock protected registers */
- SYS_LockReg();
- EMAC_init();
- NVIC_SetPriority(EMAC_TX_IRQn, 1);
- NVIC_EnableIRQ(EMAC_TX_IRQn);
- NVIC_SetPriority(EMAC_RX_IRQn, 1);
- NVIC_EnableIRQ(EMAC_RX_IRQn);
- rt_sem_init(ð_sem, "eth_sem", 0, RT_IPC_FLAG_FIFO);
- rt_thread_init(ð_tid, "eth", eth_entry, RT_NULL, eth_stack, sizeof(eth_stack), RT_THREAD_PRIORITY_MAX - 2, 10);
- rt_thread_startup(ð_tid);
- #if LWIP_IPV4 && LWIP_IGMP
- netif_set_igmp_mac_filter(eth.netif, igmp_mac_filter);
- #endif /* LWIP_IPV4 && LWIP_IGMP */
-
- return RT_EOK;
- }
- static rt_err_t rt_m480_emac_open(rt_device_t dev, rt_uint16_t oflag)
- {
- return RT_EOK;
- }
- static rt_err_t rt_m480_emac_close(rt_device_t dev)
- {
- return RT_EOK;
- }
- static rt_size_t rt_m480_emac_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
- {
- rt_set_errno(-RT_ENOSYS);
- return 0;
- }
- static rt_size_t rt_m480_emac_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
- {
- rt_set_errno(-RT_ENOSYS);
- return 0;
- }
- static rt_err_t rt_m480_emac_control(rt_device_t dev, int cmd, void *args)
- {
- switch(cmd)
- {
- case NIOCTL_GADDR:
- /* get mac address */
- if(args) rt_memcpy(args, eth_addr, 6);
- else return -RT_ERROR;
- break;
- default :
- break;
- }
- return RT_EOK;
- }
- rt_err_t rt_m480_emac_tx(rt_device_t dev, struct pbuf* p)
- {
- struct pbuf* q;
- rt_uint32_t offset;
- rt_uint8_t *buf;
- buf = emac_get_tx_buf();
- /* get free tx buffer */
- if(buf == RT_NULL)
- {
- rt_sem_control(ð_sem, RT_IPC_CMD_RESET, 0);
- EMAC->INTSTS = EMAC_INTSTS_TXCPIF_Msk;
- EMAC->INTEN |= EMAC_INTEN_TXCPIEN_Msk;
- do{
- rt_sem_take(ð_sem, 1);
- buf = emac_get_tx_buf();
- }while(buf == RT_NULL);
- }
- offset = 0;
- for (q = p; q != NULL; q = q->next)
- {
- rt_uint8_t* ptr;
- rt_uint32_t len;
- len = q->len;
- ptr = q->payload;
- // todo 优化复制
- memcpy(&buf[offset], ptr, len);
- offset += len;
- }
- #ifdef ETH_TX_DUMP
- packet_dump("TX dump", p);
- #endif
- ETH_trigger_tx(offset);
- if(EMAC->INTSTS & EMAC_INTSTS_TDUIF_Msk)
- {
- EMAC->INTSTS = EMAC_INTSTS_TDUIF_Msk;
- ETH_TRIGGER_TX();
- }
- /* Return SUCCESS */
- return RT_EOK;
- }
- struct pbuf *rt_m480_emac_rx(rt_device_t dev)
- {
- unsigned int status;
- struct pbuf* p;
- /* init p pointer */
- p = RT_NULL;
- start:
- status = cur_rx_desc_ptr->status1;
- if(status & OWNERSHIP_EMAC)
- {
- goto end;
- }
- if ((status & RXFD_RXGD) && !(status & EMAC_DMARXDESC_CRCEIF_Msk))
- {
- p = pbuf_alloc(PBUF_RAW, status & 0xFFFF, PBUF_RAM);
- if (p != RT_NULL)
- {
- RT_ASSERT(p->next == RT_NULL);
- const char * from = (const char *)(cur_rx_desc_ptr->buf);
- // todo 优化复制
- memcpy(p->payload, from, p->len);
- }
- }
- #ifdef ETH_RX_DUMP
- packet_dump("RX dump", p);
- #endif /* ETH_RX_DUMP */
- cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC;
- cur_rx_desc_ptr = cur_rx_desc_ptr->next;
- if(p == RT_NULL)
- {
- goto start;
- }
- return p;
-
- end:
- if(!(EMAC->INTEN & EMAC_INTEN_RDUIEN_Msk))
- {
- EMAC->INTSTS = (EMAC_INTSTS_RDUIF_Msk | EMAC_INTSTS_RXGDIF_Msk);
- EMAC->INTEN |= (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk);
- ETH_TRIGGER_RX();
- }
- else
- {
- EMAC->INTSTS = EMAC_INTSTS_RXGDIF_Msk;
- EMAC->INTEN |= EMAC_INTEN_RXGDIEN_Msk;
- }
-
- return RT_NULL;
- }
- static void rt_hw_m480_emac_register(char *dev_name)
- {
- rt_uint32_t value = 0;
- SYS_UnlockReg();
- FMC_Open();
- for (rt_uint8_t i = 0; i < 3; i++)
- {
- value += FMC_ReadUID(i);
- }
- FMC_Close();
- SYS_LockReg();
- eth_addr[0] = 0x00;
- eth_addr[1] = 0x00;
- eth_addr[2] = 0x00;
- eth_addr[3] = (value >> 16) & 0xff;
- eth_addr[4] = (value >> 8) & 0xff;
- eth_addr[5] = (value) & 0xff;
- eth.parent.init = rt_m480_emac_init;
- eth.parent.open = rt_m480_emac_open;
- eth.parent.close = rt_m480_emac_close;
- eth.parent.read = rt_m480_emac_read;
- eth.parent.write = rt_m480_emac_write;
- eth.parent.control = rt_m480_emac_control;
- eth.parent.user_data = RT_NULL;
- eth.eth_rx = rt_m480_emac_rx;
- eth.eth_tx = rt_m480_emac_tx;
- /* register eth device */
- eth_device_init(ð, dev_name);
- }
- static int rt_hw_nuc487_emac_init(void)
- {
- rt_hw_m480_emac_register("eh0");
- return RT_EOK;
- }
- INIT_APP_EXPORT(rt_hw_nuc487_emac_init);
- #endif
|