#include struct netif if0; uint32_t sys_now (void) { return ticks; } void dispatch_lwip (void) { #if 0 /* check if any packet received */ if (ETH_CheckFrameReceived()) ethernetif_input (&if0); #endif #if 0 if (link_lost()) netif_set_down (&if0); if (link_gained()) netif_set_up (&if0); #endif sys_check_timeouts(); #if 0 /* Fine DHCP periodic process every 500ms */ if (localtime - DHCPfineTimer >= DHCP_FINE_TIMER_MSECS) { DHCPfineTimer = localtime; dhcp_fine_tmr(); if ((DHCP_state != DHCP_ADDRESS_ASSIGNED) && (DHCP_state != DHCP_TIMEOUT)) { /* toggle LED1 to indicate DHCP on-going process */ STM_EVAL_LEDToggle (LED1); /* process DHCP state machine */ LwIP_DHCP_Process_Handle(); } } /* DHCP Coarse periodic process every 60s */ if (localtime - DHCPcoarseTimer >= DHCP_COARSE_TIMER_MSECS) { DHCPcoarseTimer = localtime; dhcp_coarse_tmr(); } #endif } void start_lwip (void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; // uint8_t macaddress[6]={0,0,0,0,0,1}; lwip_init(); IP4_ADDR (&ipaddr, 10, 32, 48, 98); IP4_ADDR (&netmask, 255, 255, 255, 0); IP4_ADDR (&gw, 10, 32, 48, 1); //Set_MAC_Address(macaddress); /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) Adds your network interface to the netif_list. Allocate a struct netif and pass a pointer to this structure as the first argument. Give pointers to cleared ip_addr structures when using DHCP, or fill them with sane numbers otherwise. The state pointer may be NULL. The init function pointer must point to a initialization function for your ethernet netif interface. The following code illustrates it's use.*/ //netif_add(&if0, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernetif_input); netif_add (&if0, &ipaddr, &netmask, &gw, NULL, steth_lwip_init , ethernet_input); /* Registers the default network interface.*/ netif_set_default (&if0); netif_set_up (&if0); } #if 0 /** ****************************************************************************** * @file netconf.c * @author MCD Application Team * @version V1.0.0 * @date 11/20/2009 * @brief Network connection configuration ****************************************************************************** * @copy * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *

© COPYRIGHT 2009 STMicroelectronics

