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:
parent
3c0f80f2f7
commit
86b62f9026
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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(Ð_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(Ð_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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue