Igor Skochinsky
/
EasyWebCR
code_red's port of EasyWeb server for LPC1768, made to compile with mbed's online compiler.
Diff: easyweb.c
- Revision:
- 0:12b53511e212
--- /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