|
@@ -0,0 +1,361 @@
|
|
|
+#include "string.h"
|
|
|
+#include "includes.h"
|
|
|
+#include "lwip/netif.h"
|
|
|
+#include "arch/ethernetif.h"
|
|
|
+#include "arch/sys_arch.h"
|
|
|
+#include "lwip/init.h"
|
|
|
+#include "lwip/timers.h"
|
|
|
+#include "lwip/tcpip.h"
|
|
|
+#include "lwip/dhcp.h"
|
|
|
+#include "lwip/inet.h"
|
|
|
+
|
|
|
+struct netif gnetif;
|
|
|
+ETH_InitTypeDef ETH_InitStructure;
|
|
|
+uint32_t EthStatus = 0;
|
|
|
+
|
|
|
+
|
|
|
+//初始ETH设备端口
|
|
|
+void ETH_GPIO_Config(void)
|
|
|
+{
|
|
|
+ GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
+
|
|
|
+ /* Enable GPIOs clocks */
|
|
|
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE |
|
|
|
+ RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG, ENABLE);
|
|
|
+
|
|
|
+ /* Enable SYSCFG clock */
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
|
|
+
|
|
|
+ /* MII/RMII Media interface selection --------------------------------------*/
|
|
|
+ SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII);
|
|
|
+
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
|
|
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
|
|
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
|
|
+
|
|
|
+ /* Configure PA1, PA2 and PA7 */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7;
|
|
|
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
|
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
|
|
|
+
|
|
|
+ /* Configure PB5 and PB8 */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_10;
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_ETH);
|
|
|
+
|
|
|
+ /* Configure PC1, PC2, PC3, PC4 and PC5 */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
|
|
|
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
|
|
|
+ GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
|
|
|
+
|
|
|
+ /* Configure PG11, PG14 and PG13 */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14;
|
|
|
+ GPIO_Init(GPIOG, &GPIO_InitStructure);
|
|
|
+ GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH);
|
|
|
+ GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH);
|
|
|
+}
|
|
|
+
|
|
|
+//硬件复位PHY
|
|
|
+void ETH_PHY_RESET(void)
|
|
|
+{
|
|
|
+ GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
+
|
|
|
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
|
|
|
+
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
|
|
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
|
|
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
|
|
+ GPIO_Init(GPIOE, &GPIO_InitStructure);
|
|
|
+
|
|
|
+ GPIO_SetBits(GPIOE, GPIO_Pin_2);
|
|
|
+ systick_delayms(10);
|
|
|
+ GPIO_ResetBits(GPIOE, GPIO_Pin_2);
|
|
|
+ systick_delayms(10);
|
|
|
+ GPIO_SetBits(GPIOE, GPIO_Pin_2);
|
|
|
+ systick_delayms(10);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//配置以太网接收中断
|
|
|
+void ETH_NVIC_Config(void)
|
|
|
+{
|
|
|
+ NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
+
|
|
|
+ /* 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);
|
|
|
+
|
|
|
+ /* Enable the Ethernet Rx Interrupt */
|
|
|
+ ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
|
|
|
+ ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
|
|
|
+ ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//配置以太网外设
|
|
|
+static void ETH_MACDMA_Config(void)
|
|
|
+{
|
|
|
+ ETH_InitTypeDef ETH_InitStructure;
|
|
|
+
|
|
|
+ /* Enable ETHERNET clock */
|
|
|
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
|
|
|
+ RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
|
|
|
+
|
|
|
+ /* Reset ETHERNET on AHB Bus */
|
|
|
+ ETH_DeInit();
|
|
|
+
|
|
|
+ /* Software reset */
|
|
|
+ ETH_SoftwareReset();
|
|
|
+
|
|
|
+ /* Wait for software reset */
|
|
|
+ while (ETH_GetSoftwareResetStatus() == SET);
|
|
|
+
|
|
|
+ /* ETHERNET Configuration --------------------------------------------------*/
|
|
|
+ /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
|
|
|
+ ETH_StructInit(Ð_InitStructure);
|
|
|
+
|
|
|
+ /* Fill ETH_InitStructure parametrs */
|
|
|
+ /*------------------------ MAC -----------------------------------*/
|
|
|
+ ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
|
|
|
+ //ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
|
|
|
+ // ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
|
|
|
+ // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
|
|
|
+
|
|
|
+ ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
|
|
|
+ ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
|
|
|
+ ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
|
|
|
+ ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
|
|
|
+ ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
|
|
|
+ ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
|
|
|
+ ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
|
|
|
+ ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
|
|
|
+#ifdef CHECKSUM_BY_HARDWARE
|
|
|
+ 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,
|
|
|
+ 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;
|
|
|
+
|
|
|
+ /* Configure Ethernet */
|
|
|
+ if(ETH_Init(Ð_InitStructure, DP83848_PHY_ADDRESS)) EthStatus = ETH_INIT_FLAG;
|
|
|
+ else EthStatus = 0;
|
|
|
+}
|
|
|
+
|
|
|
+//获取phy连接状态 1:连接 0:断开
|
|
|
+uint8_t hd_ethGetPhyStatus(void)
|
|
|
+{
|
|
|
+ if(ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BSR) & 0x00000004) return 1;
|
|
|
+ else return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void ETH_BSP_Config(void)
|
|
|
+{
|
|
|
+ ETH_GPIO_Config();
|
|
|
+ ETH_PHY_RESET();
|
|
|
+ ETH_MACDMA_Config();
|
|
|
+ if(EthStatus & ETH_INIT_FLAG) ETH_NVIC_Config();
|
|
|
+ if(hd_ethGetPhyStatus()) EthStatus |= ETH_LINK_FLAG;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//以太网中断处理函数
|
|
|
+extern OS_EVENT *ETH_RecvDataSem;
|
|
|
+void ETH_IRQHandler(void)
|
|
|
+{
|
|
|
+ /* Frame received */
|
|
|
+ if (ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
|
|
|
+ {
|
|
|
+ OSSemPost(ETH_RecvDataSem);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Clear the interrupt flags. */
|
|
|
+ /* Clear the Eth DMA Rx IT pending bits */
|
|
|
+ ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
|
|
|
+ ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
|
|
|
+}
|
|
|
+
|
|
|
+///////////////////////////////////////////////////////PHY///////////////////////////////////////////////////////////////////////////
|
|
|
+void low_level_init(struct netif *netif);
|
|
|
+void hd_ethCheckLinkStatus(uint16_t phyAddr)
|
|
|
+{
|
|
|
+ uint8_t linksta = hd_ethGetPhyStatus();
|
|
|
+
|
|
|
+ if(EthStatus & ETH_INIT_FLAG)
|
|
|
+ {
|
|
|
+ if(EthStatus & ETH_LINK_FLAG)
|
|
|
+ {
|
|
|
+ if(linksta == 0)
|
|
|
+ {
|
|
|
+ netif_set_link_down(&gnetif);
|
|
|
+ EthStatus &= ~ETH_LINK_FLAG;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(linksta != 0)
|
|
|
+ {
|
|
|
+ netif_set_link_up(&gnetif);
|
|
|
+ EthStatus |= ETH_LINK_FLAG;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(linksta != 0)
|
|
|
+ {
|
|
|
+ low_level_init(&gnetif);
|
|
|
+ netif_set_link_up(&gnetif);
|
|
|
+#if LWIP_DHCP == 1
|
|
|
+ dhcp_start(&gnetif);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void eth_link_callback(struct netif *netif)
|
|
|
+{
|
|
|
+ __IO uint32_t timeout = 0;
|
|
|
+ uint32_t tmpreg,RegValue;
|
|
|
+
|
|
|
+ if(netif_is_link_up(netif))
|
|
|
+ {
|
|
|
+ printf("network is up");
|
|
|
+
|
|
|
+ if(ETH_InitStructure.ETH_AutoNegotiation != ETH_AutoNegotiation_Disable)
|
|
|
+ {
|
|
|
+ timeout = 0;
|
|
|
+ ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_BCR, PHY_AutoNegotiation);
|
|
|
+ do
|
|
|
+ {
|
|
|
+ timeout ++;
|
|
|
+ }while(!(ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO));
|
|
|
+
|
|
|
+ RegValue = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_SR);
|
|
|
+ if(RegValue & PHY_DUPLEX_STATUS) ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
|
|
|
+ else ETH_InitStructure.ETH_Mode = ETH_Mode_HalfDuplex;
|
|
|
+ if(RegValue & PHY_SPEED_STATUS) ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
|
|
|
+ else ETH_InitStructure.ETH_Speed = ETH_Speed_100M;
|
|
|
+
|
|
|
+ tmpreg = ETH->MACCR;
|
|
|
+ tmpreg |= (uint32_t)(ETH_InitStructure.ETH_Speed | ETH_InitStructure.ETH_Mode);
|
|
|
+ ETH->MACCR = (uint32_t)tmpreg;
|
|
|
+ _eth_delay_(ETH_REG_WRITE_DELAY);
|
|
|
+ tmpreg = ETH->MACCR;
|
|
|
+ ETH->MACCR = tmpreg;
|
|
|
+ }
|
|
|
+ ETH_Start();
|
|
|
+
|
|
|
+ netif_set_up(&gnetif);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf("network is down");
|
|
|
+ ETH_Stop();
|
|
|
+ netif_set_down(&gnetif);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ethphycheck_timer(void *arg)
|
|
|
+{
|
|
|
+ LWIP_UNUSED_ARG(arg);
|
|
|
+
|
|
|
+ hd_ethCheckLinkStatus(DP83848_PHY_ADDRESS);
|
|
|
+ sys_timeout(1000, ethphycheck_timer, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+///////////////////////////////////////////////////////LWIP///////////////////////////////////////////////////////////////////////////
|
|
|
+//初始化LWIP协议栈
|
|
|
+void lwIP_Init(void)
|
|
|
+{
|
|
|
+ struct ip_addr ipaddr;
|
|
|
+ struct ip_addr netmask;
|
|
|
+ struct ip_addr gw;
|
|
|
+
|
|
|
+ tcpip_init(NULL, NULL);
|
|
|
+
|
|
|
+#if LWIP_DHCP == 1
|
|
|
+ ip_addr_set_zero(&ipaddr);
|
|
|
+ ip_addr_set_zero(&netmask);
|
|
|
+ ip_addr_set_zero(&gw);
|
|
|
+#else
|
|
|
+// IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
|
|
|
+// IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
|
|
|
+// IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
|
|
|
+#endif
|
|
|
+
|
|
|
+ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ethernetif_init, tcpip_input);
|
|
|
+ netif_set_default(&gnetif);
|
|
|
+
|
|
|
+// netif_set_up(&gnetif);
|
|
|
+ if(EthStatus == (ETH_LINK_FLAG | ETH_INIT_FLAG))
|
|
|
+ {
|
|
|
+ gnetif.flags |= NETIF_FLAG_LINK_UP;
|
|
|
+ netif_set_up(&gnetif);
|
|
|
+ ETH_Start();
|
|
|
+
|
|
|
+#if LWIP_DHCP == 1
|
|
|
+ dhcp_start(&gnetif);
|
|
|
+ while(ip_addr_cmp(&(gnetif.ip_addr), &ipaddr))
|
|
|
+ {
|
|
|
+ OSTimeDly(10/(1000/OS_TICKS_PER_SEC));
|
|
|
+ }
|
|
|
+ printf("dhcp ip_addr is %s \r\n", inet_ntoa(gnetif.ip_addr));
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ netif_set_down(&gnetif);
|
|
|
+ gnetif.flags &= ~NETIF_FLAG_LINK_UP;
|
|
|
+ ETH_Stop();
|
|
|
+ }
|
|
|
+
|
|
|
+ netif_set_link_callback(&gnetif, eth_link_callback);
|
|
|
+ sys_timeout(2000, ethphycheck_timer, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|