*/ #include "lwip/memp.h" #include "lwip/tcp.h" #include "lwip/udp.h" #include "netif/etharp.h" //include "lwip/dhcp.h" #include "ethernetif.h" #include #include "stm32f4x7_eth.h" #include #include "netconf.h" struct netif netif; uint32_t TCPTimer = 0; uint32_t ARPTimer = 0; /* Ethernet Rx & Tx DMA Descriptors */ extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; /* Ethernet Driver Receive buffers */ extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Driver Transmit buffers */ extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Global pointers to track current transmit and receive descriptors */ extern ETH_DMADESCTypeDef *DMATxDescToSet; extern ETH_DMADESCTypeDef *DMARxDescToGet; /* Put ethernet related stuff in struct so it causes less namespace pollution * and is easier to access from debugger */ struct { uint8_t connected_; uint16_t lost_links_; uint32_t last_link_up_time_; } ethernet_state; void send_raw_packet() { //ETH_TxPkt_ChainMode(l); } /** * @brief Initializes the lwIP stack * @param None * @retval None * * Should only be called once at start-up. Ethernet interface does not * need to have link for this to be called. */ /** \brief Checks PHY's link status * \returns true if there is a link, false if there is an error, or no link */ uint8_t checkEthernetLink() { // PHY_BSR -- defined in stm32f4x7_eth.h // The basic status register number for the Micrel KSZ8051MLL PHY is 0x1 // If MDIO read times out, ETH_ReadPHYRegister returns ETH_ERROR (0) which make link look down uint8_t has_link = (ETH_ReadPHYRegister (PHY_ADDRESS, PHY_BSR) & PHY_Linked_Status) ? 1 : 0; return has_link; } /** * @brief Called when a frame is received * @param None * @retval None */ void LwIP_Pkt_Handle (void) { /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */ ethernetif_input (&if0); } /** * @brief LwIP periodic tasks * @param localtime the current LocalTime value * @retval None */ #ifdef USE_DHCP /** * @brief LwIP_DHCP_Process_Handle * @param None * @retval None */ void LwIP_DHCP_Process_Handle() { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; uint8_t iptab[4]; uint8_t iptxt[20]; switch (DHCP_state) { case DHCP_START: { dhcp_start (&if0); IPaddress = 0; DHCP_state = DHCP_WAIT_ADDRESS; } break; case DHCP_WAIT_ADDRESS: { /* Read the new IP address */ IPaddress = netif.ip_addr.addr; if (IPaddress != 0) { DHCP_state = DHCP_ADDRESS_ASSIGNED; /* Stop DHCP */ dhcp_stop (&if0); } else { /* DHCP timeout */ if (netif.dhcp->tries > MAX_DHCP_TRIES) { DHCP_state = DHCP_TIMEOUT; /* Stop DHCP */ dhcp_stop (&if0); /* Static address used */ 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); netif_set_addr (&if0, &ipaddr , &netmask, &gw); } } } break; default: break; } } #endif /*void ETH_IRQHandler(void) { while(ETH_GetRxPktSize() != 0) { LwIP_Pkt_Handle(); } ETH_DMAClearITPendingBit(ETH_DMA_IT_R); ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS); }*/ /** * @brief Configures the Ethernet Interface * @param None * @retval ETH_ERROR on failure, ETH_SUCCESS on success * * Should be called everytime PHY gets a new link (in case link speed or duplex is differnet) * Before being called, ethernet link should be set to "down" with netif_set_down() * This prevents LwIP from attempt to send packets on link */ uint32_t Ethernet_Init (void) { /* Enable SYSCFG clock */ RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; /* Enable ETHERNET clock */ //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx | // RCC_AHBPeriph_ETH_MAC_Rx, ENABLE); //RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; ETH_InitTypeDef ETH_InitStructure; /* Configure MII_RMII selection bit */ SYSCFG_ETH_MediaInterfaceConfig (SYSCFG_ETH_MediaInterface_RMII); /* Reset ETHERNET on AHB Bus */ ETH_DeInit(); /* Software reset */ ETH_SoftwareReset(); //RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; /* Wait for software reset */ while (ETH_GetSoftwareResetStatus() == SET); RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; /* 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_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; /* initialize MAC address in ethernet MAC */ ETH_MACAddressConfig (ETH_MAC_Address0, netif.hwaddr); /* Configure Ethernet */ if (ETH_Init (Ð_InitStructure, PHY_ADDRESS) == ETH_ERROR) return ETH_ERROR; /* 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); #ifdef CHECKSUM_BY_HARDWARE /* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */ for (int i = 0; i < ETH_TXBUFNB; i++) ETH_DMATxDescChecksumInsertionConfig (&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull); #endif /* Note: TCP, UDP, ICMP checksum checking for received frame are enabled in DMA config */ /* Enable MAC and DMA transmission and reception */ ETH_Start(); /* Enable the Ethernet Rx Interrupt */ // ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE); // NVIC_InitTypeDef NVIC_InitStructure; /* MACCR has an errata where writes that occur next to each other can be ignored. * Have MACCR writen after a delay to guarentee that the register write goes through. */ { uint32_t i = 28 * 4; // delay about 4 us while (i-- > 0) __asm__ ("nop"); } ETH_MACReceptionCmd (ENABLE); /* 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_SetPriority(ETH_IRQn, 3); // NVIC_EnableIRQ(ETH_IRQn); return ETH_SUCCESS; } #endif