Explorar o código

add EMAC driver.

aozima %!s(int64=11) %!d(string=hai) anos
pai
achega
ff4fcd5b56

+ 1 - 1
bsp/CME_M7/CME_M7.sct

@@ -14,7 +14,7 @@ LR_IROM1 	(0)				(1024 * 128)
 	}
 
 	; RW data
-	RW_IRAM1 0x20000000 (1024 * 64)
+	RW_IRAM1 0x20000000 (1024 * 48)
 	{
 		.ANY (+RW +ZI)
 	}

+ 8 - 6
bsp/CME_M7/applications/application.c

@@ -20,6 +20,14 @@
 void rt_init_thread_entry(void* parameter)
 {
     rt_components_init();
+	
+	rt_kprintf("new");
+
+#ifdef RT_USING_LWIP
+    cme_m7_eth_init();
+
+    //set_if("e0", "192.168.3.99", "192.168.1.1", "255.255.255.0");
+#endif /* RT_USING_LWIP */
 }
 
 int rt_application_init()
@@ -39,10 +47,4 @@ int rt_application_init()
     return 0;
 }
 
-
-void NMI_Handler(void)
-{
-    rt_kprintf("NMI_Handler\n");
-}
-
 /*@}*/

+ 10 - 1
bsp/CME_M7/drivers/SConscript

@@ -3,7 +3,16 @@ Import('rtconfig')
 from building import *
 
 cwd     = os.path.join(str(Dir('#')), 'drivers')
-src	= Glob('*.c')
+
+src	= ['board.c']
+
+# add uart driver.
+src	+= ['uart.c']
+
+# add EMAC driver for Lwip.
+if GetDepend('RT_USING_LWIP') == True:
+    src += ['emac.c', 'app_phy.c']
+
 CPPPATH = [cwd]
 
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)

+ 121 - 0
bsp/CME_M7/drivers/app_phy.c

