1201 lines
35 KiB
C
1201 lines
35 KiB
C
|
|
//*****************************************************************************
|
||
|
|
//
|
||
|
|
// Ensure that the lwIP compile time options are included first.
|
||
|
|
//
|
||
|
|
//*****************************************************************************
|
||
|
|
#include <stdint.h>
|
||
|
|
#include <stdbool.h>
|
||
|
|
#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 <os_cpu.h>
|
||
|
|
#include <os_cfg.h>
|
||
|
|
#include <ucos_ii.h>
|
||
|
|
#include <cpu.h>
|
||
|
|
#include <bsp_int.h>
|
||
|
|
#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.
|
||
|
|
//! @}
|
||
|
|
//
|
||
|
|
//*****************************************************************************
|