update stm32f107 eth driver

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1725 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
wuyangyong 2011-09-24 03:24:39 +00:00
parent 3c0f80f2f7
commit 86b62f9026
7 changed files with 220 additions and 163 deletions

View File

@ -48,54 +48,57 @@ void rt_init_thread_entry(void* parameter)
/* init the elm chan FatFs filesystam*/ /* init the elm chan FatFs filesystam*/
elm_init(); elm_init();
/* mount sd card fat partition 1 as root directory */ /* init sdcard driver */
if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) rt_hw_msd_init();
{
rt_kprintf("File System initialized!\n"); /* mount sd card fat partition 1 as root directory */
} if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
else {
rt_kprintf("File System initialzation failed!\n"); rt_kprintf("File System initialized!\n");
}
else
rt_kprintf("File System initialzation failed!\n");
#endif #endif
} }
#endif #endif
/* LwIP Initialization */ /* LwIP Initialization */
#ifdef RT_USING_LWIP #ifdef RT_USING_LWIP
{ {
extern void lwip_sys_init(void); extern void lwip_sys_init(void);
/* register ethernetif device */ /* register ethernetif device */
eth_system_device_init(); eth_system_device_init();
rt_hw_stm32_eth_init(); rt_hw_stm32_eth_init();
/* re-init device driver */ /* re-init device driver */
rt_device_init_all(); rt_device_init_all();
/* init lwip system */ /* init lwip system */
lwip_sys_init(); lwip_sys_init();
rt_kprintf("TCP/IP initialized!\n"); rt_kprintf("TCP/IP initialized!\n");
} }
#endif #endif
} }
int rt_application_init() int rt_application_init()
{ {
rt_thread_t init_thread; rt_thread_t init_thread;
#if (RT_THREAD_PRIORITY_MAX == 32) #if (RT_THREAD_PRIORITY_MAX == 32)
init_thread = rt_thread_create("init", init_thread = rt_thread_create("init",
rt_init_thread_entry, RT_NULL, rt_init_thread_entry, RT_NULL,
2048, 8, 20); 2048, 8, 20);
#else #else
init_thread = rt_thread_create("init", init_thread = rt_thread_create("init",
rt_init_thread_entry, RT_NULL, rt_init_thread_entry, RT_NULL,
2048, 80, 20); 2048, 80, 20);
#endif #endif
if (init_thread != RT_NULL) if (init_thread != RT_NULL)
rt_thread_startup(init_thread); rt_thread_startup(init_thread);
return 0; return 0;
} }
/*@}*/ /*@}*/

View File

@ -6,7 +6,7 @@
#define RT_NAME_MAX 8 #define RT_NAME_MAX 8
/* RT_ALIGN_SIZE*/ /* RT_ALIGN_SIZE*/
#define RT_ALIGN_SIZE 4 #define RT_ALIGN_SIZE 8
/* PRIORITY_MAX */ /* PRIORITY_MAX */
#define RT_THREAD_PRIORITY_MAX 32 #define RT_THREAD_PRIORITY_MAX 32
@ -134,4 +134,17 @@
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 4 #define RT_LWIP_ETHTHREAD_MBOX_SIZE 4
#define RT_LWIP_ETHTHREAD_STACKSIZE 512 #define RT_LWIP_ETHTHREAD_STACKSIZE 512
/* TCP sender buffer space */
#define RT_LWIP_TCP_SND_BUF 8192
/* TCP receive window. */
#define RT_LWIP_TCP_WND 8192
#define CHECKSUM_CHECK_TCP 0
#define CHECKSUM_CHECK_IP 0
#define CHECKSUM_CHECK_UDP 0
#define CHECKSUM_GEN_TCP 0
#define CHECKSUM_GEN_IP 0
#define CHECKSUM_GEN_UDP 0
#endif #endif

View File

@ -21,7 +21,7 @@
/* STM32F10x library definitions */ /* STM32F10x library definitions */
#include <stm32f10x.h> #include <stm32f10x.h>
#define UART_RX_BUFFER_SIZE 64 #define UART_RX_BUFFER_SIZE 128
#define UART_TX_DMA_NODE_SIZE 4 #define UART_TX_DMA_NODE_SIZE 4
/* data node for Tx Mode */ /* data node for Tx Mode */

View File