@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include "app_phy.h"
+
+#define PHY_BASE_ADDR   						0x7
+
+#define PHY_REG_CONTROL             0x0
+#define PHY_REG_STATUS              0x1
+#define PHY_REG_ANE                 0x6
+#define PHY_REG_SPEC_STATUS         0x11
+#define PHY_REG_EXTEND_STATUS				0x1B
+
+#define PHY_BIT_CONTROL_RESET           0x8000			/*!< Control reg : reset */
+#define PHY_BIT_CONTROL_ANEN            0x1000			/*!< Control reg : auto-negotiation enable */
+#define PHY_BIT_CONTROL_RSAN            0x0200			/*!< Control reg : auto-negotiation restart */
+
+#define PHY_BIT_STATUS_ANC              0x0020			/*!< Status reg : auto-negotiation complete */
+#define PHY_BIT_STATUS_LINK             0x0004			/*!< Status reg : link is up */
+
+#define PHY_BIT_ANE_LPAN                0x0001			/*!< ANE reg : link partner can auto-neg */
+
+#define PHY_BIT_SPEED                   0xC000      /*!< specific status reg : speed */
+#define PHY_BIT_DUPLEX                  0x2000      /*!< specific status reg : duplex */
+
+#define PHY_BIT_AUTO_MEDIA_DISABLE      0x8000      /*!< extended status reg : auto media select disable */
+#define PHY_BIT_AUTO_MEDIA_REG_DISABLE  0x0200      /*!< extended status reg : auto media register select disable */
+
+void phy_Reset() {
+	ETH_PhyWrite(PHY_BASE_ADDR, PHY_REG_CONTROL, PHY_BIT_CONTROL_RESET);
+
+	while (1) {
+		uint32_t ret = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_CONTROL);
+	  if ((ret & PHY_BIT_CONTROL_RESET) == 0) {
+			break;
+		} 
+	}
+}
+
+void phy_AutoMediaSelect() {
+	uint32_t data;
+
+	// auto media and auto media register selection
+	data = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_EXTEND_STATUS);
+	data &= ~PHY_BIT_AUTO_MEDIA_DISABLE;
+	data &= ~PHY_BIT_AUTO_MEDIA_REG_DISABLE;
+	ETH_PhyWrite(PHY_BASE_ADDR, PHY_REG_EXTEND_STATUS, data);
+}
+
+void phy_AutoNeg() {
+	uint32_t data;
+
+	data = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_CONTROL);
+	data |= (PHY_BIT_CONTROL_ANEN | PHY_BIT_CONTROL_RSAN);
+	ETH_PhyWrite(PHY_BASE_ADDR, PHY_REG_CONTROL, data);
+
+	while (1) {
+		uint32_t ret = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_STATUS);
+	  if ((ret & PHY_BIT_STATUS_ANC) == PHY_BIT_STATUS_ANC) {
+			break;
+		} 
+	}
+}
+
+BOOL phy_IsLink() {
+	uint32_t ret = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_STATUS);
+	return (ret & PHY_BIT_STATUS_LINK) ? TRUE : FALSE;
+}
+
+BOOL phy_PartnerCanAutoNeg() {
+	uint32_t ret = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_ANE);
+	return (ret & PHY_BIT_ANE_LPAN) ? TRUE : FALSE;
+}
+
+uint32_t phy_GetSpeed() {
+	uint32_t ret = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_SPEC_STATUS);
+	return ((ret & PHY_BIT_SPEED) >> 14);
+}
+
+uint32_t phy_GetDuplex() {
+	uint32_t ret = ETH_PhyRead(PHY_BASE_ADDR, PHY_REG_SPEC_STATUS);
+	return ((ret & PHY_BIT_DUPLEX) >> 13);
+}
+
+BOOL phy_Init() {
+	phy_AutoMediaSelect();
+	phy_AutoNeg();
+
+	if (!phy_PartnerCanAutoNeg()) {
+		printf("Warning:: PHY's partner can't do auto-negotiation\n");
+	}
+
+	if (!phy_IsLink()) {
+		printf("link is down\n");
+		return FALSE;
+	}
+
+	{
+		uint32_t speed = phy_GetSpeed();
+		if (speed == PHY_SPEED_10) {
+			speed = 10;
+		} else if (speed == PHY_SPEED_100) {
+			speed = 100;
+		} else if (speed == PHY_SPEED_1000) {
+			speed = 1000;
+		}
+
+		printf("PHY runs in %dM speed %s duplex\n",
+			speed, (phy_GetDuplex() == PHY_DUPLEX_HALF) ? "half" : "full");
+	}
+		
+	// After auto-negcioation, Mawell PHY need some
+	// time to initial itself.
+	// So we have to delay some time since different 		
+	// connection way, such as direct wire, hub, switch.
+	// If not to delay, the first several sent frame 
+	// may be lost.
+	// Please according to actual environment to tune
+	// this delay.
+	udelay(200000);
+
+	return TRUE;
+}

+ 32 - 0
bsp/CME_M7/drivers/app_phy.h

@@ -0,0 +1,32 @@
+#ifndef __APP_PHY_H
+#define __APP_PHY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "cmem7_includes.h"
+
+#define PHY_SPEED_10           			0x0         /*!< SPEED : 10M  */
+#define PHY_SPEED_100          			0x1         /*!< SPEED : 100M  */
+#define PHY_SPEED_1000         			0x2         /*!< SPEED : 1000M  */
+	 
+#define PHY_DUPLEX_HALF        			0x0         /*!< DUPLEX : half  */
+#define PHY_DUPLEX_FULL        			0x1         /*!< DUPLEX : full  */
+	 
+void phy_Reset(void);
+void phy_AutoNeg(void);
+BOOL phy_IsLink(void);
+BOOL phy_PartnerCanAutoNeg(void);
+uint32_t phy_GetSpeed(void);
+uint32_t phy_GetDuplex(void);
+BOOL phy_Init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
+
+
+

+ 4 - 1
bsp/CME_M7/drivers/board.c

