Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of EasyWebCR by
easyweb.c
00001 /****************************************************************** 00002 ***** ***** 00003 ***** Name: easyweb.c ***** 00004 ***** Ver.: 1.0 ***** 00005 ***** Date: 07/05/2001 ***** 00006 ***** Auth: Andreas Dannenberg ***** 00007 ***** HTWK Leipzig ***** 00008 ***** university of applied sciences ***** 00009 ***** Germany ***** 00010 ***** adannenb@et.htwk-leipzig.de ***** 00011 ***** Func: implements a dynamic HTTP-server by using ***** 00012 ***** the easyWEB-API ***** 00013 ***** Rem.: In IAR-C, use linker option ***** 00014 ***** "-e_medium_write=_formatted_write" ***** 00015 ***** ***** 00016 ******************************************************************/ 00017 00018 // Modifications by Code Red Technologies for NXP LPC1768 00019 00020 // CodeRed - removed header for MSP430 microcontroller 00021 //#include "msp430x14x.h" 00022 00023 #include "mbed.h" 00024 00025 #include "stdlib.h" 00026 #include "stdio.h" 00027 #include "string.h" 00028 00029 #include "easyweb.h" 00030 00031 // CodeRed - removed header for original ethernet controller 00032 //#include "cs8900.c" // ethernet packet driver 00033 00034 //CodeRed - added for LPC ethernet controller 00035 #include "ethmac.h" 00036 00037 // CodeRed - include .h rather than .c file 00038 // #include "tcpip.c" // easyWEB TCP/IP stack 00039 #include "tcpip.h" // easyWEB TCP/IP stack 00040 00041 // CodeRed - added NXP LPC register definitions header 00042 // CodeRed - include renamed .h rather than .c file 00043 // #include "webside.c" // webside for our HTTP server (HTML) 00044 #include "webside.h" // webside for our HTTP server (HTML) 00045 00046 00047 00048 // CodeRed - added for use in dynamic side of web page 00049 unsigned int aaPagecounter=0; 00050 unsigned int adcValue = 0; 00051 00052 int main (void) 00053 { 00054 // CodeRed - removed init functions as not required for LPC1776 00055 // InitOsc(); 00056 // InitPorts(); 00057 00058 00059 // CodeRed - added info message 00060 printf("Setting up TCP/IP with IP address: "); 00061 printf("%d.%d.%d.%d\n",MYIP_1,MYIP_2,MYIP_3,MYIP_4); 00062 00063 TCPLowLevelInit(); 00064 00065 /* 00066 *(unsigned char *)RemoteIP = 24; // uncomment those lines to get the 00067 *((unsigned char *)RemoteIP + 1) = 8; // quote of the day from a real 00068 *((unsigned char *)RemoteIP + 2) = 69; // internet server! (gateway must be 00069 *((unsigned char *)RemoteIP + 3) = 7; // set to your LAN-router) 00070 00071 TCPLocalPort = 2025; 00072 TCPRemotePort = TCP_PORT_QOTD; 00073 00074 TCPActiveOpen(); 00075 00076 while (SocketStatus & SOCK_ACTIVE) // read the quote from memory 00077 { // by using the hardware-debugger 00078 DoNetworkStuff(); 00079 } 00080 */ 00081 00082 HTTPStatus = 0; // clear HTTP-server's flag register 00083 00084 TCPLocalPort = TCP_PORT_HTTP; // set port we want to listen to 00085 00086 // CodeRed - added info message 00087 printf("Webserver started\n"); 00088 00089 while (1) // repeat forever 00090 { 00091 if (!(SocketStatus & SOCK_ACTIVE)) TCPPassiveOpen(); // listen for incoming TCP-connection 00092 DoNetworkStuff(); // handle network and easyWEB-stack 00093 // events 00094 HTTPServer(); 00095 } 00096 } 00097 00098 // This function implements a very simple dynamic HTTP-server. 00099 // It waits until connected, then sends a HTTP-header and the 00100 // HTML-code stored in memory. Before sending, it replaces 00101 // some special strings with dynamic values. 00102 // NOTE: For strings crossing page boundaries, replacing will 00103 // not work. In this case, simply add some extra lines 00104 // (e.g. CR and LFs) to the HTML-code. 00105 00106 void HTTPServer(void) 00107 { 00108 if (SocketStatus & SOCK_CONNECTED) // check if somebody has connected to our TCP 00109 { 00110 if (SocketStatus & SOCK_DATA_AVAILABLE) // check if remote TCP sent data 00111 TCPReleaseRxBuffer(); // and throw it away 00112 00113 if (SocketStatus & SOCK_TX_BUF_RELEASED) // check if buffer is free for TX 00114 { 00115 if (!(HTTPStatus & HTTP_SEND_PAGE)) // init byte-counter and pointer to webside 00116 { // if called the 1st time 00117 HTTPBytesToSend = sizeof(WebSide) - 1; // get HTML length, ignore trailing zero 00118 PWebSide = (unsigned char *)WebSide; // pointer to HTML-code 00119 } 00120 00121 if (HTTPBytesToSend > MAX_TCP_TX_DATA_SIZE) // transmit a segment of MAX_SIZE 00122 { 00123 if (!(HTTPStatus & HTTP_SEND_PAGE)) // 1st time, include HTTP-header 00124 { 00125 memcpy(TCP_TX_BUF, GetResponse, sizeof(GetResponse) - 1); 00126 memcpy(TCP_TX_BUF + sizeof(GetResponse) - 1, PWebSide, MAX_TCP_TX_DATA_SIZE - sizeof(GetResponse) + 1); 00127 HTTPBytesToSend -= MAX_TCP_TX_DATA_SIZE - sizeof(GetResponse) + 1; 00128 PWebSide += MAX_TCP_TX_DATA_SIZE - sizeof(GetResponse) + 1; 00129 } 00130 else 00131 { 00132 memcpy(TCP_TX_BUF, PWebSide, MAX_TCP_TX_DATA_SIZE); 00133 HTTPBytesToSend -= MAX_TCP_TX_DATA_SIZE; 00134 PWebSide += MAX_TCP_TX_DATA_SIZE; 00135 } 00136 00137 TCPTxDataCount = MAX_TCP_TX_DATA_SIZE; // bytes to xfer 00138 InsertDynamicValues(); // exchange some strings... 00139 TCPTransmitTxBuffer(); // xfer buffer 00140 } 00141 else if (HTTPBytesToSend) // transmit leftover bytes 00142 { 00143 memcpy(TCP_TX_BUF, PWebSide, HTTPBytesToSend); 00144 TCPTxDataCount = HTTPBytesToSend; // bytes to xfer 00145 InsertDynamicValues(); // exchange some strings... 00146 TCPTransmitTxBuffer(); // send last segment 00147 TCPClose(); // and close connection 00148 HTTPBytesToSend = 0; // all data sent 00149 } 00150 00151 HTTPStatus |= HTTP_SEND_PAGE; // ok, 1st loop executed 00152 } 00153 } 00154 else 00155 HTTPStatus &= ~HTTP_SEND_PAGE; // reset help-flag if not connected 00156 } 00157 00158 00159 00160 00161 // Code Red - GetAD7Val function replaced 00162 // Rather than using the AD convertor, in this version we simply increment 00163 // a counter the function is called, wrapping at 1024. 00164 volatile unsigned int aaScrollbar = 400; 00165 00166 unsigned int GetAD7Val(void) 00167 { 00168 aaScrollbar = (aaScrollbar +16) % 1024; 00169 adcValue = (aaScrollbar / 10) * 1000/1024; 00170 return aaScrollbar; 00171 } 00172 00173 // Code Red - Original MSP430 version of GetAD7Val() removed 00174 /* 00175 // samples and returns the AD-converter value of channel 7 00176 // (associated with Port P6.7) 00177 00178 unsigned int GetAD7Val(void) 00179 { 00180 ADC12CTL0 = ADC12ON | SHT0_15 | REF2_5V | REFON; // ADC on, int. ref. on (2,5 V), 00181 // single channel single conversion 00182 ADC12CTL1 = ADC12SSEL_2 | ADC12DIV_7 | CSTARTADD_0 | SHP;// MCLK / 8 = 1 MHz 00183 00184 ADC12MCTL0 = SREF_1 | INCH_7; // int. ref., channel 7 00185 00186 ADC12CTL0 |= ENC; // enable conversion 00187 ADC12CTL0 |= ADC12SC; // sample & convert 00188 00189 while (ADC12CTL0 & ADC12SC); // wait until conversion is complete 00190 00191 ADC12CTL0 &= ~ENC; // disable conversion 00192 00193 return ADC12MEM0 / 41; // scale 12 bit value to 0..100% 00194 } 00195 00196 // End of Original MSP430 version of GetAD7Val() 00197 */ 00198 00199 00200 // Code Red - Original GetTempVal() removed 00201 // Function no longer used 00202 /* 00203 // samples and returns AD-converter value of channel 10 00204 // (MSP430's internal temperature reference diode) 00205 // NOTE: to get a more exact value, 8-times oversampling is used 00206 00207 unsigned int GetTempVal(void) 00208 { 00209 unsigned long ReturnValue; 00210 00211 ADC12CTL0 = ADC12ON | SHT0_15 | MSH | REFON; // ADC on, int. ref. on (1,5 V), 00212 // multiple sample & conversion 00213 ADC12CTL1 = ADC12SSEL_2 | ADC12DIV_7 | CSTARTADD_0 | CONSEQ_1 | SHP; // MCLK / 8 = 1 MHz 00214 00215 ADC12MCTL0 = SREF_1 | INCH_10; // int. ref., channel 10 00216 ADC12MCTL1 = SREF_1 | INCH_10; // int. ref., channel 10 00217 ADC12MCTL2 = SREF_1 | INCH_10; // int. ref., channel 10 00218 ADC12MCTL3 = SREF_1 | INCH_10; // int. ref., channel 10 00219 ADC12MCTL4 = SREF_1 | INCH_10; // int. ref., channel 10 00220 ADC12MCTL5 = SREF_1 | INCH_10; // int. ref., channel 10 00221 ADC12MCTL6 = SREF_1 | INCH_10; // int. ref., channel 10 00222 ADC12MCTL7 = EOS | SREF_1 | INCH_10; // int. ref., channel 10, last seg. 00223 00224 ADC12CTL0 |= ENC; // enable conversion 00225 ADC12CTL0 |= ADC12SC; // sample & convert 00226 00227 while (ADC12CTL0 & ADC12SC); // wait until conversion is complete 00228 00229 ADC12CTL0 &= ~ENC; // disable conversion 00230 00231 ReturnValue = ADC12MEM0; // sum up values... 00232 ReturnValue += ADC12MEM1; 00233 ReturnValue += ADC12MEM2; 00234 ReturnValue += ADC12MEM3; 00235 ReturnValue += ADC12MEM4; 00236 ReturnValue += ADC12MEM5; 00237 ReturnValue += ADC12MEM6; 00238 ReturnValue += ADC12MEM7; 00239 00240 ReturnValue >>= 3; // ... and divide by 8 00241 00242 if (ReturnValue < 2886) ReturnValue = 2886; // lower bound (0% = 20�C) 00243 ReturnValue = (ReturnValue - 2886) / 2.43; // convert AD-value to a temperature from 00244 // 20�C...45�C represented by a value 00245 // of 0...100% 00246 if (ReturnValue > 100) ReturnValue = 100; // upper bound (100% = 45�C) 00247 00248 return ReturnValue; 00249 } 00250 // End of Original MSP430 version of GetTempVal() 00251 */ 00252 00253 00254 // searches the TX-buffer for special strings and replaces them 00255 // with dynamic values (AD-converter results) 00256 00257 // Code Red - new version of InsertDynamicValues() 00258 void InsertDynamicValues(void) 00259 { 00260 unsigned char *Key; 00261 char NewKey[6]; 00262 unsigned int i; 00263 00264 if (TCPTxDataCount < 4) return; // there can't be any special string 00265 00266 Key = TCP_TX_BUF; 00267 00268 for (i = 0; i < (TCPTxDataCount - 3); i++) 00269 { 00270 if (*Key == 'A') 00271 if (*(Key + 1) == 'D') 00272 if (*(Key + 3) == '%') 00273 switch (*(Key + 2)) 00274 { 00275 case '8' : // "AD8%"? 00276 { 00277 sprintf(NewKey, "%04d", GetAD7Val()); // insert pseudo-ADconverter value 00278 memcpy(Key, NewKey, 4); 00279 break; 00280 } 00281 case '7' : // "AD7%"? 00282 { 00283 sprintf(NewKey, "%3u", adcValue); // copy saved value from previous read 00284 memcpy(Key, NewKey, 3); 00285 break; 00286 } 00287 case '1' : // "AD1%"? 00288 { 00289 sprintf(NewKey, "%4u", ++aaPagecounter); // increment and insert page counter 00290 memcpy(Key, NewKey, 4); 00291 // *(Key + 3) = ' '; 00292 break; 00293 } 00294 } 00295 Key++; 00296 } 00297 } 00298 00299 00300 // Code Red - commented out original InsertDynamicValues() 00301 /* 00302 void InsertDynamicValues(void) 00303 { 00304 unsigned char *Key; 00305 unsigned char NewKey[5]; 00306 unsigned int i; 00307 00308 if (TCPTxDataCount < 4) return; // there can't be any special string 00309 00310 Key = TCP_TX_BUF; 00311 00312 for (i = 0; i < (TCPTxDataCount - 3); i++) 00313 { 00314 if (*Key == 'A') 00315 if (*(Key + 1) == 'D') 00316 if (*(Key + 3) == '%') 00317 switch (*(Key + 2)) 00318 { 00319 case '7' : // "AD7%"? 00320 { 00321 sprintf(NewKey, "%3u", GetAD7Val()); // insert AD converter value 00322 memcpy(Key, NewKey, 3); // channel 7 (P6.7) 00323 break; 00324 } 00325 case 'A' : // "ADA%"? 00326 { 00327 sprintf(NewKey, "%3u", GetTempVal()); // insert AD converter value 00328 memcpy(Key, NewKey, 3); // channel 10 (temp.-diode) 00329 break; 00330 } 00331 } 00332 Key++; 00333 } 00334 } 00335 00336 // Code Red - End of original InsertDynamicValues () 00337 */ 00338 00339 // Code Red - Deleted InitOsc() and InitPorts() as not required 00340 // by LPC 1776 00341 00342 /* 00343 // enables the 8MHz crystal on XT1 and use 00344 // it as MCLK 00345 00346 void InitOsc(void) 00347 { 00348 WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer 00349 00350 BCSCTL1 |= XTS; // XT1 as high-frequency 00351 _BIC_SR(OSCOFF); // turn on XT1 oscillator 00352 00353 do // wait in loop until crystal is stable 00354 IFG1 &= ~OFIFG; 00355 while (IFG1 & OFIFG); 00356 00357 BCSCTL1 |= DIVA0; // ACLK = XT1 / 2 00358 BCSCTL1 &= ~DIVA1; 00359 00360 IE1 &= ~WDTIE; // disable WDT int. 00361 IFG1 &= ~WDTIFG; // clear WDT int. flag 00362 00363 WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL | WDTSSEL | WDTIS1; // use WDT as timer, flag each 00364 // 512 pulses from ACLK 00365 00366 while (!(IFG1 & WDTIFG)); // count 1024 pulses from XT1 (until XT1's 00367 // amplitude is OK) 00368 00369 IFG1 &= ~OFIFG; // clear osc. fault int. flag 00370 BCSCTL2 = SELM0 | SELM1; // set XT1 as MCLK 00371 } 00372 00373 void InitPorts(void) 00374 { 00375 P1SEL = 0; // switch all unused ports to output 00376 P1OUT = 0; // (rem.: ports 3 & 5 are set in "cs8900.c") 00377 P1DIR = 0xFF; 00378 00379 P2SEL = 0; 00380 P2OUT = 0; 00381 P2DIR = 0xFF; 00382 00383 P4SEL = 0; 00384 P4OUT = 0; 00385 P4DIR = 0xFF; 00386 00387 P6SEL = 0x80; // use P6.7 for the ADC module 00388 P6OUT = 0; 00389 P6DIR = 0x7F; // all output except P6.7 00390 } 00391 00392 */
Generated on Tue Jul 12 2022 18:57:49 by