@ -39,7 +39,6 @@ extern int Image$$RW_IRAM1$$ZI$$Limit;
extern int __bss_end; extern int __bss_end;
#endif #endif
#ifdef DEBUG
/******************************************************************************* /*******************************************************************************
* Function Name : assert_failed * Function Name : assert_failed
* Description : Reports the name of the source file and the source line number * Description : Reports the name of the source file and the source line number
@ -57,7 +56,6 @@ void assert_failed(u8* file, u32 line)
while (1) ; while (1) ;
} }
#endif
/** /**
* This function will startup RT-Thread RTOS. * This function will startup RT-Thread RTOS.
@ -93,11 +91,6 @@ void rtthread_startup(void)
/* init scheduler system */ /* init scheduler system */
rt_system_scheduler_init(); rt_system_scheduler_init();
#ifdef RT_USING_DFS
/* init sdcard driver */
rt_hw_msd_init();
#endif
/* init all device */ /* init all device */
rt_device_init_all(); rt_device_init_all();
@ -128,9 +121,6 @@ int main(void)
/* disable interrupt first */ /* disable interrupt first */
rt_hw_interrupt_disable(); rt_hw_interrupt_disable();
/* init system setting */
SystemInit();
/* startup RT-Thread RTOS */ /* startup RT-Thread RTOS */
rtthread_startup(); rtthread_startup();

View File