@@ -49,7 +49,10 @@ static void idle_hook(void)
  */
 void rt_hw_board_init()
 {
-    rt_thread_idle_sethook(idle_hook);
+    //rt_thread_idle_sethook(idle_hook);
+
+    /* Configure the NVIC Preemption Priority Bits */
+    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
 
     SysTick_Config(SYSTEM_CLOCK_FREQ / RT_TICK_PER_SECOND);
 

+ 457 - 0
bsp/CME_M7/drivers/emac.c

@@ -0,0 +1,457 @@
+/*
+ * File      : emac.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006-2014, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2014-08-29     aozima       first implementation
+ */
+
+#include <rtthread.h>
+#include <netif/ethernetif.h>
+#include "lwipopts.h"
+
+#include "board.h"
+
+#include "app_phy.h"
+//#include "app_bufferpool.h"
+//#include "app_bufferqueue.h"
+
+/* debug option */
+#define ETH_DEBUG
+//#define ETH_RX_DUMP
+//#define ETH_TX_DUMP
+
+#ifdef ETH_DEBUG
+#define CME_ETH_PRINTF          rt_kprintf
+#else
+#define CME_ETH_PRINTF(...)
+#endif
+
+#define MAX_ADDR_LEN 6
+struct rt_cme_eth
+{
+    /* inherit from ethernet device */
+    struct eth_device parent;
+
+    /* interface address info. */
+    rt_uint8_t  dev_addr[MAX_ADDR_LEN];			/* hw address	*/
+
+    uint32_t    ETH_Speed;
+    uint32_t    ETH_Mode;
+
+    struct rt_semaphore tx_buf_free;
+    struct rt_mutex     lock;
+};
+static struct rt_cme_eth cme_eth_device;
+
+#if defined(ETH_RX_DUMP) ||  defined(ETH_TX_DUMP)
+static void packet_dump(const char * msg, const struct pbuf* p)
+{
+    const struct pbuf* q;
+    rt_uint32_t i,j;
+    rt_uint8_t *ptr;
+
+    rt_kprintf("%s %d byte\n", msg, p->tot_len);
+
+    i=0;
+    for(q=p; q != RT_NULL; q= q->next)
+    {
+        ptr = q->payload;
+
+        for(j=0; j<q->len; j++)
+        {
+            if( (i%8) == 0 )
+            {
+                rt_kprintf("  ");
+            }
+            if( (i%16) == 0 )
+            {
+                rt_kprintf("\r\n");
+            }
+            rt_kprintf("%02x ",*ptr);
+
+            i++;
+            ptr++;
+        }
+    }
+
+    rt_kprintf("\n\n");
+}
+#else
+#define packet_dump(...)
+#endif /* dump */
+
+/////////////////////////////////////////////////////////////////
+uint32_t rxTotalMemory = 0x2000;
+uint32_t rxDescNum = 3;
+uint32_t rxBufSize = 0x400;
+uint32_t rxBaseAddr = 0x2000C000;// C000-48K
+uint32_t txBaseAddr = 0x2000E000;// E000-56K
+uint32_t txTotalMemory = 0x2000;
+BOOL isRxNoBuf = FALSE;
+
+#define ETH_MAX_PACKET_SIZE    1520    /* ETH_HEADER + ETH_EXTRA + MAX_ETH_PAYLOAD + ETH_CRC */
+#define ETH_RXBUFNB        	4
+#define ETH_TXBUFNB        	2
+
+struct eth_rx_buffer
+{
+    ETH_RX_DESC desc;
+    uint32_t buffer[ETH_MAX_PACKET_SIZE/4];
+};
+
+struct eth_tx_buffer
+{
+    ETH_TX_DESC desc;
+    uint32_t buffer[ETH_MAX_PACKET_SIZE/4];
+};
+
+static struct eth_rx_buffer rx_buffer[ETH_RXBUFNB];
+static struct eth_tx_buffer tx_buffer[ETH_TXBUFNB];
+
+static void RxDescChainInit(void)
+{
+    uint32_t i;
+
+    // initialize rx descriptor
+    ETH_RX_DESC *desc = &rx_buffer[0].desc;
+
+    for (i = 0; i < ETH_RXBUFNB; i++)
+    {
+        desc->RX_1.RX1_b.SIZE = ETH_MAX_PACKET_SIZE;
+        desc->bufAddr = (uint32_t)rx_buffer[i].buffer;
+
+        if((i+1) == ETH_RXBUFNB)
+            desc->nextDescAddr = (uint32_t)&rx_buffer[0].desc;
+        else
+            desc->nextDescAddr = (uint32_t)&rx_buffer[i+1].desc;
+
+        desc = (ETH_RX_DESC *)desc->nextDescAddr;
+    }
+
+    ETH_SetRxDescRing(&rx_buffer[0].desc);
+}
+
+static void TxDescChainInit(void)
+{
+    uint32_t i;
+
+    // initialize tx descriptor
+    ETH_TX_DESC *desc = &tx_buffer[0].desc;
+
+    for (i = 0; i < ETH_TXBUFNB; i++)
+    {
+        desc->TX_1.TX1_b.SIZE = ETH_MAX_PACKET_SIZE;
+        desc->bufAddr = (uint32_t)tx_buffer[i].buffer;
+
+        if((i+1) == ETH_TXBUFNB)
+            desc->nextDescAddr = (uint32_t)&tx_buffer[0].desc;
+        else
+            desc->nextDescAddr = (uint32_t)&tx_buffer[i+1].desc;
+
+        desc = (ETH_TX_DESC *)desc->nextDescAddr;
+    }
+
+    ETH_SetTxDescRing(&tx_buffer[0].desc);
+}
+
+/////////////////////////////////////////////////////////////////
+
+/* initialize the interface */
+static rt_err_t rt_cme_eth_init(rt_device_t dev)
+{
+    struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
+
+    ETH_InitTypeDef init;
+    ETH_FrameFilter flt;
+
+    init.ETH_Speed = phy_GetSpeed();
+    init.ETH_Duplex = phy_GetDuplex();
+    init.ETH_LinkUp = phy_IsLink();
+    init.ETH_RxEn = TRUE;
+    init.ETH_TxEn = TRUE;
+    init.ETH_ChecksumOffload = FALSE;
+    init.ETH_JumboFrame = FALSE;
+
+    memcpy(init.ETH_MacAddr, cme_eth->dev_addr, sizeof(init.ETH_MacAddr));
+//    init.ETH_MacAddr[0] = 0x00;
+//    init.ETH_MacAddr[1] = 0x1E;
+//    init.ETH_MacAddr[2] = 0xC9;
+//    init.ETH_MacAddr[3] = 0x3B;
+//    init.ETH_MacAddr[4] = 0x11;
+//    init.ETH_MacAddr[5] = 0xF8;
+
+    // Disable broadcast;
+    flt.ETH_BroadcastFilterEnable = FALSE;
+    flt.ETH_OwnFilterEnable = FALSE;
+    flt.ETH_SelfDrop = FALSE;
+    flt.ETH_SourceFilterEnable = FALSE;
+    flt.ETH_SourceDrop = FALSE;
+
+    flt.ETH_SourceMacAddr[0] = 0x00;
+    flt.ETH_SourceMacAddr[1] = 0x1E;
+    flt.ETH_SourceMacAddr[2] = 0xC9;
+    flt.ETH_SourceMacAddr[3] = 0x3B;
+    flt.ETH_SourceMacAddr[4] = 0x11;
+    flt.ETH_SourceMacAddr[5] = 0xF9;
+
+    init.ETH_Filter = &flt;
+
+    if (!phy_Init())
+    {
+        rt_kprintf("phy_Init failed!\n");
+        while (1);
+    }
+
+    if (!ETH_Init(&init))
+    {
+        rt_kprintf("ETH_Init failed!\n");
+        while (1);
+    }
+
+    RxDescChainInit();
+    TxDescChainInit();
+
+    ETH_EnableInt(ETH_INT_BUS_FATAL_ERROR, TRUE);
+
+    ETH_EnableInt(ETH_INT_RX_COMPLETE_FRAME, TRUE);
+    ETH_EnableInt(ETH_INT_RX_BUF_UNAVAI, TRUE);
+    ETH_EnableInt(ETH_INT_RX_STOP, TRUE);
+    ETH_StartRx();
+
+    ETH_EnableInt(ETH_INT_TX_COMPLETE_FRAME, TRUE);
+    ETH_StartTx();
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_cme_eth_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t rt_cme_eth_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_size_t rt_cme_eth_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_cme_eth_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_cme_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+    switch(cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get mac address */
+        if(args) rt_memcpy(args, cme_eth_device.dev_addr, 6);
+        else return -RT_ERROR;
+        break;
+
+    default :
+        break;
+    }
+
+    return RT_EOK;
+}
+
+/* ethernet device interface */
+/* transmit packet. */
+rt_err_t rt_cme_eth_tx( rt_device_t dev, struct pbuf* p)
+{
+    rt_err_t result = RT_EOK;
+    ETH_TX_DESC *desc;
+    struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
+
+    rt_mutex_take(&cme_eth->lock, RT_WAITING_FOREVER);
+
+#ifdef ETH_TX_DUMP
+    packet_dump("TX dump", p);
+#endif /* ETH_TX_DUMP */
+
+    /* get free tx buffer */
+    {
+        rt_err_t result;
+        result = rt_sem_take(&cme_eth->tx_buf_free, RT_TICK_PER_SECOND/10);
+        if (result != RT_EOK)
+        {
+            result = -RT_ERROR;
+            goto _exit;
+        }
+    }
+
+    desc = ETH_AcquireFreeTxDesc();
+    if(desc == RT_NULL)
+    {
+        CME_ETH_PRINTF("TxDesc not ready!\n");
+        RT_ASSERT(0);
+            result = -RT_ERROR;
+            goto _exit;
+    }
+
+    desc->TX_0.TX0_b.FS = TRUE;
+    desc->TX_0.TX0_b.LS = TRUE;
+    desc->TX_1.TX1_b.SIZE = p->tot_len;
+
+    pbuf_copy_partial(p, ( void *)(desc->bufAddr), p->tot_len, 0);
+
+    ETH_ReleaseTxDesc(desc);
+    ETH_ResumeTx();
+
+_exit:
+    rt_mutex_release(&cme_eth->lock);
+    return result;
+}
+
+/* reception packet. */
+struct pbuf *rt_cme_eth_rx(rt_device_t dev)
+{
+    struct pbuf* p = RT_NULL;
+    ETH_RX_DESC *desc;
+    uint32_t framelength;
+    struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
+
+    rt_mutex_take(&cme_eth->lock, RT_WAITING_FOREVER);
+
+    desc = ETH_AcquireFreeRxDesc();
+    if(desc == RT_NULL)
+    {
+        ETH_EnableInt(ETH_INT_RX_COMPLETE_FRAME, TRUE);
+        ETH_EnableInt(ETH_INT_RX_BUF_UNAVAI, TRUE);
+        ETH_ResumeRx();
+        goto _exit;
+    }
+
+    framelength = desc->RX_0.RX0_b.FL;
+
+    /* allocate buffer */
+    p = pbuf_alloc(PBUF_LINK, framelength, PBUF_RAM);
+    if (p != RT_NULL)
+    {
+        pbuf_take(p, (const void *)(desc->bufAddr), framelength);
+#ifdef ETH_RX_DUMP
+        packet_dump("RX dump", p);
+#endif /* ETH_RX_DUMP */
+    }
+
+    ETH_ReleaseRxDesc(desc);
+
+_exit:
+    rt_mutex_release(&cme_eth->lock);
+    return p;
+}
+
+static void NVIC_Configuration(void)
+{
+    NVIC_InitTypeDef NVIC_InitStructure;
+
+    /* Enable the USARTy Interrupt */
+    NVIC_InitStructure.NVIC_IRQChannel = ETH_INT_IRQn;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE;
+    NVIC_Init(&NVIC_InitStructure);
+}
+
+int cme_m7_eth_init(void)
+{
+//    /* PHY RESET: PA4 */
+//    {
+//        GPIO_ResetBits(GPIOA, GPIO_Pin_4);
+//        rt_thread_delay(2);
+//        GPIO_SetBits(GPIOA, GPIO_Pin_4);
+//        rt_thread_delay(2);
+//    }
+
+//    GPIO_Configuration();
+    NVIC_Configuration();
+
+//    cme_eth_device.ETH_Speed = ETH_Speed_100M;
+//    cme_eth_device.ETH_Mode  = ETH_Mode_FullDuplex;
+
+    /* OUI 00-80-E1 STMICROELECTRONICS. */
+    cme_eth_device.dev_addr[0] = 0x00;
+    cme_eth_device.dev_addr[1] = 0x80;
+    cme_eth_device.dev_addr[2] = 0xE1;
+    /* generate MAC addr from 96bit unique ID (only for test). */
+//    cme_eth_device.dev_addr[3] = *(rt_uint8_t*)(0x1FFF7A10+4);
+//    cme_eth_device.dev_addr[4] = *(rt_uint8_t*)(0x1FFF7A10+2);
+//    cme_eth_device.dev_addr[5] = *(rt_uint8_t*)(0x1FFF7A10+0);
+    cme_eth_device.dev_addr[3] = 12;
+    cme_eth_device.dev_addr[4] = 34;
+    cme_eth_device.dev_addr[5] = 56;
+
+    cme_eth_device.parent.parent.init       = rt_cme_eth_init;
+    cme_eth_device.parent.parent.open       = rt_cme_eth_open;
+    cme_eth_device.parent.parent.close      = rt_cme_eth_close;
+    cme_eth_device.parent.parent.read       = rt_cme_eth_read;
+    cme_eth_device.parent.parent.write      = rt_cme_eth_write;
+    cme_eth_device.parent.parent.control    = rt_cme_eth_control;
+    cme_eth_device.parent.parent.user_data  = RT_NULL;
+
+    cme_eth_device.parent.eth_rx     = rt_cme_eth_rx;
+    cme_eth_device.parent.eth_tx     = rt_cme_eth_tx;
+
+    /* init EMAC lock */
+    rt_mutex_init(&cme_eth_device.lock, "emac0", RT_IPC_FLAG_PRIO);
+
+    /* init tx buffer free semaphore */
+    rt_sem_init(&cme_eth_device.tx_buf_free,
+                "tx_buf",
+                ETH_TXBUFNB,
+                RT_IPC_FLAG_FIFO);
+
+    /* register eth device */
+    eth_device_init(&(cme_eth_device.parent), "e0");
+
+    return RT_EOK;
+}
+
+void ETH_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    if (ETH_GetIntStatus(ETH_INT_TX_COMPLETE_FRAME))
+    {
+        rt_sem_release(&cme_eth_device.tx_buf_free);
+        ETH_ClearInt(ETH_INT_TX_COMPLETE_FRAME);
+    }
+
+    if (ETH_GetIntStatus(ETH_INT_RX_STOP))
+    {
+        CME_ETH_PRINTF("ETH_INT_RX_STOP\n");
+        ETH_ClearInt(ETH_INT_RX_STOP);
+    }
+
+    if ((ETH_GetIntStatus(ETH_INT_RX_BUF_UNAVAI)) ||
+            (ETH_GetIntStatus(ETH_INT_RX_COMPLETE_FRAME)))
+    {
+        /* a frame has been received */
+        eth_device_ready(&(cme_eth_device.parent));
+
+        ETH_EnableInt(ETH_INT_RX_COMPLETE_FRAME, FALSE);
+        ETH_EnableInt(ETH_INT_RX_BUF_UNAVAI, FALSE);
+        ETH_ClearInt(ETH_INT_RX_BUF_UNAVAI);
+        ETH_ClearInt(ETH_INT_RX_COMPLETE_FRAME);
+    }
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+

+ 5 - 3
bsp/CME_M7/rtconfig.h

@@ -63,13 +63,15 @@
 #define RT_CONSOLE_DEVICE_NAME	        "uart2"
 
 /* SECTION: finsh, a C-Express shell */
-#define RT_USING_FINSH
+//#define RT_USING_FINSH
 /* Using symbol table */
 #define FINSH_USING_SYMTAB
 #define FINSH_USING_DESCRIPTION
+#define FINSH_USING_MSH
+#define FINSH_USING_MSH_ONLY
 
 //#define RT_USING_NEWLIB
-//#define RT_USING_ARM_LIBC
+#define RT_USING_ARM_LIBC
 
 /* SECTION: device filesystem */
 /* #define RT_USING_DFS */
@@ -87,7 +89,7 @@
 #define DFS_FD_MAX					4
 
 /* SECTION: lwip, a lighwight TCP/IP protocol stack */
-//#define RT_USING_LWIP
+#define RT_USING_LWIP
 /* LwIP uses RT-Thread Memory Management */
 // #define RT_LWIP_USING_RT_MEM
 /* Enable ICMP protocol*/