|
@@ -10,14 +10,14 @@
|
|
|
#include "stm32f2x7_eth.h"
|
|
|
#include "stm32f2x7_eth_conf.h"
|
|
|
|
|
|
-#define STM32_ETH_DEBUG 0
|
|
|
+#define STM32_ETH_DEBUG 0
|
|
|
//#define CHECKSUM_BY_HARDWARE /* don't ues hardware checksum. */
|
|
|
|
|
|
/* MII and RMII mode selection, for STM322xG-EVAL Board(MB786) RevB ***********/
|
|
|
-//#define MII_MODE
|
|
|
+//#define MII_MODE
|
|
|
|
|
|
#define RMII_MODE // In this case the System clock frequency is configured
|
|
|
- // to 100 MHz, for more details refer to system_stm32f2xx.c
|
|
|
+ // to 100 MHz, for more details refer to system_stm32f2xx.c
|
|
|
|
|
|
#define DP83848_PHY_ADDRESS 0x01 /* Relative to STM322xG-EVAL Board */
|
|
|
|
|
@@ -27,10 +27,10 @@
|
|
|
extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
|
|
|
|
|
|
/* Ethernet Receive buffers */
|
|
|
-extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
|
|
|
+extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
|
|
|
|
|
|
/* Ethernet Transmit buffers */
|
|
|
-extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
|
|
|
+extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
|
|
|
|
|
|
/* Global pointers to track current transmit and receive descriptors */
|
|
|
extern ETH_DMADESCTypeDef *DMATxDescToSet;
|
|
@@ -42,11 +42,11 @@ extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
|
|
|
#define MAX_ADDR_LEN 6
|
|
|
struct rt_stm32_eth
|
|
|
{
|
|
|
- /* inherit from ethernet device */
|
|
|
- struct eth_device parent;
|
|
|
+ /* inherit from ethernet device */
|
|
|
+ struct eth_device parent;
|
|
|
|
|
|
- /* interface address info. */
|
|
|
- rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
|
|
|
+ /* interface address info. */
|
|
|
+ rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
|
|
|
};
|
|
|
static struct rt_stm32_eth stm32_eth_device;
|
|
|
static struct rt_semaphore tx_wait;
|
|
@@ -61,29 +61,29 @@ void ETH_IRQHandler(void)
|
|
|
{
|
|
|
rt_uint32_t status;
|
|
|
|
|
|
- status = ETH->DMASR;
|
|
|
-
|
|
|
- /* Frame received */
|
|
|
- if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
|
|
|
- {
|
|
|
- rt_err_t result;
|
|
|
- //rt_kprintf("Frame comming\n");
|
|
|
- /* Clear the interrupt flags. */
|
|
|
- /* Clear the Eth DMA Rx IT pending bits */
|
|
|
- ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
|
|
|
-
|
|
|
- /* a frame has been received */
|
|
|
- result = eth_device_ready(&(stm32_eth_device.parent));
|
|
|
- if( result != RT_EOK ) rt_kprintf("RX err =%d\n", result );
|
|
|
- //RT_ASSERT(result == RT_EOK);
|
|
|
- }
|
|
|
- if (ETH_GetDMAITStatus(ETH_DMA_IT_T) == SET) /* packet transmission */
|
|
|
- {
|
|
|
- ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
|
|
|
- }
|
|
|
-
|
|
|
- ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
|
|
|
-//
|
|
|
+ status = ETH->DMASR;
|
|
|
+
|
|
|
+ /* Frame received */
|
|
|
+ if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
|
|
|
+ {
|
|
|
+ rt_err_t result;
|
|
|
+ //rt_kprintf("Frame comming\n");
|
|
|
+ /* Clear the interrupt flags. */
|
|
|
+ /* Clear the Eth DMA Rx IT pending bits */
|
|
|
+ ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
|
|
|
+
|
|
|
+ /* a frame has been received */
|
|
|
+ result = eth_device_ready(&(stm32_eth_device.parent));
|
|
|
+ if( result != RT_EOK ) rt_kprintf("RX err =%d\n", result );
|
|
|
+ //RT_ASSERT(result == RT_EOK);
|
|
|
+ }
|
|
|
+ if (ETH_GetDMAITStatus(ETH_DMA_IT_T) == SET) /* packet transmission */
|
|
|
+ {
|
|
|
+ ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
|
|
|
+ }
|
|
|
+
|
|
|
+ ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
|
|
|
+//
|
|
|
|
|
|
}
|
|
|
|
|
@@ -91,244 +91,244 @@ void ETH_IRQHandler(void)
|
|
|
/* initialize the interface */
|
|
|
static rt_err_t rt_stm32_eth_init(rt_device_t dev)
|
|
|
{
|
|
|
- int i;
|
|
|
-
|
|
|
- /* MAC address configuration */
|
|
|
- ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&stm32_eth_device.dev_addr[0]);
|
|
|
-
|
|
|
- /* Initialize Tx Descriptors list: Chain Mode */
|
|
|
- ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
|
|
|
- /* Initialize Rx Descriptors list: Chain Mode */
|
|
|
- ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
|
|
|
-
|
|
|
- /* Enable Ethernet Rx interrrupt */
|
|
|
- {
|
|
|
- for(i=0; i<ETH_RXBUFNB; i++)
|
|
|
- {
|
|
|
- ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #ifdef CHECKSUM_BY_HARDWARE
|
|
|
- /* Enable the checksum insertion for the Tx frames */
|
|
|
- {
|
|
|
- for(i=0; i<ETH_TXBUFNB; i++)
|
|
|
- {
|
|
|
- ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
|
|
|
- }
|
|
|
- }
|
|
|
- #endif
|
|
|
-
|
|
|
- {
|
|
|
- uint16_t tmp, i=10000;
|
|
|
-
|
|
|
- tmp = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
|
|
|
- ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CDCTRL1, BIST_CONT_MODE );
|
|
|
- ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CR, tmp | BIST_START );//BIST_START
|
|
|
-
|
|
|
- while(i--);
|
|
|
-
|
|
|
- //tmp = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
|
|
|
-
|
|
|
- if( ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR) & BIST_STATUS == BIST_STATUS )
|
|
|
- {
|
|
|
- rt_kprintf("BIST pass\n");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- uint16_t ctrl;
|
|
|
-
|
|
|
- ctrl = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CDCTRL1);
|
|
|
- rt_kprintf("BIST faild count =%d\n", BIST_ERROR_COUNT(ctrl) );
|
|
|
- }
|
|
|
- tmp &= ~BIST_START; //Stop BIST
|
|
|
- ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CR, tmp);
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /* Enable MAC and DMA transmission and reception */
|
|
|
- ETH_Start();
|
|
|
-
|
|
|
- //rt_kprintf("DMASR = 0x%X\n", ETH->DMASR );
|
|
|
-// rt_kprintf("ETH Init\n");
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* MAC address configuration */
|
|
|
+ ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&stm32_eth_device.dev_addr[0]);
|
|
|
+
|
|
|
+ /* Initialize Tx Descriptors list: Chain Mode */
|
|
|
+ ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
|
|
|
+ /* Initialize Rx Descriptors list: Chain Mode */
|
|
|
+ ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
|
|
|
+
|
|
|
+ /* Enable Ethernet Rx interrrupt */
|
|
|
+ {
|
|
|
+ for(i=0; i<ETH_RXBUFNB; i++)
|
|
|
+ {
|
|
|
+ ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #ifdef CHECKSUM_BY_HARDWARE
|
|
|
+ /* Enable the checksum insertion for the Tx frames */
|
|
|
+ {
|
|
|
+ for(i=0; i<ETH_TXBUFNB; i++)
|
|
|
+ {
|
|
|
+ ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ {
|
|
|
+ uint16_t tmp, i=10000;
|
|
|
+
|
|
|
+ tmp = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
|
|
|
+ ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CDCTRL1, BIST_CONT_MODE );
|
|
|
+ ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CR, tmp | BIST_START );//BIST_START
|
|
|
+
|
|
|
+ while(i--);
|
|
|
+
|
|
|
+ //tmp = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
|
|
|
+
|
|
|
+ if( ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR) & BIST_STATUS == BIST_STATUS )
|
|
|
+ {
|
|
|
+ rt_kprintf("BIST pass\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ uint16_t ctrl;
|
|
|
+
|
|
|
+ ctrl = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CDCTRL1);
|
|
|
+ rt_kprintf("BIST faild count =%d\n", BIST_ERROR_COUNT(ctrl) );
|
|
|
+ }
|
|
|
+ tmp &= ~BIST_START; //Stop BIST
|
|
|
+ ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CR, tmp);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Enable MAC and DMA transmission and reception */
|
|
|
+ ETH_Start();
|
|
|
+
|
|
|
+ //rt_kprintf("DMASR = 0x%X\n", ETH->DMASR );
|
|
|
+// rt_kprintf("ETH Init\n");
|
|
|
|
|
|
return RT_EOK;
|
|
|
}
|
|
|
|
|
|
static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
|
|
|
{
|
|
|
- return RT_EOK;
|
|
|
+ return RT_EOK;
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
{
|
|
|
- rt_set_errno(-RT_ENOSYS);
|
|
|
- return 0;
|
|
|
+ rt_set_errno(-RT_ENOSYS);
|
|
|
+ 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)
|
|
|
{
|
|
|
- rt_set_errno(-RT_ENOSYS);
|
|
|
- return 0;
|
|
|
+ rt_set_errno(-RT_ENOSYS);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
|
|
|
{
|
|
|
- switch(cmd)
|
|
|
- {
|
|
|
- case NIOCTL_GADDR:
|
|
|
- /* get mac address */
|
|
|
- if(args) rt_memcpy(args, stm32_eth_device.dev_addr, 6);
|
|
|
- else return -RT_ERROR;
|
|
|
- break;
|
|
|
-
|
|
|
- default :
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- return RT_EOK;
|
|
|
+ switch(cmd)
|
|
|
+ {
|
|
|
+ case NIOCTL_GADDR:
|
|
|
+ /* get mac address */
|
|
|
+ if(args) rt_memcpy(args, stm32_eth_device.dev_addr, 6);
|
|
|
+ else return -RT_ERROR;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default :
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return RT_EOK;
|
|
|
}
|
|
|
|
|
|
void show_frame(struct pbuf *q)
|
|
|
{
|
|
|
- int i = 0;
|
|
|
- int j = 0;
|
|
|
- char *ptr = q->payload;
|
|
|
+ int i = 0;
|
|
|
+ int j = 0;
|
|
|
+ char *ptr = q->payload;
|
|
|
|
|
|
- for( i = 0; i < q->len; i++ )
|
|
|
- rt_kprintf("0x%02X ", *(ptr++));
|
|
|
- rt_kprintf("\n");
|
|
|
+ for( i = 0; i < q->len; i++ )
|
|
|
+ rt_kprintf("0x%02X ", *(ptr++));
|
|
|
+ rt_kprintf("\n");
|
|
|
}
|
|
|
|
|
|
/* ethernet device interface */
|
|
|
/* transmit packet. */
|
|
|
rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
|
|
|
{
|
|
|
- rt_err_t ret;
|
|
|
- struct pbuf *q;
|
|
|
- uint32_t l = 0;
|
|
|
- u8 *buffer ;
|
|
|
-
|
|
|
- if (( ret = rt_sem_take(&tx_wait, netifGUARD_BLOCK_TIME) ) == RT_EOK)
|
|
|
- {
|
|
|
- buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
|
|
|
- for(q = p; q != NULL; q = q->next)
|
|
|
- {
|
|
|
- //show_frame(q);
|
|
|
- rt_memcpy((u8_t*)&buffer[l], q->payload, q->len);
|
|
|
- l = l + q->len;
|
|
|
- }
|
|
|
- if( ETH_Prepare_Transmit_Descriptors(l) == ETH_ERROR )
|
|
|
- rt_kprintf("Tx Error\n");
|
|
|
- //rt_sem_release(xTxSemaphore);
|
|
|
- rt_sem_release(&tx_wait);
|
|
|
- //rt_kprintf("Tx packet, len = %d\n", l);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- rt_kprintf("Tx Timeout\n");
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- /* Return SUCCESS */
|
|
|
- return RT_EOK;
|
|
|
+ rt_err_t ret;
|
|
|
+ struct pbuf *q;
|
|
|
+ uint32_t l = 0;
|
|
|
+ u8 *buffer ;
|
|
|
+
|
|
|
+ if (( ret = rt_sem_take(&tx_wait, netifGUARD_BLOCK_TIME) ) == RT_EOK)
|
|
|
+ {
|
|
|
+ buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
|
|
|
+ for(q = p; q != NULL; q = q->next)
|
|
|
+ {
|
|
|
+ //show_frame(q);
|
|
|
+ rt_memcpy((u8_t*)&buffer[l], q->payload, q->len);
|
|
|
+ l = l + q->len;
|
|
|
+ }
|
|
|
+ if( ETH_Prepare_Transmit_Descriptors(l) == ETH_ERROR )
|
|
|
+ rt_kprintf("Tx Error\n");
|
|
|
+ //rt_sem_release(xTxSemaphore);
|
|
|
+ rt_sem_release(&tx_wait);
|
|
|
+ //rt_kprintf("Tx packet, len = %d\n", l);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ rt_kprintf("Tx Timeout\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Return SUCCESS */
|
|
|
+ return RT_EOK;
|
|
|
}
|
|
|
|
|
|
/* reception packet. */
|
|
|
struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
|
|
|
{
|
|
|
- struct pbuf *p, *q;
|
|
|
- u16_t len;
|
|
|
- uint32_t l=0,i =0;
|
|
|
- FrameTypeDef frame;
|
|
|
- static framecnt = 1;
|
|
|
- u8 *buffer;
|
|
|
- __IO ETH_DMADESCTypeDef *DMARxNextDesc;
|
|
|
-
|
|
|
- p = RT_NULL;
|
|
|
-
|
|
|
-// rt_kprintf("ETH rx\n");
|
|
|
- /* Get received frame */
|
|
|
- frame = ETH_Get_Received_Frame_interrupt();
|
|
|
-
|
|
|
- if( frame.length > 0 )
|
|
|
- {
|
|
|
- /* check that frame has no error */
|
|
|
- if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET)
|
|
|
- {
|
|
|
- //rt_kprintf("Get a frame %d buf = 0x%X, len= %d\n", framecnt++, frame.buffer, frame.length);
|
|
|
- /* Obtain the size of the packet and put it into the "len" variable. */
|
|
|
- len = frame.length;
|
|
|
- buffer = (u8 *)frame.buffer;
|
|
|
-
|
|
|
- /* We allocate a pbuf chain of pbufs from the pool. */
|
|
|
- p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
|
|
- //p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
|
|
|
-
|
|
|
- /* Copy received frame from ethernet driver buffer to stack buffer */
|
|
|
- if (p != NULL)
|
|
|
- {
|
|
|
- for (q = p; q != NULL; q = q->next)
|
|
|
- {
|
|
|
- rt_memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);
|
|
|
- l = l + q->len;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Release descriptors to DMA */
|
|
|
- /* Check if received frame with multiple DMA buffer segments */
|
|
|
- if (DMA_RX_FRAME_infos->Seg_Count > 1)
|
|
|
- {
|
|
|
- DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DMARxNextDesc = frame.descriptor;
|
|
|
- }
|
|
|
-
|
|
|
- /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
|
|
|
- for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
|
|
|
- {
|
|
|
- DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
|
|
|
- DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);
|
|
|
- }
|
|
|
-
|
|
|
- /* Clear Segment_Count */
|
|
|
- DMA_RX_FRAME_infos->Seg_Count =0;
|
|
|
-
|
|
|
-
|
|
|
- /* When Rx Buffer unavailable flag is set: clear it and resume reception */
|
|
|
- if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
|
|
|
- {
|
|
|
- /* Clear RBUS ETHERNET DMA flag */
|
|
|
- ETH->DMASR = ETH_DMASR_RBUS;
|
|
|
-
|
|
|
- /* Resume DMA reception */
|
|
|
- ETH->DMARPDR = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- return p;
|
|
|
+ struct pbuf *p, *q;
|
|
|
+ u16_t len;
|
|
|
+ uint32_t l=0,i =0;
|
|
|
+ FrameTypeDef frame;
|
|
|
+ static framecnt = 1;
|
|
|
+ u8 *buffer;
|
|
|
+ __IO ETH_DMADESCTypeDef *DMARxNextDesc;
|
|
|
+
|
|
|
+ p = RT_NULL;
|
|
|
+
|
|
|
+// rt_kprintf("ETH rx\n");
|
|
|
+ /* Get received frame */
|
|
|
+ frame = ETH_Get_Received_Frame_interrupt();
|
|
|
+
|
|
|
+ if( frame.length > 0 )
|
|
|
+ {
|
|
|
+ /* check that frame has no error */
|
|
|
+ if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET)
|
|
|
+ {
|
|
|
+ //rt_kprintf("Get a frame %d buf = 0x%X, len= %d\n", framecnt++, frame.buffer, frame.length);
|
|
|
+ /* Obtain the size of the packet and put it into the "len" variable. */
|
|
|
+ len = frame.length;
|
|
|
+ buffer = (u8 *)frame.buffer;
|
|
|
+
|
|
|
+ /* We allocate a pbuf chain of pbufs from the pool. */
|
|
|
+ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
|
|
+ //p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
|
|
|
+
|
|
|
+ /* Copy received frame from ethernet driver buffer to stack buffer */
|
|
|
+ if (p != NULL)
|
|
|
+ {
|
|
|
+ for (q = p; q != NULL; q = q->next)
|
|
|
+ {
|
|
|
+ rt_memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);
|
|
|
+ l = l + q->len;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Release descriptors to DMA */
|
|
|
+ /* Check if received frame with multiple DMA buffer segments */
|
|
|
+ if (DMA_RX_FRAME_infos->Seg_Count > 1)
|
|
|
+ {
|
|
|
+ DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DMARxNextDesc = frame.descriptor;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
|
|
|
+ for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
|
|
|
+ {
|
|
|
+ DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
|
|
|
+ DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Clear Segment_Count */
|
|
|
+ DMA_RX_FRAME_infos->Seg_Count =0;
|
|
|
+
|
|
|
+
|
|
|
+ /* When Rx Buffer unavailable flag is set: clear it and resume reception */
|
|
|
+ if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
|
|
|
+ {
|
|
|
+ /* Clear RBUS ETHERNET DMA flag */
|
|
|
+ ETH->DMASR = ETH_DMASR_RBUS;
|
|
|
+
|
|
|
+ /* Resume DMA reception */
|
|
|
+ ETH->DMARPDR = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return p;
|
|
|
}
|
|
|
|
|
|
static void NVIC_Configuration(void)
|
|
|
{
|
|
|
- NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
-
|
|
|
- /* 2 bit for pre-emption priority, 2 bits for subpriority */
|
|
|
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
|
|
|
- /* Enable the Ethernet global Interrupt */
|
|
|
- NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
|
|
|
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
|
|
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
|
|
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
- NVIC_Init(&NVIC_InitStructure);
|
|
|
+ NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
+
|
|
|
+ /* 2 bit for pre-emption priority, 2 bits for subpriority */
|
|
|
+ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
|
|
|
+ /* Enable the Ethernet global Interrupt */
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init(&NVIC_InitStructure);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -383,15 +383,15 @@ static void GPIO_Configuration(void)
|
|
|
ETH_MII_TXD0/ETH_RMII_TXD0 -------> PB12
|
|
|
ETH_MII_TXD1/ETH_RMII_TXD1 -------> PB13
|
|
|
|
|
|
- **** Just for MII Mode ****
|
|
|
- ETH_MII_CRS ----------------------> PA0
|
|
|
- ETH_MII_COL ----------------------> PA3
|
|
|
- ETH_MII_TX_CLK -------------------> PC3
|
|
|
- ETH_MII_RX_ER --------------------> PB10
|
|
|
- ETH_MII_RXD2 ---------------------> PB0
|
|
|
- ETH_MII_RXD3 ---------------------> PB1
|
|
|
- ETH_MII_TXD2 ---------------------> PC2
|
|
|
- ETH_MII_TXD3 ---------------------> PB8
|
|
|
+ **** Just for MII Mode ****
|
|
|
+ ETH_MII_CRS ----------------------> PA0
|
|
|
+ ETH_MII_COL ----------------------> PA3
|
|
|
+ ETH_MII_TX_CLK -------------------> PC3
|
|
|
+ ETH_MII_RX_ER --------------------> PB10
|
|
|
+ ETH_MII_RXD2 ---------------------> PB0
|
|
|
+ ETH_MII_RXD3 ---------------------> PB1
|
|
|
+ ETH_MII_TXD2 ---------------------> PC2
|
|
|
+ ETH_MII_TXD3 ---------------------> PB8
|
|
|
*/
|
|
|
/* Configure PC1, PC4 and PC5 */
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 |GPIO_Pin_4 | GPIO_Pin_5;
|
|
@@ -450,7 +450,7 @@ static void ETH_MACDMA_Config(void)
|
|
|
|
|
|
/* Enable ETHERNET clock */
|
|
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
|
|
|
- RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
|
|
|
+ RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
|
|
|
|
|
|
/* Reset ETHERNET on AHB Bus */
|
|
|
ETH_DeInit();
|
|
@@ -468,9 +468,9 @@ static void ETH_MACDMA_Config(void)
|
|
|
/* Fill ETH_InitStructure parametrs */
|
|
|
/*------------------------ MAC -----------------------------------*/
|
|
|
ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
|
|
|
- //ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
|
|
|
+ //ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
|
|
|
// ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
|
|
|
- // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
|
|
|
+ // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
|
|
|
|
|
|
ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
|
|
|
ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
|
|
@@ -484,95 +484,95 @@ static void ETH_MACDMA_Config(void)
|
|
|
ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
|
|
|
#endif
|
|
|
|
|
|
- /*------------------------ DMA -----------------------------------*/
|
|
|
-
|
|
|
- /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
|
|
|
- the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
|
|
|
+ /*------------------------ DMA -----------------------------------*/
|
|
|
+
|
|
|
+ /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
|
|
|
+ the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
|
|
|
if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
|
|
|
- ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
|
|
|
- ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
|
|
|
- ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
|
|
|
-
|
|
|
- ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
|
|
|
- ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
|
|
|
+ ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
|
|
|
+ ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
|
|
|
+ ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
|
|
|
+
|
|
|
+ ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
|
|
|
+ ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
|
|
|
ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
|
|
|
- ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
|
|
|
- ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
|
|
|
- ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
|
|
|
+ ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
|
|
|
+ ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
|
|
|
+ ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
|
|
|
ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
|
|
|
ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
|
|
|
|
|
|
/* Configure Ethernet */
|
|
|
if( ETH_Init(Ð_InitStructure, DP83848_PHY_ADDRESS) == ETH_ERROR )
|
|
|
- rt_kprintf("ETH init error, may be no link\n");
|
|
|
+ rt_kprintf("ETH init error, may be no link\n");
|
|
|
|
|
|
/* Enable the Ethernet Rx Interrupt */
|
|
|
ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R , ENABLE);
|
|
|
}
|
|
|
|
|
|
-#define DevID_SNo0 (*((rt_uint32_t *)0x1FFF7A10));
|
|
|
-#define DevID_SNo1 (*((rt_uint32_t *)0x1FFF7A10+32));
|
|
|
+#define DevID_SNo0 (*((rt_uint32_t *)0x1FFF7A10));
|
|
|
+#define DevID_SNo1 (*((rt_uint32_t *)0x1FFF7A10+32));
|
|
|
#define DevID_SNo2 (*((rt_uint32_t *)0x1FFF7A10+64));
|
|
|
void rt_hw_stm32_eth_init(void)
|
|
|
{
|
|
|
- GPIO_Configuration();
|
|
|
- NVIC_Configuration();
|
|
|
- ETH_MACDMA_Config();
|
|
|
+ GPIO_Configuration();
|
|
|
+ NVIC_Configuration();
|
|
|
+ ETH_MACDMA_Config();
|
|
|
|
|
|
stm32_eth_device.dev_addr[0] = 0x00;
|
|
|
stm32_eth_device.dev_addr[1] = 0x60;
|
|
|
stm32_eth_device.dev_addr[2] = 0x6e;
|
|
|
- {
|
|
|
- uint32_t cpu_id[3] = {0};
|
|
|
- cpu_id[2] = DevID_SNo2; cpu_id[1] = DevID_SNo1; cpu_id[0] = DevID_SNo0;
|
|
|
-
|
|
|
- // generate MAC addr from 96bit unique ID (only for test)
|
|
|
- stm32_eth_device.dev_addr[3] = (uint8_t)((cpu_id[0]>>16)&0xFF);
|
|
|
- stm32_eth_device.dev_addr[4] = (uint8_t)((cpu_id[0]>>8)&0xFF);
|
|
|
- stm32_eth_device.dev_addr[5] = (uint8_t)(cpu_id[0]&0xFF);
|
|
|
-
|
|
|
-// stm32_eth_device.dev_addr[3] = *(rt_uint8_t*)(0x1FFF7A10+7);
|
|
|
-// stm32_eth_device.dev_addr[4] = *(rt_uint8_t*)(0x1FFF7A10+8);
|
|
|
-// stm32_eth_device.dev_addr[5] = *(rt_uint8_t*)(0x1FFF7A10+9);
|
|
|
- }
|
|
|
-
|
|
|
- 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", 1, RT_IPC_FLAG_FIFO);
|
|
|
-
|
|
|
- /* register eth device */
|
|
|
- eth_device_init(&(stm32_eth_device.parent), "e0");
|
|
|
+ {
|
|
|
+ uint32_t cpu_id[3] = {0};
|
|
|
+ cpu_id[2] = DevID_SNo2; cpu_id[1] = DevID_SNo1; cpu_id[0] = DevID_SNo0;
|
|
|
+
|
|
|
+ // generate MAC addr from 96bit unique ID (only for test)
|
|
|
+ stm32_eth_device.dev_addr[3] = (uint8_t)((cpu_id[0]>>16)&0xFF);
|
|
|
+ stm32_eth_device.dev_addr[4] = (uint8_t)((cpu_id[0]>>8)&0xFF);
|
|
|
+ stm32_eth_device.dev_addr[5] = (uint8_t)(cpu_id[0]&0xFF);
|
|
|
+
|
|
|
+// stm32_eth_device.dev_addr[3] = *(rt_uint8_t*)(0x1FFF7A10+7);
|
|
|
+// stm32_eth_device.dev_addr[4] = *(rt_uint8_t*)(0x1FFF7A10+8);
|
|
|
+// stm32_eth_device.dev_addr[5] = *(rt_uint8_t*)(0x1FFF7A10+9);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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", 1, RT_IPC_FLAG_FIFO);
|
|
|
+
|
|
|
+ /* register eth device */
|
|
|
+ eth_device_init(&(stm32_eth_device.parent), "e0");
|
|
|
}
|
|
|
static char led = 0;
|
|
|
|
|
|
void dp83483()
|
|
|
{
|
|
|
- uint16_t bsr,sts, bcr, phycr;
|
|
|
+ uint16_t bsr,sts, bcr, phycr;
|
|
|
|
|
|
- bsr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BSR);
|
|
|
- sts = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_SR);
|
|
|
- bcr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BCR);
|
|
|
- phycr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
|
|
|
+ bsr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BSR);
|
|
|
+ sts = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_SR);
|
|
|
+ bcr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BCR);
|
|
|
+ phycr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
|
|
|
|
|
|
- rt_kprintf("BCR = 0x%X\tBSR = 0x%X\tPHY_STS = 0x%X\tPHY_CR = 0x%X\n", bcr,bsr,sts, phycr);
|
|
|
+ rt_kprintf("BCR = 0x%X\tBSR = 0x%X\tPHY_STS = 0x%X\tPHY_CR = 0x%X\n", bcr,bsr,sts, phycr);
|
|
|
|
|
|
- rt_kprintf("PHY_FCSCR = 0x%X\n", ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_FCSCR ) );
|
|
|
- rt_kprintf("PHY_MISR = 0x%X\n", ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_MISR ) );
|
|
|
+ rt_kprintf("PHY_FCSCR = 0x%X\n", ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_FCSCR ) );
|
|
|
+ rt_kprintf("PHY_MISR = 0x%X\n", ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_MISR ) );
|
|
|
|
|
|
- rt_kprintf("DMASR = 0x%X\n", ETH->DMASR );
|
|
|
+ rt_kprintf("DMASR = 0x%X\n", ETH->DMASR );
|
|
|
|
|
|
- //ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_LEDCR, (uint16_t)(0x38 | led));
|
|
|
- led = (led==7)?0:7;
|
|
|
+ //ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_LEDCR, (uint16_t)(0x38 | led));
|
|
|
+ led = (led==7)?0:7;
|
|
|
|
|
|
}
|
|
|
#ifdef RT_USING_FINSH
|