@ -91,9 +91,6 @@ ETH_DMADESCTypeDef *DMAPTPRxDescToGet;
/** @defgroup ETH_Private_FunctionPrototypes /** @defgroup ETH_Private_FunctionPrototypes
* @{ * @{
*/ */
void rt_eth_phy_init(void);
/** /**
* @} * @}
*/ */
@ -219,70 +216,67 @@ uint32_t ETH_Init(ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress)
{ {
} }
if (ETH_ReadPHYRegister(PHYAddress, PHY_SR) & 0x01) /* PHY is linked */ if(ETH_InitStruct->ETH_AutoNegotiation != ETH_AutoNegotiation_Disable)
{ {
if(ETH_InitStruct->ETH_AutoNegotiation != ETH_AutoNegotiation_Disable) /* We wait for linked satus... */
{ do
/* We wait for linked satus... */ {
do timeout++;
{ } while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO));
timeout++; /* Return ERROR in case of timeout */
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO)); if(timeout == PHY_READ_TO)
/* Return ERROR in case of timeout */ {
if(timeout == PHY_READ_TO) return ETH_ERROR;
{ }
return ETH_ERROR; /* Reset Timeout counter */
} timeout = 0;
/* Reset Timeout counter */
timeout = 0;
/* Enable Auto-Negotiation */ /* Enable Auto-Negotiation */
if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_AutoNegotiation))) if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_AutoNegotiation)))
{ {
/* Return ERROR in case of write timeout */ /* Return ERROR in case of write timeout */
return ETH_ERROR; return ETH_ERROR;
} }
/* Wait until the autonegotiation will be completed */ /* Wait until the autonegotiation will be completed */
do do
{ {
timeout++; timeout++;
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO)); } while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO));
/* Return ERROR in case of timeout */ /* Return ERROR in case of timeout */
if(timeout == PHY_READ_TO) if(timeout == PHY_READ_TO)
{ {
return ETH_ERROR; return ETH_ERROR;
} }
/* Reset Timeout counter */ /* Reset Timeout counter */
timeout = 0; timeout = 0;
/* Read the result of the autonegotiation */ /* Read the result of the autonegotiation */
RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR); RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR);
/* Configure the MAC with the Duplex Mode fixed by the autonegotiation process */ /* Configure the MAC with the Duplex Mode fixed by the autonegotiation process */
if((RegValue & PHY_Duplex_Status) != (uint32_t)RESET) if((RegValue & PHY_Duplex_Status) != (uint32_t)RESET)
{ {
/* Set Ethernet duplex mode to FullDuplex following the autonegotiation */ /* Set Ethernet duplex mode to FullDuplex following the autonegotiation */
ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex; ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;
} }
else else
{ {
/* Set Ethernet duplex mode to HalfDuplex following the autonegotiation */ /* Set Ethernet duplex mode to HalfDuplex following the autonegotiation */
ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex; ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
} }
/* Configure the MAC with the speed fixed by the autonegotiation process */ /* Configure the MAC with the speed fixed by the autonegotiation process */
if(RegValue & PHY_Speed_Status) if(RegValue & PHY_Speed_Status)
{ {
/* Set Ethernet speed to 10M following the autonegotiation */ /* Set Ethernet speed to 10M following the autonegotiation */
ETH_InitStruct->ETH_Speed = ETH_Speed_10M; ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
} }
else else
{ {
/* Set Ethernet speed to 100M following the autonegotiation */ /* Set Ethernet speed to 100M following the autonegotiation */
ETH_InitStruct->ETH_Speed = ETH_Speed_100M; ETH_InitStruct->ETH_Speed = ETH_Speed_100M;
} }
}
} }
else else
{ {
@ -3063,10 +3057,14 @@ uint32_t ETH_HandlePTPRxPkt(uint8_t *ppkt, uint32_t *PTPRxTab)
*/ */
#include <rtthread.h> #include <rtthread.h>
#include <netif/ethernetif.h> #include <netif/ethernetif.h>
#include <netif/etharp.h>
#include <lwip/icmp.h>
#include "lwipopts.h" #include "lwipopts.h"
#define MII_MODE /* MII mode for STM3210C-EVAL Board (MB784) (check jumpers setting) */ #define STM32_ETH_DEBUG 0
#define MII_MODE /* MII mode for STM3210C-EVAL Board (MB784) (check jumpers setting) */
#define CHECKSUM_BY_HARDWARE
#define DP83848_PHY /* Ethernet pins mapped on STM3210C-EVAL Board */ #define DP83848_PHY /* Ethernet pins mapped on STM3210C-EVAL Board */
#define PHY_ADDRESS 0x01 /* Relative to STM3210C-EVAL Board */ #define PHY_ADDRESS 0x01 /* Relative to STM3210C-EVAL Board */
@ -3086,8 +3084,7 @@ struct rt_stm32_eth
rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
}; };
static struct rt_stm32_eth stm32_eth_device; static struct rt_stm32_eth stm32_eth_device;
static struct rt_semaphore tx_wait; static struct rt_semaphore tx_buf_free;
static rt_bool_t tx_is_waiting = RT_FALSE;
/* interrupt service routine for ETH */ /* interrupt service routine for ETH */
void ETH_IRQHandler(void) void ETH_IRQHandler(void)
@ -3097,27 +3094,22 @@ void ETH_IRQHandler(void)
/* enter interrupt */ /* enter interrupt */
rt_interrupt_enter(); rt_interrupt_enter();
if (ETH_GetDMAITStatus(ETH_DMA_IT_R) == SET) /* packet receiption */ /* get DMA IT status */
status = ETH->DMASR;
if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
{ {
/* a frame has been received */ /* a frame has been received */
eth_device_ready(&(stm32_eth_device.parent)); eth_device_ready(&(stm32_eth_device.parent));
ETH_DMAClearITPendingBit(ETH_DMA_IT_R); ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
} }
if (ETH_GetDMAITStatus(ETH_DMA_IT_T) == SET) /* packet transmission */ if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
{ {
if (tx_is_waiting == RT_TRUE) rt_sem_release(&tx_buf_free);
{
tx_is_waiting = RT_FALSE;
rt_sem_release(&tx_wait);
}
ETH_DMAClearITPendingBit(ETH_DMA_IT_T); ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
} }
status = ETH->DMASR;
/* Clear received IT */ /* Clear received IT */
if ((status & ETH_DMA_IT_NIS) != (u32)RESET) if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_NIS; ETH->DMASR = (u32)ETH_DMA_IT_NIS;
@ -3125,13 +3117,11 @@ void ETH_IRQHandler(void)
ETH->DMASR = (u32)ETH_DMA_IT_AIS; ETH->DMASR = (u32)ETH_DMA_IT_AIS;
if ((status & ETH_DMA_IT_RO) != (u32)RESET) if ((status & ETH_DMA_IT_RO) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_RO; ETH->DMASR = (u32)ETH_DMA_IT_RO;
if ((status & ETH_DMA_IT_RBU) != (u32)RESET) if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
{ {
ETH_ResumeDMAReception(); ETH_ResumeDMAReception();
ETH->DMASR = (u32)ETH_DMA_IT_RBU; ETH->DMASR = (u32)ETH_DMA_IT_RBU;
} }
if ((status & ETH_DMA_IT_TBU) != (u32)RESET) if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
{ {
ETH_ResumeDMATransmission(); ETH_ResumeDMATransmission();
@ -3236,8 +3226,9 @@ static rt_err_t rt_stm32_eth_init(rt_device_t dev)
/*------------------------ MAC -----------------------------------*/ /*------------------------ MAC -----------------------------------*/
ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable ; ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable ;
ETH_InitStructure.ETH_Speed = ETH_Speed_100M; ETH_InitStructure.ETH_Speed = ETH_Speed_100M;
ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
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; ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable; ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable;
@ -3245,28 +3236,44 @@ static rt_err_t rt_stm32_eth_init(rt_device_t dev)
ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect; ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
#ifdef CHECKSUM_BY_HARDWARE
ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
#endif
/* Configure ETHERNET */ /*------------------------ DMA -----------------------------------*/
Value = ETH_Init(&ETH_InitStructure, PHY_ADDRESS); /* 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_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_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
/* Enable DMA Receive interrupt (need to enable in this case Normal interrupt) */ /* Configure ETHERNET */
ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE); Value = ETH_Init(&ETH_InitStructure, PHY_ADDRESS);
/* Initialize Tx Descriptors list: Chain Mode */ /* Enable DMA Receive interrupt (need to enable in this case Normal interrupt) */
ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R | ETH_DMA_IT_T, ENABLE);
/* Initialize Rx Descriptors list: Chain Mode */
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
/* MAC address configuration */ /* Initialize Tx Descriptors list: Chain Mode */
ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&stm32_eth_device.dev_addr[0]); ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
/* Initialize PHY */ /* MAC address configuration */
rt_eth_phy_init(); ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&stm32_eth_device.dev_addr[0]);
/* Enable MAC and DMA transmission and reception */ /* Enable MAC and DMA transmission and reception */
ETH_Start(); ETH_Start();
return RT_EOK; return RT_EOK;
} }
static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag) static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
@ -3312,25 +3319,22 @@ static rt_err_t rt_stm32_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args
/* transmit packet. */ /* transmit packet. */
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)
{ {
#if STM32_ETH_DEBUG
int cnt = 0;
#endif
struct pbuf* q; struct pbuf* q;
rt_uint32_t offset; rt_uint32_t offset;
/* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ /* get free tx buffer */
while ((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET)
{ {
rt_err_t result; rt_err_t result;
rt_uint32_t level; result = rt_sem_take(&tx_buf_free, 2);
if (result != RT_EOK) return -RT_ERROR;
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;
}
#if STM32_ETH_DEBUG
rt_kprintf("tx dump:\n");
#endif
offset = 0; offset = 0;
for (q = p; q != NULL; q = q->next) for (q = p; q != NULL; q = q->next)
{ {
@ -3345,14 +3349,42 @@ rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
{ {
(*(__IO uint8_t *)((DMATxDescToSet->Buffer1Addr) + offset)) = *ptr; (*(__IO uint8_t *)((DMATxDescToSet->Buffer1Addr) + offset)) = *ptr;
#if STM32_ETH_DEBUG
rt_kprintf("%02x ", *ptr);
if (++cnt % 16 == 0) rt_kprintf("\n");
#endif
offset ++; ptr ++; len --; offset ++; ptr ++; len --;
} }
} }
#if STM32_ETH_DEBUG
rt_kprintf("\n");
#endif
/* Setting the Frame Length: bits[12:0] */ /* Setting the Frame Length: bits[12:0] */
DMATxDescToSet->ControlBufferSize = (p->tot_len & ETH_DMATxDesc_TBS1); DMATxDescToSet->ControlBufferSize = (p->tot_len & ETH_DMATxDesc_TBS1);
/* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */ /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS; DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
/* Enable TX Completion Interrupt */
DMATxDescToSet->Status |= ETH_DMATxDesc_IC;
#ifdef CHECKSUM_BY_HARDWARE
DMATxDescToSet->Status |= ETH_DMATxDesc_ChecksumTCPUDPICMPFull;
/* clean ICMP checksum STM32F need */
{
struct eth_hdr *ethhdr = (struct eth_hdr *)(DMATxDescToSet->Buffer1Addr);
/* is IP ? */
if( ethhdr->type == htons(ETHTYPE_IP) )
{
struct ip_hdr *iphdr = (struct ip_hdr *)(DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR);
/* is ICMP ? */
if( IPH_PROTO(iphdr) == IP_PROTO_ICMP )
{
struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)(DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR + sizeof(struct ip_hdr) );
iecho->chksum = 0;
}
}
}
#endif
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
DMATxDescToSet->Status |= ETH_DMATxDesc_OWN; DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
/* When Tx Buffer unavailable flag is set: clear it and resume transmission */ /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
@ -3362,6 +3394,9 @@ rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
ETH->DMASR = ETH_DMASR_TBUS; ETH->DMASR = ETH_DMASR_TBUS;
/* Transmit Poll Demand to resume DMA transmission*/ /* Transmit Poll Demand to resume DMA transmission*/
ETH->DMATPDR = 0; ETH->DMATPDR = 0;
#if STM32_ETH_DEBUG
rt_kprintf("transmit poll demand\n");
#endif
} }
/* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */ /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
@ -3406,6 +3441,12 @@ struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET) && ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET)) ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET))
{ {
#if STM32_ETH_DEBUG
int cnt = 0;
rt_kprintf("rx dump:\n");
#endif
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4; framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
@ -3426,10 +3467,18 @@ struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
while (len) while (len)
{ {
*ptr = (*(__IO uint8_t *)((DMARxDescToGet->Buffer1Addr) + offset)); *ptr = (*(__IO uint8_t *)((DMARxDescToGet->Buffer1Addr) + offset));
#if STM32_ETH_DEBUG
rt_kprintf("%02x ", *ptr);
if (++cnt % 16 == 0) rt_kprintf("\n");
#endif
offset ++; ptr ++; len --; offset ++; ptr ++; len --;
} }
} }
#if STM32_ETH_DEBUG
rt_kprintf("\n");
#endif
} }
} }
@ -3608,12 +3657,14 @@ void rt_hw_stm32_eth_init()
GPIO_Configuration(); GPIO_Configuration();
NVIC_Configuration(); NVIC_Configuration();
// OUI 00-80-E1 STMICROELECTRONICS
stm32_eth_device.dev_addr[0] = 0x00; stm32_eth_device.dev_addr[0] = 0x00;
stm32_eth_device.dev_addr[1] = 0x60; stm32_eth_device.dev_addr[1] = 0x80;
stm32_eth_device.dev_addr[2] = 0x6E; stm32_eth_device.dev_addr[2] = 0xE1;
stm32_eth_device.dev_addr[3] = 0x11; // generate MAC addr from 96bit unique ID (only for test)
stm32_eth_device.dev_addr[4] = 0x22; stm32_eth_device.dev_addr[3] = *(rt_uint8_t*)(0x1FFFF7E8+7);
stm32_eth_device.dev_addr[5] = 0x33; stm32_eth_device.dev_addr[4] = *(rt_uint8_t*)(0x1FFFF7E8+8);
stm32_eth_device.dev_addr[5] = *(rt_uint8_t*)(0x1FFFF7E8+9);
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;
@ -3626,8 +3677,8 @@ void rt_hw_stm32_eth_init()
stm32_eth_device.parent.eth_rx = rt_stm32_eth_rx; stm32_eth_device.parent.eth_rx = rt_stm32_eth_rx;
stm32_eth_device.parent.eth_tx = rt_stm32_eth_tx; stm32_eth_device.parent.eth_tx = rt_stm32_eth_tx;
/* init tx semaphore */ /* init tx buffer free semaphore */
rt_sem_init(&tx_wait, "tx_wait", 0, RT_IPC_FLAG_FIFO); rt_sem_init(&tx_buf_free, "tx_buf", ETH_TXBUFNB, RT_IPC_FLAG_FIFO);
/* register eth device */ /* register eth device */
eth_device_init(&(stm32_eth_device.parent), "e0"); eth_device_init(&(stm32_eth_device.parent), "e0");

View File

@ -51,7 +51,7 @@
/* Exported constants --------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the /* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */ Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT 1 */ #define USE_FULL_ASSERT 1
/* Exported macro ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT #ifdef USE_FULL_ASSERT

View File

@ -331,7 +331,7 @@
</ArmAdsMisc> </ArmAdsMisc>
<Cads> <Cads>
<interw>1</interw> <interw>1</interw>
<Optim>1</Optim> <Optim>4</Optim>
<oTime>0</oTime> <oTime>0</oTime>
<SplitLS>0</SplitLS> <SplitLS>0</SplitLS>
<OneElfS>0</OneElfS> <OneElfS>0</OneElfS>