//***************************************************************************** // // Ensure that the lwIP compile time options are included first. // //***************************************************************************** #include #include #include "bsp_sys.h" #include "BSPLwip.h" #include "BSPSys.h" #include "netif/tivaif.h" //***************************************************************************** // // The lwIP Library abstration layer provides for a host callback function to // be called periodically in the lwIP context. This is the timer interval, in // ms, for this periodic callback. If the timer interval is defined to 0 (the // default value), then no periodic host callback is performed. // //***************************************************************************** #ifndef HOST_TMR_INTERVAL #define HOST_TMR_INTERVAL 0 #else extern void lwIPHostTimerHandler(void); #endif //***************************************************************************** // // The link detect polling interval. // //***************************************************************************** #define LINK_TMR_INTERVAL 10 //***************************************************************************** // // Set the PHY configuration to the default (internal) option if necessary. // //***************************************************************************** #ifndef EMAC_PHY_CONFIG #define EMAC_PHY_CONFIG (EMAC_PHY_TYPE_INTERNAL | \ EMAC_PHY_INT_MDIX_EN | \ EMAC_PHY_AN_100B_T_FULL_DUPLEX) #endif //***************************************************************************** // // Driverlib headers needed for this library module. // //***************************************************************************** #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_nvic.h" #include "inc/hw_emac.h" #include "driverlib/debug.h" #include "driverlib/emac.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #if !NO_SYS #include #include #include #include #include #endif //***************************************************************************** // // The lwIP network interface structure for the Tiva Ethernet MAC. // //***************************************************************************** static struct netif g_sNetIF; //***************************************************************************** // // The application's interrupt handler for hardware timer events from the MAC. // //***************************************************************************** tHardwareTimerHandler g_pfnTimerHandler; //***************************************************************************** // // The local time for the lwIP Library Abstraction layer, used to support the // Host and lwIP periodic callback functions. // //***************************************************************************** #if NO_SYS uint32_t g_ui32LocalTimer = 0; #endif //***************************************************************************** // // The local time when the TCP timer was last serviced. // //***************************************************************************** #if NO_SYS static uint32_t g_ui32TCPTimer = 0; #endif //***************************************************************************** // // The local time when the HOST timer was last serviced. // //***************************************************************************** #if NO_SYS && HOST_TMR_INTERVAL static uint32_t g_ui32HostTimer = 0; #endif //***************************************************************************** // // The local time when the ARP timer was last serviced. // //***************************************************************************** #if NO_SYS && LWIP_ARP static uint32_t g_ui32ARPTimer = 0; #endif //***************************************************************************** // // The local time when the AutoIP timer was last serviced. // //***************************************************************************** #if NO_SYS && LWIP_AUTOIP static uint32_t g_ui32AutoIPTimer = 0; #endif //***************************************************************************** // // The local time when the DHCP Coarse timer was last serviced. // //***************************************************************************** #if NO_SYS && LWIP_DHCP static uint32_t g_ui32DHCPCoarseTimer = 0; #endif //***************************************************************************** // // The local time when the DHCP Fine timer was last serviced. // //***************************************************************************** #if NO_SYS && LWIP_DHCP static uint32_t g_ui32DHCPFineTimer = 0; #endif //***************************************************************************** // // The local time when the IP Reassembly timer was last serviced. // //***************************************************************************** #if NO_SYS && IP_REASSEMBLY static uint32_t g_ui32IPReassemblyTimer = 0; #endif //***************************************************************************** // // The local time when the IGMP timer was last serviced. // //***************************************************************************** #if NO_SYS && LWIP_IGMP static uint32_t g_ui32IGMPTimer = 0; #endif //***************************************************************************** // // The local time when the DNS timer was last serviced. // //***************************************************************************** #if NO_SYS && LWIP_DNS static uint32_t g_ui32DNSTimer = 0; #endif //***************************************************************************** // // The local time when the link detect timer was last serviced. // //***************************************************************************** #if NO_SYS && (LWIP_AUTOIP || LWIP_DHCP) static uint32_t g_ui32LinkTimer = 0; #endif //***************************************************************************** // // The default IP address acquisition mode. // //***************************************************************************** static uint32_t g_ui32IPMode = IPADDR_USE_STATIC; //***************************************************************************** // // The most recently detected link state. // //***************************************************************************** #if LWIP_AUTOIP || LWIP_DHCP static bool g_bLinkActive = false; #endif //***************************************************************************** // // The IP address to be used. This is used during the initialization of the // stack and when the interface configuration is changed. // //***************************************************************************** static uint32_t g_ui32IPAddr; //***************************************************************************** // // The netmask to be used. This is used during the initialization of the stack // and when the interface configuration is changed. // //***************************************************************************** static uint32_t g_ui32NetMask; //***************************************************************************** // // The gateway address to be used. This is used during the initialization of // the stack and when the interface configuration is changed. // //***************************************************************************** static uint32_t g_ui32GWAddr; //***************************************************************************** // // The handle for the "queue" (semaphore) used to signal the interrupt task // from the interrupt handler. // //***************************************************************************** #if !NO_SYS #endif //***************************************************************************** // // This task handles reading packets from the Ethernet controller and supplying // them to the TCP/IP thread. // //***************************************************************************** //***************************************************************************** // // This function performs a periodic check of the link status and responds // appropriately if it has changed. // //***************************************************************************** #if LWIP_AUTOIP || LWIP_DHCP static void lwIPLinkDetect(void) { bool bHaveLink; struct ip_addr ip_addr; struct ip_addr net_mask; struct ip_addr gw_addr; // // See if there is an active link. // bHaveLink = EMACPHYRead(EMAC0_BASE, PHY_PHYS_ADDR, EPHY_BMSR) & EPHY_BMSR_LINKSTAT; // // Return without doing anything else if the link state hasn't changed. // if(bHaveLink == g_bLinkActive) { return; } // // Save the new link state. // g_bLinkActive = bHaveLink; // // Clear any address information from the network interface. // ip_addr.addr = 0; net_mask.addr = 0; gw_addr.addr = 0; netif_set_addr(&g_sNetIF, &ip_addr, &net_mask, &gw_addr); // // See if there is a link now. // if(bHaveLink) { // // Start DHCP, if enabled. // #if LWIP_DHCP if(g_ui32IPMode == IPADDR_USE_DHCP) { dhcp_start(&g_sNetIF); } #endif // // Start AutoIP, if enabled and DHCP is not. // #if LWIP_AUTOIP if(g_ui32IPMode == IPADDR_USE_AUTOIP) { autoip_start(&g_sNetIF); } #endif } else { // // Stop DHCP, if enabled. // #if LWIP_DHCP if(g_ui32IPMode == IPADDR_USE_DHCP) { dhcp_stop(&g_sNetIF); } #endif // // Stop AutoIP, if enabled and DHCP is not. // #if LWIP_AUTOIP if(g_ui32IPMode == IPADDR_USE_AUTOIP) { autoip_stop(&g_sNetIF); } #endif } } #endif //***************************************************************************** // // This function services all of the lwIP periodic timers, including TCP and // Host timers. This should be called from the lwIP context, which may be // the Ethernet interrupt (in the case of a non-RTOS system) or the lwIP // thread, in the event that an RTOS is used. // //***************************************************************************** #if NO_SYS static void lwIPServiceTimers(void) { // // Service the host timer. // #if HOST_TMR_INTERVAL if((g_ui32LocalTimer - g_ui32HostTimer) >= HOST_TMR_INTERVAL) { g_ui32HostTimer = g_ui32LocalTimer; lwIPHostTimerHandler(); } #endif // // Service the ARP timer. // #if LWIP_ARP if((g_ui32LocalTimer - g_ui32ARPTimer) >= ARP_TMR_INTERVAL) { g_ui32ARPTimer = g_ui32LocalTimer; etharp_tmr(); } #endif // // Service the TCP timer. // #if LWIP_TCP if((g_ui32LocalTimer - g_ui32TCPTimer) >= TCP_TMR_INTERVAL) { g_ui32TCPTimer = g_ui32LocalTimer; tcp_tmr(); } #endif // // Service the AutoIP timer. // #if LWIP_AUTOIP if((g_ui32LocalTimer - g_ui32AutoIPTimer) >= AUTOIP_TMR_INTERVAL) { g_ui32AutoIPTimer = g_ui32LocalTimer; autoip_tmr(); } #endif // // Service the DCHP Coarse Timer. // #if LWIP_DHCP if((g_ui32LocalTimer - g_ui32DHCPCoarseTimer) >= DHCP_COARSE_TIMER_MSECS) { g_ui32DHCPCoarseTimer = g_ui32LocalTimer; dhcp_coarse_tmr(); } #endif // // Service the DCHP Fine Timer. // #if LWIP_DHCP if((g_ui32LocalTimer - g_ui32DHCPFineTimer) >= DHCP_FINE_TIMER_MSECS) { g_ui32DHCPFineTimer = g_ui32LocalTimer; dhcp_fine_tmr(); } #endif // // Service the IP Reassembly Timer // #if IP_REASSEMBLY if((g_ui32LocalTimer - g_ui32IPReassemblyTimer) >= IP_TMR_INTERVAL) { g_ui32IPReassemblyTimer = g_ui32LocalTimer; ip_reass_tmr(); } #endif // // Service the IGMP Timer // #if LWIP_IGMP if((g_ui32LocalTimer - g_ui32IGMPTimer) >= IGMP_TMR_INTERVAL) { g_ui32IGMPTimer = g_ui32LocalTimer; igmp_tmr(); } #endif // // Service the DNS Timer // #if LWIP_DNS if((g_ui32LocalTimer - g_ui32DNSTimer) >= DNS_TMR_INTERVAL) { g_ui32DNSTimer = g_ui32LocalTimer; dns_tmr(); } #endif // // Service the link timer. // #if LWIP_AUTOIP || LWIP_DHCP if((g_ui32LocalTimer - g_ui32LinkTimer) >= LINK_TMR_INTERVAL) { g_ui32LinkTimer = g_ui32LocalTimer; lwIPLinkDetect(); } #endif } #endif //***************************************************************************** // // Handles the timeout for the host callback function timer when using a RTOS. // //***************************************************************************** #if !NO_SYS && HOST_TMR_INTERVAL static void lwIPPrivateHostTimer(void *pvArg) { // // Call the application-supplied host timer callback function. // lwIPHostTimerHandler(); // // Re-schedule the host timer callback function timeout. // sys_timeout(HOST_TMR_INTERVAL, lwIPPrivateHostTimer, NULL); } #endif //***************************************************************************** // // Handles the timeout for the link detect timer when using a RTOS. // //***************************************************************************** #if !NO_SYS && (LWIP_AUTOIP || LWIP_DHCP) static void lwIPPrivateLinkTimer(void *pvArg) { // // Perform the link detection. // lwIPLinkDetect(); // // Re-schedule the link detect timer timeout. // sys_timeout(LINK_TMR_INTERVAL, lwIPPrivateLinkTimer, NULL); } #endif void BSP_LwipInit(NETWORK_IPADDR IpAddr, NETWORK_IPADDR MaskAddr, NETWORK_IPADDR GwAddr, uint64_t Mac) { uint8_t pui8MACArray[6]; struct ip_addr ip_addr; struct ip_addr net_mask; struct ip_addr gw_addr; // MAC地址分解 pui8MACArray[0] = Mac & 0xff; pui8MACArray[1] = (Mac & 0xff00) >> 8; pui8MACArray[2] = (Mac & 0xff0000) >> 16; pui8MACArray[3] = (Mac & 0xff000000) >> 24; pui8MACArray[4] = (Mac & 0xff00000000) >> 32; pui8MACArray[5] = (Mac & 0xff0000000000) >> 40; // IP地址组合 ip_addr.addr = (((uint32_t)IpAddr.Addr0) << 24) | (((uint32_t)IpAddr.Addr1) << 16) | (((uint32_t)IpAddr.Addr2) << 8) | ((uint32_t)IpAddr.Addr3); net_mask.addr = (((uint32_t)MaskAddr.Addr0) << 24) | (((uint32_t)MaskAddr.Addr1) << 16) | (((uint32_t)MaskAddr.Addr2) << 8) | ((uint32_t)MaskAddr.Addr3); gw_addr.addr = (((uint32_t)GwAddr.Addr0) << 24) | (((uint32_t)GwAddr.Addr1) << 16) | (((uint32_t)GwAddr.Addr2) << 8) | ((uint32_t)GwAddr.Addr3); // lwIP初始化调用 lwIPInit(BspGetSysClock(), pui8MACArray, ip_addr.addr, net_mask.addr, gw_addr.addr, IPADDR_USE_STATIC); } //***************************************************************************** // // Completes the initialization of lwIP. This is directly called when not // using a RTOS and provided as a callback to the TCP/IP thread when using a // RTOS. // //***************************************************************************** static void lwIPPrivateInit(void *pvArg) { struct ip_addr ip_addr; struct ip_addr net_mask; struct ip_addr gw_addr; // // If not using a RTOS, initialize the lwIP stack. // #if NO_SYS lwip_init(); #endif // // If using a RTOS, create a queue (to be used as a semaphore) to signal // the Ethernet interrupt task from the Ethernet interrupt handler. // #if !NO_SYS #endif // // Setup the network address values. // if(g_ui32IPMode == IPADDR_USE_STATIC) { ip_addr.addr = htonl(g_ui32IPAddr); net_mask.addr = htonl(g_ui32NetMask); gw_addr.addr = htonl(g_ui32GWAddr); } else { ip_addr.addr = 0; net_mask.addr = 0; gw_addr.addr = 0; } // // Create, configure and add the Ethernet controller interface with // default settings. ip_input should be used to send packets directly to // the stack when not using a RTOS and tcpip_input should be used to send // packets to the TCP/IP thread's queue when using a RTOS. // #if NO_SYS netif_add(&g_sNetIF, &ip_addr, &net_mask, &gw_addr, NULL, tivaif_init, ip_input); #else netif_add(&g_sNetIF, &ip_addr, &net_mask, &gw_addr, NULL, tivaif_init, tcpip_input); #endif netif_set_default(&g_sNetIF); // // Bring the interface up. // netif_set_up(&g_sNetIF); // // Setup a timeout for the host timer callback function if using a RTOS. // #if !NO_SYS && HOST_TMR_INTERVAL sys_timeout(HOST_TMR_INTERVAL, lwIPPrivateHostTimer, NULL); #endif // // Setup a timeout for the link detect callback function if using a RTOS. // #if !NO_SYS && (LWIP_AUTOIP || LWIP_DHCP) sys_timeout(LINK_TMR_INTERVAL, lwIPPrivateLinkTimer, NULL); #endif } //***************************************************************************** // //! Initializes the lwIP TCP/IP stack. //! //! \param ui32SysClkHz is the current system clock rate in Hz. //! \param pui8MAC is a pointer to a six byte array containing the MAC //! address to be used for the interface. //! \param ui32IPAddr is the IP address to be used (static). //! \param ui32NetMask is the network mask to be used (static). //! \param ui32GWAddr is the Gateway address to be used (static). //! \param ui32IPMode is the IP Address Mode. \b IPADDR_USE_STATIC will force //! static IP addressing to be used, \b IPADDR_USE_DHCP will force DHCP with //! fallback to Link Local (Auto IP), while \b IPADDR_USE_AUTOIP will force //! Link Local only. //! //! This function performs initialization of the lwIP TCP/IP stack for the //! Ethernet MAC, including DHCP and/or AutoIP, as configured. //! //! \return None. // //***************************************************************************** void lwIPInit(uint32_t ui32SysClkHz, const uint8_t *pui8MAC, uint32_t ui32IPAddr, uint32_t ui32NetMask, uint32_t ui32GWAddr, uint32_t ui32IPMode) { // 参数选择 #if LWIP_DHCP && LWIP_AUTOIP ASSERT((ui32IPMode == IPADDR_USE_STATIC) || (ui32IPMode == IPADDR_USE_DHCP) || (ui32IPMode == IPADDR_USE_AUTOIP)); #elif LWIP_DHCP ASSERT((ui32IPMode == IPADDR_USE_STATIC) || (ui32IPMode == IPADDR_USE_DHCP)); #elif LWIP_AUTOIP ASSERT((ui32IPMode == IPADDR_USE_STATIC) || (ui32IPMode == IPADDR_USE_AUTOIP)); #else ASSERT(ui32IPMode == IPADDR_USE_STATIC); #endif // 以太网外设启动 SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0); SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0); // PHY配置 if ((EMAC_PHY_CONFIG & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_INTERNAL) { if (SysCtlPeripheralPresent(SYSCTL_PERIPH_EPHY0)) { SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0); SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0); } else { while (1) {} // Internal PHY is not present on this part so hang here. } } // 等待MAC复位完成 while (!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0)) {} // 配置PHY EMACPHYConfigSet(EMAC0_BASE, EMAC_PHY_CONFIG); // 初始化MAC EMACInit(EMAC0_BASE, ui32SysClkHz, EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4, 0); // 设置MAC配置选项 EMACConfigSet(EMAC0_BASE, (EMAC_CONFIG_FULL_DUPLEX | EMAC_CONFIG_CHECKSUM_OFFLOAD | EMAC_CONFIG_7BYTE_PREAMBLE | EMAC_CONFIG_IF_GAP_96BITS | EMAC_CONFIG_USE_MACADDR0 | EMAC_CONFIG_SA_FROM_DESCRIPTOR | EMAC_CONFIG_BO_LIMIT_1024), (EMAC_MODE_RX_STORE_FORWARD | EMAC_MODE_TX_STORE_FORWARD | EMAC_MODE_TX_THRESHOLD_64_BYTES | EMAC_MODE_RX_THRESHOLD_64_BYTES), 0); // 设置MAC地址 EMACAddrSet(EMAC0_BASE, 0, (uint8_t *)pui8MAC); // 将 IP 地址、子网掩码和网关地址保存到全局变量中,以便后续使用。 g_ui32IPMode = ui32IPMode; g_ui32IPAddr = ui32IPAddr; g_ui32NetMask = ui32NetMask; g_ui32GWAddr = ui32GWAddr; // lwIP初始化 #if NO_SYS lwIPPrivateInit(0); #else tcpip_init(lwIPPrivateInit, 0); #endif } //***************************************************************************** // //! Registers an interrupt callback function to handle the IEEE-1588 timer. //! //! \param pfnTimerFunc points to a function which is called whenever the //! Ethernet MAC reports an interrupt relating to the IEEE-1588 hardware timer. //! //! This function allows an application to register a handler for all //! interrupts generated by the IEEE-1588 hardware timer in the Ethernet MAC. //! To allow minimal latency timer handling, the callback function provided //! will be called in interrupt context, regardless of whether or not lwIP is //! configured to operate with an RTOS. In an RTOS environment, the callback //! function is responsible for ensuring that all processing it performs is //! compatible with the low level interrupt context it is called in. //! //! The callback function takes two parameters. The first is the base address //! of the MAC reporting the timer interrupt and the second is the timer //! interrupt status as reported by EMACTimestampIntStatus(). Note that //! EMACTimestampIntStatus() causes the timer interrupt sources to be cleared //! so the application should not call EMACTimestampIntStatus() within the //! handler. //! //! \return None. // //***************************************************************************** void lwIPTimerCallbackRegister(tHardwareTimerHandler pfnTimerFunc) { // // Remember the callback function address passed. // g_pfnTimerHandler = pfnTimerFunc; } //***************************************************************************** // //! Handles periodic timer events for the lwIP TCP/IP stack. //! //! \param ui32TimeMS is the incremental time for this periodic interrupt. //! //! This function will update the local timer by the value in \e ui32TimeMS. //! If the system is configured for use without an RTOS, an Ethernet interrupt //! will be triggered to allow the lwIP periodic timers to be serviced in the //! Ethernet interrupt. //! //! \return None. // //***************************************************************************** #if NO_SYS void lwIPTimer(uint32_t ui32TimeMS) { // // Increment the lwIP Ethernet timer. // g_ui32LocalTimer += ui32TimeMS; // // Generate an Ethernet interrupt. This will perform the actual work // of checking the lwIP timers and taking the appropriate actions. This is // needed since lwIP is not re-entrant, and this allows all lwIP calls to // be placed inside the Ethernet interrupt handler ensuring that all calls // into lwIP are coming from the same context, preventing any reentrancy // issues. Putting all the lwIP calls in the Ethernet interrupt handler // avoids the use of mutexes to avoid re-entering lwIP. // HWREG(NVIC_SW_TRIG) |= INT_EMAC0 - 16; } #endif //***************************************************************************** // //! Handles Ethernet interrupts for the lwIP TCP/IP stack. //! //! This function handles Ethernet interrupts for the lwIP TCP/IP stack. At //! the lowest level, all receive packets are placed into a packet queue for //! processing at a higher level. Also, the transmit packet queue is checked //! and packets are drained and transmitted through the Ethernet MAC as needed. //! If the system is configured without an RTOS, additional processing is //! performed at the interrupt level. The packet queues are processed by the //! lwIP TCP/IP code, and lwIP periodic timers are serviced (as needed). //! //! \return None. // //***************************************************************************** void lwIPEthernetIntHandler(void) { uint32_t ui32Status; uint32_t ui32TimerStatus; CPU_SR_ALLOC(); #if !NO_SYS OSIntEnter(); OS_ENTER_CRITICAL(); #endif // // Read and Clear the interrupt. // ui32Status = EMACIntStatus(EMAC0_BASE, true); #if EEE_SUPPORT if(ui32Status & EMAC_INT_LPI) { EMACLPIStatus(EMAC0_BASE); } #endif // // If the PMT mode exit status bit is set then enable the MAC transmit // and receive paths, read the PMT status to clear the interrupt and // clear the interrupt flag. // if(ui32Status & EMAC_INT_POWER_MGMNT) { EMACTxEnable(EMAC0_BASE); EMACRxEnable(EMAC0_BASE); EMACPowerManagementStatusGet(EMAC0_BASE); ui32Status &= ~(EMAC_INT_POWER_MGMNT); } // // If the interrupt really came from the Ethernet and not our // timer, clear it. // if(ui32Status) { EMACIntClear(EMAC0_BASE, ui32Status); } // // Check to see whether a hardware timer interrupt has been reported. // if(ui32Status & EMAC_INT_TIMESTAMP) { // // Yes - read and clear the timestamp interrupt status. // ui32TimerStatus = EMACTimestampIntStatus(EMAC0_BASE); // // If a timer interrupt handler has been registered, call it. // if(g_pfnTimerHandler) { g_pfnTimerHandler(EMAC0_BASE, ui32TimerStatus); } } // // The handling of the interrupt is different based on the use of a RTOS. // #if NO_SYS // // No RTOS is being used. If a transmit/receive interrupt was active, // run the low-level interrupt handler. // if(ui32Status) { tivaif_interrupt(&g_sNetIF, ui32Status); } // // Service the lwIP timers. // lwIPServiceTimers(); #else if( ui32Status ) { tivaif_interrupt(&g_sNetIF, ui32Status); } // // Potentially task switch as a result of the above queue write. // OS_EXIT_CRITICAL(); OSIntExit(); #endif } //***************************************************************************** // //! Returns the IP address for this interface. //! //! This function will read and return the currently assigned IP address for //! the Stellaris Ethernet interface. //! //! \return Returns the assigned IP address for this interface. // //***************************************************************************** uint32_t lwIPLocalIPAddrGet(void) { #if LWIP_AUTOIP || LWIP_DHCP if(g_bLinkActive) { return((uint32_t)g_sNetIF.ip_addr.addr); } else { return(0xffffffff); } #else return((uint32_t)g_sNetIF.ip_addr.addr); #endif } //***************************************************************************** // //! Returns the network mask for this interface. //! //! This function will read and return the currently assigned network mask for //! the Stellaris Ethernet interface. //! //! \return the assigned network mask for this interface. // //***************************************************************************** uint32_t lwIPLocalNetMaskGet(void) { return((uint32_t)g_sNetIF.netmask.addr); } //***************************************************************************** // //! Returns the gateway address for this interface. //! //! This function will read and return the currently assigned gateway address //! for the Stellaris Ethernet interface. //! //! \return the assigned gateway address for this interface. // //***************************************************************************** uint32_t lwIPLocalGWAddrGet(void) { return((uint32_t)g_sNetIF.gw.addr); } //***************************************************************************** // //! Returns the local MAC/HW address for this interface. //! //! \param pui8MAC is a pointer to an array of bytes used to store the MAC //! address. //! //! This function will read the currently assigned MAC address into the array //! passed in \e pui8MAC. //! //! \return None. // //***************************************************************************** void lwIPLocalMACGet(uint8_t *pui8MAC) { EMACAddrGet(EMAC0_BASE, 0, pui8MAC); } //***************************************************************************** // // Completes the network configuration change. This is directly called when // not using a RTOS and provided as a callback to the TCP/IP thread when using // a RTOS. // //***************************************************************************** static void lwIPPrivateNetworkConfigChange(void *pvArg) { uint32_t ui32IPMode; struct ip_addr ip_addr; struct ip_addr net_mask; struct ip_addr gw_addr; // // Get the new address mode. // ui32IPMode = (uint32_t)pvArg; // // Setup the network address values. // if(ui32IPMode == IPADDR_USE_STATIC) { ip_addr.addr = htonl(g_ui32IPAddr); net_mask.addr = htonl(g_ui32NetMask); gw_addr.addr = htonl(g_ui32GWAddr); } #if LWIP_DHCP || LWIP_AUTOIP else { ip_addr.addr = 0; net_mask.addr = 0; gw_addr.addr = 0; } #endif // // Switch on the current IP Address Aquisition mode. // switch(g_ui32IPMode) { // // Static IP // case IPADDR_USE_STATIC: { // // Set the new address parameters. This will change the address // configuration in lwIP, and if necessary, will reset any links // that are active. This is valid for all three modes. // netif_set_addr(&g_sNetIF, &ip_addr, &net_mask, &gw_addr); // // If we are going to DHCP mode, then start the DHCP server now. // #if LWIP_DHCP if((ui32IPMode == IPADDR_USE_DHCP) && g_bLinkActive) { dhcp_start(&g_sNetIF); } #endif // // If we are going to AutoIP mode, then start the AutoIP process // now. // #if LWIP_AUTOIP if((ui32IPMode == IPADDR_USE_AUTOIP) && g_bLinkActive) { autoip_start(&g_sNetIF); } #endif // // And we're done. // break; } // // DHCP (with AutoIP fallback). // #if LWIP_DHCP case IPADDR_USE_DHCP: { // // If we are going to static IP addressing, then disable DHCP and // force the new static IP address. // if(ui32IPMode == IPADDR_USE_STATIC) { dhcp_stop(&g_sNetIF); netif_set_addr(&g_sNetIF, &ip_addr, &net_mask, &gw_addr); } // // If we are going to AUTO IP addressing, then disable DHCP, set // the default addresses, and start AutoIP. // #if LWIP_AUTOIP else if(ui32IPMode == IPADDR_USE_AUTOIP) { dhcp_stop(&g_sNetIF); netif_set_addr(&g_sNetIF, &ip_addr, &net_mask, &gw_addr); if(g_bLinkActive) { autoip_start(&g_sNetIF); } } #endif break; } #endif // // AUTOIP // #if LWIP_AUTOIP case IPADDR_USE_AUTOIP: { // // If we are going to static IP addressing, then disable AutoIP and // force the new static IP address. // if(ui32IPMode == IPADDR_USE_STATIC) { autoip_stop(&g_sNetIF); netif_set_addr(&g_sNetIF, &ip_addr, &net_mask, &gw_addr); } // // If we are going to DHCP addressing, then disable AutoIP, set the // default addresses, and start dhcp. // #if LWIP_DHCP else if(ui32IPMode == IPADDR_USE_DHCP) { autoip_stop(&g_sNetIF); netif_set_addr(&g_sNetIF, &ip_addr, &net_mask, &gw_addr); if(g_bLinkActive) { dhcp_start(&g_sNetIF); } } #endif break; } #endif } // // Bring the interface up. // netif_set_up(&g_sNetIF); // // Save the new mode. // g_ui32IPMode = ui32IPMode; } //***************************************************************************** // //! Change the configuration of the lwIP network interface. //! //! \param ui32IPAddr is the new IP address to be used (static). //! \param ui32NetMask is the new network mask to be used (static). //! \param ui32GWAddr is the new Gateway address to be used (static). //! \param ui32IPMode is the IP Address Mode. \b IPADDR_USE_STATIC 0 will //! force static IP addressing to be used, \b IPADDR_USE_DHCP will force DHCP //! with fallback to Link Local (Auto IP), while \b IPADDR_USE_AUTOIP will //! force Link Local only. //! //! This function will evaluate the new configuration data. If necessary, the //! interface will be brought down, reconfigured, and then brought back up //! with the new configuration. //! //! \return None. // //***************************************************************************** void lwIPNetworkConfigChange(uint32_t ui32IPAddr, uint32_t ui32NetMask, uint32_t ui32GWAddr, uint32_t ui32IPMode) { // // Check the parameters. // #if LWIP_DHCP && LWIP_AUTOIP ASSERT((ui32IPMode == IPADDR_USE_STATIC) || (ui32IPMode == IPADDR_USE_DHCP) || (ui32IPMode == IPADDR_USE_AUTOIP)); #elif LWIP_DHCP ASSERT((ui32IPMode == IPADDR_USE_STATIC) || (ui32IPMode == IPADDR_USE_DHCP)); #elif LWIP_AUTOIP ASSERT((ui32IPMode == IPADDR_USE_STATIC) || (ui32IPMode == IPADDR_USE_AUTOIP)); #else ASSERT(ui32IPMode == IPADDR_USE_STATIC); #endif // // Save the network configuration for later use by the private network // configuration change. // g_ui32IPAddr = ui32IPAddr; g_ui32NetMask = ui32NetMask; g_ui32GWAddr = ui32GWAddr; // // Complete the network configuration change. The remainder is done // immediately if not using a RTOS and it is deferred to the TCP/IP // thread's context if using a RTOS. // #if NO_SYS lwIPPrivateNetworkConfigChange((void *)ui32IPMode); #else tcpip_callback(lwIPPrivateNetworkConfigChange, (void *)ui32IPMode); #endif } void lwIPHostTimerHandler(void) { } //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************