Igor Skochinsky
/
EasyWebCR
code_red's port of EasyWeb server for LPC1768, made to compile with mbed's online compiler.
Revision 0:12b53511e212, committed 2010-01-29
- Comitter:
- igorsk
- Date:
- Fri Jan 29 21:46:31 2010 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 12b53511e212 easyweb.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/easyweb.c Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,392 @@ +/****************************************************************** + ***** ***** + ***** Name: easyweb.c ***** + ***** Ver.: 1.0 ***** + ***** Date: 07/05/2001 ***** + ***** Auth: Andreas Dannenberg ***** + ***** HTWK Leipzig ***** + ***** university of applied sciences ***** + ***** Germany ***** + ***** adannenb@et.htwk-leipzig.de ***** + ***** Func: implements a dynamic HTTP-server by using ***** + ***** the easyWEB-API ***** + ***** Rem.: In IAR-C, use linker option ***** + ***** "-e_medium_write=_formatted_write" ***** + ***** ***** + ******************************************************************/ + +// Modifications by Code Red Technologies for NXP LPC1768 + +// CodeRed - removed header for MSP430 microcontroller +//#include "msp430x14x.h" + +#include "mbed.h" + +#include "stdlib.h" +#include "stdio.h" +#include "string.h" + +#include "easyweb.h" + +// CodeRed - removed header for original ethernet controller +//#include "cs8900.c" // ethernet packet driver + +//CodeRed - added for LPC ethernet controller +#include "ethmac.h" + +// CodeRed - include .h rather than .c file +// #include "tcpip.c" // easyWEB TCP/IP stack +#include "tcpip.h" // easyWEB TCP/IP stack + +// CodeRed - added NXP LPC register definitions header +// CodeRed - include renamed .h rather than .c file +// #include "webside.c" // webside for our HTTP server (HTML) +#include "webside.h" // webside for our HTTP server (HTML) + + + +// CodeRed - added for use in dynamic side of web page +unsigned int aaPagecounter=0; +unsigned int adcValue = 0; + +int main (void) +{ +// CodeRed - removed init functions as not required for LPC1776 +// InitOsc(); +// InitPorts(); + + +// CodeRed - added info message + printf("Setting up TCP/IP with IP address: "); + printf("%d.%d.%d.%d\n",MYIP_1,MYIP_2,MYIP_3,MYIP_4); + + TCPLowLevelInit(); + +/* + *(unsigned char *)RemoteIP = 24; // uncomment those lines to get the + *((unsigned char *)RemoteIP + 1) = 8; // quote of the day from a real + *((unsigned char *)RemoteIP + 2) = 69; // internet server! (gateway must be + *((unsigned char *)RemoteIP + 3) = 7; // set to your LAN-router) + + TCPLocalPort = 2025; + TCPRemotePort = TCP_PORT_QOTD; + + TCPActiveOpen(); + + while (SocketStatus & SOCK_ACTIVE) // read the quote from memory + { // by using the hardware-debugger + DoNetworkStuff(); + } +*/ + + HTTPStatus = 0; // clear HTTP-server's flag register + + TCPLocalPort = TCP_PORT_HTTP; // set port we want to listen to + +// CodeRed - added info message + printf("Webserver started\n"); + + while (1) // repeat forever + { + if (!(SocketStatus & SOCK_ACTIVE)) TCPPassiveOpen(); // listen for incoming TCP-connection + DoNetworkStuff(); // handle network and easyWEB-stack + // events + HTTPServer(); + } +} + +// This function implements a very simple dynamic HTTP-server. +// It waits until connected, then sends a HTTP-header and the +// HTML-code stored in memory. Before sending, it replaces +// some special strings with dynamic values. +// NOTE: For strings crossing page boundaries, replacing will +// not work. In this case, simply add some extra lines +// (e.g. CR and LFs) to the HTML-code. + +void HTTPServer(void) +{ + if (SocketStatus & SOCK_CONNECTED) // check if somebody has connected to our TCP + { + if (SocketStatus & SOCK_DATA_AVAILABLE) // check if remote TCP sent data + TCPReleaseRxBuffer(); // and throw it away + + if (SocketStatus & SOCK_TX_BUF_RELEASED) // check if buffer is free for TX + { + if (!(HTTPStatus & HTTP_SEND_PAGE)) // init byte-counter and pointer to webside + { // if called the 1st time + HTTPBytesToSend = sizeof(WebSide) - 1; // get HTML length, ignore trailing zero + PWebSide = (unsigned char *)WebSide; // pointer to HTML-code + } + + if (HTTPBytesToSend > MAX_TCP_TX_DATA_SIZE) // transmit a segment of MAX_SIZE + { + if (!(HTTPStatus & HTTP_SEND_PAGE)) // 1st time, include HTTP-header + { + memcpy(TCP_TX_BUF, GetResponse, sizeof(GetResponse) - 1); + memcpy(TCP_TX_BUF + sizeof(GetResponse) - 1, PWebSide, MAX_TCP_TX_DATA_SIZE - sizeof(GetResponse) + 1); + HTTPBytesToSend -= MAX_TCP_TX_DATA_SIZE - sizeof(GetResponse) + 1; + PWebSide += MAX_TCP_TX_DATA_SIZE - sizeof(GetResponse) + 1; + } + else + { + memcpy(TCP_TX_BUF, PWebSide, MAX_TCP_TX_DATA_SIZE); + HTTPBytesToSend -= MAX_TCP_TX_DATA_SIZE; + PWebSide += MAX_TCP_TX_DATA_SIZE; + } + + TCPTxDataCount = MAX_TCP_TX_DATA_SIZE; // bytes to xfer + InsertDynamicValues(); // exchange some strings... + TCPTransmitTxBuffer(); // xfer buffer + } + else if (HTTPBytesToSend) // transmit leftover bytes + { + memcpy(TCP_TX_BUF, PWebSide, HTTPBytesToSend); + TCPTxDataCount = HTTPBytesToSend; // bytes to xfer + InsertDynamicValues(); // exchange some strings... + TCPTransmitTxBuffer(); // send last segment + TCPClose(); // and close connection + HTTPBytesToSend = 0; // all data sent + } + + HTTPStatus |= HTTP_SEND_PAGE; // ok, 1st loop executed + } + } + else + HTTPStatus &= ~HTTP_SEND_PAGE; // reset help-flag if not connected +} + + + + +// Code Red - GetAD7Val function replaced +// Rather than using the AD convertor, in this version we simply increment +// a counter the function is called, wrapping at 1024. +volatile unsigned int aaScrollbar = 400; + +unsigned int GetAD7Val(void) +{ + aaScrollbar = (aaScrollbar +16) % 1024; + adcValue = (aaScrollbar / 10) * 1000/1024; + return aaScrollbar; +} + +// Code Red - Original MSP430 version of GetAD7Val() removed +/* +// samples and returns the AD-converter value of channel 7 +// (associated with Port P6.7) + +unsigned int GetAD7Val(void) +{ + ADC12CTL0 = ADC12ON | SHT0_15 | REF2_5V | REFON; // ADC on, int. ref. on (2,5 V), + // single channel single conversion + ADC12CTL1 = ADC12SSEL_2 | ADC12DIV_7 | CSTARTADD_0 | SHP;// MCLK / 8 = 1 MHz + + ADC12MCTL0 = SREF_1 | INCH_7; // int. ref., channel 7 + + ADC12CTL0 |= ENC; // enable conversion + ADC12CTL0 |= ADC12SC; // sample & convert + + while (ADC12CTL0 & ADC12SC); // wait until conversion is complete + + ADC12CTL0 &= ~ENC; // disable conversion + + return ADC12MEM0 / 41; // scale 12 bit value to 0..100% +} + +// End of Original MSP430 version of GetAD7Val() +*/ + + +// Code Red - Original GetTempVal() removed +// Function no longer used +/* +// samples and returns AD-converter value of channel 10 +// (MSP430's internal temperature reference diode) +// NOTE: to get a more exact value, 8-times oversampling is used + +unsigned int GetTempVal(void) +{ + unsigned long ReturnValue; + + ADC12CTL0 = ADC12ON | SHT0_15 | MSH | REFON; // ADC on, int. ref. on (1,5 V), + // multiple sample & conversion + ADC12CTL1 = ADC12SSEL_2 | ADC12DIV_7 | CSTARTADD_0 | CONSEQ_1 | SHP; // MCLK / 8 = 1 MHz + + ADC12MCTL0 = SREF_1 | INCH_10; // int. ref., channel 10 + ADC12MCTL1 = SREF_1 | INCH_10; // int. ref., channel 10 + ADC12MCTL2 = SREF_1 | INCH_10; // int. ref., channel 10 + ADC12MCTL3 = SREF_1 | INCH_10; // int. ref., channel 10 + ADC12MCTL4 = SREF_1 | INCH_10; // int. ref., channel 10 + ADC12MCTL5 = SREF_1 | INCH_10; // int. ref., channel 10 + ADC12MCTL6 = SREF_1 | INCH_10; // int. ref., channel 10 + ADC12MCTL7 = EOS | SREF_1 | INCH_10; // int. ref., channel 10, last seg. + + ADC12CTL0 |= ENC; // enable conversion + ADC12CTL0 |= ADC12SC; // sample & convert + + while (ADC12CTL0 & ADC12SC); // wait until conversion is complete + + ADC12CTL0 &= ~ENC; // disable conversion + + ReturnValue = ADC12MEM0; // sum up values... + ReturnValue += ADC12MEM1; + ReturnValue += ADC12MEM2; + ReturnValue += ADC12MEM3; + ReturnValue += ADC12MEM4; + ReturnValue += ADC12MEM5; + ReturnValue += ADC12MEM6; + ReturnValue += ADC12MEM7; + + ReturnValue >>= 3; // ... and divide by 8 + + if (ReturnValue < 2886) ReturnValue = 2886; // lower bound (0% = 20�C) + ReturnValue = (ReturnValue - 2886) / 2.43; // convert AD-value to a temperature from + // 20�C...45�C represented by a value + // of 0...100% + if (ReturnValue > 100) ReturnValue = 100; // upper bound (100% = 45�C) + + return ReturnValue; +} +// End of Original MSP430 version of GetTempVal() +*/ + + +// searches the TX-buffer for special strings and replaces them +// with dynamic values (AD-converter results) + +// Code Red - new version of InsertDynamicValues() +void InsertDynamicValues(void) +{ + unsigned char *Key; + char NewKey[6]; + unsigned int i; + + if (TCPTxDataCount < 4) return; // there can't be any special string + + Key = TCP_TX_BUF; + + for (i = 0; i < (TCPTxDataCount - 3); i++) + { + if (*Key == 'A') + if (*(Key + 1) == 'D') + if (*(Key + 3) == '%') + switch (*(Key + 2)) + { + case '8' : // "AD8%"? + { + sprintf(NewKey, "%04d", GetAD7Val()); // insert pseudo-ADconverter value + memcpy(Key, NewKey, 4); + break; + } + case '7' : // "AD7%"? + { + sprintf(NewKey, "%3u", adcValue); // copy saved value from previous read + memcpy(Key, NewKey, 3); + break; + } + case '1' : // "AD1%"? + { + sprintf(NewKey, "%4u", ++aaPagecounter); // increment and insert page counter + memcpy(Key, NewKey, 4); +// *(Key + 3) = ' '; + break; + } + } + Key++; + } +} + + +// Code Red - commented out original InsertDynamicValues() +/* +void InsertDynamicValues(void) +{ + unsigned char *Key; + unsigned char NewKey[5]; + unsigned int i; + + if (TCPTxDataCount < 4) return; // there can't be any special string + + Key = TCP_TX_BUF; + + for (i = 0; i < (TCPTxDataCount - 3); i++) + { + if (*Key == 'A') + if (*(Key + 1) == 'D') + if (*(Key + 3) == '%') + switch (*(Key + 2)) + { + case '7' : // "AD7%"? + { + sprintf(NewKey, "%3u", GetAD7Val()); // insert AD converter value + memcpy(Key, NewKey, 3); // channel 7 (P6.7) + break; + } + case 'A' : // "ADA%"? + { + sprintf(NewKey, "%3u", GetTempVal()); // insert AD converter value + memcpy(Key, NewKey, 3); // channel 10 (temp.-diode) + break; + } + } + Key++; + } +} + +// Code Red - End of original InsertDynamicValues () +*/ + +// Code Red - Deleted InitOsc() and InitPorts() as not required +// by LPC 1776 + +/* +// enables the 8MHz crystal on XT1 and use +// it as MCLK + +void InitOsc(void) +{ + WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer + + BCSCTL1 |= XTS; // XT1 as high-frequency + _BIC_SR(OSCOFF); // turn on XT1 oscillator + + do // wait in loop until crystal is stable + IFG1 &= ~OFIFG; + while (IFG1 & OFIFG); + + BCSCTL1 |= DIVA0; // ACLK = XT1 / 2 + BCSCTL1 &= ~DIVA1; + + IE1 &= ~WDTIE; // disable WDT int. + IFG1 &= ~WDTIFG; // clear WDT int. flag + + WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL | WDTSSEL | WDTIS1; // use WDT as timer, flag each + // 512 pulses from ACLK + + while (!(IFG1 & WDTIFG)); // count 1024 pulses from XT1 (until XT1's + // amplitude is OK) + + IFG1 &= ~OFIFG; // clear osc. fault int. flag + BCSCTL2 = SELM0 | SELM1; // set XT1 as MCLK +} + +void InitPorts(void) +{ + P1SEL = 0; // switch all unused ports to output + P1OUT = 0; // (rem.: ports 3 & 5 are set in "cs8900.c") + P1DIR = 0xFF; + + P2SEL = 0; + P2OUT = 0; + P2DIR = 0xFF; + + P4SEL = 0; + P4OUT = 0; + P4DIR = 0xFF; + + P6SEL = 0x80; // use P6.7 for the ADC module + P6OUT = 0; + P6DIR = 0x7F; // all output except P6.7 +} + +*/ \ No newline at end of file
diff -r 000000000000 -r 12b53511e212 easyweb.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/easyweb.h Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,38 @@ +/****************************************************************** + ***** ***** + ***** Name: easyweb.h ***** + ***** Ver.: 1.0 ***** + ***** Date: 07/05/2001 ***** + ***** Auth: Andreas Dannenberg ***** + ***** HTWK Leipzig ***** + ***** university of applied sciences ***** + ***** Germany ***** + ***** Func: header-file for easyweb.c ***** + ***** ***** + ******************************************************************/ + +#ifndef __EASYWEB_H +#define __EASYWEB_H + +const unsigned char GetResponse[] = // 1st thing our server sends to a client +{ + "HTTP/1.0 200 OK\r\n" // protocol ver 1.0, code 200, reason OK + "Content-Type: text/html\r\n" // type of data we want to send + "\r\n" // indicate end of HTTP-header +}; +void start(void); +void InitOsc(void); // prototypes +void InitPorts(void); +void HTTPServer(void); +void InsertDynamicValues(void); +unsigned int GetAD7Val(void); +unsigned int GetTempVal(void); + +unsigned char *PWebSide; // pointer to webside +unsigned int HTTPBytesToSend; // bytes left to send + +unsigned char HTTPStatus; // status byte +#define HTTP_SEND_PAGE 0x01 // help flag + +#endif +
diff -r 000000000000 -r 12b53511e212 ethmac.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ethmac.c Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,616 @@ +/****************************************************************** + ***** ***** + ***** Name: cs8900.c ***** + ***** Ver.: 1.0 ***** + ***** Date: 07/05/2001 ***** + ***** Auth: Andreas Dannenberg ***** + ***** HTWK Leipzig ***** + ***** university of applied sciences ***** + ***** Germany ***** + ***** adannenb@et.htwk-leipzig.de ***** + ***** Func: ethernet packet-driver for use with LAN- ***** + ***** controller CS8900 from Crystal/Cirrus Logic ***** + ***** ***** + ******************************************************************/ + +// Modifications by Code Red Technologies for NXP LPC1776 +// Filename changed to ethmac.c as no longer for cs8900 + +// CodeRed - updated include to match new filename + +#include "mbed.h" + +#include "ethmac.h" + +// CodeRed - add additional includes +#include "tcpip.h" + + +// CodeRed - new static pointers for receive and transmit +static unsigned short *rxptr; +static unsigned short *txptr; + +// CodeRed - function added to write to external ethernet PHY chip +void WriteToPHY (int reg, int writeval) +{ + unsigned int loop; + // Set up address to access in MII Mgmt Address Register + LPC_EMAC->MADR = DP83848C_DEF_ADR | reg; + // Write value into MII Mgmt Write Data Register + LPC_EMAC->MWTD = writeval; + // Loop whilst write to PHY completes + for (loop = 0; loop < MII_WR_TOUT; loop++) { + if ((LPC_EMAC->MIND & MIND_BUSY) == 0) { break; } + } +} + +// CodeRed - function added to read from external ethernet PHY chip +unsigned short ReadFromPHY (unsigned char reg) +{ + unsigned int loop; + // Set up address to access in MII Mgmt Address Register + LPC_EMAC->MADR = DP83848C_DEF_ADR | reg; + // Trigger a PHY read via MII Mgmt Command Register + LPC_EMAC->MCMD = MCMD_READ; + // Loop whilst read from PHY completes + for (loop = 0; loop < MII_RD_TOUT; loop++) { + if ((LPC_EMAC->MIND & MIND_BUSY) == 0) { break; } + } + LPC_EMAC->MCMD = 0; // Cancel read + // Returned value is in MII Mgmt Read Data Register + return (LPC_EMAC->MRDD); +} + + + +// CodeRed - Init8900() replaced by Init_EthMAC() +/* +// configure port-pins for use with LAN-controller, +// reset it and send the configuration-sequence +// (InitSeq[]) + +void Init8900(void) +{ + unsigned int i; + + P3SEL = 0x30; // reserve P3.4 and P3.5 for rs232 + P3OUT = IOR | IOW; // reset outputs, control lines high + P3DIR = 0xFF; // port 3 as output (all pins but rs232) + + P5SEL = 0; // select standard port functions + P5OUT = 0; // reset outputs + P5DIR = 0xFF; // switch data port to output + + Write8900(ADD_PORT, PP_SelfCTL); + Write8900(DATA_PORT, POWER_ON_RESET); // Reset the Ethernet-Controller + + Write8900(ADD_PORT, PP_SelfST); + while (!(Read8900(DATA_PORT) & INIT_DONE)); // wait until chip-reset is done + + for (i = 0; i < sizeof InitSeq / sizeof (TInitSeq); i++) // configure the CS8900 + { + Write8900(ADD_PORT, InitSeq[i].Addr); + Write8900(DATA_PORT, InitSeq[i].Data); + } +} +*/ + +// Ethernet power/clock control bit in PCONP register +#define PCENET 0x40000000 +// Ethernet configuration for PINSEL2, as per user guide section 5.3 +#define ENET_PINSEL2_CONFIG 0x50150105 +// Ethernet configuration for PINSEL3, as per user guide section 5.4 +#define ENET_PINSEL3_CONFIG 0x00000005 +// Only bottom byte of PINSEL3 relevant to Ethernet +#define ENET_PINSEL3_MASK 0x0000000F + +void Init_EthMAC(void) +{ + unsigned int loop, value, phyid1, phyid2; + + unsigned phy_in_use = 0; + unsigned phy_linkstatus_reg; + unsigned phy_linkstatus_mask; + + // Set Ethernet power/clock control bit + LPC_SC->PCONP |= PCENET; + + //Enable Ethernet pins through PINSEL registers + LPC_PINCON->PINSEL2 = ENET_PINSEL2_CONFIG; + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~(ENET_PINSEL3_MASK)) | ENET_PINSEL3_CONFIG; + + // Set up MAC Configuration Register 1 + LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | + MAC1_RES_MCS_RX |MAC1_SIM_RES | MAC1_SOFT_RES; + + // Set up MAC Command Register + LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; + + // Short delay + for (loop = 100; loop; loop--); + + // Set up MAC Configuration Register 1 to pass all receive frames + LPC_EMAC->MAC1 = MAC1_PASS_ALL; + // Set up MAC Configuration Register 2 to append CRC and pad out frames + LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; + + // Set Ethernet Maximum Frame Register + LPC_EMAC->MAXF = ETH_MAX_FLEN; + // Set Collision Window / Retry Register + LPC_EMAC->CLRT = CLRT_DEF; + // Set Non Back-to-Back Inter-Packet-Gap Register + LPC_EMAC->IPGR = IPGR_DEF; + + // Set MAC Command Register to enable Reduced MII interface + // and prevent runt frames being filtered out + LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; + + + // Put DP83848C PHY into reset mode + WriteToPHY (PHY_REG_BMCR, 0x8000); + + // Loop until hardware reset completes + for (loop = 0; loop < 0x100000; loop++) { + value = ReadFromPHY (PHY_REG_BMCR); + if (!(value & 0x8000)) { + // Reset has completed + break; + } + } + + // Just check this actually is a DP83848C PHY + phyid1 = ReadFromPHY (PHY_REG_IDR1); + phyid2 = ReadFromPHY (PHY_REG_IDR2); + + if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == DP83848C_ID) { + phy_in_use = DP83848C_ID; + } + else if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == LAN8720_ID) { + phy_in_use = LAN8720_ID; + } + + if (phy_in_use != 0) { + // Safe to configure the PHY device + + // Set PHY to autonegotiation link speed + WriteToPHY (PHY_REG_BMCR, PHY_AUTO_NEG); + // loop until autonegotiation completes + for (loop = 0; loop < 0x100000; loop++) { + value = ReadFromPHY (PHY_REG_BMSR); + if (value & 0x0020) { + // Autonegotiation has completed + break; + } + } + } + + phy_linkstatus_reg = PHY_REG_STS; // Default to DP83848C + phy_linkstatus_mask = 0x0001; + + if (phy_in_use == LAN8720_ID) { + phy_linkstatus_reg = PHY_REG_BMSR; + phy_linkstatus_mask = 0x0002; + } + + // Now check the link status + for (loop = 0; loop < 0x10000; loop++) { + value = ReadFromPHY (phy_linkstatus_reg); + if (value & phy_linkstatus_mask) { + // The link is on + break; + } + } + + // Now configure for full/half duplex mode + if (value & 0x0004) { + // We are in full duplex is enabled mode + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } + else { + // Otherwise we are in half duplex mode + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + // Now configure 100MBit or 10MBit mode + if (value & 0x0002) { + // 10MBit mode + LPC_EMAC->SUPP = 0; + } + else { + // 100MBit mode + LPC_EMAC->SUPP = SUPP_SPEED; + } + + // Now set the Ethernet MAC Address registers + // NOTE - MAC address must be unique on the network! + LPC_EMAC->SA0 = (MYMAC_1 << 8) | MYMAC_2; // Station address 0 Reg + LPC_EMAC->SA1 = (MYMAC_3 << 8) | MYMAC_4; // Station address 1 Reg + LPC_EMAC->SA2 = (MYMAC_5 << 8) | MYMAC_6; // Station address 2 Reg + + + // Now initialise the Rx descriptors + for (loop = 0; loop < NUM_RX_FRAG; loop++) { + RX_DESC_PACKET(loop) = RX_BUF(loop); + RX_DESC_CTRL(loop) = RCTRL_INT | (ETH_FRAG_SIZE-1); + RX_STAT_INFO(loop) = 0; + RX_STAT_HASHCRC(loop) = 0; + } + + // Set up the Receive Descriptor Base address register + LPC_EMAC->RxDescriptor = RX_DESC_BASE; + // Set up the Receive Status Base address register + LPC_EMAC->RxStatus = RX_STAT_BASE; + // Setup the Receive Number of Descriptor register + LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1; + // Set Receive Consume Index register to 0 + LPC_EMAC->RxConsumeIndex = 0; + + // Now initialise the Tx descriptors + for (loop = 0; loop < NUM_TX_FRAG; loop++) { + TX_DESC_PACKET(loop) = TX_BUF(loop); + TX_DESC_CTRL(loop) = 0; + TX_STAT_INFO(loop) = 0; + } + + // Set up the Transmit Descriptor Base address register + LPC_EMAC->TxDescriptor = TX_DESC_BASE; + // Set up the Transmit Status Base address register + LPC_EMAC->TxStatus = TX_STAT_BASE; + // Setup the Transmit Number of Descriptor register + LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1; + // Set Transmit Consume Index register to 0 + LPC_EMAC->TxProduceIndex = 0; + + // Receive Broadcast and Perfect Match Packets + + + + LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN; + + // Enable interrupts MAC Module Control Interrupt Enable Register + LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; + + // Reset all ethernet interrupts in MAC module + LPC_EMAC->IntClear = 0xFFFF; + + // Finally enable receive and transmit mode in ethernet core + LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); + LPC_EMAC->MAC1 |= MAC1_REC_EN; +} + + +// CodeRed - Write8900() not needed +// for RDB1768 port + +/* +// writes a word in little-endian byte order to +// a specified port-address + +void Write8900(unsigned char Address, unsigned int Data) +{ + P5DIR = 0xFF; // data port to output + P3OUT = IOR | IOW | Address; // put address on bus + + P5OUT = Data; // write low order byte to data bus + P3OUT &= ~IOW; // toggle IOW-signal + P3OUT = IOR | IOW | (Address + 1); // and put next address on bus + + P5OUT = Data >> 8; // write high order byte to data bus + P3OUT &= ~IOW; // toggle IOW-signal + P3OUT |= IOW; +} +*/ + +// Code Red - updated for LPC1776 port +/* +// writes a word in little-endian byte order to TX_FRAME_PORT + +void WriteFrame8900(unsigned int Data) +{ + P5DIR = 0xFF; // data port to output + P3OUT = IOR | IOW | TX_FRAME_PORT; // put address on bus + + P5OUT = Data; // write low order byte to data bus + P3OUT &= ~IOW; // toggle IOW-signal + P3OUT = IOR | IOW | (TX_FRAME_PORT + 1); // and put next address on bus + + P5OUT = Data >> 8; // write high order byte to data bus + P3OUT &= ~IOW; // toggle IOW-signal + P3OUT |= IOW; +} +*/ + +// writes a word in little-endian byte order to TX_BUFFER +void WriteFrame_EthMAC(unsigned short Data) +{ + *txptr++ = Data; +} + + + +// copies bytes from MCU-memory to frame port +// NOTES: * an odd number of byte may only be transfered +// if the frame is written to the end! +// * MCU-memory MUST start at word-boundary + +// Code Red - rewritten for LPC1776 +/* +void CopyToFrame8900(void *Source, unsigned int Size) +{ + P5DIR = 0xFF; // data port to output + + while (Size > 1) { + WriteFrame8900(*((unsigned int *)Source)++); + Size -= 2; + } + + if (Size) // if odd num. of bytes... + WriteFrame8900(*(unsigned char *)Source); // write leftover byte (the LAN-controller +} // ignores the highbyte) +*/ + +void CopyToFrame_EthMAC(void *Source, unsigned int Size) +{ + unsigned int index; + unsigned short *pSource; + + pSource = (unsigned short *)Source; + Size = (Size + 1) & 0xFFFE; // round up Size to next even number + while (Size > 0) { + WriteFrame_EthMAC(*pSource++); + Size -= 2; + } + + index = LPC_EMAC->TxProduceIndex; + if (++index == NUM_TX_FRAG) + index = 0; + LPC_EMAC->TxProduceIndex = index; +} + +// CodeRed - Read8900() not needed +// for LPC1768 port +/* + +// reads a word in little-endian byte order from +// a specified port-address + +unsigned int Read8900(unsigned char Address) +{ + unsigned int ReturnValue; + + P5DIR = 0x00; // data port to input + P3OUT = IOR | IOW | Address; // put address on bus + + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue = P5IN; // get low order byte from data bus + P3OUT = IOR | IOW | (Address + 1); // IOR high and put next address on bus + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue |= P5IN << 8; // get high order byte from data bus + + P3OUT |= IOR; + + return ReturnValue; +} +*/ +// reads a word in little-endian byte order from RX_FRAME_PORT + +// Code Red - ReadFrame8900 rewritten for RDB1768 port +/* +unsigned int ReadFrame8900(void) +{ + unsigned int ReturnValue; + + P5DIR = 0x00; // data port to input + P3OUT = IOR | IOW | RX_FRAME_PORT; // access to RX_FRAME_PORT + + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue = P5IN; // get 1st byte from data bus (low-byte) + P3OUT = IOR | IOW | (RX_FRAME_PORT + 1); // IOR high and put next address on bus + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue |= P5IN << 8; // get 2nd byte from data bus (high-byte) + + P3OUT |= IOR; + + return ReturnValue; +} +*/ + +// reads a word in little-endian byte order from RX_BUFFER + +unsigned short ReadFrame_EthMAC(void) +{ + return (*rxptr++); +} + + +// reads a word in big-endian byte order from RX_FRAME_PORT +// (useful to avoid permanent byte-swapping while reading +// TCP/IP-data) + +// CodeRed - rewritten for LPC1768 +/* + +unsigned int ReadFrameBE8900(void) +{ + unsigned int ReturnValue; + + P5DIR = 0x00; // data port to input + P3OUT = IOR | IOW | RX_FRAME_PORT; // access to RX_FRAME_PORT + + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue = P5IN << 8; // get 1st byte from data bus (high-byte) + P3OUT = IOR | IOW | (RX_FRAME_PORT + 1); // IOR high and put next address on bus + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue |= P5IN; // get 2nd byte from data bus (low-byte) + + P3OUT |= IOR; + + return ReturnValue; +} +*/ + +unsigned short ReadFrameBE_EthMAC(void) +{ + unsigned short ReturnValue; + + ReturnValue = SwapBytes (*rxptr++); + return (ReturnValue); +} + +// CodeRed - not required for RDB1768 port +/* +// reads a word in little-endian byte order from +// a specified port-address +// NOTE: this func. xfers the high-byte 1st, must be used to +// access some special registers (e.g. RxStatus) + +unsigned int ReadHB1ST8900(unsigned char Address) +{ + unsigned int ReturnValue; + + P5DIR = 0x00; // data port to input + P3OUT = IOR | IOW | (Address + 1); // put address on bus + + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue = P5IN << 8; // get high order byte from data bus + P3OUT = IOR | IOW | Address; // IOR high and put next address on bus + P3OUT &= ~IOR; // IOR-signal low + + ReturnValue |= P5IN; // get low order byte from data bus + + P3OUT |= IOR; + + return ReturnValue; +} +*/ + + +// copies bytes from frame port to MCU-memory +// NOTES: * an odd number of byte may only be transfered +// if the frame is read to the end! +// * MCU-memory MUST start at word-boundary + +// Code Red - rewritten for LPC1776 port +/* +void CopyFromFrame8900(void *Dest, unsigned int Size) +{ + while (Size > 1) { + *((unsigned int *)Dest)++ = ReadFrame8900(); + Size -= 2; + } + + if (Size) // check for leftover byte... + *(unsigned char *)Dest = ReadFrame8900(); // the LAN-Controller will return 0 +} // for the highbyte +*/ + +void CopyFromFrame_EthMAC(void *Dest, unsigned short Size) +{ + unsigned short *pDest; + + pDest = (unsigned short *)Dest; + while (Size > 1) { + *pDest++ = ReadFrame_EthMAC(); + Size -= 2; + } + + if (Size) { // check for leftover byte... + *(unsigned char *)pDest = (char)ReadFrame_EthMAC();// the LAN-Controller will return 0 + } // for the highbyte +} + + + +// does a dummy read on frame-I/O-port +// NOTE: only an even number of bytes is read! + +// Code Red - updated for LPC1776 +//void DummyReadFrame8900(unsigned int Size) // discards an EVEN number of bytes +void DummyReadFrame_EthMAC(unsigned short Size) // discards an EVEN number of bytes +{ // from RX-fifo + while (Size > 1) { +// Code Red - updated for LPC1776 +// ReadFrame8900(); + ReadFrame_EthMAC(); + Size -= 2; + } +} + +// requests space in CS8900's on-chip memory for +// storing an outgoing frame + +// CodeRed - updated for LPC1768 port +/* +void RequestSend(unsigned int FrameSize) +{ + Write8900(TX_CMD_PORT, TX_START_ALL_BYTES); + Write8900(TX_LEN_PORT, FrameSize); +} +*/ +void RequestSend(unsigned short FrameSize) +{ + unsigned int index; + index = LPC_EMAC->TxProduceIndex; + txptr = (unsigned short *)TX_DESC_PACKET(index); + TX_DESC_CTRL(index) = FrameSize | TCTRL_LAST; +} + +// check if CS8900 is ready to accept the +// frame we want to send + +unsigned int Rdy4Tx(void) +{ +// Code Red - updated for LPC1768 +// Write8900(ADD_PORT, PP_BusST); +// return (Read8900(DATA_PORT) & READY_FOR_TX_NOW); + + // One the LPC the ethernet controller transmits + // much faster than the CPU can load its buffers + // so will always be ready to accept frame + return (1); + // +} + +// CodeRed - New function + +// Reads length of received ethernet frame and checks +// if destination address is a broadcast message or not. +// Then returns the frame length +unsigned short StartReadingFrame(void) +{ + unsigned short ReceiveLength; + unsigned int index; + + index = LPC_EMAC->RxConsumeIndex; + ReceiveLength = (RX_STAT_INFO(index) & RINFO_SIZE) - 3; + rxptr = (unsigned short *)RX_DESC_PACKET(index); + return(ReceiveLength); +} + +// CodeRed - new function + +void StopReadingFrame(void) +{ + unsigned int index; + index = LPC_EMAC->RxConsumeIndex; + if (++index == NUM_RX_FRAG) index = 0; + LPC_EMAC->RxConsumeIndex = index; +} + +// CodeRed - new function to check if frame has been received +unsigned int CheckIfFrameReceived(void) +{ + if (LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex) + return(1); // Yes, packet received + else + return(0); +}
diff -r 000000000000 -r 12b53511e212 ethmac.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ethmac.h Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,630 @@ +/****************************************************************** + ***** ***** + ***** Name: cs8900.h ***** + ***** Ver.: 1.0 ***** + ***** Date: 07/05/2001 ***** + ***** Auth: Andreas Dannenberg ***** + ***** HTWK Leipzig ***** + ***** university of applied sciences ***** + ***** Germany ***** + ***** adannenb@et.htwk-leipzig.de ***** + ***** Func: header-file for cs8900.c ***** + ***** ***** + ******************************************************************/ + +// Modifications by Code Red Technologies for NXP LPC1768 +// Filename changed to ethmac.h as no longer for cs8900 + +// CodeRed - update for new header filename +//#ifndef __CS8900_H +//#define __CS8900_H +#ifndef __ETHMAC_H +#define __ETHMAC_H + +#define MYMAC_1 1 // our ethernet (MAC) address +#define MYMAC_2 2 // (MUST be unique in LAN!) +#define MYMAC_3 3 +#define MYMAC_4 4 +#define MYMAC_5 5 +#define MYMAC_6 6 + + +// CodeRed - commented out original CS8900 defines +/* +#define IOR BIT6 // CS8900's ISA-bus interface pins +#define IOW BIT7 + +// definitions for Crystal CS8900 ethernet-controller +// based on linux-header by Russel Nelson + +#define PP_ChipID 0x0000 // offset 0h -> Corp-ID + // offset 2h -> Model/Product Number + // offset 3h -> Chip Revision Number + +#define PP_ISAIOB 0x0020 // IO base address +#define PP_CS8900_ISAINT 0x0022 // ISA interrupt select +#define PP_CS8900_ISADMA 0x0024 // ISA Rec DMA channel +#define PP_ISASOF 0x0026 // ISA DMA offset +#define PP_DmaFrameCnt 0x0028 // ISA DMA Frame count +#define PP_DmaByteCnt 0x002A // ISA DMA Byte count +#define PP_CS8900_ISAMemB 0x002C // Memory base +#define PP_ISABootBase 0x0030 // Boot Prom base +#define PP_ISABootMask 0x0034 // Boot Prom Mask + +// EEPROM data and command registers +#define PP_EECMD 0x0040 // NVR Interface Command register +#define PP_EEData 0x0042 // NVR Interface Data Register + +// Configuration and control registers +#define PP_RxCFG 0x0102 // Rx Bus config +#define PP_RxCTL 0x0104 // Receive Control Register +#define PP_TxCFG 0x0106 // Transmit Config Register +#define PP_TxCMD 0x0108 // Transmit Command Register +#define PP_BufCFG 0x010A // Bus configuration Register +#define PP_LineCTL 0x0112 // Line Config Register +#define PP_SelfCTL 0x0114 // Self Command Register +#define PP_BusCTL 0x0116 // ISA bus control Register +#define PP_TestCTL 0x0118 // Test Register + +// Status and Event Registers +#define PP_ISQ 0x0120 // Interrupt Status +#define PP_RxEvent 0x0124 // Rx Event Register +#define PP_TxEvent 0x0128 // Tx Event Register +#define PP_BufEvent 0x012C // Bus Event Register +#define PP_RxMiss 0x0130 // Receive Miss Count +#define PP_TxCol 0x0132 // Transmit Collision Count +#define PP_LineST 0x0134 // Line State Register +#define PP_SelfST 0x0136 // Self State register +#define PP_BusST 0x0138 // Bus Status +#define PP_TDR 0x013C // Time Domain Reflectometry + +// Initiate Transmit Registers +#define PP_TxCommand 0x0144 // Tx Command +#define PP_TxLength 0x0146 // Tx Length + +// Adress Filter Registers +#define PP_LAF 0x0150 // Hash Table +#define PP_IA 0x0158 // Physical Address Register + +// Frame Location +#define PP_RxStatus 0x0400 // Receive start of frame +#define PP_RxLength 0x0402 // Receive Length of frame +#define PP_RxFrame 0x0404 // Receive frame pointer +#define PP_TxFrame 0x0A00 // Transmit frame pointer + +// Primary I/O Base Address. If no I/O base is supplied by the user, then this +// can be used as the default I/O base to access the PacketPage Area. +#define DEFAULTIOBASE 0x0300 + +// PP_RxCFG - Receive Configuration and Interrupt Mask bit definition - Read/write +#define SKIP_1 0x0040 +#define RX_STREAM_ENBL 0x0080 +#define RX_OK_ENBL 0x0100 +#define RX_DMA_ONLY 0x0200 +#define AUTO_RX_DMA 0x0400 +#define BUFFER_CRC 0x0800 +#define RX_CRC_ERROR_ENBL 0x1000 +#define RX_RUNT_ENBL 0x2000 +#define RX_EXTRA_DATA_ENBL 0x4000 + +// PP_RxCTL - Receive Control bit definition - Read/write +#define RX_IA_HASH_ACCEPT 0x0040 +#define RX_PROM_ACCEPT 0x0080 +#define RX_OK_ACCEPT 0x0100 +#define RX_MULTCAST_ACCEPT 0x0200 +#define RX_IA_ACCEPT 0x0400 +#define RX_BROADCAST_ACCEPT 0x0800 +#define RX_BAD_CRC_ACCEPT 0x1000 +#define RX_RUNT_ACCEPT 0x2000 +#define RX_EXTRA_DATA_ACCEPT 0x4000 + +// PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write +#define TX_LOST_CRS_ENBL 0x0040 +#define TX_SQE_ERROR_ENBL 0x0080 +#define TX_OK_ENBL 0x0100 +#define TX_LATE_COL_ENBL 0x0200 +#define TX_JBR_ENBL 0x0400 +#define TX_ANY_COL_ENBL 0x0800 +#define TX_16_COL_ENBL 0x8000 + +// PP_TxCMD - Transmit Command bit definition - Read-only and +// PP_TxCommand - Write-only +#define TX_START_5_BYTES 0x0000 +#define TX_START_381_BYTES 0x0040 +#define TX_START_1021_BYTES 0x0080 +#define TX_START_ALL_BYTES 0x00C0 +#define TX_FORCE 0x0100 +#define TX_ONE_COL 0x0200 +#define TX_NO_CRC 0x1000 +#define TX_RUNT 0x2000 + +// PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write +#define GENERATE_SW_INTERRUPT 0x0040 +#define RX_DMA_ENBL 0x0080 +#define READY_FOR_TX_ENBL 0x0100 +#define TX_UNDERRUN_ENBL 0x0200 +#define RX_MISS_ENBL 0x0400 +#define RX_128_BYTE_ENBL 0x0800 +#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000 +#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000 +#define RX_DEST_MATCH_ENBL 0x8000 + +// PP_LineCTL - Line Control bit definition - Read/write +#define SERIAL_RX_ON 0x0040 +#define SERIAL_TX_ON 0x0080 +#define AUI_ONLY 0x0100 +#define AUTO_AUI_10BASET 0x0200 +#define MODIFIED_BACKOFF 0x0800 +#define NO_AUTO_POLARITY 0x1000 +#define TWO_PART_DEFDIS 0x2000 +#define LOW_RX_SQUELCH 0x4000 + +// PP_SelfCTL - Software Self Control bit definition - Read/write +#define POWER_ON_RESET 0x0040 +#define SW_STOP 0x0100 +#define SLEEP_ON 0x0200 +#define AUTO_WAKEUP 0x0400 +#define HCB0_ENBL 0x1000 +#define HCB1_ENBL 0x2000 +#define HCB0 0x4000 +#define HCB1 0x8000 + +// PP_BusCTL - ISA Bus Control bit definition - Read/write +#define RESET_RX_DMA 0x0040 +#define MEMORY_ON 0x0400 +#define DMA_BURST_MODE 0x0800 +#define IO_CHANNEL_READY_ON 0x1000 +#define RX_DMA_SIZE_64K 0x2000 +#define ENABLE_IRQ 0x8000 + +// PP_TestCTL - Test Control bit definition - Read/write +#define LINK_OFF 0x0080 +#define ENDEC_LOOPBACK 0x0200 +#define AUI_LOOPBACK 0x0400 +#define BACKOFF_OFF 0x0800 +#define FDX_8900 0x4000 + +// PP_RxEvent - Receive Event Bit definition - Read-only +#define RX_IA_HASHED 0x0040 +#define RX_DRIBBLE 0x0080 +#define RX_OK 0x0100 +#define RX_HASHED 0x0200 +#define RX_IA 0x0400 +#define RX_BROADCAST 0x0800 +#define RX_CRC_ERROR 0x1000 +#define RX_RUNT 0x2000 +#define RX_EXTRA_DATA 0x4000 +#define HASH_INDEX_MASK 0xFC00 // Hash-Table Index Mask (6 Bit) + +// PP_TxEvent - Transmit Event Bit definition - Read-only +#define TX_LOST_CRS 0x0040 +#define TX_SQE_ERROR 0x0080 +#define TX_OK 0x0100 +#define TX_LATE_COL 0x0200 +#define TX_JBR 0x0400 +#define TX_16_COL 0x8000 +#define TX_COL_COUNT_MASK 0x7800 + +// PP_BufEvent - Buffer Event Bit definition - Read-only +#define SW_INTERRUPT 0x0040 +#define RX_DMA 0x0080 +#define READY_FOR_TX 0x0100 +#define TX_UNDERRUN 0x0200 +#define RX_MISS 0x0400 +#define RX_128_BYTE 0x0800 +#define TX_COL_OVRFLW 0x1000 +#define RX_MISS_OVRFLW 0x2000 +#define RX_DEST_MATCH 0x8000 + +// PP_LineST - Ethernet Line Status bit definition - Read-only +#define LINK_OK 0x0080 +#define AUI_ON 0x0100 +#define TENBASET_ON 0x0200 +#define POLARITY_OK 0x1000 +#define CRS_OK 0x4000 + +// PP_SelfST - Chip Software Status bit definition +#define ACTIVE_33V 0x0040 +#define INIT_DONE 0x0080 +#define SI_BUSY 0x0100 +#define EEPROM_PRESENT 0x0200 +#define EEPROM_OK 0x0400 +#define EL_PRESENT 0x0800 +#define EE_SIZE_64 0x1000 + +// PP_BusST - ISA Bus Status bit definition +#define TX_BID_ERROR 0x0080 +#define READY_FOR_TX_NOW 0x0100 + +// The following block defines the ISQ event types +#define ISQ_RX_EVENT 0x0004 +#define ISQ_TX_EVENT 0x0008 +#define ISQ_BUFFER_EVENT 0x000C +#define ISQ_RX_MISS_EVENT 0x0010 +#define ISQ_TX_COL_EVENT 0x0012 + +#define ISQ_EVENT_MASK 0x003F // ISQ mask to find out type of event + +// Ports for I/O-Mode +#define RX_FRAME_PORT 0x0000 +#define TX_FRAME_PORT 0x0000 +#define TX_CMD_PORT 0x0004 +#define TX_LEN_PORT 0x0006 +#define ISQ_PORT 0x0008 +#define ADD_PORT 0x000A +#define DATA_PORT 0x000C + +#define AUTOINCREMENT 0x8000 // Bit mask to set Bit-15 for autoincrement + +// EEProm Commands +#define EEPROM_WRITE_EN 0x00F0 +#define EEPROM_WRITE_DIS 0x0000 +#define EEPROM_WRITE_CMD 0x0100 +#define EEPROM_READ_CMD 0x0200 + +// Receive Header of each packet in receive area of memory for DMA-Mode +#define RBUF_EVENT_LOW 0x0000 // Low byte of RxEvent +#define RBUF_EVENT_HIGH 0x0001 // High byte of RxEvent +#define RBUF_LEN_LOW 0x0002 // Length of received data - low byte +#define RBUF_LEN_HI 0x0003 // Length of received data - high byte +#define RBUF_HEAD_LEN 0x0004 // Length of this header + +// CodeRed - end of original CS8900 defines +*/ + +// ******* +// CodeRed - defines for LPC1768 ethernet +// ******* + +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */ +#define NUM_TX_FRAG 2 /* Num.of TX Fragments 3*1536= 4.6kB */ +#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ + +/* EMAC variables located in AHB SRAM bank 1*/ +// Below is base address for first silicon +//#define RX_DESC_BASE 0x20004000 +// Below is base address for production silicon +#define RX_DESC_BASE 0x2007c000 +#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*8) +#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*8) +#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*8) +#define RX_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*4) +#define TX_BUF_BASE (RX_BUF_BASE + NUM_RX_FRAG*ETH_FRAG_SIZE) + +/* RX and TX descriptor and status definitions. */ +#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) +#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) +#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) +#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) +#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) +#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) +#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) +#define RX_BUF(i) (RX_BUF_BASE + ETH_FRAG_SIZE*i) +#define TX_BUF(i) (TX_BUF_BASE + ETH_FRAG_SIZE*i) + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000001C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | \ + RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* ENET Device Revision ID */ +#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier */ + + +/************************************************* + * CodeRed - PHY definitions for RDB1768 rev 2 + * which uses SMSC LAN8720 PHY instead of DP83848C + *************************************************/ +#define LAN8720_ID 0x000730F0 /* PHY Identifier */ + + + + +// Code Red - not required for RDB1768 port +/* +// typedefs +typedef struct { // struct to store CS8900's + unsigned int Addr; // init-sequence + unsigned int Data; +} TInitSeq; +*/ + +// Code Red - moved into tcpip.c +/* +// constants +const unsigned char MyMAC[] = // "M1-M2-M3-M4-M5-M6" +{ + MYMAC_1, MYMAC_2, MYMAC_3, + MYMAC_4, MYMAC_5, MYMAC_6 +}; +*/ + +// Code Red - not required for RDB1768 port +/* +const TInitSeq InitSeq[] = +{ + PP_IA, MYMAC_1 + (MYMAC_2 << 8), // set our MAC as Individual Address + PP_IA + 2, MYMAC_3 + (MYMAC_4 << 8), + PP_IA + 4, MYMAC_5 + (MYMAC_6 << 8), + PP_LineCTL, SERIAL_RX_ON | SERIAL_TX_ON, // configure the Physical Interface + PP_RxCTL, RX_OK_ACCEPT | RX_IA_ACCEPT | RX_BROADCAST_ACCEPT +}; +*/ + +// prototypes + +// CodeRed - updated for LPC1768 port +/* +void Init8900(void); +void Write8900(unsigned char Address, unsigned int Data); +void WriteFrame8900(unsigned int Data); +unsigned int Read8900(unsigned char Address); +unsigned int ReadFrame8900(void); +unsigned int ReadHB1ST8900(unsigned char Address); +unsigned int ReadFrameBE8900(void); +void CopyToFrame8900(void *Source, unsigned int Size); +void CopyFromFrame8900(void *Dest, unsigned int Size); +void DummyReadFrame8900(unsigned int Size); +void RequestSend(unsigned int FrameSize); +unsigned int Rdy4Tx(void); +*/ + +void Init_EthMAC(void); +unsigned short ReadFrameBE_EthMAC(void); +void CopyToFrame_EthMAC(void *Source, unsigned int Size); +void CopyFromFrame_EthMAC(void *Dest, unsigned short Size); +void DummyReadFrame_EthMAC(unsigned short Size); +void RequestSend(unsigned short FrameSize); +unsigned int Rdy4Tx(void); +unsigned short StartReadingFrame(void); +void StopReadingFrame(void); +unsigned int CheckIfFrameReceived(void); + +#endif +
diff -r 000000000000 -r 12b53511e212 ew_systick.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ew_systick.c Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,61 @@ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Copyright (c) 2009 Code Red Technologies Ltd. +// +// ew_systick.c provided SysTick functions for use by EasyWeb port to RDB1768 +// +// Software License Agreement +// +// The software is owned by Code Red Technologies and/or its suppliers, and is +// protected under applicable copyright laws. All rights are reserved. Any +// use in violation of the foregoing restrictions may subject the user to criminal +// sanctions under applicable laws, as well as to civil liability for the breach +// of the terms and conditions of this license. +// +// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT +// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH +// CODE RED TECHNOLOGIES LTD. + +#include <mbed.h> + +extern void TCPClockHandler(void); + +volatile uint32_t TimeTick = 0; +volatile uint32_t TimeTick2 = 0; + + +// **************** +// SysTick_Handler +void SysTick_Handler(void) +{ + TimeTick++; // Increment first SysTick counter + TimeTick2++; // Increment second SysTick counter + + // After 100 ticks (100 x 10ms = 1sec) + if (TimeTick >= 100) { + TimeTick = 0; // Reset counter + LPC_GPIO1->FIOPIN ^= 1 << 25; // Toggle user LED + } + // After 20 ticks (20 x 10ms = 1/5sec) + if (TimeTick2 >= 20) { + TimeTick2 = 0; // Reset counter + TCPClockHandler(); // Call TCP handler + } +} + +// **************** +// Setup SysTick Timer to interrupt at 10 msec intervals +void Start_SysTick10ms(void) +{ + if (SysTick_Config(SystemCoreClock / 100)) { + while (1); // Capture error + } +}
diff -r 000000000000 -r 12b53511e212 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0
diff -r 000000000000 -r 12b53511e212 tcpip.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tcpip.c Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,1291 @@ +/****************************************************************** + ***** ***** + ***** Name: tcpip.c ***** + ***** Ver.: 1.0 ***** + ***** Date: 07/05/2001 ***** + ***** Auth: Andreas Dannenberg ***** + ***** HTWK Leipzig ***** + ***** university of applied sciences ***** + ***** Germany ***** + ***** adannenb@et.htwk-leipzig.de ***** + ***** Func: implements the TCP/IP-stack and provides a ***** + ***** simple API to the user ***** + ***** ***** + ******************************************************************/ + +// Modifications by Code Red Technologies for NXP LPC1768 +// Throughout file, functions of form xxx8900() renamed xxx_EthMAC() +// Other changes commented in place + +#include "tcpip.h" + +//CodeRed - added header for LPC ethernet controller +#include "ethmac.h" +// CodeRed - added library string handling header +#include <string.h> + +// CodeRed - added NXP LPC register definitions header +//#include "LPC17xx.h" + +#include "mbed.h" + +unsigned short MyIP[] = // "MYIP1.MYIP2.MYIP3.MYIP4" +{ + MYIP_1 + (MYIP_2 << 8), + MYIP_3 + (MYIP_4 << 8) +}; + +unsigned short SubnetMask[] = // "SUBMASK1.SUBMASK2.SUBMASK3.SUBMASK4" +{ + SUBMASK_1 + (SUBMASK_2 << 8), + SUBMASK_3 + (SUBMASK_4 << 8) +}; + +unsigned short GatewayIP[] = // "GWIP1.GWIP2.GWIP3.GWIP4" +{ + GWIP_1 + (GWIP_2 << 8), + GWIP_3 + (GWIP_4 << 8) +}; + +// the next 3 buffers must be word-aligned! +// (here the 'RecdIPFrameLength' above does that) +unsigned short _TxFrame1[(ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + MAX_TCP_TX_DATA_SIZE)/2]; +unsigned short _TxFrame2[(ETH_HEADER_SIZE + MAX_ETH_TX_DATA_SIZE)/2]; +unsigned short _RxTCPBuffer[MAX_TCP_RX_DATA_SIZE/2]; // space for incoming TCP-data + +unsigned short TxFrame1Size; // bytes to send in TxFrame1 +unsigned char TxFrame2Size; // bytes to send in TxFrame2 + +unsigned char TransmitControl; +#define SEND_FRAME1 0x01 +#define SEND_FRAME2 0x02 + +unsigned char TCPFlags; +#define TCP_ACTIVE_OPEN 0x01 // easyWEB shall initiate a connection +#define IP_ADDR_RESOLVED 0x02 // IP sucessfully resolved to MAC +#define TCP_TIMER_RUNNING 0x04 +#define TIMER_TYPE_RETRY 0x08 +#define TCP_CLOSE_REQUESTED 0x10 + +// easyWEB's internal variables +TTCPStateMachine TCPStateMachine; // perhaps the most important var at all ;-) +TLastFrameSent LastFrameSent; // retransmission type + +unsigned short ISNGenHigh; // upper word of our Initial Sequence Number +unsigned long TCPSeqNr; // next sequence number to send +unsigned long TCPUNASeqNr; // last unaknowledged sequence number + // incremented AFTER sending data +unsigned long TCPAckNr; // next seq to receive and ack to send + // incremented AFTER receiving data +unsigned char TCPTimer; // inc'd each 262ms +unsigned char RetryCounter; // nr. of retransmissions + +// properties of the just received frame +unsigned short RecdFrameLength; // EMAC reported frame length +unsigned short RecdFrameMAC[3]; // 48 bit MAC +unsigned short RecdFrameIP[2]; // 32 bit IP +unsigned short RecdIPFrameLength; // 16 bit IP packet length + +// easyWEB-API global vars and flags +unsigned short TCPRxDataCount; // nr. of bytes rec'd +unsigned short TCPTxDataCount; // nr. of bytes to send + +unsigned short TCPLocalPort; // TCP ports +unsigned short TCPRemotePort; + +unsigned short RemoteMAC[3]; // MAC and IP of current TCP-session +unsigned short RemoteIP[2]; + +unsigned char SocketStatus; + +void Start_SysTick10ms(void); + +// Code Red - moved myMAC definition in from original cs8900.h +unsigned char MyMAC[6] = // "M1-M2-M3-M4-M5-M6" +{ + MYMAC_6, MYMAC_5, MYMAC_4, + MYMAC_3, MYMAC_2, MYMAC_1 +}; + +// easyWEB-API function +// initalizes the LAN-controller, reset flags, starts timer-ISR + +void TCPLowLevelInit(void) +{ +// CodeRed - comment out original 8900 specific code +/* + BCSCTL1 &= ~DIVA0; // ACLK = XT1 / 4 = 2 MHz + BCSCTL1 |= DIVA1; + TACTL = ID1 | ID0 | TASSEL0 | TAIE; // stop timer, use ACLK / 8 = 250 kHz, gen. int. + TACTL |= MC1; // start timer in continuous up-mode + _EINT(); // enable interrupts + + Init8900(); +*/ + LPC_GPIO1->FIODIR = 1 << 25; // P1.25 defined as Output (LED) + + Start_SysTick10ms(); // Start SysTick timer running (10ms ticks) + + Init_EthMAC(); + + TransmitControl = 0; + TCPFlags = 0; + TCPStateMachine = CLOSED; + SocketStatus = 0; +} + +// easyWEB-API function +// does a passive open (listen on 'MyIP:TCPLocalPort' for an incoming +// connection) + +void TCPPassiveOpen(void) +{ + if (TCPStateMachine == CLOSED) + { + TCPFlags &= ~TCP_ACTIVE_OPEN; // let's do a passive open! + TCPStateMachine = LISTENING; + SocketStatus = SOCK_ACTIVE; // reset, socket now active + } +} + +// easyWEB-API function +// does an active open (tries to establish a connection between +// 'MyIP:TCPLocalPort' and 'RemoteIP:TCPRemotePort') + +void TCPActiveOpen(void) +{ + if ((TCPStateMachine == CLOSED) || (TCPStateMachine == LISTENING)) + { + TCPFlags |= TCP_ACTIVE_OPEN; // let's do an active open! + TCPFlags &= ~IP_ADDR_RESOLVED; // we haven't opponents MAC yet + + PrepareARP_REQUEST(); // ask for MAC by sending a broadcast + LastFrameSent = ARP_REQUEST; + TCPStartRetryTimer(); + SocketStatus = SOCK_ACTIVE; // reset, socket now active + } +} + +// easyWEB-API function +// closes an open connection + +void TCPClose(void) +{ + switch (TCPStateMachine) + { + case LISTENING : + case SYN_SENT : + { + TCPStateMachine = CLOSED; + TCPFlags = 0; + SocketStatus = 0; + break; + } + case SYN_RECD : + case ESTABLISHED : + { + TCPFlags |= TCP_CLOSE_REQUESTED; + break; + } + } +} + +// easyWEB-API function +// releases the receive-buffer and allows easyWEB to store new data +// NOTE: rx-buffer MUST be released periodically, else the other TCP +// get no ACKs for the data it sent + +void TCPReleaseRxBuffer(void) +{ + SocketStatus &= ~SOCK_DATA_AVAILABLE; +} + +// easyWEB-API function +// transmitts data stored in 'TCP_TX_BUF' +// NOTE: * number of bytes to transmit must have been written to 'TCPTxDataCount' +// * data-count MUST NOT exceed 'MAX_TCP_TX_DATA_SIZE' + +void TCPTransmitTxBuffer(void) +{ + if ((TCPStateMachine == ESTABLISHED) || (TCPStateMachine == CLOSE_WAIT)) + if (SocketStatus & SOCK_TX_BUF_RELEASED) + { + SocketStatus &= ~SOCK_TX_BUF_RELEASED; // occupy tx-buffer + TCPUNASeqNr += TCPTxDataCount; // advance UNA + + TxFrame1Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount; + TransmitControl |= SEND_FRAME1; + + LastFrameSent = TCP_DATA_FRAME; + TCPStartRetryTimer(); + } +} + +// CodeRed - New function to check if received frame +// was a broadcast message + +// Reads the length of the received ethernet frame and checks if the +// destination address is a broadcast message or not +unsigned int BroadcastMessage(void) +{ + unsigned short FrameDestination[3]; // to hold 48 bit MAC address + + RecdFrameLength = StartReadingFrame(); + + // Read destination address + CopyFromFrame_EthMAC(&FrameDestination, 6); + // Save it for reply + CopyFromFrame_EthMAC(&RecdFrameMAC, 6); + + if ((FrameDestination[0] == 0xFFFF) && + (FrameDestination[1] == 0xFFFF) && + (FrameDestination[2] == 0xFFFF)) { + return(1); // Broadcast message + } else { + return (0); + } +} + + +// easyWEB's 'main()'-function +// must be called from user program periodically (the often - the better) +// handles network, TCP/IP-stack and user events + +void DoNetworkStuff(void) +{ +// CodeRed - comment out original cs8900 code +/* + unsigned int ActRxEvent; // copy of cs8900's RxEvent-Register + + Write8900(ADD_PORT, PP_RxEvent); // point to RxEvent + ActRxEvent = Read8900(DATA_PORT); // read, implied skip the last frame + + if (ActRxEvent & RX_OK) + { + if (ActRxEvent & RX_IA) ProcessEthIAFrame(); + if (ActRxEvent & RX_BROADCAST) ProcessEthBroadcastFrame(); + } +*/ + + // Check to see if packet received + if (CheckIfFrameReceived()) + { + // Was it a broadcast message? + if (BroadcastMessage()) { + ProcessEthBroadcastFrame(); + } + else { + ProcessEthIAFrame(); + } + // now release ethernet controller buffer + StopReadingFrame(); + } + + +// CodeRed - now back to original code + + if (TCPFlags & TCP_TIMER_RUNNING) + if (TCPFlags & TIMER_TYPE_RETRY) + { + if (TCPTimer > RETRY_TIMEOUT) + { + TCPRestartTimer(); // set a new timeout + + if (RetryCounter) + { + TCPHandleRetransmission(); // resend last frame + RetryCounter--; + } + else + { + TCPStopTimer(); + TCPHandleTimeout(); + } + } + } + else if (TCPTimer > FIN_TIMEOUT) + { + TCPStateMachine = CLOSED; + TCPFlags = 0; // reset all flags, stop retransmission... + SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags but data available + } + + switch (TCPStateMachine) + { + case CLOSED : + case LISTENING : + { + if (TCPFlags & TCP_ACTIVE_OPEN) // stack has to open a connection? + if (TCPFlags & IP_ADDR_RESOLVED) // IP resolved? + if (!(TransmitControl & SEND_FRAME2)) // buffer free? + { +// CodeRed - change TAR -> TOTC to use LPC1768 clock +// TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | TAR; // set local ISN + TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | (LPC_TIM0->TC & 0xFFFF); // set local ISN + TCPUNASeqNr = TCPSeqNr; + TCPAckNr = 0; // we don't know what to ACK! + TCPUNASeqNr++; // count SYN as a byte + PrepareTCP_FRAME(TCP_CODE_SYN); // send SYN frame + LastFrameSent = TCP_SYN_FRAME; + TCPStartRetryTimer(); // we NEED a retry-timeout + TCPStateMachine = SYN_SENT; + } + break; + } + case SYN_RECD : + case ESTABLISHED : + { + if (TCPFlags & TCP_CLOSE_REQUESTED) // user has user initated a close? + if (!(TransmitControl & (SEND_FRAME2 | SEND_FRAME1))) // buffers free? + if (TCPSeqNr == TCPUNASeqNr) // all data ACKed? + { + TCPUNASeqNr++; + PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); + LastFrameSent = TCP_FIN_FRAME; + TCPStartRetryTimer(); + TCPStateMachine = FIN_WAIT_1; + } + break; + } + case CLOSE_WAIT : + { + if (!(TransmitControl & (SEND_FRAME2 | SEND_FRAME1))) // buffers free? + if (TCPSeqNr == TCPUNASeqNr) // all data ACKed? + { + TCPUNASeqNr++; // count FIN as a byte + PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); // we NEED a retry-timeout + LastFrameSent = TCP_FIN_FRAME; // time to say goodbye... + TCPStartRetryTimer(); + TCPStateMachine = LAST_ACK; + } + break; + } + } + + if (TransmitControl & SEND_FRAME2) + { + RequestSend(TxFrame2Size); + + if (Rdy4Tx()) // NOTE: when using a very fast MCU, maybe + SendFrame2(); // the CS8900 isn't ready yet, include + else { // a kind of timer or counter here + TCPStateMachine = CLOSED; + SocketStatus = SOCK_ERR_ETHERNET; // indicate an error to user + TCPFlags = 0; // clear all flags, stop timers etc. + } + + TransmitControl &= ~SEND_FRAME2; // clear tx-flag + } + + if (TransmitControl & SEND_FRAME1) + { + PrepareTCP_DATA_FRAME(); // build frame w/ actual SEQ, ACK.... + RequestSend(TxFrame1Size); + + if (Rdy4Tx()) // CS8900 ready to accept our frame? + SendFrame1(); // (see note above) + else { + TCPStateMachine = CLOSED; + SocketStatus = SOCK_ERR_ETHERNET; // indicate an error to user + TCPFlags = 0; // clear all flags, stop timers etc. + } + + TransmitControl &= ~SEND_FRAME1; // clear tx-flag + } +} + +// easyWEB internal function +// handles an incoming broadcast frame + +void ProcessEthBroadcastFrame(void) +{ +// CodeRed - change from int to short +// unsigned int TargetIP[2]; + unsigned short TargetIP[2]; + +// CodeRed - remove CS8900 specific code block +/* + // next two words MUST be read with High-Byte 1st (CS8900 AN181 Page 2) + ReadHB1ST8900(RX_FRAME_PORT); // ignore RxStatus Word + RecdFrameLength = ReadHB1ST8900(RX_FRAME_PORT);// get real length of frame + + DummyReadFrame8900(6); // ignore DA (FF-FF-FF-FF-FF-FF) + CopyFromFrame8900(&RecdFrameMAC, 6); // store SA (for our answer) +// Code Red - end of CS8900 specific block +*/ + + if (ReadFrameBE_EthMAC() == FRAME_ARP) // get frame type, check for ARP + if (ReadFrameBE_EthMAC() == HARDW_ETH10) // Ethernet frame + if (ReadFrameBE_EthMAC() == FRAME_IP) // check protocol + if (ReadFrameBE_EthMAC() == IP_HLEN_PLEN) // check HLEN, PLEN + if (ReadFrameBE_EthMAC() == OP_ARP_REQUEST) + { + DummyReadFrame_EthMAC(6); // ignore sender's hardware address + CopyFromFrame_EthMAC(&RecdFrameIP, 4); // read sender's protocol address + DummyReadFrame_EthMAC(6); // ignore target's hardware address + CopyFromFrame_EthMAC(&TargetIP, 4); // read target's protocol address + if (!memcmp(&MyIP, &TargetIP, 4)) // is it for us? + PrepareARP_ANSWER(); // yes->create ARP_ANSWER frame + } +} + +// easyWEB internal function +// handles an incoming frame that passed CS8900's address filter +// (individual addressed = IA) + +void ProcessEthIAFrame(void) +{ +// CodeRed - change from int to short +//unsigned int TargetIP[2]; + unsigned short TargetIP[2]; + unsigned char ProtocolType; +// CodeRed - next few lines not needed for LPC1768 port +/* + // next two words MUST be read with High-Byte 1st (CS8900 AN181 Page 2) + ReadHB1ST_EthMAC(RX_FRAME_PORT); // ignore RxStatus Word + RecdFrameLength = ReadHB1ST_EthMAC(RX_FRAME_PORT);// get real length of frame + + DummyReadFrame_EthMAC(6); // ignore DA + CopyFromFrame_EthMAC(&RecdFrameMAC, 6); // store SA (for our answer) +*/ + switch (ReadFrameBE_EthMAC()) // get frame type + { + case FRAME_ARP : // check for ARP + { + if ((TCPFlags & (TCP_ACTIVE_OPEN | IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN) + if (ReadFrameBE_EthMAC() == HARDW_ETH10) // check for the right prot. etc. + if (ReadFrameBE_EthMAC() == FRAME_IP) + if (ReadFrameBE_EthMAC() == IP_HLEN_PLEN) + if (ReadFrameBE_EthMAC() == OP_ARP_ANSWER) + { + TCPStopTimer(); // OK, now we've the MAC we wanted ;-) + CopyFromFrame_EthMAC(&RemoteMAC, 6); // extract opponents MAC + TCPFlags |= IP_ADDR_RESOLVED; + } + break; + } + case FRAME_IP : // check for IP-type + { + if ((ReadFrameBE_EthMAC() & 0xFF00 ) == IP_VER_IHL) // IPv4, IHL=5 (20 Bytes Header) + { // ignore Type Of Service + RecdIPFrameLength = ReadFrameBE_EthMAC(); // get IP frame's length + ReadFrameBE_EthMAC(); // ignore identification + + if (!(ReadFrameBE_EthMAC() & (IP_FLAG_MOREFRAG | IP_FRAGOFS_MASK))) // only unfragm. frames + { +// CodeRed - add mask +// ProtocolType = ReadFrameBE_EthMAC() ; // get protocol, ignore TTL + ProtocolType = ReadFrameBE_EthMAC() & 0xFF ; // get protocol, ignore TTL + ReadFrameBE_EthMAC(); // ignore checksum + CopyFromFrame_EthMAC(&RecdFrameIP, 4); // get source IP + CopyFromFrame_EthMAC(&TargetIP, 4); // get destination IP + + if (!memcmp(&MyIP, &TargetIP, 4)) // is it for us? + switch (ProtocolType) { + case PROT_ICMP : { ProcessICMPFrame(); break; } + case PROT_TCP : { ProcessTCPFrame(); break; } + case PROT_UDP : break; // not implemented! + } + } + } + break; + } + } +} + +// easyWEB internal function +// we've just rec'd an ICMP-frame (Internet Control Message Protocol) +// check what to do and branch to the appropriate sub-function + +void ProcessICMPFrame(void) +{ +// CodeRed - change from int to short +//unsigned int ICMPTypeAndCode; + unsigned short ICMPTypeAndCode; + + ICMPTypeAndCode = ReadFrameBE_EthMAC(); // get Message Type and Code + ReadFrameBE_EthMAC(); // ignore ICMP checksum + + switch (ICMPTypeAndCode >> 8) { // check type + case ICMP_ECHO : // is echo request? + { + PrepareICMP_ECHO_REPLY(); // echo as much as we can... + break; + } + } +} + +// easyWEB internal function +// we've just rec'd an TCP-frame (Transmission Control Protocol) +// this function mainly implements the TCP state machine according to RFC793 + +void ProcessTCPFrame(void) +{ +// CodeRed - change from int to short +/* unsigned int TCPSegSourcePort; // segment's source port + unsigned int TCPSegDestPort; // segment's destination port + unsigned long TCPSegSeq; // segment's sequence number + unsigned long TCPSegAck; // segment's acknowledge number + unsigned int TCPCode; // TCP code and header length + unsigned char TCPHeaderSize; // real TCP header length + unsigned int NrOfDataBytes; // real number of data +*/ + unsigned short TCPSegSourcePort; // segment's source port + unsigned short TCPSegDestPort; // segment's destination port + unsigned long TCPSegSeq; // segment's sequence number + unsigned long TCPSegAck; // segment's acknowledge number + unsigned short TCPCode; // TCP code and header length + unsigned char TCPHeaderSize; // real TCP header length + unsigned short NrOfDataBytes; // real number of data + + + TCPSegSourcePort = ReadFrameBE_EthMAC(); // get ports + TCPSegDestPort = ReadFrameBE_EthMAC(); + + if (TCPSegDestPort != TCPLocalPort) return; // drop segment if port doesn't match + + TCPSegSeq = (unsigned long)ReadFrameBE_EthMAC() << 16; // get segment sequence nr. + TCPSegSeq |= ReadFrameBE_EthMAC(); + + TCPSegAck = (unsigned long)ReadFrameBE_EthMAC() << 16; // get segment acknowledge nr. + TCPSegAck |= ReadFrameBE_EthMAC(); + + TCPCode = ReadFrameBE_EthMAC(); // get control bits, header length... + + TCPHeaderSize = (TCPCode & DATA_OFS_MASK) >> 10; // header length in bytes + NrOfDataBytes = RecdIPFrameLength - IP_HEADER_SIZE - TCPHeaderSize; // seg. text length + + if (NrOfDataBytes > MAX_TCP_RX_DATA_SIZE) return; // packet too large for us :...-( + + if (TCPHeaderSize > TCP_HEADER_SIZE) // ignore options if any + DummyReadFrame_EthMAC(TCPHeaderSize - TCP_HEADER_SIZE); + + switch (TCPStateMachine) // implement the TCP state machine + { + case CLOSED : + { + if (!(TCPCode & TCP_CODE_RST)) + { + TCPRemotePort = TCPSegSourcePort; + memcpy(&RemoteMAC, &RecdFrameMAC, 6); // save opponents MAC and IP + memcpy(&RemoteIP, &RecdFrameIP, 4); // for later use + + if (TCPCode & TCP_CODE_ACK) // make the reset sequence + { // acceptable to the other + TCPSeqNr = TCPSegAck; // TCP + PrepareTCP_FRAME(TCP_CODE_RST); + } + else + { + TCPSeqNr = 0; + TCPAckNr = TCPSegSeq + NrOfDataBytes; + if (TCPCode & (TCP_CODE_SYN | TCP_CODE_FIN)) TCPAckNr++; + PrepareTCP_FRAME(TCP_CODE_RST | TCP_CODE_ACK); + } + } + break; + } + case LISTENING : + { + if (!(TCPCode & TCP_CODE_RST)) // ignore segment containing RST + { + TCPRemotePort = TCPSegSourcePort; + memcpy(&RemoteMAC, &RecdFrameMAC, 6); // save opponents MAC and IP + memcpy(&RemoteIP, &RecdFrameIP, 4); // for later use + + if (TCPCode & TCP_CODE_ACK) // reset a bad + { // acknowledgement + TCPSeqNr = TCPSegAck; + PrepareTCP_FRAME(TCP_CODE_RST); + } + else if (TCPCode & TCP_CODE_SYN) + { + TCPAckNr = TCPSegSeq + 1; // get remote ISN, next byte we expect +// CodeRed - change TAR -> TOTC to use LPC1768 clock +// TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | TAR; // set local ISN + TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | (LPC_TIM0->TC & 0xFFFF); // set local ISN + TCPUNASeqNr = TCPSeqNr + 1; // one byte out -> increase by one + PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); + LastFrameSent = TCP_SYN_ACK_FRAME; + TCPStartRetryTimer(); + TCPStateMachine = SYN_RECD; + } + } + break; + } + case SYN_SENT : + { + if (memcmp(&RemoteIP, &RecdFrameIP, 4)) break; // drop segment if its IP doesn't belong + // to current session + + if (TCPSegSourcePort != TCPRemotePort) break; // drop segment if port doesn't match + + if (TCPCode & TCP_CODE_ACK) // ACK field significant? + if (TCPSegAck != TCPUNASeqNr) // is our ISN ACKed? + { + if (!(TCPCode & TCP_CODE_RST)) + { + TCPSeqNr = TCPSegAck; + PrepareTCP_FRAME(TCP_CODE_RST); + } + break; // drop segment + } + + if (TCPCode & TCP_CODE_RST) // RST?? + { + if (TCPCode & TCP_CODE_ACK) // if ACK was acceptable, reset + { // connection + TCPStateMachine = CLOSED; + TCPFlags = 0; // reset all flags, stop retransmission... + SocketStatus = SOCK_ERR_CONN_RESET; + } + break; // drop segment + } + + if (TCPCode & TCP_CODE_SYN) // SYN?? + { + TCPAckNr = TCPSegSeq; // get opponents ISN + TCPAckNr++; // inc. by one... + + if (TCPCode & TCP_CODE_ACK) + { + TCPStopTimer(); // stop retransmission, other TCP got our SYN + TCPSeqNr = TCPUNASeqNr; // advance our sequence number + + PrepareTCP_FRAME(TCP_CODE_ACK); // ACK this ISN + TCPStateMachine = ESTABLISHED; + SocketStatus |= SOCK_CONNECTED; + SocketStatus |= SOCK_TX_BUF_RELEASED; // user may send data now :-) + } + else + { + TCPStopTimer(); + PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); // our SYN isn't ACKed yet, + LastFrameSent = TCP_SYN_ACK_FRAME; // now continue with sending + TCPStartRetryTimer(); // SYN_ACK frames + TCPStateMachine = SYN_RECD; + } + } + break; + } + default : + { + if (memcmp(&RemoteIP, &RecdFrameIP, 4)) break; // drop segment if IP doesn't belong + // to current session + + if (TCPSegSourcePort != TCPRemotePort) break; // drop segment if port doesn't match + + if (TCPSegSeq != TCPAckNr) break; // drop if it's not the segment we expect + + if (TCPCode & TCP_CODE_RST) // RST?? + { + TCPStateMachine = CLOSED; // close the state machine + TCPFlags = 0; // reset all flags, stop retransmission... + SocketStatus = SOCK_ERR_CONN_RESET; // indicate an error to user + break; + } + + if (TCPCode & TCP_CODE_SYN) // SYN?? + { + PrepareTCP_FRAME(TCP_CODE_RST); // is NOT allowed here! send a reset, + TCPStateMachine = CLOSED; // close connection... + TCPFlags = 0; // reset all flags, stop retransmission... + SocketStatus = SOCK_ERR_REMOTE; // fatal error! + break; // ...and drop the frame + } + + if (!(TCPCode & TCP_CODE_ACK)) break; // drop segment if the ACK bit is off + + if (TCPSegAck == TCPUNASeqNr) // is our last data sent ACKed? + { + TCPStopTimer(); // stop retransmission + TCPSeqNr = TCPUNASeqNr; // advance our sequence number + + switch (TCPStateMachine) // change state if necessary + { + case SYN_RECD : // ACK of our SYN? + { + TCPStateMachine = ESTABLISHED; // user may send data now :-) + SocketStatus |= SOCK_CONNECTED; + break; + } + case FIN_WAIT_1 : { TCPStateMachine = FIN_WAIT_2; break; } // ACK of our FIN? + case CLOSING : { TCPStateMachine = TIME_WAIT; break; } // ACK of our FIN? + case LAST_ACK : // ACK of our FIN? + { + TCPStateMachine = CLOSED; + TCPFlags = 0; // reset all flags, stop retransmission... + SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags but data available + break; + } + case TIME_WAIT : + { + PrepareTCP_FRAME(TCP_CODE_ACK); // ACK a retransmission of remote FIN + TCPRestartTimer(); // restart TIME_WAIT timeout + break; + } + } + + if (TCPStateMachine == ESTABLISHED) // if true, give the frame buffer back + SocketStatus |= SOCK_TX_BUF_RELEASED; // to user + } + + if ((TCPStateMachine == ESTABLISHED) || (TCPStateMachine == FIN_WAIT_1) || (TCPStateMachine == FIN_WAIT_2)) + if (NrOfDataBytes) // data available? + if (!(SocketStatus & SOCK_DATA_AVAILABLE)) // rx data-buffer empty? + { + DummyReadFrame_EthMAC(6); // ignore window, checksum, urgent pointer +// CodeRed - removed unrequired & +// CopyFromFrame_EthMAC(&RxTCPBuffer, NrOfDataBytes);// fetch data and + CopyFromFrame_EthMAC(RxTCPBuffer, NrOfDataBytes);// fetch data and + + TCPRxDataCount = NrOfDataBytes; // ...tell the user... + SocketStatus |= SOCK_DATA_AVAILABLE; // indicate the new data to user + TCPAckNr += NrOfDataBytes; + PrepareTCP_FRAME(TCP_CODE_ACK); // ACK rec'd data + } + + if (TCPCode & TCP_CODE_FIN) // FIN?? + { + switch (TCPStateMachine) + { + case SYN_RECD : + case ESTABLISHED : + { + TCPStateMachine = CLOSE_WAIT; + break; + } + case FIN_WAIT_1 : + { // if our FIN was ACKed, we automatically + TCPStateMachine = CLOSING; // enter FIN_WAIT_2 (look above) and therefore + SocketStatus &= ~SOCK_CONNECTED; // TIME_WAIT + break; + } + case FIN_WAIT_2 : + { + TCPStartTimeWaitTimer(); + TCPStateMachine = TIME_WAIT; + SocketStatus &= ~SOCK_CONNECTED; + break; + } + case TIME_WAIT : + { + TCPRestartTimer(); + break; + } + } + TCPAckNr++; // ACK remote's FIN flag + PrepareTCP_FRAME(TCP_CODE_ACK); + } + } + } +} + +// easyWEB internal function +// prepares the TxFrame2-buffer to send an ARP-request + +void PrepareARP_REQUEST(void) +{ + // Ethernet + +// CodeRed - added char cast +// memset(&TxFrame2[ETH_DA_OFS], 0xFF, 6); + memset(&TxFrame2[ETH_DA_OFS], (char)0xFF, 6); // we don't know opposites MAC! + memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); +// Code Red - int-> short +// *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP); + *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP); + + // ARP + +// CodeRed - int-> short +/* *(unsigned int *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10); + *(unsigned int *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP); + *(unsigned int *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN); + *(unsigned int *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_REQUEST); +*/ + *(unsigned short *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10); + *(unsigned short *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP); + *(unsigned short *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN); + *(unsigned short *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_REQUEST); + + memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6); + memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4); + memset(&TxFrame2[ARP_TARGET_HA_OFS], 0x00, 6); // we don't know opposites MAC! + + if (((RemoteIP[0] ^ MyIP[0]) & SubnetMask[0]) || ((RemoteIP[1] ^ MyIP[1]) & SubnetMask[1])) + memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &GatewayIP, 4); // IP not in subnet, use gateway + else + memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &RemoteIP, 4); // other IP is next to us... + + TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE; + TransmitControl |= SEND_FRAME2; +} + +// easyWEB internal function +// prepares the TxFrame2-buffer to send an ARP-answer (reply) + +void PrepareARP_ANSWER(void) +{ + // Ethernet + memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6); + memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); +// CodeRed - int-> short +// *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP); + *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP); + + // ARP + +// CodeRed - int-> short +/* *(unsigned int *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10); + *(unsigned int *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP); + *(unsigned int *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN); + *(unsigned int *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_ANSWER); +*/ + *(unsigned short *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10); + *(unsigned short *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP); + *(unsigned short *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN); + *(unsigned short *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_ANSWER); + memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6); + memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4); + memcpy(&TxFrame2[ARP_TARGET_HA_OFS], &RecdFrameMAC, 6); + memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &RecdFrameIP, 4); + + TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE; + TransmitControl |= SEND_FRAME2; +} + +// easyWEB internal function +// prepares the TxFrame2-buffer to send an ICMP-echo-reply + +void PrepareICMP_ECHO_REPLY(void) +{ +// CodeRed - int-> short +// unsigned int ICMPDataCount; + unsigned short ICMPDataCount; + + if (RecdIPFrameLength > MAX_ETH_TX_DATA_SIZE) // don't overload TX-buffer + ICMPDataCount = MAX_ETH_TX_DATA_SIZE - IP_HEADER_SIZE - ICMP_HEADER_SIZE; + else + ICMPDataCount = RecdIPFrameLength - IP_HEADER_SIZE - ICMP_HEADER_SIZE; + + // Ethernet + memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6); + memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); + +// CodeRed - int-> short +// *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP); + *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP); + + // IP + +// CodeRed - int-> short +/* *(unsigned int *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL); + WriteWBE(&TxFrame2[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount); + *(unsigned int *)&TxFrame2[IP_IDENT_OFS] = 0; + *(unsigned int *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0; + *(unsigned int *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_ICMP); + *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0; + memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4); + memcpy(&TxFrame2[IP_DESTINATION_OFS], &RecdFrameIP, 4); + *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); +*/ + *(unsigned short *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL); + WriteWBE(&TxFrame2[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount); + *(unsigned short *)&TxFrame2[IP_IDENT_OFS] = 0; + *(unsigned short *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0; + *(unsigned short *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_ICMP); + *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0; + memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4); + memcpy(&TxFrame2[IP_DESTINATION_OFS], &RecdFrameIP, 4); + *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); + + // ICMP + +// CodeRed - int-> short +/* *(unsigned int *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8); + *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field + + CopyFromFrame8900(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo... + *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0); +*/ + *(unsigned short *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8); + *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field + + CopyFromFrame_EthMAC(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo... + *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0); + + + // ICMP + +// Code Red - int-> short + /* *(unsigned int *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8); + *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field + + CopyFromFrame8900(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo... + *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0); +*/ + *(unsigned short *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8); + *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field + + CopyFromFrame_EthMAC(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo... + *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0); + + + TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount; + TransmitControl |= SEND_FRAME2; +} + +// easyWEB internal function +// prepares the TxFrame2-buffer to send a general TCP frame +// the TCPCode-field is passed as an argument + +// CodeRed - int-> short +//void PrepareTCP_FRAME(unsigned int TCPCode) +void PrepareTCP_FRAME(unsigned short TCPCode) +{ + // Ethernet + memcpy(&TxFrame2[ETH_DA_OFS], &RemoteMAC, 6); + memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); + +// CodeRed - int-> short +// *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP); + *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP); + + // IP + +// Code Red - int-> short +/* *(unsigned int *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D); + + if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option + *(unsigned int *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE); + else + *(unsigned int *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE); + + *(unsigned int *)&TxFrame2[IP_IDENT_OFS] = 0; + *(unsigned int *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0; + *(unsigned int *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP); + *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0; + memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4); + memcpy(&TxFrame2[IP_DESTINATION_OFS], &RemoteIP, 4); + *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); +*/ + *(unsigned short *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D); + + if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option + *(unsigned short *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE); + else + *(unsigned short *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE); + + *(unsigned short *)&TxFrame2[IP_IDENT_OFS] = 0; + *(unsigned short *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0; + *(unsigned short *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP); + *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0; + memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4); + memcpy(&TxFrame2[IP_DESTINATION_OFS], &RemoteIP, 4); + *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); + + // TCP + WriteWBE(&TxFrame2[TCP_SRCPORT_OFS], TCPLocalPort); + WriteWBE(&TxFrame2[TCP_DESTPORT_OFS], TCPRemotePort); + + WriteDWBE(&TxFrame2[TCP_SEQNR_OFS], TCPSeqNr); + WriteDWBE(&TxFrame2[TCP_ACKNR_OFS], TCPAckNr); + +// CodeRed - int-> short +/* *(unsigned int *)&TxFrame2[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept + *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = 0; // initalize checksum + *(unsigned int *)&TxFrame2[TCP_URGENT_OFS] = 0; + + if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option + { + *(unsigned int *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x6000 | TCPCode); // TCP header length = 24 + *(unsigned int *)&TxFrame2[TCP_DATA_OFS] = SWAPB(TCP_OPT_MSS); // MSS option + *(unsigned int *)&TxFrame2[TCP_DATA_OFS + 2] = SWAPB(MAX_TCP_RX_DATA_SIZE);// max. length of TCP-data we accept + *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1); + TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE; + } + else + { + *(unsigned int *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCPCode); // TCP header length = 20 + *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1); + TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE; + } +*/ + *(unsigned short *)&TxFrame2[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept + *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = 0; // initalize checksum + *(unsigned short *)&TxFrame2[TCP_URGENT_OFS] = 0; + + if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option + { + *(unsigned short *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x6000 | TCPCode); // TCP header length = 24 + *(unsigned short *)&TxFrame2[TCP_DATA_OFS] = SWAPB(TCP_OPT_MSS); // MSS option + *(unsigned short *)&TxFrame2[TCP_DATA_OFS + 2] = SWAPB(MAX_TCP_RX_DATA_SIZE);// max. length of TCP-data we accept + *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1); + TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE; + } + else + { + *(unsigned short *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCPCode); // TCP header length = 20 + *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1); + TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE; + } + TransmitControl |= SEND_FRAME2; +} + +// easyWEB internal function +// prepares the TxFrame1-buffer to send a payload-packet + +void PrepareTCP_DATA_FRAME(void) +{ + // Ethernet + memcpy(&TxFrame1[ETH_DA_OFS], &RemoteMAC, 6); + memcpy(&TxFrame1[ETH_SA_OFS], &MyMAC, 6); +// Code Red - int-> short +// *(unsigned int *)&TxFrame1[ETH_TYPE_OFS] = SWAPB(FRAME_IP); + *(unsigned short *)&TxFrame1[ETH_TYPE_OFS] = SWAPB(FRAME_IP); + + // IP + +// CodeRed - int-> short +/* *(unsigned int *)&TxFrame1[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D); + WriteWBE(&TxFrame1[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount); + *(unsigned int *)&TxFrame1[IP_IDENT_OFS] = 0; + *(unsigned int *)&TxFrame1[IP_FLAGS_FRAG_OFS] = 0; + *(unsigned int *)&TxFrame1[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP); + *(unsigned int *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = 0; + memcpy(&TxFrame1[IP_SOURCE_OFS], &MyIP, 4); + memcpy(&TxFrame1[IP_DESTINATION_OFS], &RemoteIP, 4); + *(unsigned int *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); +*/ + *(unsigned short *)&TxFrame1[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D); + WriteWBE(&TxFrame1[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount); + *(unsigned short *)&TxFrame1[IP_IDENT_OFS] = 0; + *(unsigned short *)&TxFrame1[IP_FLAGS_FRAG_OFS] = 0; + *(unsigned short *)&TxFrame1[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP); + *(unsigned short *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = 0; + memcpy(&TxFrame1[IP_SOURCE_OFS], &MyIP, 4); + memcpy(&TxFrame1[IP_DESTINATION_OFS], &RemoteIP, 4); + *(unsigned short *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); + + + // TCP + WriteWBE(&TxFrame1[TCP_SRCPORT_OFS], TCPLocalPort); + WriteWBE(&TxFrame1[TCP_DESTPORT_OFS], TCPRemotePort); + + WriteDWBE(&TxFrame1[TCP_SEQNR_OFS], TCPSeqNr); + WriteDWBE(&TxFrame1[TCP_ACKNR_OFS], TCPAckNr); +// CodeRed - int-> short +/* *(unsigned int *)&TxFrame1[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCP_CODE_ACK); // TCP header length = 20 + *(unsigned int *)&TxFrame1[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept + *(unsigned int *)&TxFrame1[TCP_CHKSUM_OFS] = 0; + *(unsigned int *)&TxFrame1[TCP_URGENT_OFS] = 0; + *(unsigned int *)&TxFrame1[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCPTxDataCount, 1); +*/ + *(unsigned short *)&TxFrame1[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCP_CODE_ACK); // TCP header length = 20 + *(unsigned short *)&TxFrame1[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept + *(unsigned short *)&TxFrame1[TCP_CHKSUM_OFS] = 0; + *(unsigned short *)&TxFrame1[TCP_URGENT_OFS] = 0; + *(unsigned short *)&TxFrame1[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCPTxDataCount, 1); + +} + +// easyWEB internal function +// calculates the TCP/IP checksum. if 'IsTCP != 0', the TCP pseudo-header +// will be included. + +// CodeRed - int-> short +//unsigned int CalcChecksum(void *Start, unsigned int Count, unsigned char IsTCP) +unsigned short CalcChecksum(void *Start, unsigned short Count, unsigned char IsTCP) +{ +// Code Red - added pStart + unsigned short *pStart; + unsigned long Sum = 0; + + if (IsTCP) { // if we've a TCP frame... + Sum += MyIP[0]; // ...include TCP pseudo-header + Sum += MyIP[1]; + Sum += RemoteIP[0]; + Sum += RemoteIP[1]; + Sum += SwapBytes(Count); // TCP header length plus data length + Sum += SWAPB(PROT_TCP); + } + +// Code Red - modified to correct expression +/* while (Count > 1) { // sum words + Sum += *((unsigned int *)Start)++; + Count -= 2; + } + + if (Count) // add left-over byte, if any + Sum += *(unsigned char *)Start; +*/ + + pStart = (unsigned short *)Start; + while (Count > 1) { // sum words + Sum += *pStart++; + Count -= 2; + } + + if (Count) // add left-over byte, if any + Sum += *(unsigned char *)pStart; + + + while (Sum >> 16) // fold 32-bit sum to 16 bits + Sum = (Sum & 0xFFFF) + (Sum >> 16); + + return ~Sum; +} + +// easyWEB internal function +// starts the timer as a retry-timer (used for retransmission-timeout) + +void TCPStartRetryTimer(void) +{ + TCPTimer = 0; + RetryCounter = MAX_RETRYS; + TCPFlags |= TCP_TIMER_RUNNING; + TCPFlags |= TIMER_TYPE_RETRY; +} + +// easyWEB internal function +// starts the timer as a 'TIME_WAIT'-timer (used to finish a TCP-session) + +void TCPStartTimeWaitTimer(void) +{ + TCPTimer = 0; + TCPFlags |= TCP_TIMER_RUNNING; + TCPFlags &= ~TIMER_TYPE_RETRY; +} + +// easyWEB internal function +// restarts the timer + +void TCPRestartTimer(void) +{ + TCPTimer = 0; +} + +// easyWEB internal function +// stopps the timer + +void TCPStopTimer(void) +{ + TCPFlags &= ~TCP_TIMER_RUNNING; +} + +// easyWEB internal function +// if a retransmission-timeout occured, check which packet +// to resend. + +void TCPHandleRetransmission(void) +{ + switch (LastFrameSent) + { + case ARP_REQUEST : { PrepareARP_REQUEST(); break; } + case TCP_SYN_FRAME : { PrepareTCP_FRAME(TCP_CODE_SYN); break; } + case TCP_SYN_ACK_FRAME : { PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); break; } + case TCP_FIN_FRAME : { PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); break; } + case TCP_DATA_FRAME : { TransmitControl |= SEND_FRAME1; break; } + } +} + +// easyWEB internal function +// if all retransmissions failed, close connection and indicate an error + +void TCPHandleTimeout(void) +{ + TCPStateMachine = CLOSED; + + if ((TCPFlags & (TCP_ACTIVE_OPEN | IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN) + SocketStatus = SOCK_ERR_ARP_TIMEOUT; // indicate an error to user + else + SocketStatus = SOCK_ERR_TCP_TIMEOUT; + + TCPFlags = 0; // clear all flags +} + + +// CodeRed - TCPClockHandler() replaced +/* +// easyWEB internal function +// function executed every 0.262s by the MCU. used for the +// inital sequence number generator (ISN) and the TCP-timer + +interrupt [TIMERA1_VECTOR] void TCPClockHandler(void) +{ + if (TAIV == 10) // check for timer overflow, reset int.-flag + { + ISNGenHigh++; // upper 16 bits of initial sequence number + TCPTimer++; // timer for retransmissions + } +} +*/ + +// easyWEB internal function +// function executed every 0.210s by the MCU. used for the +// inital sequence number generator (ISN) and the TCP-timer + +void TCPClockHandler(void) +{ + ISNGenHigh++; // upper 16 bits of initial sequence number + TCPTimer++; // timer for retransmissions +} + + +// easyWEB internal function +// transfers the contents of 'TxFrame1'-Buffer to the CS8900A + +void SendFrame1(void) +{ +// CodeRed - updated for LPC1768 port +// CopyToFrame8900(&TxFrame1, TxFrame1Size); + CopyToFrame_EthMAC(TxFrame1, TxFrame1Size); +} + +// easyWEB internal function +// transfers the contents of 'TxFrame2'-Buffer to the CS8900A + +void SendFrame2(void) +{ +// CodeRed - updated for LPC1768 port +// CopyToFrame8900(&TxFrame2, TxFrame2Size); + CopyToFrame_EthMAC(TxFrame2, TxFrame2Size); +} + +// easyWEB internal function +// help function to write a WORD in big-endian byte-order +// to MCU-memory + +// CodeRed - int->short +//void WriteWBE(unsigned char *Add, unsigned int Data) +void WriteWBE(unsigned char *Add, unsigned short Data) +{ + *Add++ = Data >> 8; +// Code Red - added cast +// *Add = Data; + *Add = (char)Data; +} + +// easyWEB internal function +// help function to write a DWORD in big-endian byte-order +// to MCU-memory + +void WriteDWBE(unsigned char *Add, unsigned long Data) +{ + *Add++ = Data >> 24; + *Add++ = Data >> 16; + *Add++ = Data >> 8; + *Add = Data; +} + +// easyWEB internal function +// help function to swap the byte order of a WORD + +// CodeRed - int->short +//unsigned int SwapBytes(unsigned int Data) +unsigned short SwapBytes(unsigned short Data) +{ + return (Data >> 8) | (Data << 8); +} +
diff -r 000000000000 -r 12b53511e212 tcpip.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tcpip.h Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,260 @@ +/****************************************************************** + ***** ***** + ***** Name: tcpip.h ***** + ***** Ver.: 1.0 ***** + ***** Date: 07/05/2001 ***** + ***** Auth: Andreas Dannenberg ***** + ***** HTWK Leipzig ***** + ***** university of applied sciences ***** + ***** Germany ***** + ***** Func: header-file for tcpip.c ***** + ***** ***** + ******************************************************************/ + +// Modifications by Code Red Technologies for NXP LPC1776 + +#ifndef __TCPIP_H +#define __TCPIP_H + +// easyWEB-stack definitions +// Code Red - replaced original address by 192.168.0.200 +#define MYIP_1 192 // our internet protocol (IP) address +#define MYIP_2 168 +#define MYIP_3 0 +#define MYIP_4 200 +//#define MYIP_4 30 + +#define SUBMASK_1 255 // subnet mask +#define SUBMASK_2 255 +#define SUBMASK_3 255 +#define SUBMASK_4 0 + +#define GWIP_1 192 // standard gateway (used if remote +#define GWIP_2 168 // IP is no part of our subnet) +#define GWIP_3 2 +#define GWIP_4 154 + +#define RETRY_TIMEOUT 8 // wait max. 8 x 262ms for an ACK (about 2 sec.) +#define FIN_TIMEOUT 2 // max. time to wait for an ACK of a FIN + // before closing TCP state-machine (about 0.5 s) +#define MAX_RETRYS 4 // nr. of resendings before reset conn. + // total nr. of transmissions = MAX_RETRYS + 1 + +#define MAX_TCP_TX_DATA_SIZE 512 // max. outgoing TCP data size (even!) +#define MAX_TCP_RX_DATA_SIZE 256 // max. incoming TCP data size (even!) + // (increasing the buffer-size dramatically + // increases the transfer-speed!) + +#define MAX_ETH_TX_DATA_SIZE 60 // 2nd buffer, used for ARP, ICMP, TCP (even!) + // enough to echo 32 byte via ICMP + +#define DEFAULT_TTL 64 // Time To Live sent with packets + +// Ethernet network layer definitions +#define ETH_DA_OFS 0 // Destination MAC address (48 Bit) +#define ETH_SA_OFS 6 // Source MAC address (48 Bit) +#define ETH_TYPE_OFS 12 // Type field (16 Bit) +#define ETH_DATA_OFS 14 // Frame Data +#define ETH_HEADER_SIZE 14 + +#define FRAME_ARP 0x0806 // frame types (stored in Type/Length field) +#define FRAME_IP 0x0800 + +// IPv4 layer definitions +#define IP_VER_IHL_TOS_OFS ETH_DATA_OFS + 0 // Version, Header Length, Type of Service +#define IP_TOTAL_LENGTH_OFS ETH_DATA_OFS + 2 // IP Frame's Total Length +#define IP_IDENT_OFS ETH_DATA_OFS + 4 // Identifying Value +#define IP_FLAGS_FRAG_OFS ETH_DATA_OFS + 6 // Flags and Fragment Offset +#define IP_TTL_PROT_OFS ETH_DATA_OFS + 8 // Frame's Time to Live, Protocol +#define IP_HEAD_CHKSUM_OFS ETH_DATA_OFS + 10 // IP Frame's Header Checksum +#define IP_SOURCE_OFS ETH_DATA_OFS + 12 // Source Address (32 Bit) +#define IP_DESTINATION_OFS ETH_DATA_OFS + 16 // Destination Address (32 Bit) +#define IP_DATA_OFS ETH_DATA_OFS + 20 // Frame Data (if no options) +#define IP_HEADER_SIZE 20 // w/o options + +#define IP_VER_IHL 0x4500 // IPv4, Header Length = 5x32 bit +#define IP_TOS_D 0x0010 // TOS low delay +#define IP_TOS_T 0x0008 // TOS high throughput +#define IP_TOS_R 0x0004 // TOS high reliability + +#define IP_FLAG_DONTFRAG 0x4000 // don't fragment IP frame +#define IP_FLAG_MOREFRAG 0x2000 // more fragments available +#define IP_FRAGOFS_MASK 0x1FFF // indicates where this fragment belongs + +#define PROT_ICMP 1 // Internet Control Message Protocol +#define PROT_TCP 6 // Transmission Control Protocol +#define PROT_UDP 17 // User Datagram Protocol + +// ARP definitions +#define ARP_HARDW_OFS ETH_DATA_OFS + 0 // Hardware address type +#define ARP_PROT_OFS ETH_DATA_OFS + 2 // Protocol +#define ARP_HLEN_PLEN_OFS ETH_DATA_OFS + 4 // byte length of each hardw. / prot. address +#define ARP_OPCODE_OFS ETH_DATA_OFS + 6 // Opcode +#define ARP_SENDER_HA_OFS ETH_DATA_OFS + 8 // Hardw. address of sender of this packet +#define ARP_SENDER_IP_OFS ETH_DATA_OFS + 14 // IP address of sender +#define ARP_TARGET_HA_OFS ETH_DATA_OFS + 18 // Hardw. address of target of this packet +#define ARP_TARGET_IP_OFS ETH_DATA_OFS + 24 // IP address of target +#define ARP_FRAME_SIZE 28 + +#define HARDW_ETH10 1 // hardware-type 10Mbps Ethernet +#define IP_HLEN_PLEN 0x0604 // MAC = 6 byte long, IP = 4 byte long +#define OP_ARP_REQUEST 1 // operations for ARP-frames +#define OP_ARP_ANSWER 2 + +// ICMP definitions +#define ICMP_TYPE_CODE_OFS IP_DATA_OFS + 0 // type of message +#define ICMP_CHKSUM_OFS IP_DATA_OFS + 2 // checksum of ICMP-message (16 bit) +#define ICMP_DATA_OFS IP_DATA_OFS + 4 +#define ICMP_HEADER_SIZE 4 + +#define ICMP_ECHO 8 // message is an echo request +#define ICMP_ECHO_REPLY 0 // message is an echo reply + +// TCP layer definitions +#define TCP_SRCPORT_OFS IP_DATA_OFS + 0 // Source Port (16 bit) +#define TCP_DESTPORT_OFS IP_DATA_OFS + 2 // Destination Port (16 bit) +#define TCP_SEQNR_OFS IP_DATA_OFS + 4 // Sequence Number (32 bit) +#define TCP_ACKNR_OFS IP_DATA_OFS + 8 // Acknowledge Number (32 bit) +#define TCP_DATA_CODE_OFS IP_DATA_OFS + 12 // Data Offset and Control Bits (16 bit) +#define TCP_WINDOW_OFS IP_DATA_OFS + 14 // Window Size (16 bit) +#define TCP_CHKSUM_OFS IP_DATA_OFS + 16 // Checksum Field (16 bit) +#define TCP_URGENT_OFS IP_DATA_OFS + 18 // Urgent Pointer (16 bit) +#define TCP_DATA_OFS IP_DATA_OFS + 20 // Frame Data (if no options) +#define TCP_HEADER_SIZE 20 // size w/o options + +#define DATA_OFS_MASK 0xF000 // number of 32 bit words in the TCP Header + +#define TCP_CODE_FIN 0x0001 +#define TCP_CODE_SYN 0x0002 +#define TCP_CODE_RST 0x0004 +#define TCP_CODE_PSH 0x0008 +#define TCP_CODE_ACK 0x0010 +#define TCP_CODE_URG 0x0020 + +#define TCP_OPT_MSS 0x0204 // Type 2, Option Length 4 (Max. Segment Size) +#define TCP_OPT_MSS_SIZE 4 + +// define some TCP standard-ports, useful for testing... +#define TCP_PORT_ECHO 7 // echo +#define TCP_PORT_DISCARD 9 // discard +#define TCP_PORT_DAYTIME 13 // daytime +#define TCP_PORT_QOTD 17 // quote of the day +#define TCP_PORT_CHARGEN 19 // character generator +#define TCP_PORT_HTTP 80 // word wide web HTTP + +// macros +#define SWAPB(Word) ((unsigned short)((Word) << 8) | ((Word) >> 8)) + // convert little <-> big endian + +// typedefs +typedef enum { // states of the TCP-state machine + CLOSED, // according to RFC793 + LISTENING, + SYN_SENT, + SYN_RECD, + ESTABLISHED, + FIN_WAIT_1, + FIN_WAIT_2, + CLOSE_WAIT, + CLOSING, + LAST_ACK, + TIME_WAIT +} TTCPStateMachine; + +typedef enum { // type of last frame sent. used + ARP_REQUEST, // for retransmissions + TCP_SYN_FRAME, + TCP_SYN_ACK_FRAME, + TCP_FIN_FRAME, + TCP_DATA_FRAME +} TLastFrameSent; + +// constants + +// Code Red +// ifdef added as due to change to including .h files rather than .c files. +// The use of ifdef reduces the coding changes that would otherwise be required, +// depending upon which file is including this one. +// the next 3 buffers must be word-aligned! +// (here the 'RecdIPFrameLength' above does that) + +extern unsigned short _TxFrame1[(ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + MAX_TCP_TX_DATA_SIZE)/2]; +extern unsigned short _TxFrame2[(ETH_HEADER_SIZE + MAX_ETH_TX_DATA_SIZE)/2]; +extern unsigned short _RxTCPBuffer[MAX_TCP_RX_DATA_SIZE/2]; // space for incoming TCP-data +#define TxFrame1 ((unsigned char *)_TxFrame1) +#define TxFrame2 ((unsigned char *)_TxFrame2) +#define RxTCPBuffer ((unsigned char *)_RxTCPBuffer) + +// +// prototypes +void DoNetworkStuff(void); + +// Handlers for incoming frames +void ProcessEthBroadcastFrame(void); +void ProcessEthIAFrame(void); +void ProcessICMPFrame(void); +void ProcessTCPFrame(void); + +// fill TX-buffers +void PrepareARP_REQUEST(void); +void PrepareARP_ANSWER(void); +void PrepareICMP_ECHO_REPLY(void); +void PrepareTCP_FRAME(unsigned short TCPCode); +void PrepareTCP_DATA_FRAME(void); + +// general help functions +void SendFrame1(void); +void SendFrame2(void); +void TCPStartRetryTimer(void); +void TCPStartTimeWaitTimer(void); +void TCPRestartTimer(void); +void TCPStopTimer(void); +void TCPHandleRetransmission(void); +void TCPHandleTimeout(void); +unsigned short CalcChecksum(void *Start, unsigned short Count, unsigned char IsTCP); + +// functions to work with big-endian numbers +unsigned short SwapBytes(unsigned short Data); +void WriteWBE(unsigned char *Add, unsigned short Data); +void WriteDWBE(unsigned char *Add, unsigned long Data); + +// easyWEB-API functions +void TCPLowLevelInit(void); // setup timer, LAN-controller, flags... +void TCPPassiveOpen(void); // listen for a connection +void TCPActiveOpen(void); // open connection +void TCPClose(void); // close connection +void TCPReleaseRxBuffer(void); // indicate to discard rec'd packet +void TCPTransmitTxBuffer(void); // initiate transfer after TxBuffer is filled +// Code Red - added declaration for Timer0 ISR +void TCPClockHandler(void); + +// easyWEB-API global vars and flags +extern unsigned short TCPRxDataCount; // nr. of bytes rec'd +extern unsigned short TCPTxDataCount; // nr. of bytes to send + +extern unsigned short TCPLocalPort; // TCP ports +extern unsigned short TCPRemotePort; + +extern unsigned short RemoteMAC[3]; // MAC and IP of current TCP-session +extern unsigned short RemoteIP[2]; + +extern unsigned char SocketStatus; +#define SOCK_ACTIVE 0x01 // state machine NOT closed +#define SOCK_CONNECTED 0x02 // user may send & receive data +#define SOCK_DATA_AVAILABLE 0x04 // new data available +#define SOCK_TX_BUF_RELEASED 0x08 // user may fill buffer + +#define SOCK_ERROR_MASK 0xF0 // bit-mask to check for errors +#define SOCK_ERR_OK 0x00 // no error +#define SOCK_ERR_ARP_TIMEOUT 0x10 // timeout waiting for an ARP-REPLY +#define SOCK_ERR_TCP_TIMEOUT 0x20 // timeout waiting for an ACK +#define SOCK_ERR_CONN_RESET 0x30 // connection was reset by the other TCP +#define SOCK_ERR_REMOTE 0x40 // remote TCP caused fatal error +#define SOCK_ERR_ETHERNET 0x50 // network interface error (timeout) + +// easyWEB-API buffer-pointers +#define TCP_TX_BUF ((unsigned char *)TxFrame1 + ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE) +#define TCP_RX_BUF ((unsigned char *)RxTCPBuffer) + +#endif +
diff -r 000000000000 -r 12b53511e212 webside.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webside.h Fri Jan 29 21:46:31 2010 +0000 @@ -0,0 +1,145 @@ +/****************************************************************** + ***** ***** + ***** Name: webside.c ***** + ***** Ver.: 1.0 ***** + ***** Date: 07/05/2001 ***** + ***** Auth: Andreas Dannenberg ***** + ***** HTWK Leipzig ***** + ***** university of applied sciences ***** + ***** Germany ***** + ***** adannenb@et.htwk-leipzig.de ***** + ***** Func: example HTML-code for easyweb.c ***** + ***** ***** + ******************************************************************/ + +// CodeRed - Example webpage updated + +const unsigned char WebSide[] = { +"<html>\r\n" +"<head>\r\n" +"<meta http-equiv=\"refresh\" content=\"1\">\r\n" +"<title>easyWEB - dynamic Webside</title>\r\n" +"</head>\r\n" +"\r\n" +"<body bgcolor=\"red\" text=\"#FFFF00\">\r\n" +"<p><b><font color=\"#FFFFFF\" size=\"6\"><i>Hello World from Code Red Technology!</i></font></b></p>\r\n" +"\r\n" +"<p><b>This is a dynamic website hosted by the embedded Webserver</b> <b>easyWEB.</b></p>\r\n" +"<p><b>Hardware:</b></p>\r\n" +"<ul>\r\n" +"<li><b>Code Red RDB1768 Development Board - NXP LPC1768 MCU with ARM Cortex-M3 CPU</b></li>\r\n" +"<li><b>Embedded EMAC Ethernet Controller</b></li>\r\n" +"</ul>\r\n" +"\r\n" +"<p><b>Variable value: AD8% (decimal value from 'val')</b></p>\r\n" +"\r\n" +"<table bgcolor=\"#ff0000\" border=\"5\" cellpadding=\"0\" cellspacing=\"0\" width=\"500\">\r\n" +"<tr>\r\n" +"<td>\r\n" +"<table width=\"AD7%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\r\n" +"<tr><td bgcolor=\"#00ff00\"> </td></tr>\r\n" +"</table>\r\n" +"</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"\r\n" +"<table border=\"0\" width=\"540\">\r\n" +"<tr>\r\n" +"<td width=\"25%\">0</td>\r\n" +"<td width=\"25%\">256</td>\r\n" +"<td width=\"25%\">512</td>\r\n" +"<td width=\"25%\">768</td>\r\n" +"<td width=\"25%\">1024</td>\r\n" +//"<td width=\"15%\">2.5V</td>\r\n" +//"<td width=\"15%\">3V</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"\r\n" +"<br><br><br><br>\r\n" +"<table border=\"0\" width=\"500\">\r\n" +"<tr>\r\n" +"<td width=\"1%\"></td>\r\n" +"<td width=\"60%\">\r\n" +"<table bgcolor=\"red\" border=\"5\" cellpadding=\"0\" cellspacing=\"0\" width=\"350\">\r\n" +"<tr>\r\n" +"<td>\r\n" +"<p><b><font color=\"#FFFFFF\" size=\"6\"><i>Page Count: AD1%</i></font></b></p>\r\n" +"</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"\r\n" +"\r\n" +"\r\n" +"</body>\r\n" +"</html>\r\n" +"\r\n"}; + +// Code Red - Original page removed +/* +const unsigned char WebSide[] = { +"<html>\r\n" +"<head>\r\n" +"<meta http-equiv=\"refresh\" content=\"5\">\r\n" +"<title>easyWEB - dynamic Webside</title>\r\n" +"</head>\r\n" +"\r\n" +"<body bgcolor=\"#3030A0\" text=\"#FFFF00\">\r\n" +"<p><b><font color=\"#FFFFFF\" size=\"6\"><i>Hello World!</i></font></b></p>\r\n" +"\r\n" +"<p><b>This is a dynamic webside hosted by the embedded Webserver</b> <b>easyWEB.</b></p>\r\n" +"<p><b>Hardware:</b></p>\r\n" +"<ul>\r\n" +"<li><b>MSP430F149, 8 MHz, 60KB Flash, 2KB SRAM</b></li>\r\n" +"<li><b>CS8900A Crystal Ethernet Controller</b></li>\r\n" +"</ul>\r\n" +"\r\n" +"<p><b>A/D Converter Value Port P6.7:</b></p>\r\n" +"\r\n" +"<table bgcolor=\"#ff0000\" border=\"5\" cellpadding=\"0\" cellspacing=\"0\" width=\"500\">\r\n" +"<tr>\r\n" +"<td>\r\n" +"<table width=\"AD7%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\r\n" +"<tr><td bgcolor=\"#00ff00\"> </td></tr>\r\n" +"</table>\r\n" +"</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"\r\n" +"<table border=\"0\" width=\"500\">\r\n" +"<tr>\r\n" +"<td width=\"20%\">0V</td>\r\n" +"<td width=\"20%\">0,5V</td>\r\n" +"<td width=\"20%\">1V</td>\r\n" +"<td width=\"20%\">1,5V</td>\r\n" +"<td width=\"20%\">2V</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"\r\n" +"<p><b>MCU Temperature:</b></p>\r\n" +"\r\n" +"<table bgcolor=\"#ff0000\" border=\"5\" cellpadding=\"0\" cellspacing=\"0\" width=\"500\">\r\n" +"<tr>\r\n" +"<td>\r\n" +"<table width=\"ADA%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\r\n" +"<tr><td bgcolor=\"#00ff00\"> </td></tr> \r\n" +"</table>\r\n" +"</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"\r\n" +"<table border=\"0\" width=\"500\">\r\n" +"<tr>\r\n" +"<td width=\"20%\">20�C</td>\r\n" +"<td width=\"20%\">25�C</td>\r\n" +"<td width=\"20%\">30�C</td>\r\n" +"<td width=\"20%\">35�C</td>\r\n" +"<td width=\"20%\">40�C</td>\r\n" +"</tr>\r\n" +"</table>\r\n" +"</body>\r\n" +"</html>\r\n" +"\r\n"}; +*/ \ No newline at end of file