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.
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 22:58:15 by
1.7.2