Igor Skochinsky
/
EasyWebCR
code_red's port of EasyWeb server for LPC1768, made to compile with mbed's online compiler.
easyweb.c
- Committer:
- igorsk
- Date:
- 2010-01-29
- Revision:
- 0:12b53511e212
File content as of revision 0:12b53511e212:
/****************************************************************** ***** ***** ***** 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 } */