#include <eComms.h>
#include <timerUtils.h>
#include <httpPort.h> // your appcall for uip
#include <hw_ints.h>
#include <hw_nvic.h>
#include <sysctl.h>
#include <interrupt.h>
#include <gpio.h>
#include <ethernet.h>
#include <lmi_flash.h>
// uip tcp/ip stack
#include <uip.h>
#include <uip_arp.h>
//*****************************************************************************
// Macro for accessing the Ethernet header information in the buffer.
//*****************************************************************************
#define DEFAULT_IPADDR0 169
#define DEFAULT_IPADDR1 254
#define DEFAULT_IPADDR2 19
#define DEFAULT_IPADDR3 63
#define DEFAULT_NETMASK0 255
#define DEFAULT_NETMASK1 255
#define DEFAULT_NETMASK2 0
#define DEFAULT_NETMASK3 0
#define ETHERNET_PERIODIC_TIMEOUT_PERIOD 500 // ms
#define ETHERNET_PERIODIC_PRIORITY 6
UINT ethernetPeriodicEvent;
#define ETHERNET_ARP_TIMEOUT_PERIOD 10000 // 10 sec
#define ETHERNET_ARP_PRIORITY 7
UINT ethernetARPEvent;
#define ETHERNET_RX_INTERRUPT_PRIORITY 1 // highest
UINT ethernetRxInterruptEvent;
//*****************************************************************************
// The interrupt handler for the Ethernet interrupt.
//*****************************************************************************
void EthernetIntHandler(void) {
// Read and Clear the interrupt.
UINT netStatus = EthernetIntStatus(ETH_BASE, false);
EthernetIntClear(ETH_BASE, netStatus);
// Check to see if an RX Interrupt has occured.
if(netStatus & ETH_INT_RX) {
EthernetIntDisable(ETH_BASE, ETH_INT_RX);
eventReady(ethernetRxInterruptEvent);
}
}
//*****************************************************************************
// locals
//*****************************************************************************
void processNetworkARP(void) {
uip_arp_timer();
}
void processNetworkPeriodic(void) {
UINT conn;
for(conn = 0; conn < UIP_CONNS; conn++) {
uip_periodic(conn);
// If the above function invocation resulted in data that
// should be sent out on the network, the global variable
// uip_len is set to a value > 0.
if(uip_len > 0) {
uip_arp_out();
EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
uip_len = 0;
}
}
#if UIP_UDP
for(conn = 0; conn < UIP_UDP_CONNS; conn++)
{
uip_udp_periodic(i);
// If the above function invocation resulted in data that
// should be sent out on the network, the global variable
// uip_len is set to a value > 0.
if(uip_len > 0)
{
uip_arp_out();
EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
uip_len = 0;
}
}
#endif // UIP_UDP
}
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
void processNetworkInterrupt(void) {
long lPacketLength;
// Check for an RX Packet and read it.
lPacketLength =
EthernetPacketGetNonBlocking(ETH_BASE, uip_buf, sizeof(uip_buf));
if(lPacketLength > 0) {
// Set uip_len for uIP stack usage.
uip_len = (unsigned short)lPacketLength;
// renable RX Packet interrupts.
EthernetIntEnable(ETH_BASE, ETH_INT_RX);
// Process incoming IP packets here.
if(BUF->type == htons(UIP_ETHTYPE_IP)) {
uip_arp_ipin();
uip_input();
// If the above function invocation resulted in data that
// should be sent out on the network, the global variable
// uip_len is set to a value > 0.
if(uip_len > 0) {
uip_arp_out();
EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
uip_len = 0;
}
} else {
if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
// Process incoming ARP packets here.
uip_arp_arpin();
// If the above function invocation resulted in data that
// should be sent out on the network, the global variable
// uip_len is set to a value > 0.
if(uip_len > 0) {
EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
uip_len = 0;
}
}
}
} // packet rx'd
}
//*****************************************************************************
// implementations
//*****************************************************************************
BYTE initEComms(void) {
uip_ipaddr_t ipaddr;
// Check for presence of Ethernet Controller.
if(!SysCtlPeripheralPresent(SYSCTL_PERIPH_ETH)) {
return ECOMMS_NO_NETWORK;
}
// Enable and Reset the Ethernet Controller.
SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);
// Enable Port F for Ethernet LEDs.
// LED0 Bit 3 Output
// LED1 Bit 2 Output
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3, GPIO_DIR_MODE_HW);
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3,
GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
// Intialize the Ethernet Controller and disable all Ethernet Controller
// interrupt sources.
EthernetIntDisable(ETH_BASE, (ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER |
ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER | ETH_INT_RX));
UINT netStatus = EthernetIntStatus(ETH_BASE, false);
EthernetIntClear(ETH_BASE, netStatus);
// Initialize the Ethernet Controller for operation.
EthernetInitExpClk(ETH_BASE, SysCtlClockGet());
// Configure the Ethernet Controller for normal operation.
// - Full Duplex
// - TX CRC Auto Generation
// - TX Padding Enabled
EthernetConfigSet(ETH_BASE, (ETH_CFG_TX_DPLXEN | ETH_CFG_TX_CRCEN |
ETH_CFG_TX_PADEN));
// Enable the Ethernet Controller.
EthernetEnable(ETH_BASE);
// Enable the Ethernet RX Packet interrupt source.
EthernetIntEnable(ETH_BASE, ETH_INT_RX);
// Initialize the uIP TCP/IP stack.
uip_init();
uip_ipaddr( ipaddr,
DEFAULT_IPADDR0,
DEFAULT_IPADDR1,
DEFAULT_IPADDR2,
DEFAULT_IPADDR3);
uip_sethostaddr(ipaddr);
uip_ipaddr( ipaddr,
DEFAULT_NETMASK0,
DEFAULT_NETMASK1,
DEFAULT_NETMASK2,
DEFAULT_NETMASK3);
uip_setnetmask(ipaddr);
// Configure the hardware MAC address for Ethernet Controller filtering of
// incoming packets.
//
// For the Ethernet Eval Kits, the MAC address will be stored in the
// non-volatile USER0 and USER1 registers. These registers can be read
// using the FlashUserGet function, as illustrated below.
unsigned long ulUser0, ulUser1;
FlashUserGet(&ulUser0, &ulUser1);
if((ulUser0 == 0xffffffff) || (ulUser1 == 0xffffffff)) {
// We should never get here. This is an error if the MAC address has
// not been programmed into the device. Exit the program.
return ECOMMS_NO_MAC_ADDRESS;
}
// Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
// address needed to program the hardware registers, then program the MAC
// address into the Ethernet Controller registers.
struct uip_eth_addr sTempAddr;
sTempAddr.addr[0] = ((ulUser0 >> 0) & 0xff);
sTempAddr.addr[1] = ((ulUser0 >> 8) & 0xff);
sTempAddr.addr[2] = ((ulUser0 >> 16) & 0xff);
sTempAddr.addr[3] = ((ulUser1 >> 0) & 0xff);
sTempAddr.addr[4] = ((ulUser1 >> 8) & 0xff);
sTempAddr.addr[5] = ((ulUser1 >> 16) & 0xff);
// Program the hardware with it's MAC address (for filtering).
EthernetMACAddrSet(ETH_BASE, (unsigned char *)&sTempAddr);
uip_setethaddr(sTempAddr);
// Initialize the TCP/IP Application (e.g. web server).
initHttpPort();
ethernetPeriodicEvent = getEventId(
CYCLIC_TIMER,
ETHERNET_PERIODIC_TIMEOUT_PERIOD,
ETHERNET_PERIODIC_PRIORITY,
processNetworkPeriodic);
ethernetARPEvent = getEventId(
CYCLIC_TIMER,
ETHERNET_ARP_TIMEOUT_PERIOD,
ETHERNET_ARP_PRIORITY,
processNetworkARP);
ethernetRxInterruptEvent = getEventId(
INTERRUPT,
INT_ETH,
ETHERNET_RX_INTERRUPT_PRIORITY,
processNetworkInterrupt);
return ECOMMS_NETWORK_OK;
}
void startEComms(void) {
startEvent(ethernetPeriodicEvent);
startEvent(ethernetARPEvent);
startEvent(ethernetRxInterruptEvent);
}
void stopEComms(void) {
stopEvent(ethernetPeriodicEvent);
stopEvent(ethernetARPEvent);
stopEvent(ethernetRxInterruptEvent);
}
//*****************************************************************************
// get uIP type IP Address.
//*****************************************************************************
void getIPAddress(char ipAddress[16]) {
uip_ipaddr_t ipaddr;
uip_ipaddr( ipaddr,
DEFAULT_IPADDR0,
DEFAULT_IPADDR1,
DEFAULT_IPADDR2,
DEFAULT_IPADDR3);
int iIndex = 0;
unsigned char *pucTemp = (unsigned char *)ipaddr;
unsigned char ucValue;
// Process first byte of IP Address.
ucValue = pucTemp[0];
if(ucValue > 9)
{
if(ucValue > 99)
{
ipAddress[iIndex++] = '0' + (ucValue / 100);
ucValue %= 100;
}
ipAddress[iIndex++] = '0' + (ucValue / 10);
ucValue %= 10;
}
ipAddress[iIndex++] = '0' + (ucValue);
ipAddress[iIndex++] = '.';
//
// Process second byte of IP Address.
//
ucValue = pucTemp[1];
if(ucValue > 9)
{
if(ucValue > 99)
{
ipAddress[iIndex++] = '0' + (ucValue / 100);
ucValue %= 100;
}
ipAddress[iIndex++] = '0' + (ucValue / 10);
ucValue %= 10;
}
ipAddress[iIndex++] = '0' + (ucValue);
ipAddress[iIndex++] = '.';
// Process third byte of IP Address.
ucValue = pucTemp[2];
if(ucValue > 9)
{
if(ucValue > 99)
{
ipAddress[iIndex++] = '0' + (ucValue / 100);
ucValue %= 100;
}
ipAddress[iIndex++] = '0' + (ucValue / 10);
ucValue %= 10;
}
ipAddress[iIndex++] = '0' + (ucValue);
ipAddress[iIndex++] = '.';
// Process last byte of IP Address.
ucValue = pucTemp[3];
if(ucValue > 9)
{
if(ucValue > 99)
{
ipAddress[iIndex++] = '0' + (ucValue / 100);
ucValue %= 100;
}
ipAddress[iIndex++] = '0' + (ucValue / 10);
ucValue %= 10;
}
ipAddress[iIndex++] = '0' + (ucValue);
ipAddress[iIndex] = 0;
}
// accessors
UINT getEthernetRxInterruptId(void) {
return ethernetRxInterruptEvent;
}
UINT getEthernetPeriodicId(void) {
return ethernetPeriodicEvent;
}
UINT getEthernetARPId(void) {
return ethernetARPEvent;
}
|