Add new LPC1768 RedSuite demo.
diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/font.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/font.h
new file mode 100644
index 0000000..c7f07ca
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/font.h
@@ -0,0 +1,33 @@
+//*****************************************************************************

+//   +--+       

+//   | ++----+   

+//   +-++    |  

+//     |     |  

+//   +-+--+  |   

+//   | +--+--+  

+//   +----+    Copyright (c) 2009 Code Red Technologies Ltd. 

+//

+// font.h - header file for font data contained in system_fixed_be_8_15.c

+//

+// 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. 

+

+#ifndef FONT_H_

+#define FONT_H_

+

+extern const unsigned char font_data_table[];

+extern const unsigned char font_index_table[];

+

+#endif /*FONT_H_*/

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd.c
new file mode 100644
index 0000000..fed36a9
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd.c
@@ -0,0 +1,308 @@
+//*****************************************************************************

+//   +--+       

+//   | ++----+   

+//   +-++    |  

+//     |     |  

+//   +-+--+  |   

+//   | +--+--+  

+//   +----+    Copyright (c) 2009 Code Red Technologies Ltd. 

+//

+// lcd.c contains various routines to plot to the LCD display on the RDB1768

+// development board.

+//

+// 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 "lcd_commands.h"

+#include "lcd.h"

+#include "lcd_driver.h"

+#include "font.h"

+

+#include <stdlib.h>		// to provice abs() function

+

+// Routine to draw a filled rectangle to the LCD.

+// Two corners of rectangle are at (xmin,ymin) and (xmax,ymax).

+// The Rectangle is filled with the RGB565 color specified

+void LCD_FilledRect(int xmin,int xmax,int ymin,int ymax,int color)

+{

+    int i;

+

+    // Specify to LCD controller coordinates we are writing to...

+    LCDdriver_WriteCom(DD_CASET); 	// Set the column address

+    LCDdriver_WriteData(xmin);		// min address

+    LCDdriver_WriteData(xmax);		// max address

+    LCDdriver_WriteCom(DD_RASET);	// Set the row address

+    LCDdriver_WriteData(ymin + 1);	// min address

+    LCDdriver_WriteData(ymax + 1);	// max address

+    LCDdriver_WriteCom(DD_RAMWR);	// RAM Write command

+

+    // Plot the color data to the LCD buffer

+    for(i = ((xmax - xmin + 1) * (ymax - ymin + 1)); i > 0; i--)

+    {

+    	LCDdriver_WriteData(color >> 8);	// top 8 bits of RGB565 color

+    	LCDdriver_WriteData(color);			// bottom 8 bits of RGB565 color

+    }

+}

+

+// Routine to draw an unfilled rectangle to the LCD.

+// Two corners of rectangle are at (xmin,ymin) and (xmax,ymax).

+// The Rectangle is drawn in the RGB565 color specified

+void LCD_Rect(int xmin,int xmax,int ymin,int ymax,int color)

+{

+	// Draw 4 lines of rectange as 4 filled rectanges, each of 1 pixel wide

+	LCD_FilledRect(xmin,xmin,ymin,ymax,color);

+	LCD_FilledRect(xmax,xmax,ymin,ymax,color);

+	LCD_FilledRect(xmin,xmax,ymin,ymin,color);

+	LCD_FilledRect(xmin,xmax,ymax,ymax,color);

+}

+

+

+

+// Plot a point on the screen in the 6:5:6 color format

+void LCD_PlotPoint(int x,int y,int color)

+{

+    LCDdriver_WriteCom(DD_CASET);	// Set the column address 

+    LCDdriver_WriteData(x);			// min address

+    LCDdriver_WriteData(x);			// max address

+    LCDdriver_WriteCom(DD_RASET);	// Set the row address

+    LCDdriver_WriteData(y + 1);		// min address

+    LCDdriver_WriteData(y + 1);		// max address

+    LCDdriver_WriteCom(DD_RAMWR);	// RAM Write command

+    LCDdriver_WriteData(color >> 8);	// top 8 bits of RGB565 color

+    LCDdriver_WriteData(color);			// top 8 bits of RGB565 color

+}

+

+// Routine to draw a filled circle to the LCD.

+// The centre of the circle is at (x0,y0) and the circle has the 

+// specifed radius. The circle is filled with the RGB565 color 

+// The circle is drawn using the "Midpoint circle algorithm", 

+// also known as "Bresenham's circle algorithm". In order to fill

+// the circle, the algorithm has been modifed to draw a line between

+// each two points, rather than plotting the two points individually.

+void LCD_FilledCircle (int x0, int y0, int radius, int color)

+{

+  int f = 1 - radius;

+  int ddF_x = 1;

+  int ddF_y = -2 * radius;

+  int x = 0;

+  int y = radius;

+  

+  LCD_FilledRect(x0, x0 ,y0 - radius,y0 + radius, color); 

+  LCD_FilledRect(x0 - radius, x0 + radius ,y0,y0, color);  

+  

+  while(x < y)

+  {

+    if(f >= 0) 

+    {

+      y--;

+      ddF_y += 2;

+      f += ddF_y;

+    }

+    x++;

+    ddF_x += 2;

+    f += ddF_x;    

+

+    LCD_FilledRect(x0-x, x0+x ,y0 +y, y0 + y, color);    

+    LCD_FilledRect(x0-x, x0+x ,y0 - y, y0 - y, color); 

+    LCD_FilledRect(x0-y, x0+y ,y0 + x, y0 + x, color);         

+    LCD_FilledRect(x0-y, x0+y ,y0 - x, y0 - x, color); 

+  }

+}

+

+// Routine to draw an unfilled circle to the LCD.

+// The centre of the circle is at (x0,y0) and the circle has the 

+// specifed radius. The circle is drawn in the RGB565 color 

+// The circle is drawn using the "Midpoint circle algorithm", 

+// also known as "Bresenham's circle algorithm". 

+void LCD_Circle (int x0, int y0, int radius, int color)

+{

+  int f = 1 - radius;

+  int ddF_x = 1;

+  int ddF_y = -2 * radius;

+  int x = 0;

+  int y = radius;

+

+  LCD_PlotPoint(x0, y0 + radius, color);

+  LCD_PlotPoint(x0, y0 - radius, color);

+  LCD_PlotPoint(x0 + radius, y0, color);

+  LCD_PlotPoint(x0 - radius, y0, color);

+

+  while(x < y)

+  {

+    if(f >= 0) 

+    {

+      y--;

+      ddF_y += 2;

+      f += ddF_y;

+    }

+    x++;

+    ddF_x += 2;

+    f += ddF_x;    

+    LCD_PlotPoint(x0 + x, y0 + y, color);

+    LCD_PlotPoint(x0 - x, y0 + y, color);

+    LCD_PlotPoint(x0 + x, y0 - y, color);

+    LCD_PlotPoint(x0 - x, y0 - y, color);

+    LCD_PlotPoint(x0 + y, y0 + x, color);

+    LCD_PlotPoint(x0 - y, y0 + x, color);

+    LCD_PlotPoint(x0 + y, y0 - x, color);

+    LCD_PlotPoint(x0 - y, y0 - x, color);

+  }

+}

+

+// Routine to draw a line in the RGB565 color to the LCD.

+// The line is drawn from (xmin,ymin) to (xmax,ymax).

+// The algorithm used to draw the line is "Bresenham's line

+// algorithm". 

+#define SWAP(a, b)  a ^= b; b ^= a; a ^= b; 

+

+void LCD_Line (int xmin,int xmax,int ymin,int ymax,int color)

+{

+   int Dx = xmax - xmin; 

+   int Dy = ymax - ymin;

+   int steep = (abs(Dy) >= abs(Dx));

+   if (steep) {

+       SWAP(xmin, ymin);

+       SWAP(xmax, ymax);

+       // recompute Dx, Dy after swap

+       Dx = xmax - xmin;

+       Dy = ymax - ymin;

+   }

+   int xstep = 1;

+   if (Dx < 0) {

+       xstep = -1;

+       Dx = -Dx;

+   }

+   int ystep = 1;

+   if (Dy < 0) {

+       ystep = -1;		

+       Dy = -Dy; 

+   }

+   int TwoDy = 2*Dy; 

+   int TwoDyTwoDx = TwoDy - 2*Dx; // 2*Dy - 2*Dx

+   int E = TwoDy - Dx; //2*Dy - Dx

+   int y = ymin;

+   int xDraw, yDraw;

+   int x;

+   for (x = xmin; x != xmax; x += xstep) {		

+       if (steep) {			

+           xDraw = y;

+           yDraw = x;

+       } else {			

+           xDraw = x;

+           yDraw = y;

+       }

+       // plot

+       LCD_PlotPoint(xDraw, yDraw, color);

+       // next

+       if (E > 0) {

+           E += TwoDyTwoDx; //E += 2*Dy - 2*Dx;

+           y = y + ystep;

+       } else {

+           E += TwoDy; //E += 2*Dy;

+       }

+   }

+}

+

+// Routine to clear the LCD.

+// Implemented by drawing a black rectangle across the whole screen

+void LCD_ClearScreen(void)

+{	

+	LCD_FilledRect (0,LCD_MAX_X,0 , LCD_MAX_Y, COLOR_BLACK);

+}

+

+

+

+// Routine to write a single character to screen in the font pointed

+// to by pBitMap.  This routine is intended to be used via the 

+// LCD_PrintChar() and LCD_PrintString() routines, rather than called

+// directly from user code.

+void LCD_WriteBitMap8x15(int x, int y, int height, int width, unsigned char *pBitMap, int color)

+{

+	int xmax = x + width - 1;	// start at zero

+	int ymax = y + height - 1;	// start at zero

+	int iRow, iCol;

+	unsigned char ucRowData;

+	

+    LCDdriver_WriteCom(DD_CASET);	// Column address set

+    LCDdriver_WriteData(x);		// Start column

+    LCDdriver_WriteData(xmax);		// End column

+    LCDdriver_WriteCom(DD_RASET);	// Row address set

+    LCDdriver_WriteData(y);		// Start row

+    LCDdriver_WriteData(ymax);		// End row

+    LCDdriver_WriteCom(DD_RAMWR);	// Memory write

+    

+    

+    for(iRow=0;iRow<height;iRow++)

+    {

+    	ucRowData = *pBitMap++;

+    	

+    	for(iCol=0;iCol<width;iCol++)

+    	{

+

+    		// Look at each input bitmap bit

+    		// and write as a black-pixel or

+    		// a color-pixel.

+    		

+    		if(ucRowData & 0x80)  // 'color pixel'

+    		{

+            	LCDdriver_WriteData(color >> 8); 

+            	LCDdriver_WriteData(color);

+    		}

+    		else				// black pixel

+    		{

+    			LCDdriver_WriteData(0x00);

+            	LCDdriver_WriteData(0x00);

+    		}

+        	

+        	ucRowData = ucRowData<<1;

+    	}

+    }

+

+}

+

+

+// Prints the character 'c' to the LCD in the appropriate color.

+void LCD_PrintChar(int x, int y, unsigned char c, int color )

+{

+    const unsigned char index = font_index_table[c];

+    const unsigned int offset = index * 15;

+    unsigned char *pData = (unsigned char *)&font_data_table[offset];	

+

+    LCD_WriteBitMap8x15(x, y, 15, 8, pData, color);

+}

+

+// Prints the string to the LCD in the appropriate color.

+void LCD_PrintString(int x, int y, char *pcString, int iStrLen, int color)

+{

+    unsigned char index;

+    unsigned int offset;

+    unsigned char *pData;

+    unsigned char c;

+	int i;

+	

+	for(i=0;i<iStrLen;i++)

+	{

+		c = pcString[i];

+		if(c==0)

+			break;

+		index = font_index_table[c];

+	    offset = index * 15;

+	    pData = (unsigned char *)&font_data_table[offset];

+

+	    LCD_WriteBitMap8x15(x, y, 15, 8, pData, color);	

+	    x += 8;

+	}

+	

+}
\ No newline at end of file
diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd.h
new file mode 100644
index 0000000..51d52d5
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd.h
@@ -0,0 +1,92 @@
+//*****************************************************************************

+//   +--+       

+//   | ++----+   

+//   +-++    |  

+//     |     |  

+//   +-+--+  |   

+//   | +--+--+  

+//   +----+    Copyright (c) 2009 Code Red Technologies Ltd. 

+//

+// lcd.h - Routines containing primitives for writing to the LCD

+//

+//

+// 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. 

+

+

+#ifndef LCD_H_

+#define LCD_H_

+

+// Define size of LCD screen.

+

+#define LCD_MAX_X 128

+#define LCD_MAX_Y 128

+

+// Translates a 24-bit RGB color to RGB565

+#define TRANSLATE24BIT_TO_RGB565(c)    ((((c) & 0x00ff0000) >> 19) |               \

+                                 ((((c) & 0x0000ff00) >> 5) & 0x000007e0) | \

+                                 ((((c) & 0x000000ff) << 8) & 0x0000f800))

+

+// Define a basic set of 24bit colors, based on the standard "websafe" set

+#define COLOR24_AQUA	0x00FFFF

+#define COLOR24_GREY	0x808080

+#define COLOR24_NAVY 	0x000080 	

+#define COLOR24_SILVER 	0xC0C0C0

+#define COLOR24_BLACK 	0x000000 	

+#define COLOR24_GREEN 	0x008000 	

+#define COLOR24_OLIVE 	0x808000 	

+#define COLOR24_TEAL 	0x008080

+#define COLOR24_BLUE 	0x0000FF 	

+#define COLOR24_LIME 	0x00FF00 	

+#define COLOR24_PURPLE 	0x800080 	

+#define COLOR24_WHITE 	0xFFFFFF

+#define COLOR24_FUCHSIA	0xFF00FF 	

+#define COLOR24_MAROON	0x800000 	

+#define COLOR24_RED 	0xFF0000

+#define COLOR24_YELLOW 	0xFFFF00

+

+// Create a set of RGB565 colors that can be used directly within code

+#define COLOR_AQUA TRANSLATE24BIT_TO_RGB565(COLOR24_AQUA)

+#define COLOR_GREY	TRANSLATE24BIT_TO_RGB565(COLOR24_GREY)

+#define COLOR_NAVY	TRANSLATE24BIT_TO_RGB565(COLOR24_NAVY) 	

+#define COLOR_SILVER 	TRANSLATE24BIT_TO_RGB565(COLOR24_SILVER)

+#define COLOR_BLACK 	TRANSLATE24BIT_TO_RGB565(COLOR24_BLACK) 	

+#define COLOR_GREEN 	TRANSLATE24BIT_TO_RGB565(COLOR24_GREEN) 	

+#define COLOR_OLIVE 	TRANSLATE24BIT_TO_RGB565(COLOR24_OLIVE) 	

+#define COLOR_TEAL 		TRANSLATE24BIT_TO_RGB565(COLOR24_TEAL)

+#define COLOR_BLUE 		TRANSLATE24BIT_TO_RGB565(COLOR24_BLUE) 	

+#define COLOR_LIME 		TRANSLATE24BIT_TO_RGB565(COLOR24_LIME) 	

+#define COLOR_PURPLE 	TRANSLATE24BIT_TO_RGB565(COLOR24_PURPLE) 	

+#define COLOR_WHITE 	TRANSLATE24BIT_TO_RGB565(COLOR24_WHITE)

+#define COLOR_FUCHSIA	TRANSLATE24BIT_TO_RGB565(COLOR24_FUCHSIA) 	

+#define COLOR_MAROON	TRANSLATE24BIT_TO_RGB565(COLOR24_MAROON)	

+#define COLOR_RED 		TRANSLATE24BIT_TO_RGB565(COLOR24_RED)

+#define COLOR_YELLOW 	TRANSLATE24BIT_TO_RGB565(COLOR24_YELLOW)

+

+

+void LCD_Line (int xmin,int xmax,int ymin,int ymax,int color);

+void LCD_FilledRect(int xmin,int xmax,int ymin,int ymax,int color);

+void LCD_Rect(int xmin,int xmax,int ymin,int ymax,int color);

+void LCD_WriteBitMap8x15(int x, int y, int height, int width, unsigned char *pBitMap, int color);

+void LCD_PlotPoint(int x,int y,int color);

+void LCD_Circle (int x0, int y0, int radius, int color);

+void LCD_FilledCircle (int x0, int y0, int radius, int color);

+void LCD_ClearScreen(void);

+void LCD_WriteBitMap8x15(int x, int y, int height, int width, unsigned char *pBitMap, int color);

+void LCD_PrintChar(int x, int y, unsigned char c, int color );

+void LCD_PrintString(int x, int y, char *pcString, int iStrLen, int color);

+

+

+#endif /*LCD_H_*/
\ No newline at end of file
diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_commands.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_commands.h
new file mode 100644
index 0000000..37ebb39
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_commands.h
@@ -0,0 +1,53 @@
+//*****************************************************************************

+//   +--+       

+//   | ++----+   

+//   +-++    |  

+//     |     |  

+//   +-+--+  |   

+//   | +--+--+  

+//   +----+    Copyright (c) 2009 Code Red Technologies Ltd. 

+//

+// lcd_commands.h contains defines mapping onto the commands accepted by the

+// Sitronix ST7637 LCD Controller/driver used on the RDB1768 development board.//

+//

+// 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. 

+

+#ifndef LCD_COMMANDS_H_

+#define LCD_COMMANDS_H_

+

+#define DD_NOP 			0x00

+#define DD_SWRESET 		0x01	//SW reset the display

+#define DD_SLPIN		0x10	//Sleep in and booster off

+#define DD_SLPOUT		0x11	//Sleep out and booster on

+#define DD_NORON		0x13	//Partial mode off (Normal mode on)

+#define DD_DISPOFF		0x28	//Display Off

+#define DD_DISPON		0x29	//Display On

+#define DD_CASET		0x2a	//Column address set

+#define DD_RASET		0x2b	//Row address set

+#define DD_RAMWR		0x2c	//Memory write

+#define DD_MADCTR		0x36	//Memory Data Access Control

+#define DD_COLORMOD		0x3a	//Set the color mode for the display 

+#define DD_ColScanDir	0xb7	//Set the column scanning direction

+#define DD_VopSet		0xc0	//LCD supply voltage set

+#define DD_BiasSel		0xc3	//Bias selection

+#define DD_BstMbpXSel	0xc4	//Booster setting

+#define DD_AUTOLOADSET	0xd7	//Control auto load of ROM data

+#define DD_EPCTIN 		0xe0	//OTP control RD/WR

+#define DD_EPREAD		0xe3	//OTP read

+#define DD_EPCTOUT		0xe1	//OTP control cancel

+

+

+#endif /*LCD_COMMANDS_H_*/

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_driver.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_driver.c
new file mode 100644
index 0000000..857a07d
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_driver.c
@@ -0,0 +1,190 @@
+//*****************************************************************************

+//   +--+       

+//   | ++----+   

+//   +-++    |  

+//     |     |  

+//   +-+--+  |   

+//   | +--+--+  

+//   +----+    Copyright (c) 2009 Code Red Technologies Ltd. 

+//

+// lcd_driver.c contains the lowest level access routines for the Sitronix

+// ST7637 LCD Controller/driver used on the RDB1768 development board.

+//

+//

+// 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 "NXP/LPC17xx/LPC17xx.h"

+#include "lcd_driver.h"

+#include "lcd_commands.h"

+

+// Bits within GPIO port 2 used for LCD driver

+#define LCD_CSB_PIN            (1<<13)

+#define LCD_A0_PIN             (1<<8)

+#define LCD_WR_PIN             (1<<11)

+#define LCD_RD_PIN             (1<<12)

+#define LCD_DATA_PIN			0xff

+

+// Bit within GPIO port 3 used for LCD driver

+#define LCD_RESB_PIN           (1<<25)

+

+// Bits to configure as outputs for driving LCD

+#define LCD_PORT2_DIRECTIONS  (LCD_CSB_PIN | LCD_A0_PIN | LCD_WR_PIN | LCD_RD_PIN | LCD_DATA_PIN)

+#define LCD_PORT3_DIRECTIONS  (LCD_RESB_PIN)

+

+// Define names for GPIO port 2 and 3 registers to better indicate in code

+// the operation being carried out on the LCD driver hardware.

+#define LCD_DATA_CLR	FIO2CLR

+#define LCD_DATA_SET	FIO2SET

+

+#define LCD_CSB_CLR		FIO2CLR

+#define LCD_CSB_SET		FIO2SET

+

+#define LCD_RESB_CLR	FIO3CLR

+#define LCD_RESB_SET	FIO3SET

+

+#define LCD_A0_CLR		FIO2CLR

+#define LCD_A0_SET		FIO2SET

+

+#define LCD_WR_CLR		FIO2CLR

+#define LCD_WR_SET		FIO2SET

+

+#define LCD_RD_CLR		FIO2CLR

+#define LCD_RD_SET		FIO2SET

+

+// Routine to write data to LCD driver. Normally called in combination

+// with LCDdriver_WriteCom() routine

+void LCDdriver_WriteData(unsigned char LCD_Data)

+{

+    LCD_DATA_CLR = LCD_DATA_PIN;   

+    LCD_DATA_SET = LCD_Data;

+    LCD_CSB_CLR = LCD_CSB_PIN;

+    LCD_WR_CLR = LCD_WR_PIN;

+    LCD_WR_SET = LCD_WR_PIN;

+    LCD_CSB_SET = LCD_CSB_PIN;

+}

+

+// Routine to configure set LCD driver to accept particular command.

+// A call to this routine will normally be followed by a call

+// to LCDdriver_WriteData() to transfer appropriate parameters to driver.

+void LCDdriver_WriteCom(unsigned char LCD_Command)

+{

+    LCD_DATA_CLR = LCD_DATA_PIN;   

+    LCD_DATA_SET = LCD_Command;

+    LCD_A0_CLR =	LCD_A0_PIN;

+    LCD_CSB_CLR = LCD_CSB_PIN;

+    LCD_WR_CLR = LCD_WR_PIN;

+    LCD_WR_SET = LCD_WR_PIN;

+    LCD_CSB_SET = LCD_CSB_PIN;

+	LCD_A0_SET =	LCD_A0_PIN;

+}

+

+// Function to add short delays in writing things to the LCD.

+void ms_delay(int n)

+{

+   volatile int d;

+   for (d=0; d<n*3000; d++){}

+}

+

+

+// Initialize GPIO connection to the LCD driver

+void LCDdriver_ConfigGPIOtoLCD(void)

+{

+    // set direction to outputs	

+	FIO2DIR |= LCD_PORT2_DIRECTIONS;	

+	FIO3DIR |= LCD_PORT3_DIRECTIONS;

+	

+	// Set GPIO outputs connected to LCD to default values

+	LCD_CSB_SET = LCD_CSB_PIN;

+	LCD_A0_SET = LCD_A0_PIN;

+	LCD_WR_SET = LCD_WR_PIN;

+	LCD_RD_SET = LCD_RD_PIN;

+	LCD_RESB_SET = LCD_RESB_PIN;

+	LCD_DATA_CLR =  0xff; // data bus to zero 

+

+}

+

+

+// Initialisation routine to set up LCD

+void LCDdriver_initialisation(void)

+{

+	int i;		// temp loop variable

+	

+	LCDdriver_ConfigGPIOtoLCD();		// Initialize the GPIO for the display

+

+	LCDdriver_WriteCom(DD_SWRESET);		// SW reset

+	ms_delay(120);						// Small delay

+

+	LCDdriver_WriteCom(DD_AUTOLOADSET);	// disable auto loading of mask rom data

+	LCDdriver_WriteData(0xBF);

+

+	LCDdriver_WriteCom(DD_EPCTIN);			// OTP control mode=read

+	LCDdriver_WriteData(0x00);

+	ms_delay(10);							// Small delay

+

+	LCDdriver_WriteCom(DD_EPREAD);			// Start the OTP read.

+	ms_delay(20);							// Small delay

+

+	LCDdriver_WriteCom(DD_EPCTOUT);		// Cancel the OTP read (20ms should have been enough)

+

+	LCDdriver_WriteCom(DD_DISPOFF);		// display off

+

+	LCDdriver_WriteCom(DD_SLPOUT);			// Exit sleep mode.

+	ms_delay(50);							// Small delay

+

+	LCDdriver_WriteCom(DD_VopSet);			// set LCD operating voltage to 14V.

+	LCDdriver_WriteData(0x04);

+	LCDdriver_WriteData(0x01);

+

+	LCDdriver_WriteCom(DD_BiasSel);		// Select an LCD bias voltage ratio of 1/12.

+	LCDdriver_WriteData(0x00);

+

+	LCDdriver_WriteCom(DD_BstMbpXSel);		// x8 booster circuit on

+	LCDdriver_WriteData(0x07);

+

+	LCDdriver_WriteCom(DD_ColScanDir);		// Invert the column scan direction for the panel.

+	LCDdriver_WriteData(0xC0);

+

+	LCDdriver_WriteCom(DD_COLORMOD);		// 16bpp, 5-6-5 data input mode.

+	LCDdriver_WriteData(0x05);

+	

+	LCDdriver_WriteCom(DD_MADCTR);			// mem scan direction

+	LCDdriver_WriteData(0x00);

+	

+	LCDdriver_WriteCom(DD_DISPON);			// display on

+

+	// Now Clear the Screen

+	LCDdriver_WriteCom(DD_CASET);

+	LCDdriver_WriteData(0x00);

+	LCDdriver_WriteData(0x7F);

+

+	LCDdriver_WriteCom(DD_RASET);

+	LCDdriver_WriteData(0x01);

+	LCDdriver_WriteData(0x80);

+

+	LCDdriver_WriteCom(DD_RAMWR);

+	for(i = 0; i < (128 * 128); i++)

+	{

+		LCDdriver_WriteData(0x00);

+		LCDdriver_WriteData(0x00);

+	}

+

+	LCDdriver_WriteCom(DD_NORON);			// normal operation mode

+}

+

+

+

+

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_driver.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_driver.h
new file mode 100644
index 0000000..aa43648
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/lcd_driver.h
@@ -0,0 +1,36 @@
+//*****************************************************************************

+//   +--+       

+//   | ++----+   

+//   +-++    |  

+//     |     |  

+//   +-+--+  |   

+//   | +--+--+  

+//   +----+    Copyright (c) 2009 Code Red Technologies Ltd. 

+//

+// lcd_driver.h - Header file for driver for the lowest level access routines

+// for the Sitronix ST7637 LCD Controller/driver used on the RDB1768 

+// development board.

+//

+// 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. 

+

+#ifndef LCD_DRIVER_H_

+#define LCD_DRIVER_H_

+

+void LCDdriver_WriteData(unsigned char LCD_Data);

+void LCDdriver_WriteCom(unsigned char LCD_Command);

+void LCDdriver_initialisation(void);

+

+#endif /*LCD_DRIVER_H_*/

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/system_fixed_be_8_15.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/system_fixed_be_8_15.c
new file mode 100644
index 0000000..4786dcb
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LCD/system_fixed_be_8_15.c
@@ -0,0 +1,673 @@
+/*******************************************************************************************

+  Data table provides the bitmap data of each character.

+

+  To get the starting data offset of character 'A', you can use the following expression:

+

+     const unsigned char index = index_table['A'];

+     const unsigned int offset = offset_table[index];

+     const unsigned char *pData = data_table[offset];

+

+ *******************************************************************************************/

+const unsigned char font_data_table[] = {

+

+/* character 0x0020 (' '): (width=8, offset=0) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x0021 ('!'): (width=8, offset=15) */

+0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 

+0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 

+

+/* character 0x0022 ('"'): (width=8, offset=30) */

+0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x00, 0x00, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x0023 ('#'): (width=8, offset=45) */

+0x00, 0x00, 0x00, 0x36, 0x36, 0x7F, 0x36, 0x36, 

+0x36, 0x7F, 0x36, 0x36, 0x00, 0x00, 0x00, 

+

+/* character 0x0024 ('$'): (width=8, offset=60) */

+0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x30, 0x18, 

+0x0C, 0x06, 0x66, 0x3C, 0x18, 0x18, 0x00, 

+

+/* character 0x0025 ('%'): (width=8, offset=75) */

+0x00, 0x00, 0x70, 0xD8, 0xDA, 0x76, 0x0C, 0x18, 

+0x30, 0x6E, 0x5B, 0x1B, 0x0E, 0x00, 0x00, 

+

+/* character 0x0026 ('&'): (width=8, offset=90) */

+0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x60, 

+0x6F, 0x66, 0x66, 0x3B, 0x00, 0x00, 0x00, 

+

+/* character 0x0027 ('''): (width=8, offset=105) */

+0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x0028 ('('): (width=8, offset=120) */

+0x00, 0x00, 0x00, 0x0C, 0x18, 0x18, 0x30, 0x30, 

+0x30, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x00, 

+

+/* character 0x0029 (')'): (width=8, offset=135) */

+0x00, 0x00, 0x00, 0x30, 0x18, 0x18, 0x0C, 0x0C, 

+0x0C, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x00, 

+

+/* character 0x002A ('*'): (width=8, offset=150) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x1C, 0x7F, 

+0x1C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x002B ('+'): (width=8, offset=165) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 

+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x002C (','): (width=8, offset=180) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+0x00, 0x00, 0x1C, 0x1C, 0x0C, 0x18, 0x00, 

+

+/* character 0x002D ('-'): (width=8, offset=195) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x002E ('.'): (width=8, offset=210) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x00, 

+

+/* character 0x002F ('/'): (width=8, offset=225) */

+0x00, 0x00, 0x00, 0x06, 0x06, 0x0C, 0x0C, 0x18, 

+0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 

+

+/* character 0x0030 ('0'): (width=8, offset=240) */

+0x00, 0x00, 0x00, 0x1E, 0x33, 0x37, 0x37, 0x33, 

+0x3B, 0x3B, 0x33, 0x1E, 0x00, 0x00, 0x00, 

+

+/* character 0x0031 ('1'): (width=8, offset=255) */

+0x00, 0x00, 0x00, 0x0C, 0x1C, 0x7C, 0x0C, 0x0C, 

+0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 

+

+/* character 0x0032 ('2'): (width=8, offset=270) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x06, 0x0C, 

+0x18, 0x30, 0x60, 0x7E, 0x00, 0x00, 0x00, 

+

+/* character 0x0033 ('3'): (width=8, offset=285) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x06, 0x1C, 

+0x06, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0034 ('4'): (width=8, offset=300) */

+0x00, 0x00, 0x00, 0x30, 0x30, 0x36, 0x36, 0x36, 

+0x66, 0x7F, 0x06, 0x06, 0x00, 0x00, 0x00, 

+

+/* character 0x0035 ('5'): (width=8, offset=315) */

+0x00, 0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C, 

+0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 

+

+/* character 0x0036 ('6'): (width=8, offset=330) */

+0x00, 0x00, 0x00, 0x1C, 0x18, 0x30, 0x7C, 0x66, 

+0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0037 ('7'): (width=8, offset=345) */

+0x00, 0x00, 0x00, 0x7E, 0x06, 0x0C, 0x0C, 0x18, 

+0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 

+

+/* character 0x0038 ('8'): (width=8, offset=360) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x76, 0x3C, 

+0x6E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0039 ('9'): (width=8, offset=375) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 

+0x3E, 0x0C, 0x18, 0x38, 0x00, 0x00, 0x00, 

+

+/* character 0x003A (':'): (width=8, offset=390) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x00, 

+0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x00, 

+

+/* character 0x003B (';'): (width=8, offset=405) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x00, 

+0x00, 0x00, 0x1C, 0x1C, 0x0C, 0x18, 0x00, 

+

+/* character 0x003C ('<'): (width=8, offset=420) */

+0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 

+0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 

+

+/* character 0x003D ('='): (width=8, offset=435) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 

+0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x003E ('>'): (width=8, offset=450) */

+0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 

+0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 

+

+/* character 0x003F ('?'): (width=8, offset=465) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x0C, 0x18, 

+0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 

+

+/* character 0x0040 ('@'): (width=8, offset=480) */

+0x00, 0x00, 0x00, 0x7E, 0xC3, 0xC3, 0xCF, 0xDB, 

+0xDB, 0xCF, 0xC0, 0x7F, 0x00, 0x00, 0x00, 

+

+/* character 0x0041 ('A'): (width=8, offset=495) */

+0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x66, 0x66, 

+0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x0042 ('B'): (width=8, offset=510) */

+0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C, 

+0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 

+

+/* character 0x0043 ('C'): (width=8, offset=525) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x60, 0x60, 

+0x60, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0044 ('D'): (width=8, offset=540) */

+0x00, 0x00, 0x00, 0x78, 0x6C, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x6C, 0x78, 0x00, 0x00, 0x00, 

+

+/* character 0x0045 ('E'): (width=8, offset=555) */

+0x00, 0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C, 

+0x60, 0x60, 0x60, 0x7E, 0x00, 0x00, 0x00, 

+

+/* character 0x0046 ('F'): (width=8, offset=570) */

+0x00, 0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C, 

+0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 

+

+/* character 0x0047 ('G'): (width=8, offset=585) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x60, 0x60, 

+0x6E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 

+

+/* character 0x0048 ('H'): (width=8, offset=600) */

+0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7E, 

+0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x0049 ('I'): (width=8, offset=615) */

+0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 

+0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x004A ('J'): (width=8, offset=630) */

+0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 

+0x06, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x004B ('K'): (width=8, offset=645) */

+0x00, 0x00, 0x00, 0x66, 0x66, 0x6C, 0x6C, 0x78, 

+0x6C, 0x6C, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x004C ('L'): (width=8, offset=660) */

+0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 

+0x60, 0x60, 0x60, 0x7E, 0x00, 0x00, 0x00, 

+

+/* character 0x004D ('M'): (width=8, offset=675) */

+0x00, 0x00, 0x00, 0x63, 0x63, 0x77, 0x6B, 0x6B, 

+0x6B, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 

+

+/* character 0x004E ('N'): (width=8, offset=690) */

+0x00, 0x00, 0x00, 0x63, 0x63, 0x73, 0x7B, 0x6F, 

+0x67, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 

+

+/* character 0x004F ('O'): (width=8, offset=705) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0050 ('P'): (width=8, offset=720) */

+0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C, 

+0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 

+

+/* character 0x0051 ('Q'): (width=8, offset=735) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3C, 0x0C, 0x06, 0x00, 

+

+/* character 0x0052 ('R'): (width=8, offset=750) */

+0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C, 

+0x6C, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x0053 ('S'): (width=8, offset=765) */

+0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x30, 0x18, 

+0x0C, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0054 ('T'): (width=8, offset=780) */

+0x00, 0x00, 0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 

+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 

+

+/* character 0x0055 ('U'): (width=8, offset=795) */

+0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0056 ('V'): (width=8, offset=810) */

+0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 

+

+/* character 0x0057 ('W'): (width=8, offset=825) */

+0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x6B, 0x6B, 

+0x6B, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 

+

+/* character 0x0058 ('X'): (width=8, offset=840) */

+0x00, 0x00, 0x00, 0x66, 0x66, 0x34, 0x18, 0x18, 

+0x2C, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x0059 ('Y'): (width=8, offset=855) */

+0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 

+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 

+

+/* character 0x005A ('Z'): (width=8, offset=870) */

+0x00, 0x00, 0x00, 0x7E, 0x06, 0x06, 0x0C, 0x18, 

+0x30, 0x60, 0x60, 0x7E, 0x00, 0x00, 0x00, 

+

+/* character 0x005B ('['): (width=8, offset=885) */

+0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 

+0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 

+

+/* character 0x005C ('\'): (width=8, offset=900) */

+0x00, 0x00, 0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 

+0x18, 0x0C, 0x0C, 0x06, 0x06, 0x00, 0x00, 

+

+/* character 0x005D (']'): (width=8, offset=915) */

+0x00, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 

+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 

+

+/* character 0x005E ('^'): (width=8, offset=930) */

+0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x005F ('_'): (width=8, offset=945) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 

+

+/* character 0x0060 ('`'): (width=8, offset=960) */

+0x00, 0x38, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x0061 ('a'): (width=8, offset=975) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 

+0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 

+

+/* character 0x0062 ('b'): (width=8, offset=990) */

+0x00, 0x00, 0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 

+

+/* character 0x0063 ('c'): (width=8, offset=1005) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 

+0x60, 0x60, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0064 ('d'): (width=8, offset=1020) */

+0x00, 0x00, 0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 

+

+/* character 0x0065 ('e'): (width=8, offset=1035) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 

+0x7E, 0x60, 0x60, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0066 ('f'): (width=8, offset=1050) */

+0x00, 0x00, 0x00, 0x1E, 0x30, 0x30, 0x30, 0x7E, 

+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 

+

+/* character 0x0067 ('g'): (width=8, offset=1065) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x7C, 

+

+/* character 0x0068 ('h'): (width=8, offset=1080) */

+0x00, 0x00, 0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x0069 ('i'): (width=8, offset=1095) */

+0x00, 0x00, 0x18, 0x18, 0x00, 0x78, 0x18, 0x18, 

+0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 

+

+/* character 0x006A ('j'): (width=8, offset=1110) */

+0x00, 0x00, 0x0C, 0x0C, 0x00, 0x3C, 0x0C, 0x0C, 

+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x78, 

+

+/* character 0x006B ('k'): (width=8, offset=1125) */

+0x00, 0x00, 0x00, 0x60, 0x60, 0x66, 0x66, 0x6C, 

+0x78, 0x6C, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x006C ('l'): (width=8, offset=1140) */

+0x00, 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 

+0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 

+

+/* character 0x006D ('m'): (width=8, offset=1155) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x6B, 0x6B, 

+0x6B, 0x6B, 0x6B, 0x63, 0x00, 0x00, 0x00, 

+

+/* character 0x006E ('n'): (width=8, offset=1170) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x006F ('o'): (width=8, offset=1185) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 

+

+/* character 0x0070 ('p'): (width=8, offset=1200) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 

+

+/* character 0x0071 ('q'): (width=8, offset=1215) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 

+

+/* character 0x0072 ('r'): (width=8, offset=1230) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6E, 0x70, 

+0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 

+

+/* character 0x0073 ('s'): (width=8, offset=1245) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x60, 0x60, 

+0x3C, 0x06, 0x06, 0x7C, 0x00, 0x00, 0x00, 

+

+/* character 0x0074 ('t'): (width=8, offset=1260) */

+0x00, 0x00, 0x00, 0x30, 0x30, 0x7E, 0x30, 0x30, 

+0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x00, 

+

+/* character 0x0075 ('u'): (width=8, offset=1275) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 

+

+/* character 0x0076 ('v'): (width=8, offset=1290) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 

+

+/* character 0x0077 ('w'): (width=8, offset=1305) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6B, 0x6B, 

+0x6B, 0x6B, 0x36, 0x36, 0x00, 0x00, 0x00, 

+

+/* character 0x0078 ('x'): (width=8, offset=1320) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3C, 

+0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x00, 

+

+/* character 0x0079 ('y'): (width=8, offset=1335) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 

+0x66, 0x66, 0x66, 0x3C, 0x0C, 0x18, 0xF0, 

+

+/* character 0x007A ('z'): (width=8, offset=1350) */

+0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x06, 0x0C, 

+0x18, 0x30, 0x60, 0x7E, 0x00, 0x00, 0x00, 

+

+/* character 0x007B ('{'): (width=8, offset=1365) */

+0x00, 0x00, 0x00, 0x0C, 0x18, 0x18, 0x18, 0x30, 

+0x60, 0x30, 0x18, 0x18, 0x18, 0x0C, 0x00, 

+

+/* character 0x007C ('|'): (width=8, offset=1380) */

+0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 

+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 

+

+/* character 0x007D ('}'): (width=8, offset=1395) */

+0x00, 0x00, 0x00, 0x30, 0x18, 0x18, 0x18, 0x0C, 

+0x06, 0x0C, 0x18, 0x18, 0x18, 0x30, 0x00, 

+

+/* character 0x007E ('~'): (width=8, offset=1410) */

+0x00, 0x00, 0x00, 0x71, 0xDB, 0x8E, 0x00, 0x00, 

+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+

+/* character 0x007F (''): (width=8, offset=1425) */

+0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 

+0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 

+

+};

+

+

+/*******************************************************************************************

+  Index table is used to find the mapping index of a character.

+

+  If you can find a simple mathematical expression for index mapping, you can use that.

+  If you do not have such a mathematical expression, this index table is just for you.

+

+  To get the index of character 'A', you can use the following expression:

+

+     const unsigned char index = index_table['A'];

+

+ *******************************************************************************************/

+const unsigned char font_index_table[] = {

+/*		index   hexcode   decimal  char */

+/*		=====   =======   =======  ==== */

+  		  0, /*   00          0     .   */

+  		  0, /*   01          1     .   */

+  		  0, /*   02          2     .   */

+  		  0, /*   03          3     .   */

+  		  0, /*   04          4     .   */

+  		  0, /*   05          5     .   */

+  		  0, /*   06          6     .   */

+  		  0, /*   07          7     .   */

+  		  0, /*   08          8     .   */

+  		  0, /*   09          9     .   */

+  		  0, /*   0A         10     .   */

+  		  0, /*   0B         11     .   */

+  		  0, /*   0C         12     .   */

+  		  0, /*   0D         13     .   */

+  		  0, /*   0E         14     .   */

+  		  0, /*   0F         15     .   */

+  		  0, /*   10         16     .   */

+  		  0, /*   11         17     .   */

+  		  0, /*   12         18     .   */

+  		  0, /*   13         19     .   */

+  		  0, /*   14         20     .   */

+  		  0, /*   15         21     .   */

+  		  0, /*   16         22     .   */

+  		  0, /*   17         23     .   */

+  		  0, /*   18         24     .   */

+  		  0, /*   19         25     .   */

+  		  0, /*   1A         26     .   */

+  		  0, /*   1B         27     .   */

+  		  0, /*   1C         28     .   */

+  		  0, /*   1D         29     .   */

+  		  0, /*   1E         30     .   */

+  		  0, /*   1F         31     .   */

+  		  0, /*   20         32         */

+  		  1, /*   21         33     !   */

+  		  2, /*   22         34     "   */

+  		  3, /*   23         35     #   */

+  		  4, /*   24         36     $   */

+  		  5, /*   25         37     %   */

+  		  6, /*   26         38     &   */

+  		  7, /*   27         39     '   */

+  		  8, /*   28         40     (   */

+  		  9, /*   29         41     )   */

+  		 10, /*   2A         42     *   */

+  		 11, /*   2B         43     +   */

+  		 12, /*   2C         44     ,   */

+  		 13, /*   2D         45     -   */

+  		 14, /*   2E         46     .   */

+  		 15, /*   2F         47     /   */

+  		 16, /*   30         48     0   */

+  		 17, /*   31         49     1   */

+  		 18, /*   32         50     2   */

+  		 19, /*   33         51     3   */

+  		 20, /*   34         52     4   */

+  		 21, /*   35         53     5   */

+  		 22, /*   36         54     6   */

+  		 23, /*   37         55     7   */

+  		 24, /*   38         56     8   */

+  		 25, /*   39         57     9   */

+  		 26, /*   3A         58     :   */

+  		 27, /*   3B         59     ;   */

+  		 28, /*   3C         60     <   */

+  		 29, /*   3D         61     =   */

+  		 30, /*   3E         62     >   */

+  		 31, /*   3F         63     ?   */

+  		 32, /*   40         64     @   */

+  		 33, /*   41         65     A   */

+  		 34, /*   42         66     B   */

+  		 35, /*   43         67     C   */

+  		 36, /*   44         68     D   */

+  		 37, /*   45         69     E   */

+  		 38, /*   46         70     F   */

+  		 39, /*   47         71     G   */

+  		 40, /*   48         72     H   */

+  		 41, /*   49         73     I   */

+  		 42, /*   4A         74     J   */

+  		 43, /*   4B         75     K   */

+  		 44, /*   4C         76     L   */

+  		 45, /*   4D         77     M   */

+  		 46, /*   4E         78     N   */

+  		 47, /*   4F         79     O   */

+  		 48, /*   50         80     P   */

+  		 49, /*   51         81     Q   */

+  		 50, /*   52         82     R   */

+  		 51, /*   53         83     S   */

+  		 52, /*   54         84     T   */

+  		 53, /*   55         85     U   */

+  		 54, /*   56         86     V   */

+  		 55, /*   57         87     W   */

+  		 56, /*   58         88     X   */

+  		 57, /*   59         89     Y   */

+  		 58, /*   5A         90     Z   */

+  		 59, /*   5B         91     [   */

+  		 60, /*   5C         92     \   */

+  		 61, /*   5D         93     ]   */

+  		 62, /*   5E         94     ^   */

+  		 63, /*   5F         95     _   */

+  		 64, /*   60         96     `   */

+  		 65, /*   61         97     a   */

+  		 66, /*   62         98     b   */

+  		 67, /*   63         99     c   */

+  		 68, /*   64        100     d   */

+  		 69, /*   65        101     e   */

+  		 70, /*   66        102     f   */

+  		 71, /*   67        103     g   */

+  		 72, /*   68        104     h   */

+  		 73, /*   69        105     i   */

+  		 74, /*   6A        106     j   */

+  		 75, /*   6B        107     k   */

+  		 76, /*   6C        108     l   */

+  		 77, /*   6D        109     m   */

+  		 78, /*   6E        110     n   */

+  		 79, /*   6F        111     o   */

+  		 80, /*   70        112     p   */

+  		 81, /*   71        113     q   */

+  		 82, /*   72        114     r   */

+  		 83, /*   73        115     s   */

+  		 84, /*   74        116     t   */

+  		 85, /*   75        117     u   */

+  		 86, /*   76        118     v   */

+  		 87, /*   77        119     w   */

+  		 88, /*   78        120     x   */

+  		 89, /*   79        121     y   */

+  		 90, /*   7A        122     z   */

+  		 91, /*   7B        123     {   */

+  		 92, /*   7C        124     |   */

+  		 93, /*   7D        125     }   */

+  		 94, /*   7E        126     ~   */

+  		 95, /*   7F        127        */

+  		  0, /*   80        128   ? */

+  		  0, /*   81        129   � */

+  		  0, /*   82        130   ? */

+  		  0, /*   83        131   ? */

+  		  0, /*   84        132   ? */

+  		  0, /*   85        133   ? */

+  		  0, /*   86        134   ? */

+  		  0, /*   87        135   ? */

+  		  0, /*   88        136   ? */

+  		  0, /*   89        137   ? */

+  		  0, /*   8A        138   ? */

+  		  0, /*   8B        139   ? */

+  		  0, /*   8C        140   ? */

+  		  0, /*   8D        141   � */

+  		  0, /*   8E        142   ? */

+  		  0, /*   8F        143   � */

+  		  0, /*   90        144   � */

+  		  0, /*   91        145   ? */

+  		  0, /*   92        146   ? */

+  		  0, /*   93        147   ? */

+  		  0, /*   94        148   ? */

+  		  0, /*   95        149   ? */

+  		  0, /*   96        150   ? */

+  		  0, /*   97        151   ? */

+  		  0, /*   98        152   ? */

+  		  0, /*   99        153   ? */

+  		  0, /*   9A        154   ? */

+  		  0, /*   9B        155   ? */

+  		  0, /*   9C        156   ? */

+  		  0, /*   9D        157   � */

+  		  0, /*   9E        158   ? */

+  		  0, /*   9F        159   ? */

+  		  0, /*   A0        160   � */

+  		  0, /*   A1        161   � */

+  		  0, /*   A2        162   � */

+  		  0, /*   A3        163   � */

+  		  0, /*   A4        164   � */

+  		  0, /*   A5        165   � */

+  		  0, /*   A6        166   � */

+  		  0, /*   A7        167   � */

+  		  0, /*   A8        168   � */

+  		  0, /*   A9        169   � */

+  		  0, /*   AA        170   � */

+  		  0, /*   AB        171   � */

+  		  0, /*   AC        172   � */

+  		  0, /*   AD        173   � */

+  		  0, /*   AE        174   � */

+  		  0, /*   AF        175   � */

+  		  0, /*   B0        176   � */

+  		  0, /*   B1        177   � */

+  		  0, /*   B2        178   � */

+  		  0, /*   B3        179   � */

+  		  0, /*   B4        180   � */

+  		  0, /*   B5        181   � */

+  		  0, /*   B6        182   � */

+  		  0, /*   B7        183   � */

+  		  0, /*   B8        184   � */

+  		  0, /*   B9        185   � */

+  		  0, /*   BA        186   � */

+  		  0, /*   BB        187   � */

+  		  0, /*   BC        188   � */

+  		  0, /*   BD        189   � */

+  		  0, /*   BE        190   � */

+  		  0, /*   BF        191   � */

+  		  0, /*   C0        192   � */

+  		  0, /*   C1        193   � */

+  		  0, /*   C2        194   � */

+  		  0, /*   C3        195   � */

+  		  0, /*   C4        196   � */

+  		  0, /*   C5        197   � */

+  		  0, /*   C6        198   � */

+  		  0, /*   C7        199   � */

+  		  0, /*   C8        200   � */

+  		  0, /*   C9        201   � */

+  		  0, /*   CA        202   � */

+  		  0, /*   CB        203   � */

+  		  0, /*   CC        204   � */

+  		  0, /*   CD        205   � */

+  		  0, /*   CE        206   � */

+  		  0, /*   CF        207   � */

+  		  0, /*   D0        208   � */

+  		  0, /*   D1        209   � */

+  		  0, /*   D2        210   � */

+  		  0, /*   D3        211   � */

+  		  0, /*   D4        212   � */

+  		  0, /*   D5        213   � */

+  		  0, /*   D6        214   � */

+  		  0, /*   D7        215   � */

+  		  0, /*   D8        216   � */

+  		  0, /*   D9        217   � */

+  		  0, /*   DA        218   � */

+  		  0, /*   DB        219   � */

+  		  0, /*   DC        220   � */

+  		  0, /*   DD        221   � */

+  		  0, /*   DE        222   � */

+  		  0, /*   DF        223   � */

+  		  0, /*   E0        224   � */

+  		  0, /*   E1        225   � */

+  		  0, /*   E2        226   � */

+  		  0, /*   E3        227   � */

+  		  0, /*   E4        228   � */

+  		  0, /*   E5        229   � */

+  		  0, /*   E6        230   � */

+  		  0, /*   E7        231   � */

+  		  0, /*   E8        232   � */

+  		  0, /*   E9        233   � */

+  		  0, /*   EA        234   � */

+  		  0, /*   EB        235   � */

+  		  0, /*   EC        236   � */

+  		  0, /*   ED        237   � */

+  		  0, /*   EE        238   � */

+  		  0, /*   EF        239   � */

+  		  0, /*   F0        240   � */

+  		  0, /*   F1        241   � */

+  		  0, /*   F2        242   � */

+  		  0, /*   F3        243   � */

+  		  0, /*   F4        244   � */

+  		  0, /*   F5        245   � */

+  		  0, /*   F6        246   � */

+  		  0, /*   F7        247   � */

+  		  0, /*   F8        248   � */

+  		  0, /*   F9        249   � */

+  		  0, /*   FA        250   � */

+  		  0, /*   FB        251   � */

+  		  0, /*   FC        252   � */

+  		  0, /*   FD        253   � */

+  		  0, /*   FE        254   � */

+  		  0, /*   FF        255   � */

+};

+

+

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LPC17xx.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LPC17xx.h
new file mode 100644
index 0000000..09572d3
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/LPC17xx.h
@@ -0,0 +1,1080 @@
+#ifndef __LPC17xx_H

+#define __LPC17xx_H

+

+/* System Control Block (SCB) includes:

+   Flash Accelerator Module, Clocking and Power Control, External Interrupts,

+   Reset, System Control and Status

+*/

+#define SCB_BASE_ADDR   0x400FC000

+

+#define PCONP_PCTIM0    0x00000002

+#define PCONP_PCTIM1    0x00000004

+#define PCONP_PCUART0   0x00000008

+#define PCONP_PCUART1   0x00000010

+#define PCONP_PCPWM1    0x00000040

+#define PCONP_PCI2C0    0x00000080

+#define PCONP_PCSPI     0x00000100

+#define PCONP_PCRTC     0x00000200

+#define PCONP_PCSSP1    0x00000400

+#define PCONP_PCAD      0x00001000

+#define PCONP_PCCAN1    0x00002000

+#define PCONP_PCCAN2    0x00004000

+#define PCONP_PCGPIO    0x00008000

+#define PCONP_PCRIT     0x00010000

+#define PCONP_PCMCPWM   0x00020000

+#define PCONP_PCQEI     0x00040000

+#define PCONP_PCI2C1    0x00080000

+#define PCONP_PCSSP0    0x00200000

+#define PCONP_PCTIM2    0x00400000

+#define PCONP_PCTIM3    0x00800000

+#define PCONP_PCUART2   0x01000000

+#define PCONP_PCUART3   0x02000000

+#define PCONP_PCI2C2    0x04000000

+#define PCONP_PCI2S     0x08000000

+#define PCONP_PCGPDMA   0x20000000

+#define PCONP_PCENET    0x40000000

+#define PCONP_PCUSB     0x80000000

+

+#define PLLCON_PLLE     0x00000001

+#define PLLCON_PLLC     0x00000002

+#define PLLCON_MASK     0x00000003

+

+#define PLLCFG_MUL1     0x00000000

+#define PLLCFG_MUL2     0x00000001

+#define PLLCFG_MUL3     0x00000002

+#define PLLCFG_MUL4     0x00000003

+#define PLLCFG_MUL5     0x00000004

+#define PLLCFG_MUL6     0x00000005

+#define PLLCFG_MUL7     0x00000006

+#define PLLCFG_MUL8     0x00000007

+#define PLLCFG_MUL9     0x00000008

+#define PLLCFG_MUL10    0x00000009

+#define PLLCFG_MUL11    0x0000000A

+#define PLLCFG_MUL12    0x0000000B

+#define PLLCFG_MUL13    0x0000000C

+#define PLLCFG_MUL14    0x0000000D

+#define PLLCFG_MUL15    0x0000000E

+#define PLLCFG_MUL16    0x0000000F

+#define PLLCFG_MUL17    0x00000010

+#define PLLCFG_MUL18    0x00000011

+#define PLLCFG_MUL19    0x00000012

+#define PLLCFG_MUL20    0x00000013

+#define PLLCFG_MUL21    0x00000014

+#define PLLCFG_MUL22    0x00000015

+#define PLLCFG_MUL23    0x00000016

+#define PLLCFG_MUL24    0x00000017

+#define PLLCFG_MUL25    0x00000018

+#define PLLCFG_MUL26    0x00000019

+#define PLLCFG_MUL27    0x0000001A

+#define PLLCFG_MUL28    0x0000001B

+#define PLLCFG_MUL29    0x0000001C

+#define PLLCFG_MUL30    0x0000001D

+#define PLLCFG_MUL31    0x0000001E

+#define PLLCFG_MUL32    0x0000001F

+#define PLLCFG_MUL33    0x00000020

+#define PLLCFG_MUL34    0x00000021

+#define PLLCFG_MUL35    0x00000022

+#define PLLCFG_MUL36    0x00000023

+

+#define PLLCFG_DIV1     0x00000000

+#define PLLCFG_DIV2     0x00010000

+#define PLLCFG_DIV3     0x00020000

+#define PLLCFG_DIV4     0x00030000

+#define PLLCFG_DIV5     0x00040000

+#define PLLCFG_DIV6     0x00050000

+#define PLLCFG_DIV7     0x00060000

+#define PLLCFG_DIV8     0x00070000

+#define PLLCFG_DIV9     0x00080000

+#define PLLCFG_DIV10    0x00090000

+#define PLLCFG_MASK		0x00FF7FFF

+

+#define PLLSTAT_MSEL_MASK	0x00007FFF

+#define PLLSTAT_NSEL_MASK	0x00FF0000

+

+#define PLLSTAT_PLLE	(1 << 24)

+#define PLLSTAT_PLLC	(1 << 25)

+#define PLLSTAT_PLOCK	(1 << 26)

+

+#define PLLFEED_FEED1   0x000000AA

+#define PLLFEED_FEED2   0x00000055

+

+#define NVIC_IRQ_WDT         0u         // IRQ0,  exception number 16

+#define NVIC_IRQ_TIMER0      1u         // IRQ1,  exception number 17

+#define NVIC_IRQ_TIMER1      2u         // IRQ2,  exception number 18

+#define NVIC_IRQ_TIMER2      3u         // IRQ3,  exception number 19

+#define NVIC_IRQ_TIMER3      4u         // IRQ4,  exception number 20

+#define NVIC_IRQ_UART0       5u         // IRQ5,  exception number 21

+#define NVIC_IRQ_UART1       6u         // IRQ6,  exception number 22

+#define NVIC_IRQ_UART2       7u         // IRQ7,  exception number 23

+#define NVIC_IRQ_UART3       8u         // IRQ8,  exception number 24

+#define NVIC_IRQ_PWM1        9u         // IRQ9,  exception number 25

+#define NVIC_IRQ_I2C0        10u        // IRQ10, exception number 26

+#define NVIC_IRQ_I2C1        11u        // IRQ11, exception number 27

+#define NVIC_IRQ_I2C2        12u        // IRQ12, exception number 28

+#define NVIC_IRQ_SPI         13u        // IRQ13, exception number 29

+#define NVIC_IRQ_SSP0        14u        // IRQ14, exception number 30

+#define NVIC_IRQ_SSP1        15u        // IRQ15, exception number 31

+#define NVIC_IRQ_PLL0        16u        // IRQ16, exception number 32

+#define NVIC_IRQ_RTC         17u        // IRQ17, exception number 33

+#define NVIC_IRQ_EINT0       18u        // IRQ18, exception number 34

+#define NVIC_IRQ_EINT1       19u        // IRQ19, exception number 35

+#define NVIC_IRQ_EINT2       20u        // IRQ20, exception number 36

+#define NVIC_IRQ_EINT3       21u        // IRQ21, exception number 37

+#define NVIC_IRQ_ADC         22u        // IRQ22, exception number 38

+#define NVIC_IRQ_BOD         23u        // IRQ23, exception number 39

+#define NVIC_IRQ_USB         24u        // IRQ24, exception number 40

+#define NVIC_IRQ_CAN         25u        // IRQ25, exception number 41

+#define NVIC_IRQ_GPDMA       26u        // IRQ26, exception number 42

+#define NVIC_IRQ_I2S         27u        // IRQ27, exception number 43

+#define NVIC_IRQ_ETHERNET    28u        // IRQ28, exception number 44

+#define NVIC_IRQ_RIT         29u        // IRQ29, exception number 45

+#define NVIC_IRQ_MCPWM       30u        // IRQ30, exception number 46

+#define NVIC_IRQ_QE          31u        // IRQ31, exception number 47

+#define NVIC_IRQ_PLL1        32u        // IRQ32, exception number 48

+#define NVIC_IRQ_USB_ACT     33u        // IRQ33, exception number 49

+#define NVIC_IRQ_CAN_ACT     34u        // IRQ34, exception number 50

+

+

+#endif  // __LPC17xx_H

+

+

+#ifndef CMSIS_17xx_H

+#define CMSIS_17xx_H

+

+/******************************************************************************

+ * @file:    LPC17xx.h

+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File for

+ *           NXP LPC17xx Device Series

+ * @version: V1.1

+ * @date:    14th May 2009

+ *----------------------------------------------------------------------------

+ *

+ * Copyright (C) 2008 ARM Limited. All rights reserved.

+ *

+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3

+ * processor based microcontrollers.  This file can be freely distributed

+ * within development tools that are supporting such ARM based processors.

+ *

+ * 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.

+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR

+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

+ *

+ ******************************************************************************/

+

+

+#ifndef __LPC17xx_H__

+#define __LPC17xx_H__

+

+/*

+ * ==========================================================================

+ * ---------- Interrupt Number Definition -----------------------------------

+ * ==========================================================================

+ */

+

+typedef enum IRQn

+{

+/******  Cortex-M3 Processor Exceptions Numbers ***************************************************/

+  NonMaskableInt_IRQn           = -14,      /*!< 2 Non Maskable Interrupt                         */

+  MemoryManagement_IRQn         = -12,      /*!< 4 Cortex-M3 Memory Management Interrupt          */

+  BusFault_IRQn                 = -11,      /*!< 5 Cortex-M3 Bus Fault Interrupt                  */

+  UsageFault_IRQn               = -10,      /*!< 6 Cortex-M3 Usage Fault Interrupt                */

+  SVCall_IRQn                   = -5,       /*!< 11 Cortex-M3 SV Call Interrupt                   */

+  DebugMonitor_IRQn             = -4,       /*!< 12 Cortex-M3 Debug Monitor Interrupt             */

+  PendSV_IRQn                   = -2,       /*!< 14 Cortex-M3 Pend SV Interrupt                   */

+  SysTick_IRQn                  = -1,       /*!< 15 Cortex-M3 System Tick Interrupt               */

+

+/******  LPC17xx Specific Interrupt Numbers *******************************************************/

+  WDT_IRQn                      = 0,        /*!< Watchdog Timer Interrupt                         */

+  TIMER0_IRQn                   = 1,        /*!< Timer0 Interrupt                                 */

+  TIMER1_IRQn                   = 2,        /*!< Timer1 Interrupt                                 */

+  TIMER2_IRQn                   = 3,        /*!< Timer2 Interrupt                                 */

+  TIMER3_IRQn                   = 4,        /*!< Timer3 Interrupt                                 */

+  UART0_IRQn                    = 5,        /*!< UART0 Interrupt                                  */

+  UART1_IRQn                    = 6,        /*!< UART1 Interrupt                                  */

+  UART2_IRQn                    = 7,        /*!< UART2 Interrupt                                  */

+  UART3_IRQn                    = 8,        /*!< UART3 Interrupt                                  */

+  PWM1_IRQn                     = 9,        /*!< PWM1 Interrupt                                   */

+  I2C0_IRQn                     = 10,       /*!< I2C0 Interrupt                                   */

+  I2C1_IRQn                     = 11,       /*!< I2C1 Interrupt                                   */

+  I2C2_IRQn                     = 12,       /*!< I2C2 Interrupt                                   */

+  SPI_IRQn                      = 13,       /*!< SPI Interrupt                                    */

+  SSP0_IRQn                     = 14,       /*!< SSP0 Interrupt                                   */

+  SSP1_IRQn                     = 15,       /*!< SSP1 Interrupt                                   */

+  PLL0_IRQn                     = 16,       /*!< PLL0 Lock (Main PLL) Interrupt                   */

+  RTC_IRQn                      = 17,       /*!< Real Time Clock Interrupt                        */

+  EINT0_IRQn                    = 18,       /*!< External Interrupt 0 Interrupt                   */

+  EINT1_IRQn                    = 19,       /*!< External Interrupt 1 Interrupt                   */

+  EINT2_IRQn                    = 20,       /*!< External Interrupt 2 Interrupt                   */

+  EINT3_IRQn                    = 21,       /*!< External Interrupt 3 Interrupt                   */

+  ADC_IRQn                      = 22,       /*!< A/D Converter Interrupt                          */

+  BOD_IRQn                      = 23,       /*!< Brown-Out Detect Interrupt                       */

+  USB_IRQn                      = 24,       /*!< USB Interrupt                                    */

+  CAN_IRQn                      = 25,       /*!< CAN Interrupt                                    */

+  DMA_IRQn                      = 26,       /*!< General Purpose DMA Interrupt                    */

+  I2S_IRQn                      = 27,       /*!< I2S Interrupt                                    */

+  ENET_IRQn                     = 28,       /*!< Ethernet Interrupt                               */

+  RIT_IRQn                      = 29,       /*!< Repetitive Interrupt Timer Interrupt             */

+  MCPWM_IRQn                    = 30,       /*!< Motor Control PWM Interrupt                      */

+  QEI_IRQn                      = 31,       /*!< Quadrature Encoder Interface Interrupt           */

+  PLL1_IRQn                     = 32,       /*!< PLL1 Lock (USB PLL) Interrupt                    */

+} IRQn_Type;

+

+

+/*

+ * ==========================================================================

+ * ----------- Processor and Core Peripheral Section ------------------------

+ * ==========================================================================

+ */

+

+/* Configuration of the Cortex-M3 Processor and Core Peripherals */

+#define __MPU_PRESENT             1         /*!< MPU present or not                               */

+#define __NVIC_PRIO_BITS          5         /*!< Number of Bits used for Priority Levels          */

+#define __Vendor_SysTickConfig    0         /*!< Set to 1 if different SysTick Config is used     */

+

+

+//#include "..\core_cm3.h"                    /* Cortex-M3 processor and core peripherals           */

+#include "core_cm3.h"

+#include "system_LPC17xx.h"                 /* System Header                                      */

+

+

+

+/**

+ * Initialize the system clock

+ *

+ * @param  none

+ * @return none

+ *

+ * @brief  Setup the microcontroller system.

+ *         Initialize the System and update the SystemFrequency variable.

+ */

+extern void SystemInit (void);

+

+

+/******************************************************************************/

+/*                Device Specific Peripheral registers structures             */

+/******************************************************************************/

+

+/*------------- System Control (SC) ------------------------------------------*/

+typedef struct

+{

+  __IO uint32_t FLASHCFG;               /* Flash Accelerator Module           */

+       uint32_t RESERVED0[31];

+  __IO uint32_t PLL0CON;                /* Clocking and Power Control         */

+  __IO uint32_t PLL0CFG;

+  __I  uint32_t PLL0STAT;

+  __O  uint32_t PLL0FEED;

+       uint32_t RESERVED1[4];

+  __IO uint32_t PLL1CON;

+  __IO uint32_t PLL1CFG;

+  __I  uint32_t PLL1STAT;

+  __O  uint32_t PLL1FEED;

+       uint32_t RESERVED2[4];

+  __IO uint32_t PCON;

+  __IO uint32_t PCONP;

+       uint32_t RESERVED3[15];

+  __IO uint32_t CCLKCFG;

+  __IO uint32_t USBCLKCFG;

+  __IO uint32_t CLKSRCSEL;

+       uint32_t RESERVED4[12];

+  __IO uint32_t EXTINT;                 /* External Interrupts                */

+       uint32_t RESERVED5;

+  __IO uint32_t EXTMODE;

+  __IO uint32_t EXTPOLAR;

+       uint32_t RESERVED6[12];

+  __IO uint32_t RSID;                   /* Reset                              */

+       uint32_t RESERVED7[7];

+  __IO uint32_t SCS;                    /* Syscon Miscellaneous Registers     */

+  __IO uint32_t IRCTRIM;                /* Clock Dividers                     */

+  __IO uint32_t PCLKSEL0;

+  __IO uint32_t PCLKSEL1;

+       uint32_t RESERVED8[4];

+  __IO uint32_t USBIntSt;               /* USB Device/OTG Interrupt Register  */

+       uint32_t RESERVED9;

+  __IO uint32_t CLKOUTCFG;              /* Clock Output Configuration         */

+ } SC_TypeDef;

+

+/*------------- Pin Connect Block (PINCON) -----------------------------------*/

+typedef struct

+{

+  __IO uint32_t PINSEL0;

+  __IO uint32_t PINSEL1;

+  __IO uint32_t PINSEL2;

+  __IO uint32_t PINSEL3;

+  __IO uint32_t PINSEL4;

+  __IO uint32_t PINSEL5;

+  __IO uint32_t PINSEL6;

+  __IO uint32_t PINSEL7;

+  __IO uint32_t PINSEL8;

+  __IO uint32_t PINSEL9;

+  __IO uint32_t PINSEL10;

+       uint32_t RESERVED0[5];

+  __IO uint32_t PINMODE0;

+  __IO uint32_t PINMODE1;

+  __IO uint32_t PINMODE2;

+  __IO uint32_t PINMODE3;

+  __IO uint32_t PINMODE4;

+  __IO uint32_t PINMODE5;

+  __IO uint32_t PINMODE6;

+  __IO uint32_t PINMODE7;

+  __IO uint32_t PINMODE8;

+  __IO uint32_t PINMODE9;

+  __IO uint32_t PINMODE_OD0;

+  __IO uint32_t PINMODE_OD1;

+  __IO uint32_t PINMODE_OD2;

+  __IO uint32_t PINMODE_OD3;

+  __IO uint32_t PINMODE_OD4;

+} PINCON_TypeDef;

+

+/*------------- General Purpose Input/Output (GPIO) --------------------------*/

+typedef struct

+{

+  __IO uint32_t FIODIR;

+       uint32_t RESERVED0[3];

+  __IO uint32_t FIOMASK;

+  __IO uint32_t FIOPIN;

+  __IO uint32_t FIOSET;

+  __O  uint32_t FIOCLR;

+} GPIO_TypeDef;

+

+typedef struct

+{

+  __I  uint32_t IntStatus;

+  __I  uint32_t IO0IntStatR;

+  __I  uint32_t IO0IntStatF;

+  __O  uint32_t IO0IntClr;

+  __IO uint32_t IO0IntEnR;

+  __IO uint32_t IO0IntEnF;

+       uint32_t RESERVED0[3];

+  __I  uint32_t IO2IntStatR;

+  __I  uint32_t IO2IntStatF;

+  __O  uint32_t IO2IntClr;

+  __IO uint32_t IO2IntEnR;

+  __IO uint32_t IO2IntEnF;

+} GPIOINT_TypeDef;

+

+/*------------- Timer (TIM) --------------------------------------------------*/

+typedef struct

+{

+  __IO uint32_t IR;

+  __IO uint32_t TCR;

+  __IO uint32_t TC;

+  __IO uint32_t PR;

+  __IO uint32_t PC;

+  __IO uint32_t MCR;

+  __IO uint32_t MR0;

+  __IO uint32_t MR1;

+  __IO uint32_t MR2;

+  __IO uint32_t MR3;

+  __IO uint32_t CCR;

+  __I  uint32_t CR0;

+  __I  uint32_t CR1;

+       uint32_t RESERVED0[2];

+  __IO uint32_t EMR;

+       uint32_t RESERVED1[24];

+  __IO uint32_t CTCR;

+} TIM_TypeDef;

+

+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/

+typedef struct

+{

+  __IO uint32_t IR;

+  __IO uint32_t TCR;

+  __IO uint32_t TC;

+  __IO uint32_t PR;

+  __IO uint32_t PC;

+  __IO uint32_t MCR;

+  __IO uint32_t MR0;

+  __IO uint32_t MR1;

+  __IO uint32_t MR2;

+  __IO uint32_t MR3;

+  __IO uint32_t CCR;

+  __I  uint32_t CR0;

+  __I  uint32_t CR1;

+  __I  uint32_t CR2;

+  __I  uint32_t CR3;

+  __IO uint32_t MR4;

+  __IO uint32_t MR5;

+  __IO uint32_t MR6;

+  __IO uint32_t PCR;

+  __IO uint32_t LER;

+       uint32_t RESERVED0[7];

+  __IO uint32_t CTCR;

+} PWM_TypeDef;

+

+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/

+typedef struct

+{

+  union {

+  __I  uint8_t  RBR;

+  __O  uint8_t  THR;

+  __IO uint8_t  DLL;

+       uint32_t RESERVED0;

+  };

+  union {

+  __IO uint8_t  DLM;

+  __IO uint32_t IER;

+  };

+  union {

+  __I  uint32_t IIR;

+  __O  uint8_t  FCR;

+  };

+  __IO uint8_t  LCR;

+       uint8_t  RESERVED1[7];

+  __IO uint8_t  LSR;

+       uint8_t  RESERVED2[7];

+  __IO uint8_t  SCR;

+       uint8_t  RESERVED3[3];

+  __IO uint32_t ACR;

+  __IO uint8_t  ICR;

+       uint8_t  RESERVED4[3];

+  __IO uint8_t  FDR;

+       uint8_t  RESERVED5[7];

+  __IO uint8_t  TER;

+       uint8_t  RESERVED6[27];

+  __IO uint8_t  RS485CTRL;

+       uint8_t  RESERVED7[3];

+  __IO uint8_t  ADRMATCH;

+} UART_TypeDef;

+

+typedef struct

+{

+  union {

+  __I  uint8_t  RBR;

+  __O  uint8_t  THR;

+  __IO uint8_t  DLL;

+       uint32_t RESERVED0;

+  };

+  union {

+  __IO uint8_t  DLM;

+  __IO uint32_t IER;

+  };

+  union {

+  __I  uint32_t IIR;

+  __O  uint8_t  FCR;

+  };

+  __IO uint8_t  LCR;

+       uint8_t  RESERVED1[3];

+  __IO uint8_t  MCR;

+       uint8_t  RESERVED2[3];

+  __IO uint8_t  LSR;

+       uint8_t  RESERVED3[3];

+  __IO uint8_t  MSR;

+       uint8_t  RESERVED4[3];

+  __IO uint8_t  SCR;

+       uint8_t  RESERVED5[3];

+  __IO uint32_t ACR;

+       uint32_t RESERVED6;

+  __IO uint32_t FDR;

+       uint32_t RESERVED7;

+  __IO uint8_t  TER;

+       uint8_t  RESERVED8[27];

+  __IO uint8_t  RS485CTRL;

+       uint8_t  RESERVED9[3];

+  __IO uint8_t  ADRMATCH;

+       uint8_t  RESERVED10[3];

+  __IO uint8_t  RS485DLY;

+} UART1_TypeDef;

+

+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/

+typedef struct

+{

+  __IO uint32_t SPCR;

+  __I  uint32_t SPSR;

+  __IO uint32_t SPDR;

+  __IO uint32_t SPCCR;

+       uint32_t RESERVED0[3];

+  __IO uint32_t SPINT;

+} SPI_TypeDef;

+

+/*------------- Synchronous Serial Communication (SSP) -----------------------*/

+typedef struct

+{

+  __IO uint32_t CR0;

+  __IO uint32_t CR1;

+  __IO uint32_t DR;

+  __I  uint32_t SR;

+  __IO uint32_t CPSR;

+  __IO uint32_t IMSC;

+  __IO uint32_t RIS;

+  __IO uint32_t MIS;

+  __IO uint32_t ICR;

+  __IO uint32_t DMACR;

+} SSP_TypeDef;

+

+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/

+typedef struct

+{

+  __IO uint32_t I2CONSET;

+  __I  uint32_t I2STAT;

+  __IO uint32_t I2DAT;

+  __IO uint32_t I2ADR0;

+  __IO uint32_t I2SCLH;

+  __IO uint32_t I2SCLL;

+  __O  uint32_t I2CONCLR;

+  __IO uint32_t MMCTRL;

+  __IO uint32_t I2ADR1;

+  __IO uint32_t I2ADR2;

+  __IO uint32_t I2ADR3;

+  __I  uint32_t I2DATA_BUFFER;

+  __IO uint32_t I2MASK0;

+  __IO uint32_t I2MASK1;

+  __IO uint32_t I2MASK2;

+  __IO uint32_t I2MASK3;

+} I2C_TypeDef;

+

+/*------------- Inter IC Sound (I2S) -----------------------------------------*/

+typedef struct

+{

+  __IO uint32_t I2SDAO;

+  __IO  uint32_t I2SDAI;

+  __O  uint32_t I2STXFIFO;

+  __I  uint32_t I2SRXFIFO;

+  __I  uint32_t I2SSTATE;

+  __IO uint32_t I2SDMA1;

+  __IO uint32_t I2SDMA2;

+  __IO uint32_t I2SIRQ;

+  __IO uint32_t I2STXRATE;

+  __IO uint32_t I2SRXRATE;

+  __IO uint32_t I2STXBITRATE;

+  __IO uint32_t I2SRXBITRATE;

+  __IO uint32_t I2STXMODE;

+  __IO uint32_t I2SRXMODE;

+} I2S_TypeDef;

+

+/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/

+typedef struct

+{

+  __IO uint32_t RICOMPVAL;

+  __IO uint32_t RIMASK;

+  __IO uint8_t  RICTRL;

+       uint8_t  RESERVED0[3];

+  __IO uint32_t RICOUNTER;

+} RIT_TypeDef;

+

+/*------------- Real-Time Clock (RTC) ----------------------------------------*/

+typedef struct

+{

+  __IO uint8_t  ILR;

+       uint8_t  RESERVED0[3];

+  __IO uint8_t  CCR;

+       uint8_t  RESERVED1[3];

+  __IO uint8_t  CIIR;

+       uint8_t  RESERVED2[3];

+  __IO uint8_t  AMR;

+       uint8_t  RESERVED3[3];

+  __I  uint32_t CTIME0;

+  __I  uint32_t CTIME1;

+  __I  uint32_t CTIME2;

+  __IO uint8_t  SEC;

+       uint8_t  RESERVED4[3];

+  __IO uint8_t  MIN;

+       uint8_t  RESERVED5[3];

+  __IO uint8_t  HOUR;

+       uint8_t  RESERVED6[3];

+  __IO uint8_t  DOM;

+       uint8_t  RESERVED7[3];

+  __IO uint8_t  DOW;

+       uint8_t  RESERVED8[3];

+  __IO uint16_t DOY;

+       uint16_t RESERVED9;

+  __IO uint8_t  MONTH;

+       uint8_t  RESERVED10[3];

+  __IO uint16_t YEAR;

+       uint16_t RESERVED11;

+  __IO uint32_t CALIBRATION;

+  __IO uint32_t GPREG0;

+  __IO uint32_t GPREG1;

+  __IO uint32_t GPREG2;

+  __IO uint32_t GPREG3;

+  __IO uint32_t GPREG4;

+  __IO uint8_t  WAKEUPDIS;

+       uint8_t  RESERVED12[3];

+  __IO uint8_t  PWRCTRL;

+       uint8_t  RESERVED13[3];

+  __IO uint8_t  ALSEC;

+       uint8_t  RESERVED14[3];

+  __IO uint8_t  ALMIN;

+       uint8_t  RESERVED15[3];

+  __IO uint8_t  ALHOUR;

+       uint8_t  RESERVED16[3];

+  __IO uint8_t  ALDOM;

+       uint8_t  RESERVED17[3];

+  __IO uint8_t  ALDOW;

+       uint8_t  RESERVED18[3];

+  __IO uint16_t ALDOY;

+       uint16_t RESERVED19;

+  __IO uint8_t  ALMON;

+       uint8_t  RESERVED20[3];

+  __IO uint16_t ALYEAR;

+       uint16_t RESERVED21;

+} RTC_TypeDef;

+

+/*------------- Watchdog Timer (WDT) -----------------------------------------*/

+typedef struct

+{

+  __IO uint8_t  WDMOD;

+       uint8_t  RESERVED0[3];

+  __IO uint32_t WDTC;

+  __O  uint8_t  WDFEED;

+       uint8_t  RESERVED1[3];

+  __I  uint32_t WDTV;

+  __IO uint32_t WDCLKSEL;

+} WDT_TypeDef;

+

+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/

+typedef struct

+{

+  __IO uint32_t ADCR;

+  __IO uint32_t ADGDR;

+       uint32_t RESERVED0;

+  __IO uint32_t ADINTEN;

+  __I  uint32_t ADDR0;

+  __I  uint32_t ADDR1;

+  __I  uint32_t ADDR2;

+  __I  uint32_t ADDR3;

+  __I  uint32_t ADDR4;

+  __I  uint32_t ADDR5;

+  __I  uint32_t ADDR6;

+  __I  uint32_t ADDR7;

+  __I  uint32_t ADSTAT;

+  __IO uint32_t ADTRM;

+} ADC_TypeDef;

+

+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/

+typedef struct

+{

+  __IO uint32_t DACR;

+  __IO uint32_t DACCTRL;

+  __IO uint16_t DACCNTVAL;

+} DAC_TypeDef;

+

+/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/

+typedef struct

+{

+  __I  uint32_t MCCON;

+  __O  uint32_t MCCON_SET;

+  __O  uint32_t MCCON_CLR;

+  __I  uint32_t MCCAPCON;

+  __O  uint32_t MCCAPCON_SET;

+  __O  uint32_t MCCAPCON_CLR;

+  __IO uint32_t MCTIM0;

+  __IO uint32_t MCTIM1;

+  __IO uint32_t MCTIM2;

+  __IO uint32_t MCPER0;

+  __IO uint32_t MCPER1;

+  __IO uint32_t MCPER2;

+  __IO uint32_t MCPW0;

+  __IO uint32_t MCPW1;

+  __IO uint32_t MCPW2;

+  __IO uint32_t MCDEADTIME;

+  __IO uint32_t MCCCP;

+  __IO uint32_t MCCR0;

+  __IO uint32_t MCCR1;

+  __IO uint32_t MCCR2;

+  __I  uint32_t MCINTEN;

+  __O  uint32_t MCINTEN_SET;

+  __O  uint32_t MCINTEN_CLR;

+  __I  uint32_t MCCNTCON;

+  __O  uint32_t MCCNTCON_SET;

+  __O  uint32_t MCCNTCON_CLR;

+  __I  uint32_t MCINTFLAG;

+  __O  uint32_t MCINTFLAG_SET;

+  __O  uint32_t MCINTFLAG_CLR;

+  __O  uint32_t MCCAP_CLR;

+} MCPWM_TypeDef;

+

+/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/

+typedef struct

+{

+  __O  uint32_t QEICON;

+  __I  uint32_t QEISTAT;

+  __IO uint32_t QEICONF;

+  __I  uint32_t QEIPOS;

+  __IO uint32_t QEIMAXPOS;

+  __IO uint32_t CMPOS0;

+  __IO uint32_t CMPOS1;

+  __IO uint32_t CMPOS2;

+  __I  uint32_t INXCNT;

+  __IO uint32_t INXCMP;

+  __IO uint32_t QEILOAD;

+  __I  uint32_t QEITIME;

+  __I  uint32_t QEIVEL;

+  __I  uint32_t QEICAP;

+  __IO uint32_t VELCOMP;

+  __IO uint32_t FILTER;

+       uint32_t RESERVED0[998];

+  __O  uint32_t QEIIEC;

+  __O  uint32_t QEIIES;

+  __I  uint32_t QEIINTSTAT;

+  __I  uint32_t QEIIE;

+  __O  uint32_t QEICLR;

+  __O  uint32_t QEISET;

+} QEI_TypeDef;

+

+/*------------- Controller Area Network (CAN) --------------------------------*/

+typedef struct

+{

+  __IO uint32_t mask[512];              /* ID Masks                           */

+} CANAF_RAM_TypeDef;

+

+typedef struct                          /* Acceptance Filter Registers        */

+{

+  __IO uint32_t AFMR;

+  __IO uint32_t SFF_sa;

+  __IO uint32_t SFF_GRP_sa;

+  __IO uint32_t EFF_sa;

+  __IO uint32_t EFF_GRP_sa;

+  __IO uint32_t ENDofTable;

+  __I  uint32_t LUTerrAd;

+  __I  uint32_t LUTerr;

+} CANAF_TypeDef;

+

+typedef struct                          /* Central Registers                  */

+{

+  __I  uint32_t CANTxSR;

+  __I  uint32_t CANRxSR;

+  __I  uint32_t CANMSR;

+} CANCR_TypeDef;

+

+typedef struct                          /* Controller Registers               */

+{

+  __IO uint32_t MOD;

+  __O  uint32_t CMR;

+  __IO uint32_t GSR;

+  __I  uint32_t ICR;

+  __IO uint32_t IER;

+  __IO uint32_t BTR;

+  __IO uint32_t EWL;

+  __I  uint32_t SR;

+  __IO uint32_t RFS;

+  __IO uint32_t RID;

+  __IO uint32_t RDA;

+  __IO uint32_t RDB;

+  __IO uint32_t TFI1;

+  __IO uint32_t TID1;

+  __IO uint32_t TDA1;

+  __IO uint32_t TDB1;

+  __IO uint32_t TFI2;

+  __IO uint32_t TID2;

+  __IO uint32_t TDA2;

+  __IO uint32_t TDB2;

+  __IO uint32_t TFI3;

+  __IO uint32_t TID3;

+  __IO uint32_t TDA3;

+  __IO uint32_t TDB3;

+} CAN_TypeDef;

+

+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/

+typedef struct                          /* Common Registers                   */

+{

+  __I  uint32_t DMACIntStat;

+  __I  uint32_t DMACIntTCStat;

+  __O  uint32_t DMACIntTCClear;

+  __I  uint32_t DMACIntErrStat;

+  __O  uint32_t DMACIntErrClr;

+  __I  uint32_t DMACRawIntTCStat;

+  __I  uint32_t DMACRawIntErrStat;

+  __I  uint32_t DMACEnbldChns;

+  __IO uint32_t DMACSoftBReq;

+  __IO uint32_t DMACSoftSReq;

+  __IO uint32_t DMACSoftLBReq;

+  __IO uint32_t DMACSoftLSReq;

+  __IO uint32_t DMACConfig;

+  __IO uint32_t DMACSync;

+} GPDMA_TypeDef;

+

+typedef struct                          /* Channel Registers                  */

+{

+  __IO uint32_t DMACCSrcAddr;

+  __IO uint32_t DMACCDestAddr;

+  __IO uint32_t DMACCLLI;

+  __IO uint32_t DMACCControl;

+  __IO uint32_t DMACCConfig;

+} GPDMACH_TypeDef;

+

+/*------------- Universal Serial Bus (USB) -----------------------------------*/

+typedef struct

+{

+  __I  uint32_t HcRevision;             /* USB Host Registers                 */

+  __IO uint32_t HcControl;

+  __IO uint32_t HcCommandStatus;

+  __IO uint32_t HcInterruptStatus;

+  __IO uint32_t HcInterruptEnable;

+  __IO uint32_t HcInterruptDisable;

+  __IO uint32_t HcHCCA;

+  __I  uint32_t HcPeriodCurrentED;

+  __IO uint32_t HcControlHeadED;

+  __IO uint32_t HcControlCurrentED;

+  __IO uint32_t HcBulkHeadED;

+  __IO uint32_t HcBulkCurrentED;

+  __I  uint32_t HcDoneHead;

+  __IO uint32_t HcFmInterval;

+  __I  uint32_t HcFmRemaining;

+  __I  uint32_t HcFmNumber;

+  __IO uint32_t HcPeriodicStart;

+  __IO uint32_t HcLSTreshold;

+  __IO uint32_t HcRhDescriptorA;

+  __IO uint32_t HcRhDescriptorB;

+  __IO uint32_t HcRhStatus;

+  __IO uint32_t HcRhPortStatus1;

+  __IO uint32_t HcRhPortStatus2;

+       uint32_t RESERVED0[40];

+  __I  uint32_t Module_ID;

+

+  __I  uint32_t OTGIntSt;               /* USB On-The-Go Registers            */

+  __IO uint32_t OTGIntEn;

+  __O  uint32_t OTGIntSet;

+  __O  uint32_t OTGIntClr;

+  __IO uint32_t OTGStCtrl;

+  __IO uint32_t OTGTmr;

+       uint32_t RESERVED1[58];

+

+  __I  uint32_t USBDevIntSt;            /* USB Device Interrupt Registers     */

+  __IO uint32_t USBDevIntEn;

+  __O  uint32_t USBDevIntClr;

+  __O  uint32_t USBDevIntSet;

+

+  __O  uint32_t USBCmdCode;             /* USB Device SIE Command Registers   */

+  __I  uint32_t USBCmdData;

+

+  __I  uint32_t USBRxData;              /* USB Device Transfer Registers      */

+  __O  uint32_t USBTxData;

+  __I  uint32_t USBRxPLen;

+  __O  uint32_t USBTxPLen;

+  __IO uint32_t USBCtrl;

+  __O  uint32_t USBDevIntPri;

+

+  __I  uint32_t USBEpIntSt;             /* USB Device Endpoint Interrupt Regs */

+  __IO uint32_t USBEpIntEn;

+  __O  uint32_t USBEpIntClr;

+  __O  uint32_t USBEpIntSet;

+  __O  uint32_t USBEpIntPri;

+

+  __IO uint32_t USBReEp;                /* USB Device Endpoint Realization Reg*/

+  __O  uint32_t USBEpInd;

+  __IO uint32_t USBMaxPSize;

+

+  __I  uint32_t USBDMARSt;              /* USB Device DMA Registers           */

+  __O  uint32_t USBDMARClr;

+  __O  uint32_t USBDMARSet;

+       uint32_t RESERVED2[9];

+  __IO uint32_t USBUDCAH;

+  __I  uint32_t USBEpDMASt;

+  __O  uint32_t USBEpDMAEn;

+  __O  uint32_t USBEpDMADis;

+  __I  uint32_t USBDMAIntSt;

+  __IO uint32_t USBDMAIntEn;

+       uint32_t RESERVED3[2];

+  __I  uint32_t USBEoTIntSt;

+  __O  uint32_t USBEoTIntClr;

+  __O  uint32_t USBEoTIntSet;

+  __I  uint32_t USBNDDRIntSt;

+  __O  uint32_t USBNDDRIntClr;

+  __O  uint32_t USBNDDRIntSet;

+  __I  uint32_t USBSysErrIntSt;

+  __O  uint32_t USBSysErrIntClr;

+  __O  uint32_t USBSysErrIntSet;

+       uint32_t RESERVED4[15];

+

+  __I  uint32_t I2C_RX;                 /* USB OTG I2C Registers              */

+  __O  uint32_t I2C_WO;

+  __I  uint32_t I2C_STS;

+  __IO uint32_t I2C_CTL;

+  __IO uint32_t I2C_CLKHI;

+  __O  uint32_t I2C_CLKLO;

+       uint32_t RESERVED5[823];

+

+  union {

+  __IO uint32_t USBClkCtrl;             /* USB Clock Control Registers        */

+  __IO uint32_t OTGClkCtrl;

+  } ;

+  union {

+  __I  uint32_t USBClkSt;

+  __I  uint32_t OTGClkSt;

+  };

+} USB_TypeDef;

+

+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/

+typedef struct

+{

+  __IO uint32_t MAC1;                   /* MAC Registers                      */

+  __IO uint32_t MAC2;

+  __IO uint32_t IPGT;

+  __IO uint32_t IPGR;

+  __IO uint32_t CLRT;

+  __IO uint32_t MAXF;

+  __IO uint32_t SUPP;

+  __IO uint32_t TEST;

+  __IO uint32_t MCFG;

+  __IO uint32_t MCMD;

+  __IO uint32_t MADR;

+  __O  uint32_t MWTD;

+  __I  uint32_t MRDD;

+  __I  uint32_t MIND;

+       uint32_t RESERVED0[2];

+  __IO uint32_t SA0;

+  __IO uint32_t SA1;

+  __IO uint32_t SA2;

+       uint32_t RESERVED1[45];

+  __IO uint32_t Command;                /* Control Registers                  */

+  __I  uint32_t Status;

+  __IO uint32_t RxDescriptor;

+  __IO uint32_t RxStatus;

+  __IO uint32_t RxDescriptorNumber;

+  __I  uint32_t RxProduceIndex;

+  __IO uint32_t RxConsumeIndex;

+  __IO uint32_t TxDescriptor;

+  __IO uint32_t TxStatus;

+  __IO uint32_t TxDescriptorNumber;

+  __IO uint32_t TxProduceIndex;

+  __I  uint32_t TxConsumeIndex;

+       uint32_t RESERVED2[10];

+  __I  uint32_t TSV0;

+  __I  uint32_t TSV1;

+  __I  uint32_t RSV;

+       uint32_t RESERVED3[3];

+  __IO uint32_t FlowControlCounter;

+  __I  uint32_t FlowControlStatus;

+       uint32_t RESERVED4[34];

+  __IO uint32_t RxFilterCtrl;           /* Rx Filter Registers                */

+  __IO uint32_t RxFilterWoLStatus;

+  __IO uint32_t RxFilterWoLClear;

+       uint32_t RESERVED5;

+  __IO uint32_t HashFilterL;

+  __IO uint32_t HashFilterH;

+       uint32_t RESERVED6[882];

+  __I  uint32_t IntStatus;              /* Module Control Registers           */

+  __IO uint32_t IntEnable;

+  __O  uint32_t IntClear;

+  __O  uint32_t IntSet;

+       uint32_t RESERVED7;

+  __IO uint32_t PowerDown;

+       uint32_t RESERVED8;

+  __IO uint32_t Module_ID;

+} EMAC_TypeDef;

+

+/******************************************************************************/

+/*                         Peripheral memory map                              */

+/******************************************************************************/

+/* Base addresses                                                             */

+#define FLASH_BASE            (0x00000000UL)

+#define RAM_BASE              (0x10000000UL)

+#define GPIO_BASE             (0x2009C000UL)

+#define APB0_BASE             (0x40000000UL)

+#define APB1_BASE             (0x40080000UL)

+#define AHB_BASE              (0x50000000UL)

+#define CM3_BASE              (0xE0000000UL)

+

+/* APB0 peripherals                                                           */

+#define WDT_BASE              (APB0_BASE + 0x00000)

+#define TIM0_BASE             (APB0_BASE + 0x04000)

+#define TIM1_BASE             (APB0_BASE + 0x08000)

+#define UART0_BASE            (APB0_BASE + 0x0C000)

+#define UART1_BASE            (APB0_BASE + 0x10000)

+#define PWM1_BASE             (APB0_BASE + 0x18000)

+#define I2C0_BASE             (APB0_BASE + 0x1C000)

+#define SPI_BASE              (APB0_BASE + 0x20000)

+#define RTC_BASE              (APB0_BASE + 0x24000)

+#define GPIOINT_BASE          (APB0_BASE + 0x28080)

+#define PINCON_BASE           (APB0_BASE + 0x2C000)

+#define SSP1_BASE             (APB0_BASE + 0x30000)

+#define ADC_BASE              (APB0_BASE + 0x34000)

+#define CANAF_RAM_BASE        (APB0_BASE + 0x38000)

+#define CANAF_BASE            (APB0_BASE + 0x3C000)

+#define CANCR_BASE            (APB0_BASE + 0x40000)

+#define CAN1_BASE             (APB0_BASE + 0x44000)

+#define CAN2_BASE             (APB0_BASE + 0x48000)

+#define I2C1_BASE             (APB0_BASE + 0x5C000)

+

+/* APB1 peripherals                                                           */

+#define SSP0_BASE             (APB1_BASE + 0x08000)

+#define DAC_BASE              (APB1_BASE + 0x0C000)

+#define TIM2_BASE             (APB1_BASE + 0x10000)

+#define TIM3_BASE             (APB1_BASE + 0x14000)

+#define UART2_BASE            (APB1_BASE + 0x18000)

+#define UART3_BASE            (APB1_BASE + 0x1C000)

+#define I2C2_BASE             (APB1_BASE + 0x20000)

+#define I2S_BASE              (APB1_BASE + 0x28000)

+#define RIT_BASE              (APB1_BASE + 0x30000)

+#define MCPWM_BASE            (APB1_BASE + 0x38000)

+#define QEI_BASE              (APB1_BASE + 0x3C000)

+#define SC_BASE               (APB1_BASE + 0x7C000)

+

+/* AHB peripherals                                                            */

+#define EMAC_BASE             (AHB_BASE  + 0x00000)

+#define GPDMA_BASE            (AHB_BASE  + 0x04000)

+#define GPDMACH0_BASE         (AHB_BASE  + 0x04100)

+#define GPDMACH1_BASE         (AHB_BASE  + 0x04120)

+#define GPDMACH2_BASE         (AHB_BASE  + 0x04140)

+#define GPDMACH3_BASE         (AHB_BASE  + 0x04160)

+#define GPDMACH4_BASE         (AHB_BASE  + 0x04180)

+#define GPDMACH5_BASE         (AHB_BASE  + 0x041A0)

+#define GPDMACH6_BASE         (AHB_BASE  + 0x041C0)

+#define GPDMACH7_BASE         (AHB_BASE  + 0x041E0)

+#define USB_BASE              (AHB_BASE  + 0x0C000)

+

+/* GPIOs                                                                      */

+#define GPIO0_BASE            (GPIO_BASE + 0x00000)

+#define GPIO1_BASE            (GPIO_BASE + 0x00020)

+#define GPIO2_BASE            (GPIO_BASE + 0x00040)

+#define GPIO3_BASE            (GPIO_BASE + 0x00060)

+#define GPIO4_BASE            (GPIO_BASE + 0x00080)

+

+

+/******************************************************************************/

+/*                         Peripheral declaration                             */

+/******************************************************************************/

+#define SC                    ((       SC_TypeDef *)        SC_BASE)

+#define GPIO0                 ((     GPIO_TypeDef *)     GPIO0_BASE)

+#define GPIO1                 ((     GPIO_TypeDef *)     GPIO1_BASE)

+#define GPIO2                 ((     GPIO_TypeDef *)     GPIO2_BASE)

+#define GPIO3                 ((     GPIO_TypeDef *)     GPIO3_BASE)

+#define GPIO4                 ((     GPIO_TypeDef *)     GPIO4_BASE)

+#define WDT                   ((      WDT_TypeDef *)       WDT_BASE)

+#define TIM0                  ((      TIM_TypeDef *)      TIM0_BASE)

+#define TIM1                  ((      TIM_TypeDef *)      TIM1_BASE)

+#define TIM2                  ((      TIM_TypeDef *)      TIM2_BASE)

+#define TIM3                  ((      TIM_TypeDef *)      TIM3_BASE)

+#define RIT                   ((      RIT_TypeDef *)       RIT_BASE)

+#define UART0                 ((     UART_TypeDef *)     UART0_BASE)

+#define UART1                 ((    UART1_TypeDef *)     UART1_BASE)

+#define UART2                 ((     UART_TypeDef *)     UART2_BASE)

+#define UART3                 ((     UART_TypeDef *)     UART3_BASE)

+#define PWM1                  ((      PWM_TypeDef *)      PWM1_BASE)

+#define I2C0                  ((      I2C_TypeDef *)      I2C0_BASE)

+#define I2C1                  ((      I2C_TypeDef *)      I2C1_BASE)

+#define I2C2                  ((      I2C_TypeDef *)      I2C2_BASE)

+#define I2S                   ((      I2S_TypeDef *)       I2S_BASE)

+#define SPI                   ((      SPI_TypeDef *)       SPI_BASE)

+#define RTC                   ((      RTC_TypeDef *)       RTC_BASE)

+#define GPIOINT               ((  GPIOINT_TypeDef *)   GPIOINT_BASE)

+#define PINCON                ((   PINCON_TypeDef *)    PINCON_BASE)

+#define SSP0                  ((      SSP_TypeDef *)      SSP0_BASE)

+#define SSP1                  ((      SSP_TypeDef *)      SSP1_BASE)

+#define ADC                   ((      ADC_TypeDef *)       ADC_BASE)

+#define DAC                   ((      DAC_TypeDef *)       DAC_BASE)

+#define CANAF_RAM             ((CANAF_RAM_TypeDef *) CANAF_RAM_BASE)

+#define CANAF                 ((    CANAF_TypeDef *)     CANAF_BASE)

+#define CANCR                 ((    CANCR_TypeDef *)     CANCR_BASE)

+#define CAN1                  ((      CAN_TypeDef *)      CAN1_BASE)

+#define CAN2                  ((      CAN_TypeDef *)      CAN2_BASE)

+#define MCPWM                 ((    MCPWM_TypeDef *)     MCPWM_BASE)

+#define QEI                   ((      QEI_TypeDef *)       QEI_BASE)

+#define EMAC                  ((     EMAC_TypeDef *)      EMAC_BASE)

+#define GPDMA                 ((    GPDMA_TypeDef *)     GPDMA_BASE)

+#define GPDMACH0              ((  GPDMACH_TypeDef *)  GPDMACH0_BASE)

+#define GPDMACH1              ((  GPDMACH_TypeDef *)  GPDMACH1_BASE)

+#define GPDMACH2              ((  GPDMACH_TypeDef *)  GPDMACH2_BASE)

+#define GPDMACH3              ((  GPDMACH_TypeDef *)  GPDMACH3_BASE)

+#define GPDMACH4              ((  GPDMACH_TypeDef *)  GPDMACH4_BASE)

+#define GPDMACH5              ((  GPDMACH_TypeDef *)  GPDMACH5_BASE)

+#define GPDMACH6              ((  GPDMACH_TypeDef *)  GPDMACH6_BASE)

+#define GPDMACH7              ((  GPDMACH_TypeDef *)  GPDMACH7_BASE)

+#define USB                   ((      USB_TypeDef *)       USB_BASE)

+

+#endif  // __LPC17xx_H__

+

+

+#endif

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/ParTest.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/ParTest.c
new file mode 100644
index 0000000..f6298c5
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/ParTest.c
@@ -0,0 +1,133 @@
+/*

+	FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.

+

+	This file is part of the FreeRTOS.org distribution.

+

+	FreeRTOS.org is free software; you can redistribute it and/or modify it

+	under the terms of the GNU General Public License (version 2) as published

+	by the Free Software Foundation and modified by the FreeRTOS exception.

+	**NOTE** The exception to the GPL is included to allow you to distribute a

+	combined work that includes FreeRTOS.org without being obliged to provide

+	the source code for any proprietary components.  Alternative commercial

+	license and support terms are also available upon request.  See the

+	licensing section of http://www.FreeRTOS.org for full details.

+

+	FreeRTOS.org is distributed in the hope that it will be useful,	but WITHOUT

+	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

+	FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for

+	more details.

+

+	You should have received a copy of the GNU General Public License along

+	with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59

+	Temple Place, Suite 330, Boston, MA  02111-1307  USA.

+

+

+	***************************************************************************

+	*                                                                         *

+	* Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *

+	*                                                                         *

+	* This is a concise, step by step, 'hands on' guide that describes both   *

+	* general multitasking concepts and FreeRTOS specifics. It presents and   *

+	* explains numerous examples that are written using the FreeRTOS API.     *

+	* Full source code for all the examples is provided in an accompanying    *

+	* .zip file.                                                              *

+	*                                                                         *

+	***************************************************************************

+

+	1 tab == 4 spaces!

+

+	Please ensure to read the configuration and relevant port sections of the

+	online documentation.

+

+	http://www.FreeRTOS.org - Documentation, latest information, license and

+	contact details.

+

+	http://www.SafeRTOS.com - A version that is certified for use in safety

+	critical systems.

+

+	http://www.OpenRTOS.com - Commercial support, development, porting,

+	licensing and training services.

+*/

+

+/* FreeRTOS.org includes. */

+#include "FreeRTOS.h"

+

+/* Demo application includes. */

+#include "partest.h"

+

+#define LED_2 ( 1UL << 24UL )

+#define LED_3 ( 1UL << 25UL )

+#define LED_4 ( 1UL << 28UL )

+#define LED_5 ( 1UL << 29UL )

+

+#define partstFIO1_BITS			( LED_2 | LED_3 | LED_4 | LED_5 )

+#define partstNUM_LEDS			( 4 )

+

+static unsigned long ulLEDs[] = { LED_3, LED_2, LED_5, LED_4 };

+

+/*-----------------------------------------------------------

+ * Simple parallel port IO routines.

+ *-----------------------------------------------------------*/

+

+void vParTestInitialise( void )

+{

+	/* LEDs on port 1. */

+	GPIO1->FIODIR  = partstFIO1_BITS;

+	

+	/* Start will all LEDs off. */

+	GPIO1->FIOCLR = partstFIO1_BITS;

+}

+/*-----------------------------------------------------------*/

+

+void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )

+{

+	if( uxLED < partstNUM_LEDS )

+	{

+		/* Set of clear the output. */

+		if( xValue )

+		{

+			GPIO1->FIOCLR = ulLEDs[ uxLED ];

+		}

+		else

+		{

+			GPIO1->FIOSET = ulLEDs[ uxLED ];

+		}

+	}

+}

+/*-----------------------------------------------------------*/

+

+void vParTestToggleLED( unsigned portBASE_TYPE uxLED )

+{

+	if( uxLED < partstNUM_LEDS )

+	{

+		if( GPIO1->FIOPIN & ulLEDs[ uxLED ] )

+		{

+			GPIO1->FIOCLR = ulLEDs[ uxLED ];

+		}

+		else

+		{

+			GPIO1->FIOSET = ulLEDs[ uxLED ];

+		}

+	}

+}

+/*-----------------------------------------------------------*/

+

+unsigned portBASE_TYPE uxParTextGetLED( unsigned portBASE_TYPE uxLED )

+{

+	if( uxLED < partstNUM_LEDS )

+	{

+		return ( GPIO1->FIOPIN & ulLEDs[ uxLED ] );

+	}

+	else

+	{

+		return 0;

+	}

+}

+/*-----------------------------------------------------------*/

+

+

+

+

+

+

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/core_cm3.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/core_cm3.h
new file mode 100644
index 0000000..b6f9696
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/core_cm3.h
@@ -0,0 +1,1367 @@
+/******************************************************************************

+ * @file:    core_cm3.h

+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File

+ * @version: V1.20

+ * @date:    22. May 2009

+ *----------------------------------------------------------------------------

+ *

+ * Copyright (C) 2009 ARM Limited. All rights reserved.

+ *

+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx 

+ * processor based microcontrollers.  This file can be freely distributed 

+ * within development tools that are supporting such ARM based processors. 

+ *

+ * 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.

+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR

+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

+ *

+ ******************************************************************************/

+

+#ifndef __CM3_CORE_H__

+#define __CM3_CORE_H__

+

+#ifdef __cplusplus

+ extern "C" {

+#endif 

+

+#define __CM3_CMSIS_VERSION_MAIN  (0x01)                                                       /*!< [31:16] CMSIS HAL main version */

+#define __CM3_CMSIS_VERSION_SUB   (0x20)                                                       /*!< [15:0]  CMSIS HAL sub version  */

+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number       */

+

+#define __CORTEX_M                (0x03)                                                       /*!< Cortex core                    */

+

+/**

+ *  Lint configuration \n

+ *  ----------------------- \n

+ *

+ *  The following Lint messages will be suppressed and not shown: \n

+ *  \n

+ *    --- Error 10: --- \n

+ *    register uint32_t __regBasePri         __asm("basepri"); \n

+ *    Error 10: Expecting ';' \n

+ *     \n

+ *    --- Error 530: --- \n

+ *    return(__regBasePri); \n

+ *    Warning 530: Symbol '__regBasePri' (line 264) not initialized \n

+ *     \n

+ *    --- Error 550: --- \n

+ *      __regBasePri = (basePri & 0x1ff); \n

+ *    } \n

+ *    Warning 550: Symbol '__regBasePri' (line 271) not accessed \n

+ *     \n

+ *    --- Error 754: --- \n

+ *    uint32_t RESERVED0[24]; \n

+ *    Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced \n

+ *     \n

+ *    --- Error 750: --- \n

+ *    #define __CM3_CORE_H__ \n

+ *    Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n

+ *     \n

+ *    --- Error 528: --- \n

+ *    static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n

+ *    Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n

+ *     \n

+ *    --- Error 751: --- \n

+ *    } InterruptType_Type; \n

+ *    Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n

+ * \n

+ * \n

+ *    Note:  To re-enable a Message, insert a space before 'lint' * \n

+ *

+ */

+

+/*lint -save */

+/*lint -e10  */

+/*lint -e530 */

+/*lint -e550 */

+/*lint -e754 */

+/*lint -e750 */

+/*lint -e528 */

+/*lint -e751 */

+

+

+#include <stdint.h>                           /* Include standard types */

+

+#if defined (__ICCARM__)

+  #include <intrinsics.h>                     /* IAR Intrinsics   */

+#endif

+

+

+#ifndef __NVIC_PRIO_BITS

+  #define __NVIC_PRIO_BITS    4               /*!< standard definition for NVIC Priority Bits */

+#endif

+

+

+

+

+/**

+ * IO definitions

+ *

+ * define access restrictions to peripheral registers

+ */

+

+#ifdef __cplusplus

+#define     __I     volatile                  /*!< defines 'read only' permissions      */

+#else

+#define     __I     volatile const            /*!< defines 'read only' permissions      */

+#endif

+#define     __O     volatile                  /*!< defines 'write only' permissions     */

+#define     __IO    volatile                  /*!< defines 'read / write' permissions   */

+

+

+

+/*******************************************************************************

+ *                 Register Abstraction

+ ******************************************************************************/

+

+

+/* System Reset */

+#define NVIC_VECTRESET              0         /*!< Vector Reset Bit             */

+#define NVIC_SYSRESETREQ            2         /*!< System Reset Request         */

+#define NVIC_AIRCR_VECTKEY    (0x5FA << 16)   /*!< AIRCR Key for write access   */

+#define NVIC_AIRCR_ENDIANESS        15        /*!< Endianess                    */

+

+/* Core Debug */

+#define CoreDebug_DEMCR_TRCENA (1 << 24)      /*!< DEMCR TRCENA enable          */

+#define ITM_TCR_ITMENA              1         /*!< ITM enable                   */

+

+

+

+

+/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */

+typedef struct

+{

+  __IO uint32_t ISER[8];                      /*!< Interrupt Set Enable Register            */

+       uint32_t RESERVED0[24];

+  __IO uint32_t ICER[8];                      /*!< Interrupt Clear Enable Register          */

+       uint32_t RSERVED1[24];

+  __IO uint32_t ISPR[8];                      /*!< Interrupt Set Pending Register           */

+       uint32_t RESERVED2[24];

+  __IO uint32_t ICPR[8];                      /*!< Interrupt Clear Pending Register         */

+       uint32_t RESERVED3[24];

+  __IO uint32_t IABR[8];                      /*!< Interrupt Active bit Register            */

+       uint32_t RESERVED4[56];

+  __IO uint8_t  IP[240];                      /*!< Interrupt Priority Register, 8Bit wide   */

+       uint32_t RESERVED5[644];

+  __O  uint32_t STIR;                         /*!< Software Trigger Interrupt Register      */

+}  NVIC_Type;

+

+

+/* memory mapping struct for System Control Block */

+typedef struct

+{

+  __I  uint32_t CPUID;                        /*!< CPU ID Base Register                                     */

+  __IO uint32_t ICSR;                         /*!< Interrupt Control State Register                         */

+  __IO uint32_t VTOR;                         /*!< Vector Table Offset Register                             */

+  __IO uint32_t AIRCR;                        /*!< Application Interrupt / Reset Control Register           */

+  __IO uint32_t SCR;                          /*!< System Control Register                                  */

+  __IO uint32_t CCR;                          /*!< Configuration Control Register                           */

+  __IO uint8_t  SHP[12];                      /*!< System Handlers Priority Registers (4-7, 8-11, 12-15)    */

+  __IO uint32_t SHCSR;                        /*!< System Handler Control and State Register                */

+  __IO uint32_t CFSR;                         /*!< Configurable Fault Status Register                       */

+  __IO uint32_t HFSR;                         /*!< Hard Fault Status Register                               */

+  __IO uint32_t DFSR;                         /*!< Debug Fault Status Register                              */

+  __IO uint32_t MMFAR;                        /*!< Mem Manage Address Register                              */

+  __IO uint32_t BFAR;                         /*!< Bus Fault Address Register                               */

+  __IO uint32_t AFSR;                         /*!< Auxiliary Fault Status Register                          */

+  __I  uint32_t PFR[2];                       /*!< Processor Feature Register                               */

+  __I  uint32_t DFR;                          /*!< Debug Feature Register                                   */

+  __I  uint32_t ADR;                          /*!< Auxiliary Feature Register                               */

+  __I  uint32_t MMFR[4];                      /*!< Memory Model Feature Register                            */

+  __I  uint32_t ISAR[5];                      /*!< ISA Feature Register                                     */

+} SCB_Type;

+

+

+/* memory mapping struct for SysTick */

+typedef struct

+{

+  __IO uint32_t CTRL;                         /*!< SysTick Control and Status Register */

+  __IO uint32_t LOAD;                         /*!< SysTick Reload Value Register       */

+  __IO uint32_t VAL;                          /*!< SysTick Current Value Register      */

+  __I  uint32_t CALIB;                        /*!< SysTick Calibration Register        */

+} SysTick_Type;

+

+

+/* memory mapping structur for ITM */

+typedef struct

+{

+  __O  union  

+  {

+    __O  uint8_t    u8;                       /*!< ITM Stimulus Port 8-bit               */

+    __O  uint16_t   u16;                      /*!< ITM Stimulus Port 16-bit              */

+    __O  uint32_t   u32;                      /*!< ITM Stimulus Port 32-bit              */

+  }  PORT [32];                               /*!< ITM Stimulus Port Registers           */

+       uint32_t RESERVED0[864];

+  __IO uint32_t TER;                          /*!< ITM Trace Enable Register             */

+       uint32_t RESERVED1[15];

+  __IO uint32_t TPR;                          /*!< ITM Trace Privilege Register          */

+       uint32_t RESERVED2[15];

+  __IO uint32_t TCR;                          /*!< ITM Trace Control Register            */

+       uint32_t RESERVED3[29];

+  __IO uint32_t IWR;                          /*!< ITM Integration Write Register        */

+  __IO uint32_t IRR;                          /*!< ITM Integration Read Register         */

+  __IO uint32_t IMCR;                         /*!< ITM Integration Mode Control Register */

+       uint32_t RESERVED4[43];

+  __IO uint32_t LAR;                          /*!< ITM Lock Access Register              */

+  __IO uint32_t LSR;                          /*!< ITM Lock Status Register              */

+       uint32_t RESERVED5[6];

+  __I  uint32_t PID4;                         /*!< ITM Product ID Registers              */

+  __I  uint32_t PID5;

+  __I  uint32_t PID6;

+  __I  uint32_t PID7;

+  __I  uint32_t PID0;

+  __I  uint32_t PID1;

+  __I  uint32_t PID2;

+  __I  uint32_t PID3;

+  __I  uint32_t CID0;

+  __I  uint32_t CID1;

+  __I  uint32_t CID2;

+  __I  uint32_t CID3;

+} ITM_Type;

+

+

+/* memory mapped struct for Interrupt Type */

+typedef struct

+{

+       uint32_t RESERVED0;

+  __I  uint32_t ICTR;                         /*!< Interrupt Control Type Register  */

+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))

+  __IO uint32_t ACTLR;                        /*!< Auxiliary Control Register       */

+#else

+       uint32_t RESERVED1;

+#endif

+} InterruptType_Type;

+

+

+/* Memory Protection Unit */

+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)

+typedef struct

+{

+  __I  uint32_t TYPE;                         /*!< MPU Type Register                               */

+  __IO uint32_t CTRL;                         /*!< MPU Control Register                            */

+  __IO uint32_t RNR;                          /*!< MPU Region RNRber Register                      */

+  __IO uint32_t RBAR;                         /*!< MPU Region Base Address Register                */

+  __IO uint32_t RASR;                         /*!< MPU Region Attribute and Size Register          */

+  __IO uint32_t RBAR_A1;                      /*!< MPU Alias 1 Region Base Address Register        */

+  __IO uint32_t RASR_A1;                      /*!< MPU Alias 1 Region Attribute and Size Register  */

+  __IO uint32_t RBAR_A2;                      /*!< MPU Alias 2 Region Base Address Register        */

+  __IO uint32_t RASR_A2;                      /*!< MPU Alias 2 Region Attribute and Size Register  */

+  __IO uint32_t RBAR_A3;                      /*!< MPU Alias 3 Region Base Address Register        */

+  __IO uint32_t RASR_A3;                      /*!< MPU Alias 3 Region Attribute and Size Register  */

+} MPU_Type;

+#endif

+

+

+/* Core Debug Register */

+typedef struct

+{

+  __IO uint32_t DHCSR;                        /*!< Debug Halting Control and Status Register       */

+  __O  uint32_t DCRSR;                        /*!< Debug Core Register Selector Register           */

+  __IO uint32_t DCRDR;                        /*!< Debug Core Register Data Register               */

+  __IO uint32_t DEMCR;                        /*!< Debug Exception and Monitor Control Register    */

+} CoreDebug_Type;

+

+

+/* Memory mapping of Cortex-M3 Hardware */

+#define SCS_BASE            (0xE000E000)                              /*!< System Control Space Base Address    */

+#define ITM_BASE            (0xE0000000)                              /*!< ITM Base Address                     */

+#define CoreDebug_BASE      (0xE000EDF0)                              /*!< Core Debug Base Address              */

+#define SysTick_BASE        (SCS_BASE +  0x0010)                      /*!< SysTick Base Address                 */

+#define NVIC_BASE           (SCS_BASE +  0x0100)                      /*!< NVIC Base Address                    */

+#define SCB_BASE            (SCS_BASE +  0x0D00)                      /*!< System Control Block Base Address    */

+

+#define InterruptType       ((InterruptType_Type *) SCS_BASE)         /*!< Interrupt Type Register              */

+#define SCB                 ((SCB_Type *)           SCB_BASE)         /*!< SCB configuration struct             */

+#define SysTick             ((SysTick_Type *)       SysTick_BASE)     /*!< SysTick configuration struct         */

+#define NVIC                ((NVIC_Type *)          NVIC_BASE)        /*!< NVIC configuration struct            */

+#define ITM                 ((ITM_Type *)           ITM_BASE)         /*!< ITM configuration struct             */

+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct      */

+

+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)

+  #define MPU_BASE          (SCS_BASE +  0x0D90)                      /*!< Memory Protection Unit               */

+  #define MPU               ((MPU_Type*)            MPU_BASE)         /*!< Memory Protection Unit               */

+#endif

+

+

+

+/*******************************************************************************

+ *                Hardware Abstraction Layer

+ ******************************************************************************/

+

+

+#if defined ( __CC_ARM   )

+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */

+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */

+

+#elif defined ( __ICCARM__ )

+  #define __ASM           __asm                                       /*!< asm keyword for IAR Compiler           */

+  #define __INLINE        inline                                      /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */

+

+#elif defined   (  __GNUC__  )

+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */

+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */

+

+#elif defined   (  __TASKING__  )

+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler          */

+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler       */

+

+#endif

+

+

+/* ###################  Compiler specific Intrinsics  ########################### */

+

+#if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/

+/* ARM armcc specific functions */

+

+#define __enable_fault_irq                __enable_fiq

+#define __disable_fault_irq               __disable_fiq

+

+#define __NOP                             __nop

+#define __WFI                             __wfi

+#define __WFE                             __wfe

+#define __SEV                             __sev

+#define __ISB()                           __isb(0)

+#define __DSB()                           __dsb(0)

+#define __DMB()                           __dmb(0)

+#define __REV                             __rev

+#define __RBIT                            __rbit

+#define __LDREXB(ptr)                     ((unsigned char ) __ldrex(ptr))

+#define __LDREXH(ptr)                     ((unsigned short) __ldrex(ptr))

+#define __LDREXW(ptr)                     ((unsigned int  ) __ldrex(ptr))

+#define __STREXB(value, ptr)              __strex(value, ptr)

+#define __STREXH(value, ptr)              __strex(value, ptr)

+#define __STREXW(value, ptr)              __strex(value, ptr)

+

+

+/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */

+/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */

+/* intrinsic void __enable_irq();     */

+/* intrinsic void __disable_irq();    */

+

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @param  none

+ * @return uint32_t ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+extern uint32_t __get_PSP(void);

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  uint32_t Process Stack Pointer

+ * @return none

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+extern void __set_PSP(uint32_t topOfProcStack);

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @param  none

+ * @return uint32_t Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+extern uint32_t __get_MSP(void);

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  uint32_t Main Stack Pointer

+ * @return none

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+extern void __set_MSP(uint32_t topOfMainStack);

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param  uint16_t value to reverse

+ * @return uint32_t reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+extern uint32_t __REV16(uint16_t value);

+

+/*

+ * @brief  Reverse byte order in signed short value with sign extension to integer

+ *

+ * @param  int16_t value to reverse

+ * @return int32_t reversed value

+ *

+ * Reverse byte order in signed short value with sign extension to integer

+ */

+extern int32_t __REVSH(int16_t value);

+

+

+#if (__ARMCC_VERSION < 400000)

+

+/**

+ * @brief  Remove the exclusive lock created by ldrex

+ *

+ * @param  none

+ * @return none

+ *

+ * Removes the exclusive lock which is created by ldrex.

+ */

+extern void __CLREX(void);

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @param  none

+ * @return uint32_t BasePriority

+ *

+ * Return the content of the base priority register

+ */

+extern uint32_t __get_BASEPRI(void);

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  uint32_t BasePriority

+ * @return none

+ *

+ * Set the base priority register

+ */

+extern void __set_BASEPRI(uint32_t basePri);

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @param  none

+ * @return uint32_t PriMask

+ *

+ * Return the state of the priority mask bit from the priority mask

+ * register

+ */

+extern uint32_t __get_PRIMASK(void);

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param  uint32_t PriMask

+ * @return none

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+extern void __set_PRIMASK(uint32_t priMask);

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @param  none

+ * @return uint32_t FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+extern uint32_t __get_FAULTMASK(void);

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  uint32_t faultMask value

+ * @return none

+ *

+ * Set the fault mask register

+ */

+extern void __set_FAULTMASK(uint32_t faultMask);

+

+/**

+ * @brief  Return the Control Register value

+ * 

+ * @param  none

+ * @return uint32_t Control value

+ *

+ * Return the content of the control register

+ */

+extern uint32_t __get_CONTROL(void);

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  uint32_t Control value

+ * @return none

+ *

+ * Set the control register

+ */

+extern void __set_CONTROL(uint32_t control);

+

+#else  /* (__ARMCC_VERSION >= 400000)  */

+

+

+/**

+ * @brief  Remove the exclusive lock created by ldrex

+ *

+ * @param  none

+ * @return none

+ *

+ * Removes the exclusive lock which is created by ldrex.

+ */

+#define __CLREX                           __clrex

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @param  none

+ * @return uint32_t BasePriority

+ *

+ * Return the content of the base priority register

+ */

+static __INLINE uint32_t  __get_BASEPRI(void)

+{

+  register uint32_t __regBasePri         __ASM("basepri");

+  return(__regBasePri);

+}

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  uint32_t BasePriority

+ * @return none

+ *

+ * Set the base priority register

+ */

+static __INLINE void __set_BASEPRI(uint32_t basePri)

+{

+  register uint32_t __regBasePri         __ASM("basepri");

+  __regBasePri = (basePri & 0x1ff);

+}

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @param  none

+ * @return uint32_t PriMask

+ *

+ * Return the state of the priority mask bit from the priority mask

+ * register

+ */

+static __INLINE uint32_t __get_PRIMASK(void)

+{

+  register uint32_t __regPriMask         __ASM("primask");

+  return(__regPriMask);

+}

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param  uint32_t PriMask

+ * @return none

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+static __INLINE void __set_PRIMASK(uint32_t priMask)

+{

+  register uint32_t __regPriMask         __ASM("primask");

+  __regPriMask = (priMask);

+}

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @param  none

+ * @return uint32_t FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+static __INLINE uint32_t __get_FAULTMASK(void)

+{

+  register uint32_t __regFaultMask       __ASM("faultmask");

+  return(__regFaultMask);

+}

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  uint32_t faultMask value

+ * @return none

+ *

+ * Set the fault mask register

+ */

+static __INLINE void __set_FAULTMASK(uint32_t faultMask)

+{

+  register uint32_t __regFaultMask       __ASM("faultmask");

+  __regFaultMask = (faultMask & 1);

+}

+

+/**

+ * @brief  Return the Control Register value

+ * 

+ * @param  none

+ * @return uint32_t Control value

+ *

+ * Return the content of the control register

+ */

+static __INLINE uint32_t __get_CONTROL(void)

+{

+  register uint32_t __regControl         __ASM("control");

+  return(__regControl);

+}

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  uint32_t Control value

+ * @return none

+ *

+ * Set the control register

+ */

+static __INLINE void __set_CONTROL(uint32_t control)

+{

+  register uint32_t __regControl         __ASM("control");

+  __regControl = control;

+}

+

+#endif /* __ARMCC_VERSION  */ 

+

+

+

+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/

+/* IAR iccarm specific functions */

+

+#define __enable_irq                              __enable_interrupt        /*!< global Interrupt enable */

+#define __disable_irq                             __disable_interrupt       /*!< global Interrupt disable */

+

+static __INLINE void __enable_fault_irq()         { __ASM ("cpsie f"); }

+static __INLINE void __disable_fault_irq()        { __ASM ("cpsid f"); }

+

+#define __NOP                                     __no_operation()          /*!< no operation intrinsic in IAR Compiler */ 

+static __INLINE  void __WFI()                     { __ASM ("wfi"); }

+static __INLINE  void __WFE()                     { __ASM ("wfe"); }

+static __INLINE  void __SEV()                     { __ASM ("sev"); }

+static __INLINE  void __CLREX()                   { __ASM ("clrex"); }

+

+/* intrinsic void __ISB(void)                                     */

+/* intrinsic void __DSB(void)                                     */

+/* intrinsic void __DMB(void)                                     */

+/* intrinsic void __set_PRIMASK();                                */

+/* intrinsic void __get_PRIMASK();                                */

+/* intrinsic void __set_FAULTMASK();                              */

+/* intrinsic void __get_FAULTMASK();                              */

+/* intrinsic uint32_t __REV(uint32_t value);                      */

+/* intrinsic uint32_t __REVSH(uint32_t value);                    */

+/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */

+/* intrinsic unsigned long __LDREX(unsigned long *);              */

+

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @param  none

+ * @return uint32_t ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+extern uint32_t __get_PSP(void);

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  uint32_t Process Stack Pointer

+ * @return none

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+extern void __set_PSP(uint32_t topOfProcStack);

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @param  none

+ * @return uint32_t Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+extern uint32_t __get_MSP(void);

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  uint32_t Main Stack Pointer

+ * @return none

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+extern void __set_MSP(uint32_t topOfMainStack);

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param  uint16_t value to reverse

+ * @return uint32_t reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+extern uint32_t __REV16(uint16_t value);

+

+/**

+ * @brief  Reverse bit order of value

+ *

+ * @param  uint32_t value to reverse

+ * @return uint32_t reversed value

+ *

+ * Reverse bit order of value

+ */

+extern uint32_t __RBIT(uint32_t value);

+

+/**

+ * @brief  LDR Exclusive

+ *

+ * @param  uint8_t* address

+ * @return uint8_t value of (*address)

+ *

+ * Exclusive LDR command

+ */

+extern uint8_t __LDREXB(uint8_t *addr);

+

+/**

+ * @brief  LDR Exclusive

+ *

+ * @param  uint16_t* address

+ * @return uint16_t value of (*address)

+ *

+ * Exclusive LDR command

+ */

+extern uint16_t __LDREXH(uint16_t *addr);

+

+/**

+ * @brief  LDR Exclusive

+ *

+ * @param  uint32_t* address

+ * @return uint32_t value of (*address)

+ *

+ * Exclusive LDR command

+ */

+extern uint32_t __LDREXW(uint32_t *addr);

+

+/**

+ * @brief  STR Exclusive

+ *

+ * @param  uint8_t *address

+ * @param  uint8_t value to store

+ * @return uint32_t successful / failed

+ *

+ * Exclusive STR command

+ */

+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);

+

+/**

+ * @brief  STR Exclusive

+ *

+ * @param  uint16_t *address

+ * @param  uint16_t value to store

+ * @return uint32_t successful / failed

+ *

+ * Exclusive STR command

+ */

+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);

+

+/**

+ * @brief  STR Exclusive

+ *

+ * @param  uint32_t *address

+ * @param  uint32_t value to store

+ * @return uint32_t successful / failed

+ *

+ * Exclusive STR command

+ */

+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);

+

+

+

+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/

+/* GNU gcc specific functions */

+

+static __INLINE void __enable_irq()               { __ASM volatile ("cpsie i"); }

+static __INLINE void __disable_irq()              { __ASM volatile ("cpsid i"); }

+

+static __INLINE void __enable_fault_irq()         { __ASM volatile ("cpsie f"); }

+static __INLINE void __disable_fault_irq()        { __ASM volatile ("cpsid f"); }

+

+static __INLINE void __NOP()                      { __ASM volatile ("nop"); }

+static __INLINE void __WFI()                      { __ASM volatile ("wfi"); }

+static __INLINE void __WFE()                      { __ASM volatile ("wfe"); }

+static __INLINE void __SEV()                      { __ASM volatile ("sev"); }

+static __INLINE void __ISB()                      { __ASM volatile ("isb"); }

+static __INLINE void __DSB()                      { __ASM volatile ("dsb"); }

+static __INLINE void __DMB()                      { __ASM volatile ("dmb"); }

+static __INLINE void __CLREX()                    { __ASM volatile ("clrex"); }

+

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @param  none

+ * @return uint32_t ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+extern uint32_t __get_PSP(void);

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  uint32_t Process Stack Pointer

+ * @return none

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+extern void __set_PSP(uint32_t topOfProcStack);

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @param  none

+ * @return uint32_t Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+extern uint32_t __get_MSP(void);

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  uint32_t Main Stack Pointer

+ * @return none

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+extern void __set_MSP(uint32_t topOfMainStack);

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @param  none

+ * @return uint32_t BasePriority

+ *

+ * Return the content of the base priority register

+ */

+extern uint32_t __get_BASEPRI(void);

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  uint32_t BasePriority

+ * @return none

+ *

+ * Set the base priority register

+ */

+extern void __set_BASEPRI(uint32_t basePri);

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @param  none

+ * @return uint32_t PriMask

+ *

+ * Return the state of the priority mask bit from the priority mask

+ * register

+ */

+extern uint32_t  __get_PRIMASK(void);

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param  uint32_t PriMask

+ * @return none

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+extern void __set_PRIMASK(uint32_t priMask);

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @param  none

+ * @return uint32_t FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+extern uint32_t __get_FAULTMASK(void);

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  uint32_t faultMask value

+ * @return none

+ *

+ * Set the fault mask register

+ */

+extern void __set_FAULTMASK(uint32_t faultMask);

+

+/**

+ * @brief  Return the Control Register value

+* 

+*  @param  none

+*  @return uint32_t Control value

+ *

+ * Return the content of the control register

+ */

+extern uint32_t __get_CONTROL(void);

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  uint32_t Control value

+ * @return none

+ *

+ * Set the control register

+ */

+extern void __set_CONTROL(uint32_t control);

+

+/**

+ * @brief  Reverse byte order in integer value

+ *

+ * @param  uint32_t value to reverse

+ * @return uint32_t reversed value

+ *

+ * Reverse byte order in integer value

+ */

+extern uint32_t __REV(uint32_t value);

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param  uint16_t value to reverse

+ * @return uint32_t reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+extern uint32_t __REV16(uint16_t value);

+

+/*

+ * Reverse byte order in signed short value with sign extension to integer

+ *

+ * @param  int16_t value to reverse

+ * @return int32_t reversed value

+ *

+ * @brief  Reverse byte order in signed short value with sign extension to integer

+ */

+extern int32_t __REVSH(int16_t value);

+

+/**

+ * @brief  Reverse bit order of value

+ *

+ * @param  uint32_t value to reverse

+ * @return uint32_t reversed value

+ *

+ * Reverse bit order of value

+ */

+extern uint32_t __RBIT(uint32_t value);

+

+/**

+ * @brief  LDR Exclusive

+ *

+ * @param  uint8_t* address

+ * @return uint8_t value of (*address)

+ *

+ * Exclusive LDR command

+ */

+extern uint8_t __LDREXB(uint8_t *addr);

+

+/**

+ * @brief  LDR Exclusive

+ *

+ * @param  uint16_t* address

+ * @return uint16_t value of (*address)

+ *

+ * Exclusive LDR command

+ */

+extern uint16_t __LDREXH(uint16_t *addr);

+

+/**

+ * @brief  LDR Exclusive

+ *

+ * @param  uint32_t* address

+ * @return uint32_t value of (*address)

+ *

+ * Exclusive LDR command

+ */

+extern uint32_t __LDREXW(uint32_t *addr);

+

+/**

+ * @brief  STR Exclusive

+ *

+ * @param  uint8_t *address

+ * @param  uint8_t value to store

+ * @return uint32_t successful / failed

+ *

+ * Exclusive STR command

+ */

+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);

+

+/**

+ * @brief  STR Exclusive

+ *

+ * @param  uint16_t *address

+ * @param  uint16_t value to store

+ * @return uint32_t successful / failed

+ *

+ * Exclusive STR command

+ */

+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);

+

+/**

+ * @brief  STR Exclusive

+ *

+ * @param  uint32_t *address

+ * @param  uint32_t value to store

+ * @return uint32_t successful / failed

+ *

+ * Exclusive STR command

+ */

+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);

+

+

+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/

+/* TASKING carm specific functions */

+

+/*

+ * The CMSIS functions have been implemented as intrinsics in the compiler.

+ * Please use "carm -?i" to get an up to date list of all instrinsics,

+ * Including the CMSIS ones.

+ */

+

+#endif

+

+

+

+/* ##########################   NVIC functions  #################################### */

+

+

+/**

+ * @brief  Set the Priority Grouping in NVIC Interrupt Controller

+ *

+ * @param  uint32_t priority_grouping is priority grouping field

+ * @return none 

+ *

+ * Set the priority grouping field using the required unlock sequence.

+ * The parameter priority_grouping is assigned to the field 

+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.

+ * In case of a conflict between priority grouping and available

+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.

+ */

+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)

+{

+  uint32_t reg_value;

+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */

+  

+  reg_value  = SCB->AIRCR;                                                    /* read old register configuration    */

+  reg_value &= ~((0xFFFFU << 16) | (0x0F << 8));                              /* clear bits to change               */

+  reg_value  = ((reg_value | NVIC_AIRCR_VECTKEY | (PriorityGroupTmp << 8)));  /* Insert write key and priorty group */

+  SCB->AIRCR = reg_value;

+}

+

+/**

+ * @brief  Get the Priority Grouping from NVIC Interrupt Controller

+ *

+ * @param  none

+ * @return uint32_t   priority grouping field 

+ *

+ * Get the priority grouping from NVIC Interrupt Controller.

+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.

+ */

+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)

+{

+  return ((SCB->AIRCR >> 8) & 0x07);                                          /* read priority grouping field */

+}

+

+/**

+ * @brief  Enable Interrupt in NVIC Interrupt Controller

+ *

+ * @param  IRQn_Type IRQn specifies the interrupt number

+ * @return none 

+ *

+ * Enable a device specific interupt in the NVIC interrupt controller.

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)

+{

+  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */

+}

+

+/**

+ * @brief  Disable the interrupt line for external interrupt specified

+ * 

+ * @param  IRQn_Type IRQn is the positive number of the external interrupt

+ * @return none

+ * 

+ * Disable a device specific interupt in the NVIC interrupt controller.

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)

+{

+  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */

+}

+

+/**

+ * @brief  Read the interrupt pending bit for a device specific interrupt source

+ * 

+ * @param  IRQn_Type IRQn is the number of the device specifc interrupt

+ * @return uint32_t 1 if pending interrupt else 0

+ *

+ * Read the pending register in NVIC and return 1 if its status is pending, 

+ * otherwise it returns 0

+ */

+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)

+{

+  return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */

+}

+

+/**

+ * @brief  Set the pending bit for an external interrupt

+ * 

+ * @param  IRQn_Type IRQn is the Number of the interrupt

+ * @return none

+ *

+ * Set the pending bit for the specified interrupt.

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)

+{

+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */

+}

+

+/**

+ * @brief  Clear the pending bit for an external interrupt

+ *

+ * @param  IRQn_Type IRQn is the Number of the interrupt

+ * @return none

+ *

+ * Clear the pending bit for the specified interrupt. 

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)

+{

+  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */

+}

+

+/**

+ * @brief  Read the active bit for an external interrupt

+ *

+ * @param  IRQn_Type  IRQn is the Number of the interrupt

+ * @return uint32_t   1 if active else 0

+ *

+ * Read the active register in NVIC and returns 1 if its status is active, 

+ * otherwise it returns 0.

+ */

+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)

+{

+  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */

+}

+

+/**

+ * @brief  Set the priority for an interrupt

+ *

+ * @param  IRQn_Type IRQn is the Number of the interrupt

+ * @param  priority is the priority for the interrupt

+ * @return none

+ *

+ * Set the priority for the specified interrupt. The interrupt 

+ * number can be positive to specify an external (device specific) 

+ * interrupt, or negative to specify an internal (core) interrupt. \n

+ *

+ * Note: The priority cannot be set for every core interrupt.

+ */

+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

+{

+  if(IRQn < 0) {

+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */

+  else {

+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts      */

+}

+

+/**

+ * @brief  Read the priority for an interrupt

+ *

+ * @param  IRQn_Type IRQn is the Number of the interrupt

+ * @return uint32_t  priority is the priority for the interrupt

+ *

+ * Read the priority for the specified interrupt. The interrupt 

+ * number can be positive to specify an external (device specific) 

+ * interrupt, or negative to specify an internal (core) interrupt.

+ *

+ * The returned priority value is automatically aligned to the implemented

+ * priority bits of the microcontroller.

+ *

+ * Note: The priority cannot be set for every core interrupt.

+ */

+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)

+{

+

+  if(IRQn < 0) {

+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M3 system interrupts */

+  else {

+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */

+}

+

+

+/**

+ * @brief  Encode the priority for an interrupt

+ *

+ * @param  uint32_t PriorityGroup   is the used priority group

+ * @param  uint32_t PreemptPriority is the preemptive priority value (starting from 0)

+ * @param  uint32_t SubPriority     is the sub priority value (starting from 0)

+ * @return uint32_t                    the priority for the interrupt

+ *

+ * Encode the priority for an interrupt with the given priority group,

+ * preemptive priority value and sub priority value.

+ * In case of a conflict between priority grouping and available

+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.

+ *

+ * The returned priority value can be used for NVIC_SetPriority(...) function

+ */

+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)

+{

+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */

+  uint32_t PreemptPriorityBits;

+  uint32_t SubPriorityBits;

+

+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;

+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;

+ 

+  return (

+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |

+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))

+         );

+}

+

+

+/**

+ * @brief  Decode the priority of an interrupt

+ *

+ * @param  uint32_t   Priority       the priority for the interrupt

+ * @param  uint32_t   PrioGroup   is the used priority group

+ * @param  uint32_t* pPreemptPrio is the preemptive priority value (starting from 0)

+ * @param  uint32_t* pSubPrio     is the sub priority value (starting from 0)

+ * @return none

+ *

+ * Decode an interrupt priority value with the given priority group to 

+ * preemptive priority value and sub priority value.

+ * In case of a conflict between priority grouping and available

+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.

+ *

+ * The priority value can be retrieved with NVIC_GetPriority(...) function

+ */

+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)

+{

+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */

+  uint32_t PreemptPriorityBits;

+  uint32_t SubPriorityBits;

+

+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;

+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;

+  

+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);

+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);

+}

+

+

+

+/* ##################################    SysTick function  ############################################ */

+

+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)

+

+/* SysTick constants */

+#define SYSTICK_ENABLE              0                                          /* Config-Bit to start or stop the SysTick Timer                         */

+#define SYSTICK_TICKINT             1                                          /* Config-Bit to enable or disable the SysTick interrupt                 */

+#define SYSTICK_CLKSOURCE           2                                          /* Clocksource has the offset 2 in SysTick Control and Status Register   */

+#define SYSTICK_MAXCOUNT       ((1<<24) -1)                                    /* SysTick MaxCount                                                      */

+

+/**

+ * @brief  Initialize and start the SysTick counter and its interrupt.

+ *

+ * @param  uint32_t ticks is the number of ticks between two interrupts

+ * @return  none

+ *

+ * Initialise the system tick timer and its interrupt and start the

+ * system tick timer / counter in free running mode to generate 

+ * periodical interrupts.

+ */

+static __INLINE uint32_t SysTick_Config(uint32_t ticks)

+{ 

+  if (ticks > SYSTICK_MAXCOUNT)  return (1);                                             /* Reload value impossible */

+

+  SysTick->LOAD  =  (ticks & SYSTICK_MAXCOUNT) - 1;                                      /* set reload register */

+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);                            /* set Priority for Cortex-M0 System Interrupts */

+  SysTick->VAL   =  (0x00);                                                              /* Load the SysTick Counter Value */

+  SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */

+  return (0);                                                                            /* Function successful */

+}

+

+#endif

+

+

+

+

+

+/* ##################################    Reset function  ############################################ */

+

+/**

+ * @brief  Initiate a system reset request.

+ *

+ * @param   none

+ * @return  none

+ *

+ * Initialize a system reset request to reset the MCU

+ */

+static __INLINE void NVIC_SystemReset(void)

+{

+  SCB->AIRCR  = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1<<NVIC_SYSRESETREQ)); /* Keep priority group unchanged */

+  __DSB();                                                                             /* Ensure completion of memory access */              

+  while(1);                                                                            /* wait until reset */

+}

+

+

+/* ##################################    Debug Output  function  ############################################ */

+

+

+/**

+ * @brief  Outputs a character via the ITM channel 0

+ *

+ * @param   uint32_t character to output

+ * @return  uint32_t input character

+ *

+ * The function outputs a character via the ITM channel 0. 

+ * The function returns when no debugger is connected that has booked the output.  

+ * It is blocking when a debugger is connected, but the previous character send is not transmitted. 

+ */

+static __INLINE uint32_t ITM_SendChar (uint32_t ch)

+{

+  if (ch == '\n') ITM_SendChar('\r');

+  

+  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA)  &&

+      (ITM->TCR & ITM_TCR_ITMENA)                  &&

+      (ITM->TER & (1UL << 0))  ) 

+  {

+    while (ITM->PORT[0].u32 == 0);

+    ITM->PORT[0].u8 = (uint8_t) ch;

+  }  

+  return (ch);

+}

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* __CM3_CORE_H__ */

+

+/*lint -restore */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/cr_startup_lpc17.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/cr_startup_lpc17.c
new file mode 100644
index 0000000..5b92363
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/cr_startup_lpc17.c
@@ -0,0 +1,312 @@
+//*****************************************************************************

+//   +--+       

+//   | ++----+   

+//   +-++    |  

+//     |     |  

+//   +-+--+  |   

+//   | +--+--+  

+//   +----+    Copyright (c) 2009 Code Red Technologies Ltd. 

+//

+// Microcontroller Startup code for use with Red Suite

+//

+// 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. 

+//

+//*****************************************************************************

+#define WEAK __attribute__ ((weak))

+#define ALIAS(f) __attribute__ ((weak, alias (#f)))

+

+//*****************************************************************************

+//

+// Forward declaration of the default handlers.

+//

+//*****************************************************************************

+void Reset_Handler(void);

+void ResetISR(void) ALIAS(Reset_Handler);

+static void NMI_Handler(void);

+static void HardFault_Handler(void);

+static void MemManage_Handler(void);

+static void BusFault_Handler(void);

+static void UsageFault_Handler(void);

+static void DebugMon_Handler(void);

+

+//*****************************************************************************

+//

+// Forward declaration of the specific IRQ handlers. These are aliased

+// to the IntDefaultHandler, which is a 'forever' loop. When the application

+// defines a handler (with the same name), this will automatically take 

+// precedence over these weak definitions

+//

+//*****************************************************************************

+void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);

+void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);

+void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);

+void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);

+void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);

+void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);

+void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);

+void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);

+void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);

+void PWM1_IRQHandler(void) ALIAS(IntDefaultHandler);

+void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);

+void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);

+void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);

+void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);

+void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);

+void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);

+void PLL0_IRQHandler(void) ALIAS(IntDefaultHandler);

+void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);

+void EINT0_IRQHandler(void) ALIAS(IntDefaultHandler);

+void EINT1_IRQHandler(void) ALIAS(IntDefaultHandler);

+void EINT2_IRQHandler(void) ALIAS(IntDefaultHandler);

+void EINT3_IRQHandler(void) ALIAS(IntDefaultHandler);

+void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);

+void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);

+void USB_IRQHandler(void) ALIAS(IntDefaultHandler);

+void CAN_IRQHandler(void) ALIAS(IntDefaultHandler);

+void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);

+void I2S_IRQHandler(void) ALIAS(IntDefaultHandler);

+void ENET_IRQHandler(void) ALIAS(IntDefaultHandler);

+void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);

+void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);

+void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);

+void PLL1_IRQHandler(void) ALIAS(IntDefaultHandler);

+

+extern void xPortSysTickHandler(void);

+extern void xPortPendSVHandler(void);

+extern void vPortSVCHandler( void );

+extern void vEMAC_ISR( void );

+

+

+//*****************************************************************************

+//

+// The entry point for the C++ library startup

+//

+//*****************************************************************************

+extern WEAK void __libc_init_array(void);

+

+//*****************************************************************************

+//

+// The entry point for the application.

+// __main() is the entry point for redlib based applications

+// main() is the entry point for newlib based applications

+//

+//*****************************************************************************

+extern WEAK void __main(void);

+extern WEAK void main(void);

+//*****************************************************************************

+//

+// External declaration for the pointer to the stack top from the Linker Script

+//

+//*****************************************************************************

+extern void _vStackTop;

+

+//*****************************************************************************

+//

+// The vector table.

+// This relies on the linker script to place at correct location in memory.

+//

+//*****************************************************************************

+__attribute__ ((section(".isr_vector")))

+void (* const g_pfnVectors[])(void) =

+{

+	// Core Level - CM3

+	(void *)&_vStackTop,					// The initial stack pointer

+	Reset_Handler,							// The reset handler

+	NMI_Handler,							// The NMI handler

+	HardFault_Handler,						// The hard fault handler

+	MemManage_Handler,						// The MPU fault handler

+	BusFault_Handler,						// The bus fault handler

+	UsageFault_Handler,						// The usage fault handler

+	0,										// Reserved

+	0,										// Reserved

+	0,										// Reserved

+	0,										// Reserved

+	vPortSVCHandler,                        // SVCall handler

+	DebugMon_Handler,						// Debug monitor handler

+	0,										// Reserved

+	xPortPendSVHandler,                     // The PendSV handler

+	xPortSysTickHandler,                    // The SysTick handler

+

+	// Chip Level - LPC17

+	WDT_IRQHandler,							// 16, 0x40 - WDT

+	TIMER0_IRQHandler,						// 17, 0x44 - TIMER0

+	TIMER1_IRQHandler,						// 18, 0x48 - TIMER1

+	TIMER2_IRQHandler,						// 19, 0x4c - TIMER2

+	TIMER3_IRQHandler,						// 20, 0x50 - TIMER3

+	UART0_IRQHandler,						// 21, 0x54 - UART0

+	UART1_IRQHandler,						// 22, 0x58 - UART1

+	UART2_IRQHandler,						// 23, 0x5c - UART2

+	UART3_IRQHandler,						// 24, 0x60 - UART3

+	PWM1_IRQHandler,						// 25, 0x64 - PWM1

+	I2C0_IRQHandler,						// 26, 0x68 - I2C0

+	I2C1_IRQHandler,						// 27, 0x6c - I2C1

+	I2C2_IRQHandler,						// 28, 0x70 - I2C2

+	SPI_IRQHandler,							// 29, 0x74 - SPI

+	SSP0_IRQHandler,						// 30, 0x78 - SSP0

+	SSP1_IRQHandler,						// 31, 0x7c - SSP1

+	PLL0_IRQHandler,						// 32, 0x80 - PLL0 (Main PLL)

+	RTC_IRQHandler,							// 33, 0x84 - RTC

+	EINT0_IRQHandler,						// 34, 0x88 - EINT0

+	EINT1_IRQHandler,						// 35, 0x8c - EINT1

+	EINT2_IRQHandler,						// 36, 0x90 - EINT2

+	EINT3_IRQHandler,						// 37, 0x94 - EINT3

+	ADC_IRQHandler,							// 38, 0x98 - ADC

+	BOD_IRQHandler,							// 39, 0x9c - BOD

+	USB_IRQHandler,							// 40, 0xA0 - USB

+	CAN_IRQHandler,							// 41, 0xa4 - CAN

+	DMA_IRQHandler,							// 42, 0xa8 - GP DMA

+	I2S_IRQHandler,							// 43, 0xac - I2S

+	    vEMAC_ISR,                      		// Ethernet.

+	RIT_IRQHandler,							// 45, 0xb4 - RITINT

+	MCPWM_IRQHandler,						// 46, 0xb8 - Motor Control PWM

+	QEI_IRQHandler,							// 47, 0xbc - Quadrature Encoder

+	PLL1_IRQHandler,						// 48, 0xc0 - PLL1 (USB PLL)

+};

+

+//*****************************************************************************

+//

+// The following are constructs created by the linker, indicating where the

+// the "data" and "bss" segments reside in memory.  The initializers for the

+// for the "data" segment resides immediately following the "text" segment.

+//

+//*****************************************************************************

+extern unsigned long _etext;

+extern unsigned long _data;

+extern unsigned long _edata;

+extern unsigned long _bss;

+extern unsigned long _ebss;

+

+//*****************************************************************************

+// Reset entry point for your code.

+// Sets up a simple runtime environment and initializes the C/C++

+// library.

+//

+//*****************************************************************************

+void Reset_Handler(void)

+{

+    unsigned long *pulSrc, *pulDest;

+

+    //

+    // Copy the data segment initializers from flash to SRAM.

+    //

+    pulSrc = &_etext;

+    for(pulDest = &_data; pulDest < &_edata; )

+    {

+        *pulDest++ = *pulSrc++;

+    }

+

+    //

+    // Zero fill the bss segment.  This is done with inline assembly since this

+    // will clear the value of pulDest if it is not kept in a register.

+    //

+    __asm("    ldr     r0, =_bss\n"

+          "    ldr     r1, =_ebss\n"

+          "    mov     r2, #0\n"

+          "    .thumb_func\n"

+          "zero_loop:\n"

+          "        cmp     r0, r1\n"

+          "        it      lt\n"

+          "        strlt   r2, [r0], #4\n"

+          "        blt     zero_loop");

+

+    //

+    // Call C++ library initilisation, if present

+    //

+	if (__libc_init_array)

+		__libc_init_array() ;

+

+	//

+	// Call the application's entry point.

+	// __main() is the entry point for redlib based applications (which calls main())

+	// main() is the entry point for newlib based applications

+	//

+	if (__main)

+		__main() ;

+	else

+		main() ;

+

+	//

+	// main() shouldn't return, but if it does, we'll just enter an infinite loop 

+	//

+	while (1) {

+		;

+	}

+}

+

+//*****************************************************************************

+//

+// This is the code that gets called when the processor receives a NMI.  This

+// simply enters an infinite loop, preserving the system state for examination

+// by a debugger.

+//

+//*****************************************************************************

+static void NMI_Handler(void)

+{

+    while(1)

+    {

+    }

+}

+

+static void HardFault_Handler(void)

+{

+    while(1)

+    {

+    }

+}

+

+static void MemManage_Handler(void)

+{

+    while(1)

+    {

+    }

+}

+

+static void BusFault_Handler(void)

+{

+    while(1)

+    {

+    }

+}

+

+static void UsageFault_Handler(void)

+{

+    while(1)

+    {

+    }

+}

+

+static void DebugMon_Handler(void)

+{

+    while(1)

+    {

+    }

+}

+

+//*****************************************************************************

+//

+// Processor ends up here if an unexpected interrupt occurs or a handler

+// is not present in the application code.

+//

+//*****************************************************************************

+static void IntDefaultHandler(void)

+{

+    //

+    // Go into an infinite loop.

+    //

+    while(1)

+    {

+    }

+}

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/main.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/main.c
new file mode 100644
index 0000000..c9aadff
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/main.c
@@ -0,0 +1,339 @@
+/*

+	FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.

+

+	This file is part of the FreeRTOS.org distribution.

+

+	FreeRTOS.org is free software; you can redistribute it and/or modify it

+	under the terms of the GNU General Public License (version 2) as published

+	by the Free Software Foundation and modified by the FreeRTOS exception.

+	**NOTE** The exception to the GPL is included to allow you to distribute a

+	combined work that includes FreeRTOS.org without being obliged to provide

+	the source code for any proprietary components.  Alternative commercial

+	license and support terms are also available upon request.  See the

+	licensing section of http://www.FreeRTOS.org for full details.

+

+	FreeRTOS.org is distributed in the hope that it will be useful,	but WITHOUT

+	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

+	FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for

+	more details.

+

+	You should have received a copy of the GNU General Public License along

+	with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59

+	Temple Place, Suite 330, Boston, MA  02111-1307  USA.

+

+

+	***************************************************************************

+	*                                                                         *

+	* Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *

+	*                                                                         *

+	* This is a concise, step by step, 'hands on' guide that describes both   *

+	* general multitasking concepts and FreeRTOS specifics. It presents and   *

+	* explains numerous examples that are written using the FreeRTOS API.     *

+	* Full source code for all the examples is provided in an accompanying    *

+	* .zip file.                                                              *

+	*                                                                         *

+	***************************************************************************

+

+	1 tab == 4 spaces!

+

+	Please ensure to read the configuration and relevant port sections of the

+	online documentation.

+

+	http://www.FreeRTOS.org - Documentation, latest information, license and

+	contact details.

+

+	http://www.SafeRTOS.com - A version that is certified for use in safety

+	critical systems.

+

+	http://www.OpenRTOS.com - Commercial support, development, porting,

+	licensing and training services.

+*/

+

+

+/*

+ * Creates all the demo application tasks, then starts the scheduler.  The WEB

+ * documentation provides more details of the standard demo application tasks

+ * (which just exist to test the kernel port and provide an example of how to use

+ * each FreeRTOS API function).

+ *

+ * In addition to the standard demo tasks, the following tasks and tests are

+ * defined and/or created within this file:

+ *

+ * "Check" hook -  This only executes fully every five seconds from the tick

+ * hook.  Its main function is to check that all the standard demo tasks are

+ * still operational.  The status can be viewed using on the Task Stats page

+ * served by the WEB server.

+ *

+ * "uIP" task -  This is the task that handles the uIP stack.  All TCP/IP

+ * processing is performed in this task.

+ */

+

+/* Standard includes. */

+#include "stdio.h"

+

+/* Scheduler includes. */

+#include "FreeRTOS.h"

+#include "task.h"

+

+/* Demo app includes. */

+#include "BlockQ.h"

+#include "integer.h"

+#include "blocktim.h"

+#include "flash.h"

+#include "partest.h"

+#include "semtest.h"

+#include "PollQ.h"

+#include "GenQTest.h"

+#include "QPeek.h"

+#include "recmutex.h"

+

+/* Red Suite includes. */

+#include "lcd_driver.h"

+#include "lcd.h"

+

+/*-----------------------------------------------------------*/

+

+/* The time between cycles of the 'check' functionality (defined within the

+tick hook. */

+#define mainCHECK_DELAY						( ( portTickType ) 5000 / portTICK_RATE_MS )

+

+/* Task priorities. */

+#define mainQUEUE_POLL_PRIORITY				( tskIDLE_PRIORITY + 2 )

+#define mainSEM_TEST_PRIORITY				( tskIDLE_PRIORITY + 1 )

+#define mainBLOCK_Q_PRIORITY				( tskIDLE_PRIORITY + 2 )

+#define mainUIP_TASK_PRIORITY				( tskIDLE_PRIORITY + 3 )

+#define mainINTEGER_TASK_PRIORITY           ( tskIDLE_PRIORITY )

+#define mainGEN_QUEUE_TASK_PRIORITY			( tskIDLE_PRIORITY )

+#define mainFLASH_TASK_PRIORITY				( tskIDLE_PRIORITY + 2 )

+

+/* The WEB server has a larger stack as it utilises stack hungry string

+handling library calls. */

+#define mainBASIC_WEB_STACK_SIZE            ( configMINIMAL_STACK_SIZE * 4 )

+

+/* The message displayed by the WEB server when all tasks are executing

+without an error being reported. */

+#define mainPASS_STATUS_MESSAGE				"All tasks are executing without error."

+

+/*-----------------------------------------------------------*/

+

+/*

+ * Configure the hardware for the demo.

+ */

+static void prvSetupHardware( void );

+

+/*

+ * The task that handles the uIP stack.  All TCP/IP processing is performed in

+ * this task.

+ */

+extern void vuIP_Task( void *pvParameters );

+

+/*

+ * Simply returns the current status message for display on served WEB pages.

+ */

+char *pcGetTaskStatusMessage( void );

+

+/*-----------------------------------------------------------*/

+

+/* Holds the status message displayed by the WEB server. */

+static char *pcStatusMessage = mainPASS_STATUS_MESSAGE;

+

+/*-----------------------------------------------------------*/

+

+int main( void )

+{

+char cIPAddress[ 16 ]; /* Enough space for "xxx.xxx.xxx.xxx\0". */

+

+	/* Configure the hardware for use by this demo. */

+	prvSetupHardware();

+

+	/* Start the standard demo tasks.  These are just here to exercise the

+	kernel port and provide examples of how the FreeRTOS API can be used. */

+	vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );

+    vCreateBlockTimeTasks();

+    vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );

+    vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );

+    vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );

+    vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );

+    vStartQueuePeekTasks();

+    vStartRecursiveMutexTasks();

+	vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );

+

+	/* Display the IP address, then create the uIP task.  The WEB server runs 

+	in this task. */

+	LCDdriver_initialisation();

+	LCD_PrintString( 5, 10, "FreeRTOS.org", 14, COLOR_GREEN);

+	sprintf( cIPAddress, "%d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );

+	LCD_PrintString( 5, 30, cIPAddress, 14, COLOR_RED);

+    xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );

+

+    /* Start the scheduler. */

+	vTaskStartScheduler();

+

+    /* Will only get here if there was insufficient memory to create the idle

+    task.  The idle task is created within vTaskStartScheduler(). */

+	for( ;; );

+}

+/*-----------------------------------------------------------*/

+

+void vApplicationTickHook( void )

+{

+static unsigned portLONG ulTicksSinceLastDisplay = 0;

+

+	/* Called from every tick interrupt as described in the comments at the top

+	of this file.

+

+	Have enough ticks passed to make it	time to perform our health status

+	check again? */

+	ulTicksSinceLastDisplay++;

+	if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )

+	{

+		/* Reset the counter so these checks run again in mainCHECK_DELAY

+		ticks time. */

+		ulTicksSinceLastDisplay = 0;

+

+		/* Has an error been found in any task? */

+		if( xAreGenericQueueTasksStillRunning() != pdTRUE )

+		{

+			pcStatusMessage = "An error has been detected in the Generic Queue test/demo.";

+		}

+		else if( xAreQueuePeekTasksStillRunning() != pdTRUE )

+		{

+			pcStatusMessage = "An error has been detected in the Peek Queue test/demo.";

+		}

+		else if( xAreBlockingQueuesStillRunning() != pdTRUE )

+		{

+			pcStatusMessage = "An error has been detected in the Block Queue test/demo.";

+		}

+		else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )

+		{

+			pcStatusMessage = "An error has been detected in the Block Time test/demo.";

+		}

+	    else if( xAreSemaphoreTasksStillRunning() != pdTRUE )

+	    {

+	        pcStatusMessage = "An error has been detected in the Semaphore test/demo.";

+	    }

+	    else if( xArePollingQueuesStillRunning() != pdTRUE )

+	    {

+	        pcStatusMessage = "An error has been detected in the Poll Queue test/demo.";

+	    }

+	    else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )

+	    {

+	        pcStatusMessage = "An error has been detected in the Int Math test/demo.";

+	    }

+	    else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )

+	    {

+	    	pcStatusMessage = "An error has been detected in the Mutex test/demo.";

+	    }

+	}

+}

+/*-----------------------------------------------------------*/

+

+char *pcGetTaskStatusMessage( void )

+{

+	/* Not bothered about a critical section here. */

+	return pcStatusMessage;

+}

+/*-----------------------------------------------------------*/

+

+void prvSetupHardware( void )

+{

+	/* Disable peripherals power. */

+	SC->PCONP = 0;

+

+	/* Enable GPIO power. */

+	SC->PCONP = PCONP_PCGPIO;

+

+	/* Disable TPIU. */

+	PINCON->PINSEL10 = 0;

+

+	/* Disconnect the main PLL. */

+	SC->PLL0CON &= ~PLLCON_PLLC;

+	SC->PLL0FEED = PLLFEED_FEED1;

+	SC->PLL0FEED = PLLFEED_FEED2;

+	while ((SC->PLL0STAT & PLLSTAT_PLLC) != 0);

+

+	/* Turn off the main PLL. */

+	SC->PLL0CON &= ~PLLCON_PLLE;

+	SC->PLL0FEED = PLLFEED_FEED1;

+	SC->PLL0FEED = PLLFEED_FEED2;

+	while ((SC->PLL0STAT & PLLSTAT_PLLE) != 0);

+

+	/* No CPU clock divider. */

+	SC->CCLKCFG = 0;

+

+	/* OSCEN. */

+	SC->SCS = 0x20;

+	while ((SC->SCS & 0x40) == 0);

+

+	/* Use main oscillator. */

+	SC->CLKSRCSEL = 1;

+	SC->PLL0CFG = (PLLCFG_MUL16 | PLLCFG_DIV1);

+

+	SC->PLL0FEED = PLLFEED_FEED1;

+	SC->PLL0FEED = PLLFEED_FEED2;

+

+	/*  Activate the PLL by turning it on then feeding the correct

+	sequence of bytes. */

+	SC->PLL0CON  = PLLCON_PLLE;

+	SC->PLL0FEED = PLLFEED_FEED1;

+	SC->PLL0FEED = PLLFEED_FEED2;

+

+	/* 6x CPU clock divider (64 MHz) */

+	SC->CCLKCFG = 5;

+

+	/*  Wait for the PLL to lock. */

+	while ((SC->PLL0STAT & PLLSTAT_PLOCK) == 0);

+

+	/*  Connect the PLL. */

+	SC->PLL0CON  = PLLCON_PLLC | PLLCON_PLLE;

+	SC->PLL0FEED = PLLFEED_FEED1;

+	SC->PLL0FEED = PLLFEED_FEED2;

+

+	/*  Setup the peripheral bus to be the same as the PLL output (64 MHz). */

+	SC->PCLKSEL0 = 0x05555555;

+

+	/* Configure the LEDs. */

+	vParTestInitialise();

+}

+/*-----------------------------------------------------------*/

+

+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName )

+{

+	/* This function will get called if a task overflows its stack. */

+

+	( void ) pxTask;

+	( void ) pcTaskName;

+

+	for( ;; );

+}

+/*-----------------------------------------------------------*/

+

+void vConfigureTimerForRunTimeStats( void )

+{

+const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;

+

+	/* This function configures a timer that is used as the time base when

+	collecting run time statistical information - basically the percentage

+	of CPU time that each task is utilising.  It is called automatically when

+	the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set

+	to 1). */

+

+	/* Power up and feed the timer. */

+	SC->PCONP |= 0x02UL;

+	SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);

+

+	/* Reset Timer 0 */

+	TIM0->TCR = TCR_COUNT_RESET;

+

+	/* Just count up. */

+	TIM0->CTCR = CTCR_CTM_TIMER;

+

+	/* Prescale to a frequency that is good enough to get a decent resolution,

+	but not too fast so as to overflow all the time. */

+	TIM0->PR =  ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;

+

+	/* Start the counter. */

+	TIM0->TCR = TCR_COUNT_ENABLE;

+}

+/*-----------------------------------------------------------*/

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/printf-stdarg.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/printf-stdarg.c
new file mode 100644
index 0000000..b5ac41b
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/printf-stdarg.c
@@ -0,0 +1,293 @@
+/*

+	Copyright 2001, 2002 Georges Menie (www.menie.org)

+	stdarg version contributed by Christian Ettinger

+

+    This program is free software; you can redistribute it and/or modify

+    it under the terms of the GNU Lesser General Public License as published by

+    the Free Software Foundation; either version 2 of the License, or

+    (at your option) any later version.

+

+    This program is distributed in the hope that it will be useful,

+    but WITHOUT ANY WARRANTY; without even the implied warranty of

+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+    GNU Lesser General Public License for more details.

+

+    You should have received a copy of the GNU Lesser General Public License

+    along with this program; if not, write to the Free Software

+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+*/

+

+/*

+	putchar is the only external dependency for this file,

+	if you have a working putchar, leave it commented out.

+	If not, uncomment the define below and

+	replace outbyte(c) by your own function call.

+

+*/

+

+#define putchar(c) c

+

+#include <stdarg.h>

+

+static void printchar(char **str, int c)

+{

+	//extern int putchar(int c);

+	

+	if (str) {

+		**str = (char)c;

+		++(*str);

+	}

+	else

+	{ 

+		(void)putchar(c);

+	}

+}

+

+#define PAD_RIGHT 1

+#define PAD_ZERO 2

+

+static int prints(char **out, const char *string, int width, int pad)

+{

+	register int pc = 0, padchar = ' ';

+

+	if (width > 0) {

+		register int len = 0;

+		register const char *ptr;

+		for (ptr = string; *ptr; ++ptr) ++len;

+		if (len >= width) width = 0;

+		else width -= len;

+		if (pad & PAD_ZERO) padchar = '0';

+	}

+	if (!(pad & PAD_RIGHT)) {

+		for ( ; width > 0; --width) {

+			printchar (out, padchar);

+			++pc;

+		}

+	}

+	for ( ; *string ; ++string) {

+		printchar (out, *string);

+		++pc;

+	}

+	for ( ; width > 0; --width) {

+		printchar (out, padchar);

+		++pc;

+	}

+

+	return pc;

+}

+

+/* the following should be enough for 32 bit int */

+#define PRINT_BUF_LEN 12

+

+static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)

+{

+	char print_buf[PRINT_BUF_LEN];

+	register char *s;

+	register int t, neg = 0, pc = 0;

+	register unsigned int u = (unsigned int)i;

+

+	if (i == 0) {

+		print_buf[0] = '0';

+		print_buf[1] = '\0';

+		return prints (out, print_buf, width, pad);

+	}

+

+	if (sg && b == 10 && i < 0) {

+		neg = 1;

+		u = (unsigned int)-i;

+	}

+

+	s = print_buf + PRINT_BUF_LEN-1;

+	*s = '\0';

+

+	while (u) {

+		t = (unsigned int)u % b;

+		if( t >= 10 )

+			t += letbase - '0' - 10;

+		*--s = (char)(t + '0');

+		u /= b;

+	}

+

+	if (neg) {

+		if( width && (pad & PAD_ZERO) ) {

+			printchar (out, '-');

+			++pc;

+			--width;

+		}

+		else {

+			*--s = '-';

+		}

+	}

+

+	return pc + prints (out, s, width, pad);

+}

+

+static int print( char **out, const char *format, va_list args )

+{

+	register int width, pad;

+	register int pc = 0;

+	char scr[2];

+

+	for (; *format != 0; ++format) {

+		if (*format == '%') {

+			++format;

+			width = pad = 0;

+			if (*format == '\0') break;

+			if (*format == '%') goto out;

+			if (*format == '-') {

+				++format;

+				pad = PAD_RIGHT;

+			}

+			while (*format == '0') {

+				++format;

+				pad |= PAD_ZERO;

+			}

+			for ( ; *format >= '0' && *format <= '9'; ++format) {

+				width *= 10;

+				width += *format - '0';

+			}

+			if( *format == 's' ) {

+				register char *s = (char *)va_arg( args, int );

+				pc += prints (out, s?s:"(null)", width, pad);

+				continue;

+			}

+			if( *format == 'd' ) {

+				pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');

+				continue;

+			}

+			if( *format == 'x' ) {

+				pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');

+				continue;

+			}

+			if( *format == 'X' ) {

+				pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');

+				continue;

+			}

+			if( *format == 'u' ) {

+				pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');

+				continue;

+			}

+			if( *format == 'c' ) {

+				/* char are converted to int then pushed on the stack */

+				scr[0] = (char)va_arg( args, int );

+				scr[1] = '\0';

+				pc += prints (out, scr, width, pad);

+				continue;

+			}

+		}

+		else {

+		out:

+			printchar (out, *format);

+			++pc;

+		}

+	}

+	if (out) **out = '\0';

+	va_end( args );

+	return pc;

+}

+

+int printf(const char *format, ...)

+{

+        va_list args;

+        

+        va_start( args, format );

+        return print( 0, format, args );

+}

+

+int sprintf(char *out, const char *format, ...)

+{

+        va_list args;

+        

+        va_start( args, format );

+        return print( &out, format, args );

+}

+

+

+int snprintf( char *buf, unsigned int count, const char *format, ... )

+{

+        va_list args;

+        

+        ( void ) count;

+        

+        va_start( args, format );

+        return print( &buf, format, args );

+}

+

+

+#ifdef TEST_PRINTF

+int main(void)

+{

+	char *ptr = "Hello world!";

+	char *np = 0;

+	int i = 5;

+	unsigned int bs = sizeof(int)*8;

+	int mi;

+	char buf[80];

+

+	mi = (1 << (bs-1)) + 1;

+	printf("%s\n", ptr);

+	printf("printf test\n");

+	printf("%s is null pointer\n", np);

+	printf("%d = 5\n", i);

+	printf("%d = - max int\n", mi);

+	printf("char %c = 'a'\n", 'a');

+	printf("hex %x = ff\n", 0xff);

+	printf("hex %02x = 00\n", 0);

+	printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);

+	printf("%d %s(s)%", 0, "message");

+	printf("\n");

+	printf("%d %s(s) with %%\n", 0, "message");

+	sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);

+	sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);

+	sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);

+	sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);

+	sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);

+	sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);

+	sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);

+	sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);

+

+	return 0;

+}

+

+/*

+ * if you compile this file with

+ *   gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c

+ * you will get a normal warning:

+ *   printf.c:214: warning: spurious trailing `%' in format

+ * this line is testing an invalid % at the end of the format string.

+ *

+ * this should display (on 32bit int machine) :

+ *

+ * Hello world!

+ * printf test

+ * (null) is null pointer

+ * 5 = 5

+ * -2147483647 = - max int

+ * char a = 'a'

+ * hex ff = ff

+ * hex 00 = 00

+ * signed -3 = unsigned 4294967293 = hex fffffffd

+ * 0 message(s)

+ * 0 message(s) with %

+ * justif: "left      "

+ * justif: "     right"

+ *  3: 0003 zero padded

+ *  3: 3    left justif.

+ *  3:    3 right justif.

+ * -3: -003 zero padded

+ * -3: -3   left justif.

+ * -3:   -3 right justif.

+ */

+

+#endif

+

+

+/* To keep linker happy. */

+int	write( int i, char* c, int n)

+{

+	(void)i;

+	(void)n;

+	(void)c;

+	return 0;

+}

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug.ld b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug.ld
new file mode 100644
index 0000000..b05cf72
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug.ld
@@ -0,0 +1,78 @@
+/*

+ * GENERATED FILE - DO NOT EDIT

+ * (C) Code Red Technologies Ltd, 2008-9    

+ * Generated C linker script file for LPC1768 

+ * (created from nxp_lpc13_c.ld (v2.0.11 (200907061347)) on Thu Jul 09 12:44:31 BST 2009)

+*/

+

+INCLUDE "rtosdemo_rdb1768_Debug_lib.ld "
+INCLUDE "rtosdemo_rdb1768_Debug_mem.ld "

+

+ENTRY(ResetISR)

+

+SECTIONS

+{

+	.text :

+	{

+		KEEP(*(.isr_vector))

+		*(.text*)

+		*(.rodata*)

+

+	} > FLASH

+

+

+	/* for exception handling/unwind - some Newlib functions (in common with C++ and STDC++) use this. */

+	

+	.ARM.extab : 

+	{

+		*(.ARM.extab* .gnu.linkonce.armextab.*)

+	} > FLASH

+

+	__exidx_start = .;

+	.ARM.exidx :

+	{

+		*(.ARM.exidx* .gnu.linkonce.armexidx.*)

+	} > FLASH

+	__exidx_end = .;

+

+	_etext = .;

+		

+	.data : AT (__exidx_end)

+	{

+		_data = .;

+		*(vtable)

+		*(.data*)

+		_edata = .;

+	} > SRAM

+

+	/* zero initialized data */

+	.bss :

+	{

+		_bss = .;

+		*(.bss*)

+		*(COMMON)

+		_ebss = .;

+	} > SRAM

+	

+	/* Where we put the heap with cr_clib */

+	.cr_heap :

+	{

+		end = .;

+		_pvHeapStart = .;

+	} > SRAM

+

+/*

+	Note: (ref: M0000066)

+	Moving the stack down by 16 is to work around a GDB bug.

+	This space can be reclaimed for Production Builds.

+*/	

+	_vStackTop = _vRamTop - 16;

+	

+	.ETHRAM :

+	{

+	} > AHBRAM0

+	

+	.USBRAM :

+	{

+	} > AHBRAM1

+}

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug_lib.ld b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug_lib.ld
new file mode 100644
index 0000000..aa6d699
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug_lib.ld
@@ -0,0 +1,8 @@
+/*

+ * GENERATED FILE - DO NOT EDIT

+ * (C) Code Red Technologies Ltd, 2008-9

+ * Generated linker script library include file for Newlib (none) 

+ * (created from newlib_none_c.ld (v2.0.11 (200907061347)) on Thu Jul 09 13:02:36 BST 2009)

+*/

+

+GROUP(libgcc.a libc.a)

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug_mem.ld b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug_mem.ld
new file mode 100644
index 0000000..7c9bf63
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/rtosdemo_rdb1768_Debug_mem.ld
@@ -0,0 +1,16 @@
+/*

+ * GENERATED FILE - DO NOT EDIT

+ * (C) Code Red Technologies Ltd, 2008-9

+ * Generated linker script include file for 

+ * (created from LinkMemoryTemplate (v2.0.11 (200907061347)) on Thu Jul 09 12:44:31 BST 2009)

+*/

+

+MEMORY

+{

+     FLASH (rx) : ORIGIN = 0x0 LENGTH = 0x80000

+     SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000

+	 AHBSRAM0   : ORIGIN = 0x2007c000, LENGTH = 0x4000

+	 AHBSRAM1   : ORIGIN = 0x20080000, LENGTH = 0x4000

+}

+

+_vRamTop = 0x10000000 + 0x8000;

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/syscalls.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/syscalls.c
new file mode 100644
index 0000000..3053cfa
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/syscalls.c
@@ -0,0 +1,82 @@
+/* Don't need anything here. */
+
+#include <stdlib.h>
+#include <sys/stat.h>
+
+int _read_r (struct _reent *r, int file, char * ptr, int len)
+{
+	( void ) r;
+	( void ) file;
+	( void ) ptr;
+	( void ) len;
+	return -1;
+}
+
+/***************************************************************************/
+
+int _lseek_r (struct _reent *r, int file, int ptr, int dir)
+{
+	( void ) r;
+	( void ) file;
+	( void ) ptr;
+	( void ) dir;
+	
+	return 0;
+}
+
+/***************************************************************************/
+
+int _write_r (struct _reent *r, int file, char * ptr, int len)
+{  
+	( void ) r;
+	( void ) file;
+	( void ) ptr;
+	( void ) len;
+	
+	return 0;
+}
+
+/***************************************************************************/
+
+int _close_r (struct _reent *r, int file)
+{
+	( void ) r;
+	( void ) file;
+
+	return 0;
+}
+
+/***************************************************************************/
+
+caddr_t _sbrk_r (struct _reent *r, int incr)
+{
+	( void ) r;
+	( void ) incr;
+	
+	return 0;
+}
+
+/***************************************************************************/
+
+int _fstat_r (struct _reent *r, int file, struct stat * st)
+{
+	( void ) r;
+	( void ) file;
+	( void ) st;
+	
+	return 0;
+}
+
+/***************************************************************************/
+
+int _isatty_r(struct _reent *r, int fd)
+{
+	( void ) r;
+	( void ) fd;
+	
+	return 0;
+}
+
+
+
+
diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/system_LPC17xx.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/system_LPC17xx.h
new file mode 100644
index 0000000..a5c9727
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/system_LPC17xx.h
@@ -0,0 +1,40 @@
+/******************************************************************************

+ * @file:    system_LPC17xx.h

+ * @purpose: CMSIS Cortex-M3 Device Peripheral Access Layer Header File

+ *           for the NXP LPC17xx Device Series 

+ * @version: V1.0

+ * @date:    25. Nov. 2008

+ *----------------------------------------------------------------------------

+ *

+ * Copyright (C) 2008 ARM Limited. All rights reserved.

+ *

+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3 

+ * processor based microcontrollers.  This file can be freely distributed 

+ * within development tools that are supporting such ARM based processors. 

+ *

+ * 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.

+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR

+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

+ *

+ ******************************************************************************/

+

+

+#ifndef __SYSTEM_LPC17xx_H

+#define __SYSTEM_LPC17xx_H

+

+extern uint32_t SystemFrequency;    /*!< System Clock Frequency (Core Clock)  */

+

+

+/**

+ * Initialize the system

+ *

+ * @param  none

+ * @return none

+ *

+ * @brief  Setup the microcontroller system.

+ *         Initialize the System and update the SystemFrequency variable.

+ */

+extern void SystemInit (void);

+#endif

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/EthDev.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/EthDev.h
new file mode 100644
index 0000000..f67789f
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/EthDev.h
@@ -0,0 +1,111 @@
+/*

+ * @file:    EthDev.h

+ * @purpose: Ethernet Device Definitions

+ * @version: V1.10

+ * @date:    24. Feb. 2009

+ *----------------------------------------------------------------------------

+ *

+ * Copyright (C) 2009 ARM Limited. All rights reserved.

+ *

+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3

+ * processor based microcontrollers.  This file can be freely distributed

+ * within development tools that are supporting such ARM based processors.

+ *

+ * 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.

+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR

+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

+ *

+ */

+

+#ifndef _ETHDEV__H

+#define _ETHDEV__H

+

+#ifndef NULL

+ #define NULL   0

+#endif

+

+/*----------------------------------------------------------------------------

+  Ethernet Device Defines

+ *----------------------------------------------------------------------------*/

+#define EthDev_ADDR_SIZE        6                      /*!< Ethernet Address size in bytes */

+#define EthDev_MTU_SIZE         1514                   /*!< Maximum Transmission Unit      */

+

+

+/*----------------------------------------------------------------------------

+  Ethernet Device Configuration and Control Command Defines

+ *----------------------------------------------------------------------------*/

+typedef enum {

+  EthDev_LINK_DOWN              = 0,                   /*!< Ethernet link not established */

+  EthDev_LINK_UP                = 1,                   /*!< Ethernet link established */

+} EthDev_LINK;

+

+typedef enum {

+  EthDev_SPEED_10M              = 0,                   /*!< 10.0 Mbps link speed  */

+  EthDev_SPEED_100M             = 1,                   /*!< 100.0 Mbps link speed */

+  EthDev_SPEED_1000M            = 2,                   /*!< 1.0 Gbps link speed   */

+} EthDev_SPEED;

+

+typedef enum {

+  EthDev_DUPLEX_HALF            = 0,                   /*!< Link half duplex */

+  EthDev_DUPLEX_FULL            = 1,                   /*!< Link full duplex */

+} EthDev_DUPLEX;

+

+typedef enum {

+  EthDev_MODE_AUTO              = 0,

+  EthDev_MODE_10M_FULL          = 1,

+  EthDev_MODE_10M_HALF          = 2,

+  EthDev_MODE_100M_FULL         = 3,

+  EthDev_MODE_100M_HALF         = 4,

+  EthDev_MODE_1000M_FULL        = 5,

+  EthDev_MODE_1000M_HALF        = 6,

+} EthDev_MODE;

+

+typedef struct {

+  EthDev_LINK   Link   : 1;

+  EthDev_DUPLEX Duplex : 1;

+  EthDev_SPEED  Speed  : 2;

+} EthDev_STATUS;

+

+

+/*----------------------------------------------------------------------------

+  Ethernet Device IO Block Structure

+ *----------------------------------------------------------------------------*/

+typedef struct {

+

+   /* Initialized by the user application before call to Init. */

+   EthDev_MODE   Mode;

+   unsigned char HwAddr[EthDev_ADDR_SIZE];

+   void         *(*RxFrame)      (int size);

+   void          (*RxFrameReady) (int size);

+

+   /* Initialized by Ethernet driver. */

+   int           (*Init)       (void);

+   int           (*UnInit)     (void);

+   int           (*SetMCFilter)(int NumHwAddr, unsigned char *pHwAddr);

+   int           (*TxFrame)    (void *pData, int size);

+   void          (*Lock)       (void);

+   void          (*UnLock)     (void);

+   EthDev_STATUS (*LinkChk)    (void);

+} EthDev_IOB;

+

+

+/*

+ * Look for received data.  If data is found then uip_buf is assigned to the

+ * new data and the length of the data is returned.  If no data is found then

+ * uip_buf is not updated and 0 is returned.

+ */

+unsigned long 	ulGetEMACRxData( void );

+

+/*

+ * Send usTxDataLen bytes from uip_buf.

+ */

+void vSendEMACTxData( unsigned short usTxDataLen );

+

+/*

+ * Prepare the Ethernet hardware ready for TCP/IP comms.

+ */

+long lEMACInit(void);

+

+#endif

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/EthDev_LPC17xx.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/EthDev_LPC17xx.h
new file mode 100644
index 0000000..9313443
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/EthDev_LPC17xx.h
@@ -0,0 +1,331 @@
+/*

+ * @file:    EthDev_LPC17xx.h

+ * @purpose: Ethernet Device Definitions for NXP LPC17xx

+ * @version: V0.01

+ * @date:    14. May 2009

+ *----------------------------------------------------------------------------

+ *

+ * Copyright (C) 2009 ARM Limited. All rights reserved.

+ *

+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3

+ * processor based microcontrollers.  This file can be freely distributed

+ * within development tools that are supporting such ARM based processors.

+ *

+ * 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.

+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR

+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

+ *

+ */

+

+#ifndef __ETHDEV_LPC17XX_H

+#define __ETHDEV_LPC17XX_H

+

+#include <stdint.h>

+

+/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */

+#define NUM_RX_FRAG         3           /* Num.of RX Fragments. */

+#define NUM_TX_FRAG         2           /* Num.of TX Fragments. */

+#define ETH_FRAG_SIZE       1536        /* Packet Fragment size 1536 Bytes   */

+

+#define ETH_MAX_FLEN        1536        /* Max. Ethernet Frame Size          */

+

+typedef struct {                        /* RX Descriptor struct              */

+   uint32_t Packet;

+   uint32_t Ctrl;

+} RX_DESC_TypeDef;

+

+typedef struct {                        /* RX Status struct                  */

+   uint32_t Info;

+   uint32_t HashCRC;

+} RX_STAT_TypeDef;

+

+typedef struct {                        /* TX Descriptor struct              */

+   uint32_t Packet;

+   uint32_t Ctrl;

+} TX_DESC_TypeDef;

+

+typedef struct {                        /* TX Status struct                  */

+   uint32_t Info;

+} TX_STAT_TypeDef;

+

+

+/* EMAC variables located in AHB SRAM bank 1*/

+#define AHB_SRAM_BANK1_BASE  0x2007c000UL

+#define RX_DESC_BASE        (AHB_SRAM_BANK1_BASE         )

+#define RX_STAT_BASE        (RX_DESC_BASE + NUM_RX_FRAG*(2*4))     /* 2 * uint32_t, see RX_DESC_TypeDef */

+#define TX_DESC_BASE        (RX_STAT_BASE + NUM_RX_FRAG*(2*4))     /* 2 * uint32_t, see RX_STAT_TypeDef */

+#define TX_STAT_BASE        (TX_DESC_BASE + NUM_TX_FRAG*(2*4))     /* 2 * uint32_t, see TX_DESC_TypeDef */

+#define ETH_BUF_BASE		(TX_STAT_BASE + NUM_TX_FRAG*(1*4))     /* 1 * uint32_t, see TX_STAT_TypeDef */

+

+/* 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 ETH_BUF(i)          ( ETH_BUF_BASE + ETH_FRAG_SIZE*i )

+#define ETH_NUM_BUFFERS		( NUM_TX_FRAG + NUM_RX_FRAG + 1 ) /* There are in fact 2 more buffers than descriptors as the two Tx descriptors use the same buffer to speed up the uip Tx. */

+

+

+/* 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   */

+#define SUPP_RES_RMII       0x00000800  /* Reset Reduced MII Logic           */

+

+/* 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        0x0000003C  /* 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 PHY_AUTO_NEG_COMPLETE 0x0020	/* Auto negotiation have finished.   */

+

+#define DP83848C_DEF_ADR    0x0100      /* Default PHY device address        */

+#define DP83848C_ID         0x20005C90  /* PHY Identifier                    */

+

+#endif

+

+/*----------------------------------------------------------------------------

+ * end of file

+ *---------------------------------------------------------------------------*/

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/clock-arch.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/clock-arch.h
new file mode 100644
index 0000000..cde657b
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/clock-arch.h
@@ -0,0 +1,42 @@
+/*

+ * Copyright (c) 2006, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $

+ */

+

+#ifndef __CLOCK_ARCH_H__

+#define __CLOCK_ARCH_H__

+

+#include "FreeRTOS.h"

+

+typedef unsigned long clock_time_t;

+#define CLOCK_CONF_SECOND configTICK_RATE_HZ

+

+#endif /* __CLOCK_ARCH_H__ */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/clock.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/clock.h
new file mode 100644
index 0000000..dae6874
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/clock.h
@@ -0,0 +1,88 @@
+/**

+ * \defgroup clock Clock interface

+ *

+ * The clock interface is the interface between the \ref timer "timer library"

+ * and the platform specific clock functionality. The clock

+ * interface must be implemented for each platform that uses the \ref

+ * timer "timer library".

+ *

+ * The clock interface does only one this: it measures time. The clock

+ * interface provides a macro, CLOCK_SECOND, which corresponds to one

+ * second of system time.

+ *

+ * \sa \ref timer "Timer library"

+ *

+ * @{

+ */

+

+/*

+ * Copyright (c) 2004, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $

+ */

+#ifndef __CLOCK_H__

+#define __CLOCK_H__

+

+#include "clock-arch.h"

+

+/**

+ * Initialize the clock library.

+ *

+ * This function initializes the clock library and should be called

+ * from the main() function of the system.

+ *

+ */

+void clock_init(void);

+

+/**

+ * Get the current clock time.

+ *

+ * This function returns the current system clock time.

+ *

+ * \return The current clock time, measured in system ticks.

+ */

+clock_time_t clock_time(void);

+

+/**

+ * A second, measured in system clock time.

+ *

+ * \hideinitializer

+ */

+#ifdef CLOCK_CONF_SECOND

+#define CLOCK_SECOND CLOCK_CONF_SECOND

+#else

+#define CLOCK_SECOND (clock_time_t)32

+#endif

+

+#endif /* __CLOCK_H__ */

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/emac.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/emac.c
new file mode 100644
index 0000000..768c8d4
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/emac.c
@@ -0,0 +1,602 @@
+/*

+	FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.

+

+	This file is part of the FreeRTOS.org distribution.

+

+	FreeRTOS.org is free software; you can redistribute it and/or modify it

+	under the terms of the GNU General Public License (version 2) as published

+	by the Free Software Foundation and modified by the FreeRTOS exception.

+	**NOTE** The exception to the GPL is included to allow you to distribute a

+	combined work that includes FreeRTOS.org without being obliged to provide

+	the source code for any proprietary components.  Alternative commercial

+	license and support terms are also available upon request.  See the

+	licensing section of http://www.FreeRTOS.org for full details.

+

+	FreeRTOS.org is distributed in the hope that it will be useful,	but WITHOUT

+	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

+	FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for

+	more details.

+

+	You should have received a copy of the GNU General Public License along

+	with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59

+	Temple Place, Suite 330, Boston, MA  02111-1307  USA.

+

+

+	***************************************************************************

+	*                                                                         *

+	* Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *

+	*                                                                         *

+	* This is a concise, step by step, 'hands on' guide that describes both   *

+	* general multitasking concepts and FreeRTOS specifics. It presents and   *

+	* explains numerous examples that are written using the FreeRTOS API.     *

+	* Full source code for all the examples is provided in an accompanying    *

+	* .zip file.                                                              *

+	*                                                                         *

+	***************************************************************************

+

+	1 tab == 4 spaces!

+

+	Please ensure to read the configuration and relevant port sections of the

+	online documentation.

+

+	http://www.FreeRTOS.org - Documentation, latest information, license and

+	contact details.

+

+	http://www.SafeRTOS.com - A version that is certified for use in safety

+	critical systems.

+

+	http://www.OpenRTOS.com - Commercial support, development, porting,

+	licensing and training services.

+*/

+

+/* Originally adapted from file written by Andreas Dannenberg.  Supplied with permission. */

+

+/* Kernel includes. */

+#include "FreeRTOS.h"

+#include "task.h"

+#include "semphr.h"

+

+/* Hardware specific includes. */

+#include "EthDev_LPC17xx.h"

+

+/* Time to wait between each inspection of the link status. */

+#define emacWAIT_FOR_LINK_TO_ESTABLISH ( 500 / portTICK_RATE_MS )

+

+/* Short delay used in several places during the initialisation process. */

+#define emacSHORT_DELAY				   ( 2 )

+

+/* Hardware specific bit definitions. */

+#define emacLINK_ESTABLISHED		( 0x0001 )

+#define emacFULL_DUPLEX_ENABLED		( 0x0004 )

+#define emac10BASE_T_MODE			( 0x0002 )

+#define emacPINSEL2_VALUE 0x50150105

+

+/* If no buffers are available, then wait this long before looking again.... */

+#define emacBUFFER_WAIT_DELAY	( 3 / portTICK_RATE_MS )

+

+/* ...and don't look more than this many times. */

+#define emacBUFFER_WAIT_ATTEMPTS	( 30 )

+

+/* Index to the Tx descriptor that is always used first for every Tx.  The second

+descriptor is then used to re-send in order to speed up the uIP Tx process. */

+#define emacTX_DESC_INDEX			( 0 )

+

+/*-----------------------------------------------------------*/

+

+/*

+ * Configure both the Rx and Tx descriptors during the init process.

+ */

+static void prvInitDescriptors( void );

+

+/*

+ * Setup the IO and peripherals required for Ethernet communication.

+ */

+static void prvSetupEMACHardware( void );

+

+/*

+ * Control the auto negotiate process.

+ */

+static void prvConfigurePHY( void );

+

+/*

+ * Wait for a link to be established, then setup the PHY according to the link

+ * parameters.

+ */

+static long prvSetupLinkStatus( void );

+

+/*

+ * Search the pool of buffers to find one that is free.  If a buffer is found

+ * mark it as in use before returning its address.

+ */

+static unsigned char *prvGetNextBuffer( void );

+

+/*

+ * Return an allocated buffer to the pool of free buffers.

+ */

+static void prvReturnBuffer( unsigned char *pucBuffer );

+

+/*

+ * Send lValue to the lPhyReg within the PHY.

+ */

+static long prvWritePHY( long lPhyReg, long lValue );

+

+/*

+ * Read a value from ucPhyReg within the PHY.  *plStatus will be set to

+ * pdFALSE if there is an error.

+ */

+static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus );

+

+/*-----------------------------------------------------------*/

+

+/* The semaphore used to wake the uIP task when data arrives. */

+extern xSemaphoreHandle xEMACSemaphore;

+

+/* Each ucBufferInUse index corresponds to a position in the pool of buffers.

+If the index contains a 1 then the buffer within pool is in use, if it

+contains a 0 then the buffer is free. */

+static unsigned char ucBufferInUse[ ETH_NUM_BUFFERS ] = { pdFALSE };

+

+/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers

+allocated within this file. */

+unsigned char * uip_buf;

+

+/* Store the length of the data being sent so the data can be sent twice.  The

+value will be set back to 0 once the data has been sent twice. */

+static unsigned short usSendLen = 0;

+

+/*-----------------------------------------------------------*/

+

+long lEMACInit( void )

+{

+long lReturn = pdPASS;

+unsigned long ulID1, ulID2;

+

+	/* Reset peripherals, configure port pins and registers. */

+	prvSetupEMACHardware();

+

+	/* Check the PHY part number is as expected. */

+	ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn );

+	ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn );

+	if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) == DP83848C_ID )

+	{

+		/* Set the Ethernet MAC Address registers */

+		EMAC->SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1;

+		EMAC->SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3;

+		EMAC->SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5;

+

+		/* Initialize Tx and Rx DMA Descriptors */

+		prvInitDescriptors();

+

+		/* Receive broadcast and perfect match packets */

+		EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;

+

+		/* Setup the PHY. */

+		prvConfigurePHY();

+	}

+	else

+	{

+		lReturn = pdFAIL;

+	}

+

+	/* Check the link status. */

+	if( lReturn == pdPASS )

+	{

+		lReturn = prvSetupLinkStatus();

+	}

+

+	if( lReturn == pdPASS )

+	{

+		/* Initialise uip_buf to ensure it points somewhere valid. */

+		uip_buf = prvGetNextBuffer();

+

+		/* Reset all interrupts */

+		EMAC->IntClear = ( INT_RX_OVERRUN | INT_RX_ERR | INT_RX_FIN | INT_RX_DONE | INT_TX_UNDERRUN | INT_TX_ERR | INT_TX_FIN | INT_TX_DONE | INT_SOFT_INT | INT_WAKEUP );

+

+		/* Enable receive and transmit mode of MAC Ethernet core */

+		EMAC->Command |= ( CR_RX_EN | CR_TX_EN );

+		EMAC->MAC1 |= MAC1_REC_EN;

+	}

+

+	return lReturn;

+}

+/*-----------------------------------------------------------*/

+

+static unsigned char *prvGetNextBuffer( void )

+{

+long x;

+unsigned char *pucReturn = NULL;

+unsigned long ulAttempts = 0;

+

+	while( pucReturn == NULL )

+	{

+		/* Look through the buffers to find one that is not in use by

+		anything else. */

+		for( x = 0; x < ETH_NUM_BUFFERS; x++ )

+		{

+			if( ucBufferInUse[ x ] == pdFALSE )

+			{

+				ucBufferInUse[ x ] = pdTRUE;

+				pucReturn = ( unsigned char * ) ETH_BUF( x );

+				break;

+			}

+		}

+

+		/* Was a buffer found? */

+		if( pucReturn == NULL )

+		{

+			ulAttempts++;

+

+			if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )

+			{

+				break;

+			}

+

+			/* Wait then look again. */

+			vTaskDelay( emacBUFFER_WAIT_DELAY );

+		}

+	}

+

+	return pucReturn;

+}

+/*-----------------------------------------------------------*/

+

+static void prvInitDescriptors( void )

+{

+long x, lNextBuffer = 0;

+

+	for( x = 0; x < NUM_RX_FRAG; x++ )

+	{

+		/* Allocate the next Ethernet buffer to this descriptor. */

+		RX_DESC_PACKET( x ) = ETH_BUF( lNextBuffer );

+		RX_DESC_CTRL( x ) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );

+		RX_STAT_INFO( x ) = 0;

+		RX_STAT_HASHCRC( x ) = 0;

+

+		/* The Ethernet buffer is now in use. */

+		ucBufferInUse[ lNextBuffer ] = pdTRUE;

+		lNextBuffer++;

+	}

+

+	/* Set EMAC Receive Descriptor Registers. */

+	EMAC->RxDescriptor = RX_DESC_BASE;

+	EMAC->RxStatus = RX_STAT_BASE;

+	EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1;

+

+	/* Rx Descriptors Point to 0 */

+	EMAC->RxConsumeIndex = 0;

+

+	/* A buffer is not allocated to the Tx descriptors until they are actually

+	used. */

+	for( x = 0; x < NUM_TX_FRAG; x++ )

+	{

+		TX_DESC_PACKET( x ) = ( unsigned long ) NULL;

+		TX_DESC_CTRL( x ) = 0;

+		TX_STAT_INFO( x ) = 0;

+	}

+

+	/* Set EMAC Transmit Descriptor Registers. */

+	EMAC->TxDescriptor = TX_DESC_BASE;

+	EMAC->TxStatus = TX_STAT_BASE;

+	EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1;

+

+	/* Tx Descriptors Point to 0 */

+	EMAC->TxProduceIndex = 0;

+}

+/*-----------------------------------------------------------*/

+

+static void prvSetupEMACHardware( void )

+{

+unsigned short us;

+long x, lDummy;

+

+	/* Enable P1 Ethernet Pins. */

+	PINCON->PINSEL2 = emacPINSEL2_VALUE;

+	PINCON->PINSEL3 = ( PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005;

+

+	/* Power Up the EMAC controller. */

+	SC->PCONP |= PCONP_PCENET;

+	vTaskDelay( emacSHORT_DELAY );

+

+	/* Reset all EMAC internal modules. */

+	EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;

+	EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;

+

+	/* A short delay after reset. */

+	vTaskDelay( emacSHORT_DELAY );

+

+	/* Initialize MAC control registers. */

+	EMAC->MAC1 = MAC1_PASS_ALL;

+	EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;

+	EMAC->MAXF = ETH_MAX_FLEN;

+	EMAC->CLRT = CLRT_DEF;

+	EMAC->IPGR = IPGR_DEF;

+

+	/* Enable Reduced MII interface. */

+	EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;

+

+	/* Reset Reduced MII Logic. */

+	EMAC->SUPP = SUPP_RES_RMII;

+	vTaskDelay( emacSHORT_DELAY );

+	EMAC->SUPP = 0;

+

+	/* Put the PHY in reset mode */

+	prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );

+	prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );

+

+	/* Wait for hardware reset to end. */

+	for( x = 0; x < 100; x++ )

+	{

+		vTaskDelay( emacSHORT_DELAY * 5 );

+		us = prvReadPHY( PHY_REG_BMCR, &lDummy );

+		if( !( us & MCFG_RES_MII ) )

+		{

+			/* Reset complete */

+			break;

+		}

+	}

+}

+/*-----------------------------------------------------------*/

+

+static void prvConfigurePHY( void )

+{

+unsigned short us;

+long x, lDummy;

+

+	/* Auto negotiate the configuration. */

+	if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) )

+	{

+		vTaskDelay( emacSHORT_DELAY * 5 );

+

+		for( x = 0; x < 10; x++ )

+		{

+			us = prvReadPHY( PHY_REG_BMSR, &lDummy );

+

+			if( us & PHY_AUTO_NEG_COMPLETE )

+			{

+				break;

+			}

+

+			vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );

+		}

+	}

+}

+/*-----------------------------------------------------------*/

+

+static long prvSetupLinkStatus( void )

+{

+long lReturn = pdFAIL, x;

+unsigned short usLinkStatus;

+

+	/* Wait with timeout for the link to be established. */

+	for( x = 0; x < 10; x++ )

+	{

+		usLinkStatus = prvReadPHY( PHY_REG_STS, &lReturn );

+		if( usLinkStatus & emacLINK_ESTABLISHED )

+		{

+			/* Link is established. */

+			lReturn = pdPASS;

+			break;

+		}

+

+        vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );

+	}

+

+	if( lReturn == pdPASS )

+	{

+		/* Configure Full/Half Duplex mode. */

+		if( usLinkStatus & emacFULL_DUPLEX_ENABLED )

+		{

+			/* Full duplex is enabled. */

+			EMAC->MAC2 |= MAC2_FULL_DUP;

+			EMAC->Command |= CR_FULL_DUP;

+			EMAC->IPGT = IPGT_FULL_DUP;

+		}

+		else

+		{

+			/* Half duplex mode. */

+			EMAC->IPGT = IPGT_HALF_DUP;

+		}

+

+		/* Configure 100MBit/10MBit mode. */

+		if( usLinkStatus & emac10BASE_T_MODE )

+		{

+			/* 10MBit mode. */

+			EMAC->SUPP = 0;

+		}

+		else

+		{

+			/* 100MBit mode. */

+			EMAC->SUPP = SUPP_SPEED;

+		}

+	}

+

+	return lReturn;

+}

+/*-----------------------------------------------------------*/

+

+static void prvReturnBuffer( unsigned char *pucBuffer )

+{

+unsigned long ul;

+

+	/* Return a buffer to the pool of free buffers. */

+	for( ul = 0; ul < ETH_NUM_BUFFERS; ul++ )

+	{

+		if( ETH_BUF( ul ) == ( unsigned long ) pucBuffer )

+		{

+			ucBufferInUse[ ul ] = pdFALSE;

+			break;

+		}

+	}

+}

+/*-----------------------------------------------------------*/

+

+unsigned long ulGetEMACRxData( void )

+{

+unsigned long ulLen = 0;

+long lIndex;

+

+	if( EMAC->RxProduceIndex != EMAC->RxConsumeIndex )

+	{

+		/* Mark the current buffer as free as uip_buf is going to be set to

+		the buffer that contains the received data. */

+		prvReturnBuffer( uip_buf );

+

+		ulLen = ( RX_STAT_INFO( EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3;

+		uip_buf = ( unsigned char * ) RX_DESC_PACKET( EMAC->RxConsumeIndex );

+

+		/* Allocate a new buffer to the descriptor. */

+        RX_DESC_PACKET( EMAC->RxConsumeIndex ) = ( unsigned long ) prvGetNextBuffer();

+

+		/* Move the consume index onto the next position, ensuring it wraps to

+		the beginning at the appropriate place. */

+		lIndex = EMAC->RxConsumeIndex;

+

+		lIndex++;

+		if( lIndex >= NUM_RX_FRAG )

+		{

+			lIndex = 0;

+		}

+

+		EMAC->RxConsumeIndex = lIndex;

+	}

+

+	return ulLen;

+}

+/*-----------------------------------------------------------*/

+

+void vSendEMACTxData( unsigned short usTxDataLen )

+{

+unsigned long ulAttempts = 0UL;

+

+	/* Check to see if the Tx descriptor is free, indicated by its buffer being

+	NULL. */

+	while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL )

+	{

+		/* Wait for the Tx descriptor to become available. */

+		vTaskDelay( emacBUFFER_WAIT_DELAY );

+

+		ulAttempts++;

+		if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS )

+		{

+			/* Something has gone wrong as the Tx descriptor is still in use.

+			Clear it down manually, the data it was sending will probably be

+			lost. */

+			prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );

+			break;

+		}

+	}

+

+	/* Setup the Tx descriptor for transmission.  Remember the length of the

+	data being sent so the second descriptor can be used to send it again from

+	within the ISR. */

+	usSendLen = usTxDataLen;

+	TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf;

+	TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT );

+	EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 );

+

+	/* uip_buf is being sent by the Tx descriptor.  Allocate a new buffer. */

+	uip_buf = prvGetNextBuffer();

+}

+/*-----------------------------------------------------------*/

+

+static long prvWritePHY( long lPhyReg, long lValue )

+{

+const long lMaxTime = 10;

+long x;

+

+	EMAC->MADR = DP83848C_DEF_ADR | lPhyReg;

+	EMAC->MWTD = lValue;

+

+	x = 0;

+	for( x = 0; x < lMaxTime; x++ )

+	{

+		if( ( EMAC->MIND & MIND_BUSY ) == 0 )

+		{

+			/* Operation has finished. */

+			break;

+		}

+

+		vTaskDelay( emacSHORT_DELAY );

+	}

+

+	if( x < lMaxTime )

+	{

+		return pdPASS;

+	}

+	else

+	{

+		return pdFAIL;

+	}

+}

+/*-----------------------------------------------------------*/

+

+static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus )

+{

+long x;

+const long lMaxTime = 10;

+

+	EMAC->MADR = DP83848C_DEF_ADR | ucPhyReg;

+	EMAC->MCMD = MCMD_READ;

+

+	for( x = 0; x < lMaxTime; x++ )

+	{

+		/* Operation has finished. */

+		if( ( EMAC->MIND & MIND_BUSY ) == 0 )

+		{

+			break;

+		}

+

+		vTaskDelay( emacSHORT_DELAY );

+	}

+

+	EMAC->MCMD = 0;

+

+	if( x >= lMaxTime )

+	{

+		*plStatus = pdFAIL;

+	}

+

+	return( EMAC->MRDD );

+}

+/*-----------------------------------------------------------*/

+

+void vEMAC_ISR( void )

+{

+unsigned long ulStatus;

+long lHigherPriorityTaskWoken = pdFALSE;

+

+	ulStatus = EMAC->IntStatus;

+

+	/* Clear the interrupt. */

+	EMAC->IntClear = ulStatus;

+

+	if( ulStatus & INT_RX_DONE )

+	{

+		/* Ensure the uIP task is not blocked as data has arrived. */

+		xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );

+	}

+

+	if( ulStatus & INT_TX_DONE )

+	{

+		if( usSendLen > 0 )

+		{

+			/* Send the data again, using the second descriptor.  As there are

+			only two descriptors the index is set back to 0. */

+			TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );

+			TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );

+			EMAC->TxProduceIndex = ( emacTX_DESC_INDEX );

+

+			/* This is the second Tx so set usSendLen to 0 to indicate that the

+			Tx descriptors will be free again. */

+			usSendLen = 0UL;

+		}

+		else

+		{

+			/* The Tx buffer is no longer required. */

+			prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );

+            TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;

+		}

+	}

+

+	portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );

+}

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings
new file mode 100644
index 0000000..0d3c30c
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings
@@ -0,0 +1,35 @@
+http_http "http://"

+http_200 "200 "

+http_301 "301 "

+http_302 "302 "

+http_get "GET "

+http_10 "HTTP/1.0"

+http_11 "HTTP/1.1"

+http_content_type "content-type: "

+http_texthtml "text/html"

+http_location "location: "

+http_host "host: "

+http_crnl "\r\n"

+http_index_html "/index.html"

+http_404_html "/404.html"

+http_referer "Referer:"

+http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n"

+http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n"

+http_content_type_plain "Content-type: text/plain\r\n\r\n"

+http_content_type_html "Content-type: text/html\r\n\r\n"

+http_content_type_css  "Content-type: text/css\r\n\r\n"

+http_content_type_text "Content-type: text/text\r\n\r\n"

+http_content_type_png  "Content-type: image/png\r\n\r\n"

+http_content_type_gif  "Content-type: image/gif\r\n\r\n"

+http_content_type_jpg  "Content-type: image/jpeg\r\n\r\n"

+http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"

+http_html ".html"

+http_shtml ".shtml"

+http_htm ".htm"

+http_css ".css"

+http_png ".png"

+http_gif ".gif"

+http_jpg ".jpg"

+http_text ".txt"

+http_txt ".txt"

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings.c
new file mode 100644
index 0000000..ef7a41c
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings.c
@@ -0,0 +1,102 @@
+const char http_http[8] = 

+/* "http://" */

+{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };

+const char http_200[5] = 

+/* "200 " */

+{0x32, 0x30, 0x30, 0x20, };

+const char http_301[5] = 

+/* "301 " */

+{0x33, 0x30, 0x31, 0x20, };

+const char http_302[5] = 

+/* "302 " */

+{0x33, 0x30, 0x32, 0x20, };

+const char http_get[5] = 

+/* "GET " */

+{0x47, 0x45, 0x54, 0x20, };

+const char http_10[9] = 

+/* "HTTP/1.0" */

+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };

+const char http_11[9] = 

+/* "HTTP/1.1" */

+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };

+const char http_content_type[15] = 

+/* "content-type: " */

+{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, };

+const char http_texthtml[10] = 

+/* "text/html" */

+{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };

+const char http_location[11] = 

+/* "location: " */

+{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };

+const char http_host[7] = 

+/* "host: " */

+{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };

+const char http_crnl[3] = 

+/* "\r\n" */

+{0xd, 0xa, };

+const char http_index_html[12] = 

+/* "/index.html" */

+{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };

+const char http_404_html[10] = 

+/* "/404.html" */

+{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };

+const char http_referer[9] = 

+/* "Referer:" */

+{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };

+const char http_header_200[84] = 

+/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */

+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };

+const char http_header_404[91] = 

+/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */

+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };

+const char http_content_type_plain[29] = 

+/* "Content-type: text/plain\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, };

+const char http_content_type_html[28] = 

+/* "Content-type: text/html\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, };

+const char http_content_type_css [27] = 

+/* "Content-type: text/css\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, };

+const char http_content_type_text[28] = 

+/* "Content-type: text/text\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, };

+const char http_content_type_png [28] = 

+/* "Content-type: image/png\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, };

+const char http_content_type_gif [28] = 

+/* "Content-type: image/gif\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, };

+const char http_content_type_jpg [29] = 

+/* "Content-type: image/jpeg\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, };

+const char http_content_type_binary[43] = 

+/* "Content-type: application/octet-stream\r\n\r\n" */

+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, };

+const char http_html[6] = 

+/* ".html" */

+{0x2e, 0x68, 0x74, 0x6d, 0x6c, };

+const char http_shtml[7] = 

+/* ".shtml" */

+{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };

+const char http_htm[5] = 

+/* ".htm" */

+{0x2e, 0x68, 0x74, 0x6d, };

+const char http_css[5] = 

+/* ".css" */

+{0x2e, 0x63, 0x73, 0x73, };

+const char http_png[5] = 

+/* ".png" */

+{0x2e, 0x70, 0x6e, 0x67, };

+const char http_gif[5] = 

+/* ".gif" */

+{0x2e, 0x67, 0x69, 0x66, };

+const char http_jpg[5] = 

+/* ".jpg" */

+{0x2e, 0x6a, 0x70, 0x67, };

+const char http_text[5] = 

+/* ".txt" */

+{0x2e, 0x74, 0x78, 0x74, };

+const char http_txt[5] = 

+/* ".txt" */

+{0x2e, 0x74, 0x78, 0x74, };

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings.h
new file mode 100644
index 0000000..acbe7e1
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/http-strings.h
@@ -0,0 +1,34 @@
+extern const char http_http[8];

+extern const char http_200[5];

+extern const char http_301[5];

+extern const char http_302[5];

+extern const char http_get[5];

+extern const char http_10[9];

+extern const char http_11[9];

+extern const char http_content_type[15];

+extern const char http_texthtml[10];

+extern const char http_location[11];

+extern const char http_host[7];

+extern const char http_crnl[3];

+extern const char http_index_html[12];

+extern const char http_404_html[10];

+extern const char http_referer[9];

+extern const char http_header_200[84];

+extern const char http_header_404[91];

+extern const char http_content_type_plain[29];

+extern const char http_content_type_html[28];

+extern const char http_content_type_css [27];

+extern const char http_content_type_text[28];

+extern const char http_content_type_png [28];

+extern const char http_content_type_gif [28];

+extern const char http_content_type_jpg [29];

+extern const char http_content_type_binary[43];

+extern const char http_html[6];

+extern const char http_shtml[7];

+extern const char http_htm[5];

+extern const char http_css[5];

+extern const char http_png[5];

+extern const char http_gif[5];

+extern const char http_jpg[5];

+extern const char http_text[5];

+extern const char http_txt[5];

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-cgi.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-cgi.c
new file mode 100644
index 0000000..2be6e3e
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-cgi.c
@@ -0,0 +1,304 @@
+/**

+ * \addtogroup httpd

+ * @{

+ */

+

+/**

+ * \file

+ *         Web server script interface

+ * \author

+ *         Adam Dunkels <adam@sics.se>

+ *

+ */

+

+/*

+ * Copyright (c) 2001-2006, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $

+ *

+ */

+

+#include "uip.h"

+#include "psock.h"

+#include "httpd.h"

+#include "httpd-cgi.h"

+#include "httpd-fs.h"

+

+#include <stdio.h>

+#include <string.h>

+

+HTTPD_CGI_CALL(file, "file-stats", file_stats);

+HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats);

+HTTPD_CGI_CALL(net, "net-stats", net_stats);

+HTTPD_CGI_CALL(rtos, "rtos-stats", rtos_stats );

+HTTPD_CGI_CALL(run, "run-time", run_time );

+HTTPD_CGI_CALL(io, "led-io", led_io );

+

+

+static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, &rtos, &run, &io, NULL };

+

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(nullfunction(struct httpd_state *s, char *ptr))

+{

+  PSOCK_BEGIN(&s->sout);

+  ( void ) ptr;

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+httpd_cgifunction

+httpd_cgi(char *name)

+{

+  const struct httpd_cgi_call **f;

+

+  /* Find the matching name in the table, return the function. */

+  for(f = calls; *f != NULL; ++f) {

+    if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) {

+      return (*f)->function;

+    }

+  }

+  return nullfunction;

+}

+/*---------------------------------------------------------------------------*/

+static unsigned short

+generate_file_stats(void *arg)

+{

+  char *f = (char *)arg;

+  return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f));

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(file_stats(struct httpd_state *s, char *ptr))

+{

+  PSOCK_BEGIN(&s->sout);

+

+  PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1);

+

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+static const char closed[] =   /*  "CLOSED",*/

+{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};

+static const char syn_rcvd[] = /*  "SYN-RCVD",*/

+{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56,

+ 0x44,  0};

+static const char syn_sent[] = /*  "SYN-SENT",*/

+{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e,

+ 0x54,  0};

+static const char established[] = /*  "ESTABLISHED",*/

+{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48,

+ 0x45, 0x44, 0};

+static const char fin_wait_1[] = /*  "FIN-WAIT-1",*/

+{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,

+ 0x54, 0x2d, 0x31, 0};

+static const char fin_wait_2[] = /*  "FIN-WAIT-2",*/

+{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,

+ 0x54, 0x2d, 0x32, 0};

+static const char closing[] = /*  "CLOSING",*/

+{0x43, 0x4c, 0x4f, 0x53, 0x49,

+ 0x4e, 0x47, 0};

+static const char time_wait[] = /*  "TIME-WAIT,"*/

+{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41,

+ 0x49, 0x54, 0};

+static const char last_ack[] = /*  "LAST-ACK"*/

+{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43,

+ 0x4b, 0};

+

+static const char *states[] = {

+  closed,

+  syn_rcvd,

+  syn_sent,

+  established,

+  fin_wait_1,

+  fin_wait_2,

+  closing,

+  time_wait,

+  last_ack};

+

+

+static unsigned short

+generate_tcp_stats(void *arg)

+{

+  struct uip_conn *conn;

+  struct httpd_state *s = (struct httpd_state *)arg;

+

+  conn = &uip_conns[s->count];

+  return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,

+		 "<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n",

+		 htons(conn->lport),

+		 htons(conn->ripaddr[0]) >> 8,

+		 htons(conn->ripaddr[0]) & 0xff,

+		 htons(conn->ripaddr[1]) >> 8,

+		 htons(conn->ripaddr[1]) & 0xff,

+		 htons(conn->rport),

+		 states[conn->tcpstateflags & UIP_TS_MASK],

+		 conn->nrtx,

+		 conn->timer,

+		 (uip_outstanding(conn))? '*':' ',

+		 (uip_stopped(conn))? '!':' ');

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr))

+{

+

+  PSOCK_BEGIN(&s->sout);

+  ( void ) ptr;

+  for(s->count = 0; s->count < UIP_CONNS; ++s->count) {

+    if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {

+      PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s);

+    }

+  }

+

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+static unsigned short

+generate_net_stats(void *arg)

+{

+  struct httpd_state *s = (struct httpd_state *)arg;

+  return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,

+		  "%5u\n", ((uip_stats_t *)&uip_stat)[s->count]);

+}

+

+static

+PT_THREAD(net_stats(struct httpd_state *s, char *ptr))

+{

+  PSOCK_BEGIN(&s->sout);

+

+  ( void ) ptr;

+#if UIP_STATISTICS

+

+  for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t);

+      ++s->count) {

+    PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s);

+  }

+

+#endif /* UIP_STATISTICS */

+

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+

+extern void vTaskList( signed char *pcWriteBuffer );

+extern char *pcGetTaskStatusMessage( void );

+static char cCountBuf[ 128 ];

+long lRefreshCount = 0;

+static unsigned short

+generate_rtos_stats(void *arg)

+{

+	( void ) arg;

+	lRefreshCount++;

+	sprintf( cCountBuf, "<p><br>Refresh count = %d<p><br>%s", (int)lRefreshCount, pcGetTaskStatusMessage() );

+    vTaskList( uip_appdata );

+	strcat( uip_appdata, cCountBuf );

+

+	return strlen( uip_appdata );

+}

+/*---------------------------------------------------------------------------*/

+

+

+static

+PT_THREAD(rtos_stats(struct httpd_state *s, char *ptr))

+{

+  PSOCK_BEGIN(&s->sout);

+  ( void ) ptr;

+  PSOCK_GENERATOR_SEND(&s->sout, generate_rtos_stats, NULL);

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+

+char *pcStatus;

+unsigned long ulString;

+

+static unsigned short generate_io_state( void *arg )

+{

+extern long uxParTextGetLED( unsigned long ulLED );

+const unsigned long ulLEDNo = 3;

+

+	( void ) arg;

+

+	if( uxParTextGetLED( ulLEDNo ) == 0 )

+	{

+		pcStatus = "";

+	}

+	else

+	{

+		pcStatus = "checked";

+	}

+

+	sprintf( uip_appdata,

+		"<input type=\"checkbox\" name=\"LED0\" value=\"1\" %s>LED<p><p>", pcStatus );

+

+	return strlen( uip_appdata );

+}

+/*---------------------------------------------------------------------------*/

+

+extern void vTaskGetRunTimeStats( signed char *pcWriteBuffer );

+static unsigned short

+generate_runtime_stats(void *arg)

+{

+	( void ) arg;

+	lRefreshCount++;

+	sprintf( cCountBuf, "<p><br>Refresh count = %d", (int)lRefreshCount );

+    vTaskGetRunTimeStats( uip_appdata );

+	strcat( uip_appdata, cCountBuf );

+

+	return strlen( uip_appdata );

+}

+/*---------------------------------------------------------------------------*/

+

+

+static

+PT_THREAD(run_time(struct httpd_state *s, char *ptr))

+{

+  PSOCK_BEGIN(&s->sout);

+  ( void ) ptr;

+  PSOCK_GENERATOR_SEND(&s->sout, generate_runtime_stats, NULL);

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+

+

+static PT_THREAD(led_io(struct httpd_state *s, char *ptr))

+{

+  PSOCK_BEGIN(&s->sout);

+  ( void ) ptr;

+  PSOCK_GENERATOR_SEND(&s->sout, generate_io_state, NULL);

+  PSOCK_END(&s->sout);

+}

+

+/** @} */

+

+

+

+

+

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-cgi.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-cgi.h
new file mode 100644
index 0000000..7ae9283
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-cgi.h
@@ -0,0 +1,84 @@
+/**

+ * \addtogroup httpd

+ * @{

+ */

+

+/**

+ * \file

+ *         Web server script interface header file

+ * \author

+ *         Adam Dunkels <adam@sics.se>

+ *

+ */

+

+

+

+/*

+ * Copyright (c) 2001, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: httpd-cgi.h,v 1.2 2006/06/11 21:46:38 adam Exp $

+ *

+ */

+

+#ifndef __HTTPD_CGI_H__

+#define __HTTPD_CGI_H__

+

+#include "psock.h"

+#include "httpd.h"

+

+typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *));

+

+httpd_cgifunction httpd_cgi(char *name);

+

+struct httpd_cgi_call {

+  const char *name;

+  const httpd_cgifunction function;

+};

+

+/**

+ * \brief      HTTPD CGI function declaration

+ * \param name The C variable name of the function

+ * \param str  The string name of the function, used in the script file

+ * \param function A pointer to the function that implements it

+ *

+ *             This macro is used for declaring a HTTPD CGI

+ *             function. This function is then added to the list of

+ *             HTTPD CGI functions with the httpd_cgi_add() function.

+ *

+ * \hideinitializer

+ */

+#define HTTPD_CGI_CALL(name, str, function) \

+static PT_THREAD(function(struct httpd_state *, char *)); \

+static const struct httpd_cgi_call name = {str, function}

+

+void httpd_cgi_init(void);

+#endif /* __HTTPD_CGI_H__ */

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs.c
new file mode 100644
index 0000000..dc4aef0
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs.c
@@ -0,0 +1,132 @@
+/*

+ * Copyright (c) 2001, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the lwIP TCP/IP stack.

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $

+ */

+

+#include "httpd.h"

+#include "httpd-fs.h"

+#include "httpd-fsdata.h"

+

+#ifndef NULL

+#define NULL 0

+#endif /* NULL */

+

+#include "httpd-fsdata.c"

+

+#if HTTPD_FS_STATISTICS

+static u16_t count[HTTPD_FS_NUMFILES];

+#endif /* HTTPD_FS_STATISTICS */

+

+/*-----------------------------------------------------------------------------------*/

+static u8_t

+httpd_fs_strcmp(const char *str1, const char *str2)

+{

+  u8_t i;

+  i = 0;

+ loop:

+

+  if(str2[i] == 0 ||

+     str1[i] == '\r' ||

+     str1[i] == '\n') {

+    return 0;

+  }

+

+  if(str1[i] != str2[i]) {

+    return 1;

+  }

+

+

+  ++i;

+  goto loop;

+}

+/*-----------------------------------------------------------------------------------*/

+int

+httpd_fs_open(const char *name, struct httpd_fs_file *file)

+{

+#if HTTPD_FS_STATISTICS

+  u16_t i = 0;

+#endif /* HTTPD_FS_STATISTICS */

+  struct httpd_fsdata_file_noconst *f;

+

+  for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;

+      f != NULL;

+      f = (struct httpd_fsdata_file_noconst *)f->next) {

+

+    if(httpd_fs_strcmp(name, f->name) == 0) {

+      file->data = f->data;

+      file->len = f->len;

+#if HTTPD_FS_STATISTICS

+      ++count[i];

+#endif /* HTTPD_FS_STATISTICS */

+      return 1;

+    }

+#if HTTPD_FS_STATISTICS

+    ++i;

+#endif /* HTTPD_FS_STATISTICS */

+

+  }

+  return 0;

+}

+/*-----------------------------------------------------------------------------------*/

+void

+httpd_fs_init(void)

+{

+#if HTTPD_FS_STATISTICS

+  u16_t i;

+  for(i = 0; i < HTTPD_FS_NUMFILES; i++) {

+    count[i] = 0;

+  }

+#endif /* HTTPD_FS_STATISTICS */

+}

+/*-----------------------------------------------------------------------------------*/

+#if HTTPD_FS_STATISTICS

+u16_t httpd_fs_count

+(char *name)

+{

+  struct httpd_fsdata_file_noconst *f;

+  u16_t i;

+

+  i = 0;

+  for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;

+      f != NULL;

+      f = (struct httpd_fsdata_file_noconst *)f->next) {

+

+    if(httpd_fs_strcmp(name, f->name) == 0) {

+      return count[i];

+    }

+    ++i;

+  }

+  return 0;

+}

+#endif /* HTTPD_FS_STATISTICS */

+/*-----------------------------------------------------------------------------------*/

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs.h
new file mode 100644
index 0000000..b594eea
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs.h
@@ -0,0 +1,57 @@
+/*

+ * Copyright (c) 2001, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the lwIP TCP/IP stack.

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $

+ */

+#ifndef __HTTPD_FS_H__

+#define __HTTPD_FS_H__

+

+#define HTTPD_FS_STATISTICS 1

+

+struct httpd_fs_file {

+  char *data;

+  int len;

+};

+

+/* file must be allocated by caller and will be filled in

+   by the function. */

+int httpd_fs_open(const char *name, struct httpd_fs_file *file);

+

+#ifdef HTTPD_FS_STATISTICS

+#if HTTPD_FS_STATISTICS == 1

+u16_t httpd_fs_count(char *name);

+#endif /* HTTPD_FS_STATISTICS */

+#endif /* HTTPD_FS_STATISTICS */

+

+void httpd_fs_init(void);

+

+#endif /* __HTTPD_FS_H__ */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/404.html b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/404.html
new file mode 100644
index 0000000..43e7f4c
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/404.html
@@ -0,0 +1,8 @@
+<html>

+  <body bgcolor="white">

+    <center>

+      <h1>404 - file not found</h1>

+      <h3>Go <a href="/">here</a> instead.</h3>

+    </center>

+  </body>

+</html>
\ No newline at end of file
diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/index.html b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/index.html
new file mode 100644
index 0000000..4937dc6
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+<html>

+  <head>

+    <title>FreeRTOS.org uIP WEB server demo</title>

+  </head>

+  <BODY onLoad="window.setTimeout(&quot;location.href='index.shtml'&quot;,100)">

+<font face="arial">

+Loading index.shtml.  Click <a href="index.shtml">here</a> if not automatically redirected.

+</font>

+</font>

+</body>

+</html>

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/index.shtml b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/index.shtml
new file mode 100644
index 0000000..29d242c
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/index.shtml
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+<html>

+  <head>

+    <title>FreeRTOS.org uIP WEB server demo</title>

+  </head>

+  <BODY onLoad="window.setTimeout(&quot;location.href='index.shtml'&quot;,2000)">

+<font face="arial">

+<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>

+<br><p>

+<hr>

+<br><p>

+<h2>Task statistics</h2>

+Page will refresh every 2 seconds.<p>

+<font face="courier"><pre>Task          State  Priority  Stack	#<br>************************************************<br>

+%! rtos-stats

+</pre></font>

+</font>

+</body>

+</html>

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/io.shtml b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/io.shtml
new file mode 100644
index 0000000..fd0697d
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/io.shtml
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+<html>

+  <head>

+    <title>FreeRTOS.org uIP WEB server demo</title>

+  </head>

+  <BODY>

+<font face="arial">

+<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>

+<br><p>

+<hr>

+<b>LED and LCD IO</b><br>

+

+<p>

+

+Use the check box to turn on or off the LED, enter text to display on the OLED display, then click "Update IO".

+

+

+<p>

+<form name="aForm" action="/io.shtml" method="get">

+%! led-io

+<p>

+<input type="submit" value="Update IO">

+</form>

+<br><p>

+</font>

+</body>

+</html>

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/runtime.shtml b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/runtime.shtml
new file mode 100644
index 0000000..67cae46
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/runtime.shtml
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+<html>

+  <head>

+    <title>FreeRTOS.org uIP WEB server demo</title>

+  </head>

+  <BODY onLoad="window.setTimeout(&quot;location.href='runtime.shtml'&quot;,2000)">

+<font face="arial">

+<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>

+<br><p>

+<hr>

+<br><p>

+<h2>Run-time statistics</h2>

+Page will refresh every 2 seconds.<p>

+<font face="courier"><pre>Task            Abs Time      % Time<br>****************************************<br>

+%! run-time

+</pre></font>

+</font>

+</body>

+</html>

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/stats.shtml b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/stats.shtml
new file mode 100644
index 0000000..d95a693
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/stats.shtml
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+<html>

+  <head>

+    <title>FreeRTOS.org uIP WEB server demo</title>

+  </head>

+  <BODY>

+<font face="arial">

+<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>

+<br><p>

+<hr>

+<br><p>

+<h2>Network statistics</h2>

+<table width="300" border="0">

+<tr><td align="left"><font face="courier"><pre>

+IP           Packets dropped

+             Packets received

+             Packets sent

+IP errors    IP version/header length

+             IP length, high byte

+             IP length, low byte

+             IP fragments

+             Header checksum

+             Wrong protocol

+ICMP	     Packets dropped

+             Packets received

+             Packets sent

+             Type errors

+TCP          Packets dropped

+             Packets received

+             Packets sent

+             Checksum errors

+             Data packets without ACKs

+             Resets

+             Retransmissions

+	     No connection avaliable

+	     Connection attempts to closed ports

+</pre></font></td><td><pre>%! net-stats

+</pre></table>

+</font>

+</body>

+</html>

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/tcp.shtml b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/tcp.shtml
new file mode 100644
index 0000000..4105367
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fs/tcp.shtml
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+<html>

+  <head>

+    <title>FreeRTOS.org uIP WEB server demo</title>

+  </head>

+  <BODY>

+<font face="arial">

+<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>

+<br><p>

+<hr>

+<br>

+<h2>Network connections</h2>

+<p>

+<table>

+<tr><th>Local</th><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Flags</th></tr>

+%! tcp-connections

+</pre></font>

+</font>

+</body>

+</html>

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fsdata.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fsdata.c
new file mode 100644
index 0000000..c8b2a80
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fsdata.c
@@ -0,0 +1,557 @@
+static const char data_404_html[] = {

+	/* /404.html */

+	0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,

+	0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c, 

+	0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 

+	0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, 

+	0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e, 

+	0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 

+	0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 

+	0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 

+	0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, 

+	0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 

+	0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, 

+	0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 

+	0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 

+	0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 

+	0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 

+0};

+

+static const char data_index_html[] = {

+	/* /index.html */

+	0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,

+	0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 

+	0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 

+	0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 

+	0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 

+	0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 

+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 

+	0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 

+	0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 

+	0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 

+	0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, 

+	0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 

+	0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 

+	0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, 

+	0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, 

+	0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f, 

+	0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e, 

+	0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 

+	0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, 

+	0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 

+	0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x69, 0x6e, 0x64, 0x65, 

+	0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x26, 0x71, 

+	0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x31, 0x30, 0x30, 0x29, 0x22, 

+	0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 

+	0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 

+	0x3e, 0xa, 0x4c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 

+	0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 

+	0x6c, 0x2e, 0x20, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20, 

+	0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 

+	0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 

+	0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 

+	0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x75, 

+	0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 

+	0x79, 0x20, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 

+	0x65, 0x64, 0x2e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 

+	0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 

+	0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 

+	0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};

+

+static const char data_index_shtml[] = {

+	/* /index.shtml */

+	0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,

+	0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 

+	0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 

+	0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 

+	0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 

+	0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 

+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 

+	0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 

+	0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 

+	0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 

+	0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, 

+	0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 

+	0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 

+	0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, 

+	0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, 

+	0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f, 

+	0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e, 

+	0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 

+	0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, 

+	0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 

+	0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x69, 0x6e, 0x64, 0x65, 

+	0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x26, 0x71, 

+	0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x32, 0x30, 0x30, 0x30, 0x29, 

+	0x22, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 

+	0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 

+	0x22, 0x3e, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 

+	0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 

+	0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 

+	0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 

+	0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 

+	0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 

+	0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 

+	0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 

+	0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 

+	0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 

+	0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 

+	0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 

+	0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 

+	0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 

+	0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 

+	0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 

+	0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 

+	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 

+	0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 

+	0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 

+	0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 

+	0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 

+	0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 

+	0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 

+	0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 

+	0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 

+	0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 

+	0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 

+	0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 

+	0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 

+	0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 

+	0x32, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x73, 0x74, 0x61, 

+	0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 

+	0x32, 0x3e, 0xa, 0x50, 0x61, 0x67, 0x65, 0x20, 0x77, 0x69, 

+	0x6c, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 

+	0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x32, 0x20, 0x73, 

+	0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x2e, 0x3c, 0x70, 0x3e, 

+	0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 

+	0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 

+	0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x54, 0x61, 0x73, 

+	0x6b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x20, 0x50, 0x72, 

+	0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x20, 0x53, 0x74, 

+	0x61, 0x63, 0x6b, 0x9, 0x23, 0x3c, 0x62, 0x72, 0x3e, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3c, 0x62, 0x72, 

+	0x3e, 0xa, 0x25, 0x21, 0x20, 0x72, 0x74, 0x6f, 0x73, 0x2d, 

+	0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, 

+	0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 

+	0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 

+	0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 

+	0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};

+

+static const char data_io_shtml[] = {

+	/* /io.shtml */

+	0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,

+	0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 

+	0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 

+	0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 

+	0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 

+	0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 

+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 

+	0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 

+	0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 

+	0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 

+	0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, 

+	0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 

+	0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 

+	0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, 

+	0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, 

+	0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa, 

+	0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 

+	0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa, 

+	0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 

+	0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 

+	0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 

+	0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 

+	0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 

+	0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, 

+	0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 

+	0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, 

+	0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 

+	0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 

+	0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 

+	0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 

+	0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 

+	0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 

+	0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 

+	0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 

+	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 

+	0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 

+	0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 

+	0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65, 

+	0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, 

+	0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, 

+	0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 

+	0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x3e, 

+	0x4c, 0x45, 0x44, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4c, 0x43, 

+	0x44, 0x20, 0x49, 0x4f, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x62, 

+	0x72, 0x3e, 0xa, 0xa, 0x3c, 0x70, 0x3e, 0xa, 0xa, 0x55, 

+	0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x65, 

+	0x63, 0x6b, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x74, 0x6f, 0x20, 

+	0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 

+	0x20, 0x6f, 0x66, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4c, 

+	0x45, 0x44, 0x2c, 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 

+	0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, 

+	0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74, 

+	0x68, 0x65, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x20, 0x64, 0x69, 

+	0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, 

+	0x6e, 0x20, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x22, 0x55, 

+	0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x49, 0x4f, 0x22, 0x2e, 

+	0xa, 0xa, 0xa, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 

+	0x72, 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 

+	0x46, 0x6f, 0x72, 0x6d, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 

+	0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68, 

+	0x74, 0x6d, 0x6c, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 

+	0x64, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x3e, 0xa, 0x25, 

+	0x21, 0x20, 0x6c, 0x65, 0x64, 0x2d, 0x69, 0x6f, 0xa, 0x3c, 

+	0x70, 0x3e, 0xa, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 

+	0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 

+	0x69, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 

+	0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x49, 0x4f, 

+	0x22, 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 

+	0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 

+	0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 0x62, 

+	0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 

+	0x6c, 0x3e, 0xa, 0xa, 0};

+

+static const char data_runtime_shtml[] = {

+	/* /runtime.shtml */

+	0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,

+	0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 

+	0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 

+	0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 

+	0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 

+	0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 

+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 

+	0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 

+	0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 

+	0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 

+	0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, 

+	0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 

+	0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 

+	0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, 

+	0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, 

+	0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f, 

+	0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e, 

+	0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 

+	0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, 

+	0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 

+	0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x72, 0x75, 0x6e, 0x74, 

+	0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, 

+	0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x32, 0x30, 0x30, 

+	0x30, 0x29, 0x22, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 

+	0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 

+	0x61, 0x6c, 0x22, 0x3e, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 

+	0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 

+	0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x61, 0x73, 

+	0x6b, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 

+	0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 

+	0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 

+	0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 

+	0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, 0x20, 0x54, 

+	0x69, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 

+	0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 

+	0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 

+	0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 

+	0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, 0x20, 0x53, 

+	0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, 

+	0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x43, 0x6f, 

+	0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 

+	0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 

+	0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 

+	0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 

+	0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, 0x74, 0x6f, 

+	0x73, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, 0x46, 0x72, 

+	0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 0x72, 0x67, 

+	0x20, 0x48, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, 

+	0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 

+	0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 

+	0x3d, 0x22, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 

+	0x22, 0x3e, 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0xa, 0x3c, 

+	0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x72, 

+	0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 

+	0x3c, 0x68, 0x32, 0x3e, 0x52, 0x75, 0x6e, 0x2d, 0x74, 0x69, 

+	0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 

+	0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xa, 0x50, 

+	0x61, 0x67, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x72, 

+	0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x20, 0x65, 0x76, 0x65, 

+	0x72, 0x79, 0x20, 0x32, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 

+	0x64, 0x73, 0x2e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 

+	0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, 

+	0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, 

+	0x72, 0x65, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 

+	0x62, 0x73, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x25, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x3c, 

+	0x62, 0x72, 0x3e, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 

+	0x2a, 0x2a, 0x2a, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x25, 0x21, 

+	0x20, 0x72, 0x75, 0x6e, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0xa, 

+	0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 

+	0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 

+	0x3e, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 

+	0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};

+

+static const char data_stats_shtml[] = {

+	/* /stats.shtml */

+	0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,

+	0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 

+	0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 

+	0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 

+	0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 

+	0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 

+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 

+	0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 

+	0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 

+	0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 

+	0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, 

+	0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 

+	0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 

+	0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, 

+	0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, 

+	0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa, 

+	0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 

+	0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa, 

+	0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 

+	0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 

+	0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 

+	0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 

+	0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 

+	0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, 

+	0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 

+	0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, 

+	0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 

+	0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 

+	0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 

+	0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 

+	0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 

+	0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 

+	0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 

+	0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 

+	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 

+	0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 

+	0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 

+	0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65, 

+	0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, 

+	0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, 

+	0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 

+	0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x72, 

+	0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x4e, 

+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 

+	0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 

+	0x32, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 

+	0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, 0x30, 

+	0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 

+	0x30, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 

+	0x64, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, 

+	0x65, 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 

+	0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75, 

+	0x72, 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65, 

+	0x3e, 0xa, 0x49, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 

+	0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 

+	0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 

+	0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 

+	0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 

+	0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x49, 0x50, 0x20, 

+	0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x20, 0x20, 0x20, 0x20, 

+	0x49, 0x50, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 

+	0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6c, 0x65, 

+	0x6e, 0x67, 0x74, 0x68, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 

+	0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68, 

+	0x69, 0x67, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 

+	0x68, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74, 

+	0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72, 

+	0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xa, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68, 

+	0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xa, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 0x74, 

+	0x6f, 0x63, 0x6f, 0x6c, 0xa, 0x49, 0x43, 0x4d, 0x50, 0x9, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 

+	0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 

+	0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 

+	0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 

+	0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 

+	0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x54, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 

+	0x73, 0xa, 0x54, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 

+	0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 

+	0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 

+	0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 

+	0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 

+	0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65, 

+	0x72, 0x72, 0x6f, 0x72, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 

+	0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 

+	0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 

+	0x41, 0x43, 0x4b, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 

+	0x73, 0x65, 0x74, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 

+	0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 

+	0x6f, 0x6e, 0x73, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 

+	0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, 0x6c, 0x69, 0x61, 

+	0x62, 0x6c, 0x65, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, 

+	0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 

+	0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20, 

+	0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20, 

+	0x70, 0x6f, 0x72, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, 

+	0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c, 

+	0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x70, 

+	0x72, 0x65, 0x3e, 0x25, 0x21, 0x20, 0x6e, 0x65, 0x74, 0x2d, 

+	0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, 

+	0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 

+	0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 

+	0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 

+	0x74, 0x6d, 0x6c, 0x3e, 0xa, 0};

+

+static const char data_tcp_shtml[] = {

+	/* /tcp.shtml */

+	0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,

+	0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 

+	0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 

+	0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 

+	0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 

+	0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 

+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 

+	0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 

+	0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 

+	0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 

+	0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, 

+	0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 

+	0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 

+	0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 

+	0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, 

+	0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, 

+	0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 

+	0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa, 

+	0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 

+	0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa, 

+	0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 

+	0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 

+	0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 

+	0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 

+	0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 

+	0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, 

+	0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 

+	0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, 

+	0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 

+	0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 

+	0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 

+	0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 

+	0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 

+	0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 

+	0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 

+	0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 

+	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 

+	0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 

+	0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 

+	0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65, 

+	0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 

+	0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 

+	0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, 

+	0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, 

+	0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 

+	0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x72, 

+	0x3e, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x4e, 0x65, 0x74, 0x77, 

+	0x6f, 0x72, 0x6b, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 

+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 

+	0xa, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 

+	0x65, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, 

+	0x3e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68, 

+	0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 

+	0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 

+	0x53, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 

+	0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 

+	0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 

+	0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69, 

+	0x6d, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 

+	0x68, 0x3e, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, 

+	0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21, 

+	0x20, 0x74, 0x63, 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 

+	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa, 0x3c, 0x2f, 0x70, 

+	0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 

+	0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 

+	0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 

+	0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};

+

+const struct httpd_fsdata_file file_404_html[] = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10, 0}};

+

+const struct httpd_fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12, 0}};

+

+const struct httpd_fsdata_file file_index_shtml[] = {{file_index_html, data_index_shtml, data_index_shtml + 13, sizeof(data_index_shtml) - 13, 0}};

+

+const struct httpd_fsdata_file file_io_shtml[] = {{file_index_shtml, data_io_shtml, data_io_shtml + 10, sizeof(data_io_shtml) - 10, 0}};

+

+const struct httpd_fsdata_file file_runtime_shtml[] = {{file_io_shtml, data_runtime_shtml, data_runtime_shtml + 15, sizeof(data_runtime_shtml) - 15, 0}};

+

+const struct httpd_fsdata_file file_stats_shtml[] = {{file_runtime_shtml, data_stats_shtml, data_stats_shtml + 13, sizeof(data_stats_shtml) - 13, 0}};

+

+const struct httpd_fsdata_file file_tcp_shtml[] = {{file_stats_shtml, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11, 0}};

+

+#define HTTPD_FS_ROOT file_tcp_shtml

+

+#define HTTPD_FS_NUMFILES 7

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fsdata.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fsdata.h
new file mode 100644
index 0000000..52d35c2
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd-fsdata.h
@@ -0,0 +1,64 @@
+/*

+ * Copyright (c) 2001, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the lwIP TCP/IP stack.

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $

+ */

+#ifndef __HTTPD_FSDATA_H__

+#define __HTTPD_FSDATA_H__

+

+#include "uip.h"

+

+struct httpd_fsdata_file {

+  const struct httpd_fsdata_file *next;

+  const char *name;

+  const char *data;

+  const int len;

+#ifdef HTTPD_FS_STATISTICS

+#if HTTPD_FS_STATISTICS == 1

+  u16_t count;

+#endif /* HTTPD_FS_STATISTICS */

+#endif /* HTTPD_FS_STATISTICS */

+};

+

+struct httpd_fsdata_file_noconst {

+  struct httpd_fsdata_file *next;

+  char *name;

+  char *data;

+  int len;

+#ifdef HTTPD_FS_STATISTICS

+#if HTTPD_FS_STATISTICS == 1

+  u16_t count;

+#endif /* HTTPD_FS_STATISTICS */

+#endif /* HTTPD_FS_STATISTICS */

+};

+

+#endif /* __HTTPD_FSDATA_H__ */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd.c
new file mode 100644
index 0000000..c416cc1
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd.c
@@ -0,0 +1,346 @@
+/**

+ * \addtogroup apps

+ * @{

+ */

+

+/**

+ * \defgroup httpd Web server

+ * @{

+ * The uIP web server is a very simplistic implementation of an HTTP

+ * server. It can serve web pages and files from a read-only ROM

+ * filesystem, and provides a very small scripting language.

+

+ */

+

+/**

+ * \file

+ *         Web server

+ * \author

+ *         Adam Dunkels <adam@sics.se>

+ */

+

+

+/*

+ * Copyright (c) 2004, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $

+ */

+

+#include "uip.h"

+#include "httpd.h"

+#include "httpd-fs.h"

+#include "httpd-cgi.h"

+#include "http-strings.h"

+

+#include <string.h>

+

+#define STATE_WAITING 0

+#define STATE_OUTPUT  1

+

+#define ISO_nl      0x0a

+#define ISO_space   0x20

+#define ISO_bang    0x21

+#define ISO_percent 0x25

+#define ISO_period  0x2e

+#define ISO_slash   0x2f

+#define ISO_colon   0x3a

+

+

+/*---------------------------------------------------------------------------*/

+static unsigned short

+generate_part_of_file(void *state)

+{

+  struct httpd_state *s = (struct httpd_state *)state;

+

+  if(s->file.len > uip_mss()) {

+    s->len = uip_mss();

+  } else {

+    s->len = s->file.len;

+  }

+  memcpy(uip_appdata, s->file.data, s->len);

+  

+  return s->len;

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(send_file(struct httpd_state *s))

+{

+  PSOCK_BEGIN(&s->sout);

+  

+  do {

+    PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s);

+    s->file.len -= s->len;

+    s->file.data += s->len;

+  } while(s->file.len > 0);

+      

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(send_part_of_file(struct httpd_state *s))

+{

+  PSOCK_BEGIN(&s->sout);

+

+  PSOCK_SEND(&s->sout, s->file.data, s->len);

+  

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+static void

+next_scriptstate(struct httpd_state *s)

+{

+  char *p;

+  p = strchr(s->scriptptr, ISO_nl) + 1;

+  s->scriptlen -= (unsigned short)(p - s->scriptptr);

+  s->scriptptr = p;

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(handle_script(struct httpd_state *s))

+{

+  char *ptr;

+  

+  PT_BEGIN(&s->scriptpt);

+

+

+  while(s->file.len > 0) {

+

+    /* Check if we should start executing a script. */

+    if(*s->file.data == ISO_percent &&

+       *(s->file.data + 1) == ISO_bang) {

+      s->scriptptr = s->file.data + 3;

+      s->scriptlen = s->file.len - 3;

+      if(*(s->scriptptr - 1) == ISO_colon) {

+	httpd_fs_open(s->scriptptr + 1, &s->file);

+	PT_WAIT_THREAD(&s->scriptpt, send_file(s));

+      } else {

+	PT_WAIT_THREAD(&s->scriptpt,

+		       httpd_cgi(s->scriptptr)(s, s->scriptptr));

+      }

+      next_scriptstate(s);

+      

+      /* The script is over, so we reset the pointers and continue

+	 sending the rest of the file. */

+      s->file.data = s->scriptptr;

+      s->file.len = s->scriptlen;

+    } else {

+      /* See if we find the start of script marker in the block of HTML

+	 to be sent. */

+

+      if(s->file.len > uip_mss()) {

+	s->len = uip_mss();

+      } else {

+	s->len = s->file.len;

+      }

+

+      if(*s->file.data == ISO_percent) {

+	ptr = strchr(s->file.data + 1, ISO_percent);

+      } else {

+	ptr = strchr(s->file.data, ISO_percent);

+      }

+      if(ptr != NULL &&

+	 ptr != s->file.data) {

+	s->len = (int)(ptr - s->file.data);

+	if(s->len >= uip_mss()) {

+	  s->len = uip_mss();

+	}

+      }

+      PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s));

+      s->file.data += s->len;

+      s->file.len -= s->len;

+      

+    }

+  }

+  

+  PT_END(&s->scriptpt);

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr))

+{

+  char *ptr;

+

+  PSOCK_BEGIN(&s->sout);

+

+  PSOCK_SEND_STR(&s->sout, statushdr);

+

+  ptr = strrchr(s->filename, ISO_period);

+  if(ptr == NULL) {

+    PSOCK_SEND_STR(&s->sout, http_content_type_binary);

+  } else if(strncmp(http_html, ptr, 5) == 0 ||

+	    strncmp(http_shtml, ptr, 6) == 0) {

+    PSOCK_SEND_STR(&s->sout, http_content_type_html);

+  } else if(strncmp(http_css, ptr, 4) == 0) {

+    PSOCK_SEND_STR(&s->sout, http_content_type_css);

+  } else if(strncmp(http_png, ptr, 4) == 0) {

+    PSOCK_SEND_STR(&s->sout, http_content_type_png);

+  } else if(strncmp(http_gif, ptr, 4) == 0) {

+    PSOCK_SEND_STR(&s->sout, http_content_type_gif);

+  } else if(strncmp(http_jpg, ptr, 4) == 0) {

+    PSOCK_SEND_STR(&s->sout, http_content_type_jpg);

+  } else {

+    PSOCK_SEND_STR(&s->sout, http_content_type_plain);

+  }

+  PSOCK_END(&s->sout);

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(handle_output(struct httpd_state *s))

+{

+  char *ptr;

+  

+  PT_BEGIN(&s->outputpt);

+ 

+  if(!httpd_fs_open(s->filename, &s->file)) {

+    httpd_fs_open(http_404_html, &s->file);

+    strcpy(s->filename, http_404_html);

+    PT_WAIT_THREAD(&s->outputpt,

+		   send_headers(s,

+		   http_header_404));

+    PT_WAIT_THREAD(&s->outputpt,

+		   send_file(s));

+  } else {

+    PT_WAIT_THREAD(&s->outputpt,

+		   send_headers(s,

+		   http_header_200));

+    ptr = strchr(s->filename, ISO_period);

+    if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) {

+      PT_INIT(&s->scriptpt);

+      PT_WAIT_THREAD(&s->outputpt, handle_script(s));

+    } else {

+      PT_WAIT_THREAD(&s->outputpt,

+		     send_file(s));

+    }

+  }

+  PSOCK_CLOSE(&s->sout);

+  PT_END(&s->outputpt);

+}

+/*---------------------------------------------------------------------------*/

+static

+PT_THREAD(handle_input(struct httpd_state *s))

+{

+  PSOCK_BEGIN(&s->sin);

+

+  PSOCK_READTO(&s->sin, ISO_space);

+

+  

+  if(strncmp(s->inputbuf, http_get, 4) != 0) {

+    PSOCK_CLOSE_EXIT(&s->sin);

+  }

+  PSOCK_READTO(&s->sin, ISO_space);

+

+  if(s->inputbuf[0] != ISO_slash) {

+    PSOCK_CLOSE_EXIT(&s->sin);

+  }

+

+  if(s->inputbuf[1] == ISO_space) {

+    strncpy(s->filename, http_index_html, sizeof(s->filename));

+  } else {

+

+    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;

+

+    /* Process any form input being sent to the server. */

+    {

+        extern void vApplicationProcessFormInput( char *pcInputString );

+        vApplicationProcessFormInput( s->inputbuf );

+    }

+

+    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));

+  }

+

+  /*  httpd_log_file(uip_conn->ripaddr, s->filename);*/

+  

+  s->state = STATE_OUTPUT;

+

+  while(1) {

+    PSOCK_READTO(&s->sin, ISO_nl);

+

+    if(strncmp(s->inputbuf, http_referer, 8) == 0) {

+      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;

+      /*      httpd_log(&s->inputbuf[9]);*/

+    }

+  }

+  

+  PSOCK_END(&s->sin);

+}

+/*---------------------------------------------------------------------------*/

+static void

+handle_connection(struct httpd_state *s)

+{

+  handle_input(s);

+  if(s->state == STATE_OUTPUT) {

+    handle_output(s);

+  }

+}

+/*---------------------------------------------------------------------------*/

+void

+httpd_appcall(void)

+{

+  struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate);

+

+  if(uip_closed() || uip_aborted() || uip_timedout()) {

+  } else if(uip_connected()) {

+    PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);

+    PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);

+    PT_INIT(&s->outputpt);

+    s->state = STATE_WAITING;

+    /*    timer_set(&s->timer, CLOCK_SECOND * 100);*/

+    s->timer = 0;

+    handle_connection(s);

+  } else if(s != NULL) {

+    if(uip_poll()) {

+      ++s->timer;

+      if(s->timer >= 20) {

+	uip_abort();

+      }

+    } else {

+      s->timer = 0;

+    }

+    handle_connection(s);

+  } else {

+    uip_abort();

+  }

+}

+/*---------------------------------------------------------------------------*/

+/**

+ * \brief      Initialize the web server

+ *

+ *             This function initializes the web server and should be

+ *             called at system boot-up.

+ */

+void

+httpd_init(void)

+{

+  uip_listen(HTONS(80));

+}

+/*---------------------------------------------------------------------------*/

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd.h
new file mode 100644
index 0000000..7f7a666
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/httpd.h
@@ -0,0 +1,62 @@
+/*

+ * Copyright (c) 2001-2005, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $

+ *

+ */

+

+#ifndef __HTTPD_H__

+#define __HTTPD_H__

+

+#include "psock.h"

+#include "httpd-fs.h"

+

+struct httpd_state {

+  unsigned char timer;

+  struct psock sin, sout;

+  struct pt outputpt, scriptpt;

+  char inputbuf[50];

+  char filename[20];

+  char state;

+  struct httpd_fs_file file;

+  int len;

+  char *scriptptr;

+  int scriptlen;

+  

+  unsigned short count;

+};

+

+void httpd_init(void);

+void httpd_appcall(void);

+

+void httpd_log(char *msg);

+void httpd_log_file(u16_t *requester, char *file);

+

+#endif /* __HTTPD_H__ */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/lc-switch.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/lc-switch.h
new file mode 100644
index 0000000..17c8811
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/lc-switch.h
@@ -0,0 +1,76 @@
+/*

+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $

+ */

+

+/**

+ * \addtogroup lc

+ * @{

+ */

+

+/**

+ * \file

+ * Implementation of local continuations based on switch() statment

+ * \author Adam Dunkels <adam@sics.se>

+ *

+ * This implementation of local continuations uses the C switch()

+ * statement to resume execution of a function somewhere inside the

+ * function's body. The implementation is based on the fact that

+ * switch() statements are able to jump directly into the bodies of

+ * control structures such as if() or while() statmenets.

+ *

+ * This implementation borrows heavily from Simon Tatham's coroutines

+ * implementation in C:

+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

+ */

+

+#ifndef __LC_SWITCH_H__

+#define __LC_SWTICH_H__

+

+/* WARNING! lc implementation using switch() does not work if an

+   LC_SET() is done within another switch() statement! */

+

+/** \hideinitializer */

+typedef unsigned short lc_t;

+

+#define LC_INIT(s) s = 0;

+

+#define LC_RESUME(s) switch(s) { case 0:

+

+#define LC_SET(s) s = __LINE__; case __LINE__:

+

+#define LC_END(s) }

+

+#endif /* __LC_SWITCH_H__ */

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/lc.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/lc.h
new file mode 100644
index 0000000..3ad83cd
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/lc.h
@@ -0,0 +1,131 @@
+/*

+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $

+ */

+

+/**

+ * \addtogroup pt

+ * @{

+ */

+

+/**

+ * \defgroup lc Local continuations

+ * @{

+ *

+ * Local continuations form the basis for implementing protothreads. A

+ * local continuation can be <i>set</i> in a specific function to

+ * capture the state of the function. After a local continuation has

+ * been set can be <i>resumed</i> in order to restore the state of the

+ * function at the point where the local continuation was set.

+ *

+ *

+ */

+

+/**

+ * \file lc.h

+ * Local continuations

+ * \author

+ * Adam Dunkels <adam@sics.se>

+ *

+ */

+

+#ifdef DOXYGEN

+/**

+ * Initialize a local continuation.

+ *

+ * This operation initializes the local continuation, thereby

+ * unsetting any previously set continuation state.

+ *

+ * \hideinitializer

+ */

+#define LC_INIT(lc)

+

+/**

+ * Set a local continuation.

+ *

+ * The set operation saves the state of the function at the point

+ * where the operation is executed. As far as the set operation is

+ * concerned, the state of the function does <b>not</b> include the

+ * call-stack or local (automatic) variables, but only the program

+ * counter and such CPU registers that needs to be saved.

+ *

+ * \hideinitializer

+ */

+#define LC_SET(lc)

+

+/**

+ * Resume a local continuation.

+ *

+ * The resume operation resumes a previously set local continuation, thus

+ * restoring the state in which the function was when the local

+ * continuation was set. If the local continuation has not been

+ * previously set, the resume operation does nothing.

+ *

+ * \hideinitializer

+ */

+#define LC_RESUME(lc)

+

+/**

+ * Mark the end of local continuation usage.

+ *

+ * The end operation signifies that local continuations should not be

+ * used any more in the function. This operation is not needed for

+ * most implementations of local continuation, but is required by a

+ * few implementations.

+ *

+ * \hideinitializer

+ */

+#define LC_END(lc)

+

+/**

+ * \var typedef lc_t;

+ *

+ * The local continuation type.

+ *

+ * \hideinitializer

+ */

+#endif /* DOXYGEN */

+

+#ifndef __LC_H__

+#define __LC_H__

+

+#ifdef LC_CONF_INCLUDE

+#include LC_CONF_INCLUDE

+#else

+#include "lc-switch.h"

+#endif /* LC_CONF_INCLUDE */

+

+#endif /* __LC_H__ */

+

+/** @} */

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/makefsdata b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/makefsdata
new file mode 100644
index 0000000..8d2715a
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/makefsdata
@@ -0,0 +1,78 @@
+#!/usr/bin/perl

+

+open(OUTPUT, "> httpd-fsdata.c");

+

+chdir("httpd-fs");

+

+opendir(DIR, ".");

+@files =  grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);

+closedir(DIR);

+

+foreach $file (@files) {  

+   

+    if(-d $file && $file !~ /^\./) {

+	print "Processing directory $file\n";

+	opendir(DIR, $file);

+	@newfiles =  grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);

+	closedir(DIR);

+	printf "Adding files @newfiles\n";

+	@files = (@files, map { $_ = "$file/$_" } @newfiles);

+	next;

+    }

+}

+

+foreach $file (@files) {

+    if(-f $file) {

+	

+	print "Adding file $file\n";

+	

+	open(FILE, $file) || die "Could not open file $file\n";

+

+	$file =~ s-^-/-;

+	$fvar = $file;

+	$fvar =~ s-/-_-g;

+	$fvar =~ s-\.-_-g;

+	# for AVR, add PROGMEM here

+	print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");

+	print(OUTPUT "\t/* $file */\n\t");

+	for($j = 0; $j < length($file); $j++) {

+	    printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));

+	}

+	printf(OUTPUT "0,\n");

+	

+	

+	$i = 0;        

+	while(read(FILE, $data, 1)) {

+	    if($i == 0) {

+		print(OUTPUT "\t");

+	    }

+	    printf(OUTPUT "%#02x, ", unpack("C", $data));

+	    $i++;

+	    if($i == 10) {

+		print(OUTPUT "\n");

+		$i = 0;

+	    }

+	}

+	print(OUTPUT "0};\n\n");

+	close(FILE);

+	push(@fvars, $fvar);

+	push(@pfiles, $file);

+    }

+}

+

+for($i = 0; $i < @fvars; $i++) {

+    $file = $pfiles[$i];

+    $fvar = $fvars[$i];

+

+    if($i == 0) {

+        $prevfile = "NULL";

+    } else {

+        $prevfile = "file" . $fvars[$i - 1];

+    }

+    print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");

+    print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");

+    print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");

+}

+

+print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n");

+print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n");

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/makestrings b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/makestrings
new file mode 100644
index 0000000..8a13c6d
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/makestrings
@@ -0,0 +1,40 @@
+#!/usr/bin/perl

+

+

+sub stringify {

+  my $name = shift(@_);

+  open(OUTPUTC, "> $name.c");

+  open(OUTPUTH, "> $name.h");

+  

+  open(FILE, "$name");

+  

+  while(<FILE>) {

+    if(/(.+) "(.+)"/) {

+      $var = $1;

+      $data = $2;

+      

+      $datan = $data;

+      $datan =~ s/\\r/\r/g;

+      $datan =~ s/\\n/\n/g;

+      $datan =~ s/\\01/\01/g;      

+      $datan =~ s/\\0/\0/g;

+      

+      printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1);

+      printf(OUTPUTC "/* \"$data\" */\n");

+      printf(OUTPUTC "{");

+      for($j = 0; $j < length($datan); $j++) {

+	printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1)));

+      }

+      printf(OUTPUTC "};\n");

+      

+      printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1);

+      

+    }

+  }

+  close(OUTPUTC);

+  close(OUTPUTH);

+}

+stringify("http-strings");

+

+exit 0;

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/psock.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/psock.c
new file mode 100644
index 0000000..0c390d0
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/psock.c
@@ -0,0 +1,339 @@
+/*

+ * Copyright (c) 2004, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $

+ */

+

+#include <stdio.h>

+#include <string.h>

+

+#include "uipopt.h"

+#include "psock.h"

+#include "uip.h"

+

+#define STATE_NONE 0

+#define STATE_ACKED 1

+#define STATE_READ 2

+#define STATE_BLOCKED_NEWDATA 3

+#define STATE_BLOCKED_CLOSE 4

+#define STATE_BLOCKED_SEND 5

+#define STATE_DATA_SENT 6

+

+/*

+ * Return value of the buffering functions that indicates that a

+ * buffer was not filled by incoming data.

+ *

+ */

+#define BUF_NOT_FULL 0

+#define BUF_NOT_FOUND 0

+

+/*

+ * Return value of the buffering functions that indicates that a

+ * buffer was completely filled by incoming data.

+ *

+ */

+#define BUF_FULL 1

+

+/*

+ * Return value of the buffering functions that indicates that an

+ * end-marker byte was found.

+ *

+ */

+#define BUF_FOUND 2

+

+/*---------------------------------------------------------------------------*/

+static void

+buf_setup(struct psock_buf *buf,

+	  u8_t *bufptr, u16_t bufsize)

+{

+  buf->ptr = bufptr;

+  buf->left = bufsize;

+}

+/*---------------------------------------------------------------------------*/

+static u8_t

+buf_bufdata(struct psock_buf *buf, u16_t len,

+	    u8_t **dataptr, u16_t *datalen)

+{

+  ( void ) len;

+  if(*datalen < buf->left) {

+    memcpy(buf->ptr, *dataptr, *datalen);

+    buf->ptr += *datalen;

+    buf->left -= *datalen;

+    *dataptr += *datalen;

+    *datalen = 0;

+    return BUF_NOT_FULL;

+  } else if(*datalen == buf->left) {

+    memcpy(buf->ptr, *dataptr, *datalen);

+    buf->ptr += *datalen;

+    buf->left = 0;

+    *dataptr += *datalen;

+    *datalen = 0;

+    return BUF_FULL;

+  } else {

+    memcpy(buf->ptr, *dataptr, buf->left);

+    buf->ptr += buf->left;

+    *datalen -= buf->left;

+    *dataptr += buf->left;

+    buf->left = 0;

+    return BUF_FULL;

+  }

+}

+/*---------------------------------------------------------------------------*/

+static u8_t

+buf_bufto(register struct psock_buf *buf, u8_t endmarker,

+	  register u8_t **dataptr, register u16_t *datalen)

+{

+  u8_t c;

+  while(buf->left > 0 && *datalen > 0) {

+    c = *buf->ptr = **dataptr;

+    ++*dataptr;

+    ++buf->ptr;

+    --*datalen;

+    --buf->left;

+    

+    if(c == endmarker) {

+      return BUF_FOUND;

+    }

+  }

+

+  if(*datalen == 0) {

+    return BUF_NOT_FOUND;

+  }

+

+  while(*datalen > 0) {

+    c = **dataptr;

+    --*datalen;

+    ++*dataptr;

+    

+    if(c == endmarker) {

+      return BUF_FOUND | BUF_FULL;

+    }

+  }

+  

+  return BUF_FULL;

+}

+/*---------------------------------------------------------------------------*/

+static char

+send_data(register struct psock *s)

+{

+  if(s->state != STATE_DATA_SENT || uip_rexmit()) {

+    if(s->sendlen > uip_mss()) {

+      uip_send(s->sendptr, uip_mss());

+    } else {

+      uip_send(s->sendptr, s->sendlen);

+    }

+    s->state = STATE_DATA_SENT;

+    return 1;

+  }

+  return 0;

+}

+/*---------------------------------------------------------------------------*/

+static char

+data_acked(register struct psock *s)

+{

+  if(s->state == STATE_DATA_SENT && uip_acked()) {

+    if(s->sendlen > uip_mss()) {

+      s->sendlen -= uip_mss();

+      s->sendptr += uip_mss();

+    } else {

+      s->sendptr += s->sendlen;

+      s->sendlen = 0;

+    }

+    s->state = STATE_ACKED;

+    return 1;

+  }

+  return 0;

+}

+/*---------------------------------------------------------------------------*/

+PT_THREAD(psock_send(register struct psock *s, const char *buf,

+		     unsigned int len))

+{

+  PT_BEGIN(&s->psockpt);

+

+  /* If there is no data to send, we exit immediately. */

+  if(len == 0) {

+    PT_EXIT(&s->psockpt);

+  }

+

+  /* Save the length of and a pointer to the data that is to be

+     sent. */

+  s->sendptr = (unsigned char*)buf;

+  s->sendlen = len;

+

+  s->state = STATE_NONE;

+

+  /* We loop here until all data is sent. The s->sendlen variable is

+     updated by the data_sent() function. */

+  while(s->sendlen > 0) {

+

+    /*

+     * The condition for this PT_WAIT_UNTIL is a little tricky: the

+     * protothread will wait here until all data has been acknowledged

+     * (data_acked() returns true) and until all data has been sent

+     * (send_data() returns true). The two functions data_acked() and

+     * send_data() must be called in succession to ensure that all

+     * data is sent. Therefore the & operator is used instead of the

+     * && operator, which would cause only the data_acked() function

+     * to be called when it returns false.

+     */

+    PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));

+  }

+

+  s->state = STATE_NONE;

+  

+  PT_END(&s->psockpt);

+}

+/*---------------------------------------------------------------------------*/

+PT_THREAD(psock_generator_send(register struct psock *s,

+			       unsigned short (*generate)(void *), void *arg))

+{

+  PT_BEGIN(&s->psockpt);

+

+  /* Ensure that there is a generator function to call. */

+  if(generate == NULL) {

+    PT_EXIT(&s->psockpt);

+  }

+

+  /* Call the generator function to generate the data in the

+     uip_appdata buffer. */

+  s->sendlen = generate(arg);

+  s->sendptr = uip_appdata;

+

+  s->state = STATE_NONE;  

+  do {

+    /* Call the generator function again if we are called to perform a

+       retransmission. */

+    if(uip_rexmit()) {

+      generate(arg);

+    }

+    /* Wait until all data is sent and acknowledged. */

+    PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));

+  } while(s->sendlen > 0);

+  

+  s->state = STATE_NONE;

+  

+  PT_END(&s->psockpt);

+}

+/*---------------------------------------------------------------------------*/

+u16_t

+psock_datalen(struct psock *psock)

+{

+  return psock->bufsize - psock->buf.left;

+}

+/*---------------------------------------------------------------------------*/

+char

+psock_newdata(struct psock *s)

+{

+  if(s->readlen > 0) {

+    /* There is data in the uip_appdata buffer that has not yet been

+       read with the PSOCK_READ functions. */

+    return 1;

+  } else if(s->state == STATE_READ) {

+    /* All data in uip_appdata buffer already consumed. */

+    s->state = STATE_BLOCKED_NEWDATA;

+    return 0;

+  } else if(uip_newdata()) {

+    /* There is new data that has not been consumed. */

+    return 1;

+  } else {

+    /* There is no new data. */

+    return 0;

+  }

+}

+/*---------------------------------------------------------------------------*/

+PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))

+{

+  PT_BEGIN(&psock->psockpt);

+

+  buf_setup(&psock->buf, (unsigned char*)psock->bufptr, psock->bufsize);

+  

+  /* XXX: Should add buf_checkmarker() before do{} loop, if

+     incoming data has been handled while waiting for a write. */

+

+  do {

+    if(psock->readlen == 0) {

+      PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));

+      psock->state = STATE_READ;

+      psock->readptr = (u8_t *)uip_appdata;

+      psock->readlen = uip_datalen();

+    }

+  } while((buf_bufto(&psock->buf, c,

+		     &psock->readptr,

+		     &psock->readlen) & BUF_FOUND) == 0);

+  

+  if(psock_datalen(psock) == 0) {

+    psock->state = STATE_NONE;

+    PT_RESTART(&psock->psockpt);

+  }

+  PT_END(&psock->psockpt);

+}

+/*---------------------------------------------------------------------------*/

+PT_THREAD(psock_readbuf(register struct psock *psock))

+{

+  PT_BEGIN(&psock->psockpt);

+

+  buf_setup(&psock->buf, (unsigned char * ) psock->bufptr, psock->bufsize);

+  

+  /* XXX: Should add buf_checkmarker() before do{} loop, if

+     incoming data has been handled while waiting for a write. */

+

+  do {

+    if(psock->readlen == 0) {

+      PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));

+      printf("Waited for newdata\n");

+      psock->state = STATE_READ;

+      psock->readptr = (u8_t *)uip_appdata;

+      psock->readlen = uip_datalen();

+    }

+  } while(buf_bufdata(&psock->buf, psock->bufsize,

+			 &psock->readptr,

+			 &psock->readlen) != BUF_FULL);

+

+  if(psock_datalen(psock) == 0) {

+    psock->state = STATE_NONE;

+    PT_RESTART(&psock->psockpt);

+  }

+  PT_END(&psock->psockpt);

+}

+/*---------------------------------------------------------------------------*/

+void

+psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)

+{

+  psock->state = STATE_NONE;

+  psock->readlen = 0;

+  psock->bufptr = buffer;

+  psock->bufsize = buffersize;

+  buf_setup(&psock->buf, (unsigned char*) buffer, buffersize);

+  PT_INIT(&psock->pt);

+  PT_INIT(&psock->psockpt);

+}

+/*---------------------------------------------------------------------------*/

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/psock.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/psock.h
new file mode 100644
index 0000000..8d41258
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/psock.h
@@ -0,0 +1,380 @@
+/*

+ * Copyright (c) 2004, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $

+ */

+

+/**

+ * \defgroup psock Protosockets library

+ * @{

+ *

+ * The protosocket library provides an interface to the uIP stack that is

+ * similar to the traditional BSD socket interface. Unlike programs

+ * written for the ordinary uIP event-driven interface, programs

+ * written with the protosocket library are executed in a sequential

+ * fashion and does not have to be implemented as explicit state

+ * machines.

+ *

+ * Protosockets only work with TCP connections.

+ *

+ * The protosocket library uses \ref pt protothreads to provide

+ * sequential control flow. This makes the protosockets lightweight in

+ * terms of memory, but also means that protosockets inherits the

+ * functional limitations of protothreads. Each protosocket lives only

+ * within a single function. Automatic variables (stack variables) are

+ * not retained across a protosocket library function call.

+ *

+ * \note Because the protosocket library uses protothreads, local

+ * variables will not always be saved across a call to a protosocket

+ * library function. It is therefore advised that local variables are

+ * used with extreme care.

+ *

+ * The protosocket library provides functions for sending data without

+ * having to deal with retransmissions and acknowledgements, as well

+ * as functions for reading data without having to deal with data

+ * being split across more than one TCP segment.

+ *

+ * Because each protosocket runs as a protothread, the protosocket has to be

+ * started with a call to PSOCK_BEGIN() at the start of the function

+ * in which the protosocket is used. Similarly, the protosocket protothread can

+ * be terminated by a call to PSOCK_EXIT().

+ *

+ */

+

+/**

+ * \file

+ * Protosocket library header file

+ * \author

+ * Adam Dunkels <adam@sics.se>

+ *

+ */

+

+#ifndef __PSOCK_H__

+#define __PSOCK_H__

+

+#include "uipopt.h"

+#include "pt.h"

+

+ /*

+ * The structure that holds the state of a buffer.

+ *

+ * This structure holds the state of a uIP buffer. The structure has

+ * no user-visible elements, but is used through the functions

+ * provided by the library.

+ *

+ */

+struct psock_buf {

+  u8_t *ptr;

+  unsigned short left;

+};

+

+/**

+ * The representation of a protosocket.

+ *

+ * The protosocket structrure is an opaque structure with no user-visible

+ * elements.

+ */

+struct psock {

+  struct pt pt, psockpt; /* Protothreads - one that's using the psock

+			    functions, and one that runs inside the

+			    psock functions. */

+  const u8_t *sendptr;   /* Pointer to the next data to be sent. */

+  u8_t *readptr;         /* Pointer to the next data to be read. */

+  

+  char *bufptr;          /* Pointer to the buffer used for buffering

+			    incoming data. */

+  

+  u16_t sendlen;         /* The number of bytes left to be sent. */

+  u16_t readlen;         /* The number of bytes left to be read. */

+

+  struct psock_buf buf;  /* The structure holding the state of the

+			    input buffer. */

+  unsigned int bufsize;  /* The size of the input buffer. */

+  

+  unsigned char state;   /* The state of the protosocket. */

+};

+

+void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);

+/**

+ * Initialize a protosocket.

+ *

+ * This macro initializes a protosocket and must be called before the

+ * protosocket is used. The initialization also specifies the input buffer

+ * for the protosocket.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket to be

+ * initialized

+ *

+ * \param buffer (char *) A pointer to the input buffer for the

+ * protosocket.

+ *

+ * \param buffersize (unsigned int) The size of the input buffer.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_INIT(psock, buffer, buffersize) \

+  psock_init(psock, buffer, buffersize)

+

+/**

+ * Start the protosocket protothread in a function.

+ *

+ * This macro starts the protothread associated with the protosocket and

+ * must come before other protosocket calls in the function it is used.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket to be

+ * started.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))

+

+PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));

+/**

+ * Send data.

+ *

+ * This macro sends data over a protosocket. The protosocket protothread blocks

+ * until all data has been sent and is known to have been received by

+ * the remote end of the TCP connection.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket over which

+ * data is to be sent.

+ *

+ * \param data (char *) A pointer to the data that is to be sent.

+ *

+ * \param datalen (unsigned int) The length of the data that is to be

+ * sent.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_SEND(psock, data, datalen)		\

+    PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))

+

+/**

+ * \brief      Send a null-terminated string.

+ * \param psock Pointer to the protosocket.

+ * \param str  The string to be sent.

+ *

+ *             This function sends a null-terminated string over the

+ *             protosocket.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_SEND_STR(psock, str)      		\

+    PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))

+

+PT_THREAD(psock_generator_send(struct psock *psock,

+				unsigned short (*f)(void *), void *arg));

+

+/**

+ * \brief      Generate data with a function and send it

+ * \param psock Pointer to the protosocket.

+ * \param generator Pointer to the generator function

+ * \param arg   Argument to the generator function

+ *

+ *             This function generates data and sends it over the

+ *             protosocket. This can be used to dynamically generate

+ *             data for a transmission, instead of generating the data

+ *             in a buffer beforehand. This function reduces the need for

+ *             buffer memory. The generator function is implemented by

+ *             the application, and a pointer to the function is given

+ *             as an argument with the call to PSOCK_GENERATOR_SEND().

+ *

+ *             The generator function should place the generated data

+ *             directly in the uip_appdata buffer, and return the

+ *             length of the generated data. The generator function is

+ *             called by the protosocket layer when the data first is

+ *             sent, and once for every retransmission that is needed.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_GENERATOR_SEND(psock, generator, arg)     \

+    PT_WAIT_THREAD(&((psock)->pt),					\

+		   psock_generator_send(psock, generator, arg))

+

+

+/**

+ * Close a protosocket.

+ *

+ * This macro closes a protosocket and can only be called from within the

+ * protothread in which the protosocket lives.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket that is to

+ * be closed.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_CLOSE(psock) uip_close()

+

+PT_THREAD(psock_readbuf(struct psock *psock));

+/**

+ * Read data until the buffer is full.

+ *

+ * This macro will block waiting for data and read the data into the

+ * input buffer specified with the call to PSOCK_INIT(). Data is read

+ * until the buffer is full..

+ *

+ * \param psock (struct psock *) A pointer to the protosocket from which

+ * data should be read.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_READBUF(psock)				\

+  PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))

+

+PT_THREAD(psock_readto(struct psock *psock, unsigned char c));

+/**

+ * Read data up to a specified character.

+ *

+ * This macro will block waiting for data and read the data into the

+ * input buffer specified with the call to PSOCK_INIT(). Data is only

+ * read until the specifieed character appears in the data stream.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket from which

+ * data should be read.

+ *

+ * \param c (char) The character at which to stop reading.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_READTO(psock, c)				\

+  PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))

+

+/**

+ * The length of the data that was previously read.

+ *

+ * This macro returns the length of the data that was previously read

+ * using PSOCK_READTO() or PSOCK_READ().

+ *

+ * \param psock (struct psock *) A pointer to the protosocket holding the data.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_DATALEN(psock) psock_datalen(psock)

+

+u16_t psock_datalen(struct psock *psock);

+

+/**

+ * Exit the protosocket's protothread.

+ *

+ * This macro terminates the protothread of the protosocket and should

+ * almost always be used in conjunction with PSOCK_CLOSE().

+ *

+ * \sa PSOCK_CLOSE_EXIT()

+ *

+ * \param psock (struct psock *) A pointer to the protosocket.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))

+

+/**

+ * Close a protosocket and exit the protosocket's protothread.

+ *

+ * This macro closes a protosocket and exits the protosocket's protothread.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_CLOSE_EXIT(psock)		\

+  do {						\

+    PSOCK_CLOSE(psock);			\

+    PSOCK_EXIT(psock);			\

+  } while(0)

+

+/**

+ * Declare the end of a protosocket's protothread.

+ *

+ * This macro is used for declaring that the protosocket's protothread

+ * ends. It must always be used together with a matching PSOCK_BEGIN()

+ * macro.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_END(psock) PT_END(&((psock)->pt))

+

+char psock_newdata(struct psock *s);

+

+/**

+ * Check if new data has arrived on a protosocket.

+ *

+ * This macro is used in conjunction with the PSOCK_WAIT_UNTIL()

+ * macro to check if data has arrived on a protosocket.

+ *

+ * \param psock (struct psock *) A pointer to the protosocket.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_NEWDATA(psock) psock_newdata(psock)

+

+/**

+ * Wait until a condition is true.

+ *

+ * This macro blocks the protothread until the specified condition is

+ * true. The macro PSOCK_NEWDATA() can be used to check if new data

+ * arrives when the protosocket is waiting.

+ *

+ * Typically, this macro is used as follows:

+ *

+ \code

+ PT_THREAD(thread(struct psock *s, struct timer *t))

+ {

+   PSOCK_BEGIN(s);

+

+   PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));

+   

+   if(PSOCK_NEWDATA(s)) {

+     PSOCK_READTO(s, '\n');

+   } else {

+     handle_timed_out(s);

+   }

+   

+   PSOCK_END(s);

+ }

+ \endcode

+ *

+ * \param psock (struct psock *) A pointer to the protosocket.

+ * \param condition The condition to wait for.

+ *

+ * \hideinitializer

+ */

+#define PSOCK_WAIT_UNTIL(psock, condition)    \

+  PT_WAIT_UNTIL(&((psock)->pt), (condition));

+

+#define PSOCK_WAIT_THREAD(psock, condition)   \

+  PT_WAIT_THREAD(&((psock)->pt), (condition))

+

+#endif /* __PSOCK_H__ */

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/pt.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/pt.h
new file mode 100644
index 0000000..00ddd44
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/pt.h
@@ -0,0 +1,323 @@
+/*

+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $

+ */

+

+/**

+ * \addtogroup pt

+ * @{

+ */

+

+/**

+ * \file

+ * Protothreads implementation.

+ * \author

+ * Adam Dunkels <adam@sics.se>

+ *

+ */

+

+#ifndef __PT_H__

+#define __PT_H__

+

+#include "lc.h"

+

+struct pt {

+  lc_t lc;

+};

+

+#define PT_WAITING 0

+#define PT_EXITED  1

+#define PT_ENDED   2

+#define PT_YIELDED 3

+

+/**

+ * \name Initialization

+ * @{

+ */

+

+/**

+ * Initialize a protothread.

+ *

+ * Initializes a protothread. Initialization must be done prior to

+ * starting to execute the protothread.

+ *

+ * \param pt A pointer to the protothread control structure.

+ *

+ * \sa PT_SPAWN()

+ *

+ * \hideinitializer

+ */

+#define PT_INIT(pt)   LC_INIT((pt)->lc)

+

+/** @} */

+

+/**

+ * \name Declaration and definition

+ * @{

+ */

+

+/**

+ * Declaration of a protothread.

+ *

+ * This macro is used to declare a protothread. All protothreads must

+ * be declared with this macro.

+ *

+ * \param name_args The name and arguments of the C function

+ * implementing the protothread.

+ *

+ * \hideinitializer

+ */

+#define PT_THREAD(name_args) char name_args

+

+/**

+ * Declare the start of a protothread inside the C function

+ * implementing the protothread.

+ *

+ * This macro is used to declare the starting point of a

+ * protothread. It should be placed at the start of the function in

+ * which the protothread runs. All C statements above the PT_BEGIN()

+ * invokation will be executed each time the protothread is scheduled.

+ *

+ * \param pt A pointer to the protothread control structure.

+ *

+ * \hideinitializer

+ */

+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)

+

+/**

+ * Declare the end of a protothread.

+ *

+ * This macro is used for declaring that a protothread ends. It must

+ * always be used together with a matching PT_BEGIN() macro.

+ *

+ * \param pt A pointer to the protothread control structure.

+ *

+ * \hideinitializer

+ */

+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \

+                   PT_INIT(pt); return PT_ENDED; }

+

+/** @} */

+

+/**

+ * \name Blocked wait

+ * @{

+ */

+

+/**

+ * Block and wait until condition is true.

+ *

+ * This macro blocks the protothread until the specified condition is

+ * true.

+ *

+ * \param pt A pointer to the protothread control structure.

+ * \param condition The condition.

+ *

+ * \hideinitializer

+ */

+#define PT_WAIT_UNTIL(pt, condition)	        \

+  do {						\

+    LC_SET((pt)->lc);				\

+    if(!(condition)) {				\

+      return PT_WAITING;			\

+    }						\

+  } while(0)

+

+/**

+ * Block and wait while condition is true.

+ *

+ * This function blocks and waits while condition is true. See

+ * PT_WAIT_UNTIL().

+ *

+ * \param pt A pointer to the protothread control structure.

+ * \param cond The condition.

+ *

+ * \hideinitializer

+ */

+#define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))

+

+/** @} */

+

+/**

+ * \name Hierarchical protothreads

+ * @{

+ */

+

+/**

+ * Block and wait until a child protothread completes.

+ *

+ * This macro schedules a child protothread. The current protothread

+ * will block until the child protothread completes.

+ *

+ * \note The child protothread must be manually initialized with the

+ * PT_INIT() function before this function is used.

+ *

+ * \param pt A pointer to the protothread control structure.

+ * \param thread The child protothread with arguments

+ *

+ * \sa PT_SPAWN()

+ *

+ * \hideinitializer

+ */

+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))

+

+/**

+ * Spawn a child protothread and wait until it exits.

+ *

+ * This macro spawns a child protothread and waits until it exits. The

+ * macro can only be used within a protothread.

+ *

+ * \param pt A pointer to the protothread control structure.

+ * \param child A pointer to the child protothread's control structure.

+ * \param thread The child protothread with arguments

+ *

+ * \hideinitializer

+ */

+#define PT_SPAWN(pt, child, thread)		\

+  do {						\

+    PT_INIT((child));				\

+    PT_WAIT_THREAD((pt), (thread));		\

+  } while(0)

+

+/** @} */

+

+/**

+ * \name Exiting and restarting

+ * @{

+ */

+

+/**

+ * Restart the protothread.

+ *

+ * This macro will block and cause the running protothread to restart

+ * its execution at the place of the PT_BEGIN() call.

+ *

+ * \param pt A pointer to the protothread control structure.

+ *

+ * \hideinitializer

+ */

+#define PT_RESTART(pt)				\

+  do {						\

+    PT_INIT(pt);				\

+    return PT_WAITING;			\

+  } while(0)

+

+/**

+ * Exit the protothread.

+ *

+ * This macro causes the protothread to exit. If the protothread was

+ * spawned by another protothread, the parent protothread will become

+ * unblocked and can continue to run.

+ *

+ * \param pt A pointer to the protothread control structure.

+ *

+ * \hideinitializer

+ */

+#define PT_EXIT(pt)				\

+  do {						\

+    PT_INIT(pt);				\

+    return PT_EXITED;			\

+  } while(0)

+

+/** @} */

+

+/**

+ * \name Calling a protothread

+ * @{

+ */

+

+/**

+ * Schedule a protothread.

+ *

+ * This function shedules a protothread. The return value of the

+ * function is non-zero if the protothread is running or zero if the

+ * protothread has exited.

+ *

+ * \param f The call to the C function implementing the protothread to

+ * be scheduled

+ *

+ * \hideinitializer

+ */

+#define PT_SCHEDULE(f) ((f) == PT_WAITING)

+

+/** @} */

+

+/**

+ * \name Yielding from a protothread

+ * @{

+ */

+

+/**

+ * Yield from the current protothread.

+ *

+ * This function will yield the protothread, thereby allowing other

+ * processing to take place in the system.

+ *

+ * \param pt A pointer to the protothread control structure.

+ *

+ * \hideinitializer

+ */

+#define PT_YIELD(pt)				\

+  do {						\

+    PT_YIELD_FLAG = 0;				\

+    LC_SET((pt)->lc);				\

+    if(PT_YIELD_FLAG == 0) {			\

+      return PT_YIELDED;			\

+    }						\

+  } while(0)

+

+/**

+ * \brief      Yield from the protothread until a condition occurs.

+ * \param pt   A pointer to the protothread control structure.

+ * \param cond The condition.

+ *

+ *             This function will yield the protothread, until the

+ *             specified condition evaluates to true.

+ *

+ *

+ * \hideinitializer

+ */

+#define PT_YIELD_UNTIL(pt, cond)		\

+  do {						\

+    PT_YIELD_FLAG = 0;				\

+    LC_SET((pt)->lc);				\

+    if((PT_YIELD_FLAG == 0) || !(cond)) {	\

+      return PT_YIELDED;			\

+    }						\

+  } while(0)

+

+/** @} */

+

+#endif /* __PT_H__ */

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/timer.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/timer.c
new file mode 100644
index 0000000..8c270b2
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/timer.c
@@ -0,0 +1,127 @@
+/**

+ * \addtogroup timer

+ * @{

+ */

+

+/**

+ * \file

+ * Timer library implementation.

+ * \author

+ * Adam Dunkels <adam@sics.se>

+ */

+

+/*

+ * Copyright (c) 2004, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $

+ */

+

+#include "clock.h"

+#include "timer.h"

+

+/*---------------------------------------------------------------------------*/

+/**

+ * Set a timer.

+ *

+ * This function is used to set a timer for a time sometime in the

+ * future. The function timer_expired() will evaluate to true after

+ * the timer has expired.

+ *

+ * \param t A pointer to the timer

+ * \param interval The interval before the timer expires.

+ *

+ */

+void

+timer_set(struct timer *t, clock_time_t interval)

+{

+  t->interval = interval;

+  t->start = clock_time();

+}

+/*---------------------------------------------------------------------------*/

+/**

+ * Reset the timer with the same interval.

+ *

+ * This function resets the timer with the same interval that was

+ * given to the timer_set() function. The start point of the interval

+ * is the exact time that the timer last expired. Therefore, this

+ * function will cause the timer to be stable over time, unlike the

+ * timer_rester() function.

+ *

+ * \param t A pointer to the timer.

+ *

+ * \sa timer_restart()

+ */

+void

+timer_reset(struct timer *t)

+{

+  t->start += t->interval;

+}

+/*---------------------------------------------------------------------------*/

+/**

+ * Restart the timer from the current point in time

+ *

+ * This function restarts a timer with the same interval that was

+ * given to the timer_set() function. The timer will start at the

+ * current time.

+ *

+ * \note A periodic timer will drift if this function is used to reset

+ * it. For preioric timers, use the timer_reset() function instead.

+ *

+ * \param t A pointer to the timer.

+ *

+ * \sa timer_reset()

+ */

+void

+timer_restart(struct timer *t)

+{

+  t->start = clock_time();

+}

+/*---------------------------------------------------------------------------*/

+/**

+ * Check if a timer has expired.

+ *

+ * This function tests if a timer has expired and returns true or

+ * false depending on its status.

+ *

+ * \param t A pointer to the timer

+ *

+ * \return Non-zero if the timer has expired, zero otherwise.

+ *

+ */

+int

+timer_expired(struct timer *t)

+{

+  return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;

+}

+/*---------------------------------------------------------------------------*/

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/timer.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/timer.h
new file mode 100644
index 0000000..e28e3ca
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/timer.h
@@ -0,0 +1,86 @@
+/**

+ * \defgroup timer Timer library

+ *

+ * The timer library provides functions for setting, resetting and

+ * restarting timers, and for checking if a timer has expired. An

+ * application must "manually" check if its timers have expired; this

+ * is not done automatically.

+ *

+ * A timer is declared as a \c struct \c timer and all access to the

+ * timer is made by a pointer to the declared timer.

+ *

+ * \note The timer library uses the \ref clock "Clock library" to

+ * measure time. Intervals should be specified in the format used by

+ * the clock library.

+ *

+ * @{

+ */

+

+

+/**

+ * \file

+ * Timer library header file.

+ * \author

+ * Adam Dunkels <adam@sics.se>

+ */

+

+/*

+ * Copyright (c) 2004, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * Author: Adam Dunkels <adam@sics.se>

+ *

+ * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $

+ */

+#ifndef __TIMER_H__

+#define __TIMER_H__

+

+#include "clock.h"

+

+/**

+ * A timer.

+ *

+ * This structure is used for declaring a timer. The timer must be set

+ * with timer_set() before it can be used.

+ *

+ * \hideinitializer

+ */

+struct timer {

+  clock_time_t start;

+  clock_time_t interval;

+};

+

+void timer_set(struct timer *t, clock_time_t interval);

+void timer_reset(struct timer *t);

+void timer_restart(struct timer *t);

+int timer_expired(struct timer *t);

+

+#endif /* __TIMER_H__ */

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uIP_Task.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uIP_Task.c
new file mode 100644
index 0000000..e5274c9
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uIP_Task.c
@@ -0,0 +1,270 @@
+/*

+	FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.

+

+	This file is part of the FreeRTOS.org distribution.

+

+	FreeRTOS.org is free software; you can redistribute it and/or modify it

+	under the terms of the GNU General Public License (version 2) as published

+	by the Free Software Foundation and modified by the FreeRTOS exception.

+	**NOTE** The exception to the GPL is included to allow you to distribute a

+	combined work that includes FreeRTOS.org without being obliged to provide

+	the source code for any proprietary components.  Alternative commercial

+	license and support terms are also available upon request.  See the

+	licensing section of http://www.FreeRTOS.org for full details.

+

+	FreeRTOS.org is distributed in the hope that it will be useful,	but WITHOUT

+	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

+	FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for

+	more details.

+

+	You should have received a copy of the GNU General Public License along

+	with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59

+	Temple Place, Suite 330, Boston, MA  02111-1307  USA.

+

+

+	***************************************************************************

+	*                                                                         *

+	* Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *

+	*                                                                         *

+	* This is a concise, step by step, 'hands on' guide that describes both   *

+	* general multitasking concepts and FreeRTOS specifics. It presents and   *

+	* explains numerous examples that are written using the FreeRTOS API.     *

+	* Full source code for all the examples is provided in an accompanying    *

+	* .zip file.                                                              *

+	*                                                                         *

+	***************************************************************************

+

+	1 tab == 4 spaces!

+

+	Please ensure to read the configuration and relevant port sections of the

+	online documentation.

+

+	http://www.FreeRTOS.org - Documentation, latest information, license and

+	contact details.

+

+	http://www.SafeRTOS.com - A version that is certified for use in safety

+	critical systems.

+

+	http://www.OpenRTOS.com - Commercial support, development, porting,

+	licensing and training services.

+*/

+

+/* Standard includes. */

+#include <string.h>

+

+/* Scheduler includes. */

+#include "FreeRTOS.h"

+#include "task.h"

+#include "semphr.h"

+

+/* uip includes. */

+#include "uip.h"

+#include "uip_arp.h"

+#include "httpd.h"

+#include "timer.h"

+#include "clock-arch.h"

+

+/* Demo includes. */

+#include "EthDev_LPC17xx.h"

+#include "EthDev.h"

+#include "ParTest.h"

+

+/*-----------------------------------------------------------*/

+

+/* How long to wait before attempting to connect the MAC again. */

+#define uipINIT_WAIT    ( 100 / portTICK_RATE_MS )

+

+/* Shortcut to the header within the Rx buffer. */

+#define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])

+

+/* Standard constant. */

+#define uipTOTAL_FRAME_HEADER_SIZE	54

+

+/*-----------------------------------------------------------*/

+

+/*

+ * Setup the MAC address in the MAC itself, and in the uIP stack.

+ */

+static void prvSetMACAddress( void );

+

+/*

+ * Port functions required by the uIP stack.

+ */

+void clock_init( void );

+clock_time_t clock_time( void );

+

+/*-----------------------------------------------------------*/

+

+/* The semaphore used by the ISR to wake the uIP task. */

+xSemaphoreHandle xEMACSemaphore = NULL;

+

+/*-----------------------------------------------------------*/

+

+void clock_init(void)

+{

+	/* This is done when the scheduler starts. */

+}

+/*-----------------------------------------------------------*/

+

+clock_time_t clock_time( void )

+{

+	return xTaskGetTickCount();

+}

+/*-----------------------------------------------------------*/

+

+void vuIP_Task( void *pvParameters )

+{

+portBASE_TYPE i;

+uip_ipaddr_t xIPAddr;

+struct timer periodic_timer, arp_timer;

+extern void ( vEMAC_ISR_Wrapper )( void );

+

+	( void ) pvParameters;

+

+	/* Initialise the uIP stack. */

+	timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );

+	timer_set( &arp_timer, configTICK_RATE_HZ * 10 );

+	uip_init();

+	uip_ipaddr( xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );

+	uip_sethostaddr( xIPAddr );

+	uip_ipaddr( xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );

+	uip_setnetmask( xIPAddr );

+	httpd_init();

+

+	/* Create the semaphore used to wake the uIP task. */

+	vSemaphoreCreateBinary( xEMACSemaphore );

+

+	/* Initialise the MAC. */

+	while( lEMACInit() != pdPASS )

+    {

+        vTaskDelay( uipINIT_WAIT );

+    }

+

+	portENTER_CRITICAL();

+	{

+		EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE );

+

+		/* Set the interrupt priority to the max permissible to cause some

+		interrupt nesting. */

+		NVIC_SetPriority( ENET_IRQn, configMAX_SYSCALL_INTERRUPT_PRIORITY );

+

+		/* Enable the interrupt. */

+		NVIC_EnableIRQ( ENET_IRQn );

+		prvSetMACAddress();

+	}

+	portEXIT_CRITICAL();

+

+

+	for( ;; )

+	{

+		/* Is there received data ready to be processed? */

+		uip_len = ulGetEMACRxData();

+

+		if( ( uip_len > 0 ) && ( uip_buf != NULL ) )

+		{

+			/* Standard uIP loop taken from the uIP manual. */

+			if( xHeader->type == htons( UIP_ETHTYPE_IP ) )

+			{

+				uip_arp_ipin();

+				uip_input();

+

+				/* If the above function invocation resulted in data that

+				should be sent out on the network, the global variable

+				uip_len is set to a value > 0. */

+				if( uip_len > 0 )

+				{

+					uip_arp_out();

+					vSendEMACTxData( uip_len );

+				}

+			}

+			else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )

+			{

+				uip_arp_arpin();

+

+				/* If the above function invocation resulted in data that

+				should be sent out on the network, the global variable

+				uip_len is set to a value > 0. */

+				if( uip_len > 0 )

+				{

+					vSendEMACTxData( uip_len );

+				}

+			}

+		}

+		else

+		{

+			if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) )

+			{

+				timer_reset( &periodic_timer );

+				for( i = 0; i < UIP_CONNS; i++ )

+				{

+					uip_periodic( i );

+

+					/* If the above function invocation resulted in data that

+					should be sent out on the network, the global variable

+					uip_len is set to a value > 0. */

+					if( uip_len > 0 )

+					{

+						uip_arp_out();

+						vSendEMACTxData( uip_len );

+					}

+				}

+

+				/* Call the ARP timer function every 10 seconds. */

+				if( timer_expired( &arp_timer ) )

+				{

+					timer_reset( &arp_timer );

+					uip_arp_timer();

+				}

+			}

+			else

+			{

+				/* We did not receive a packet, and there was no periodic

+				processing to perform.  Block for a fixed period.  If a packet

+				is received during this period we will be woken by the ISR

+				giving us the Semaphore. */

+				xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );

+			}

+		}

+	}

+}

+/*-----------------------------------------------------------*/

+

+static void prvSetMACAddress( void )

+{

+struct uip_eth_addr xAddr;

+

+	/* Configure the MAC address in the uIP stack. */

+	xAddr.addr[ 0 ] = configMAC_ADDR0;

+	xAddr.addr[ 1 ] = configMAC_ADDR1;

+	xAddr.addr[ 2 ] = configMAC_ADDR2;

+	xAddr.addr[ 3 ] = configMAC_ADDR3;

+	xAddr.addr[ 4 ] = configMAC_ADDR4;

+	xAddr.addr[ 5 ] = configMAC_ADDR5;

+	uip_setethaddr( xAddr );

+}

+/*-----------------------------------------------------------*/

+

+void vApplicationProcessFormInput( portCHAR *pcInputString )

+{

+char *c;

+const unsigned long ulLEDNo = 3;

+

+	/* Process the form input sent by the IO page of the served HTML. */

+

+	c = strstr( pcInputString, "?" );

+    if( c )

+    {

+		/* Turn LED's on or off in accordance with the check box status. */

+		if( strstr( c, "LED0=1" ) != NULL )

+		{

+			/* Set LED7. */

+			vParTestSetLED( ulLEDNo, pdFALSE );

+		}

+		else

+		{

+			/* Clear LED7. */

+			vParTestSetLED( ulLEDNo, pdTRUE );

+		}

+    }

+}

+

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip-conf.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip-conf.h
new file mode 100644
index 0000000..b52b23f
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip-conf.h
@@ -0,0 +1,159 @@
+/**

+ * \addtogroup uipopt

+ * @{

+ */

+

+/**

+ * \name Project-specific configuration options

+ * @{

+ *

+ * uIP has a number of configuration options that can be overridden

+ * for each project. These are kept in a project-specific uip-conf.h

+ * file and all configuration names have the prefix UIP_CONF.

+ */

+

+/*

+ * Copyright (c) 2006, Swedish Institute of Computer Science.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the Institute nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $

+ */

+

+/**

+ * \file

+ *         An example uIP configuration file

+ * \author

+ *         Adam Dunkels <adam@sics.se>

+ */

+

+#ifndef __UIP_CONF_H__

+#define __UIP_CONF_H__

+

+#include <stdint.h>

+

+#define UIP_CONF_EXTERNAL_BUFFER

+

+/**

+ * 8 bit datatype

+ *

+ * This typedef defines the 8-bit type used throughout uIP.

+ *

+ * \hideinitializer

+ */

+typedef uint8_t u8_t;

+

+/**

+ * 16 bit datatype

+ *

+ * This typedef defines the 16-bit type used throughout uIP.

+ *

+ * \hideinitializer

+ */

+typedef uint16_t u16_t;

+

+/**

+ * Statistics datatype

+ *

+ * This typedef defines the dataype used for keeping statistics in

+ * uIP.

+ *

+ * \hideinitializer

+ */

+typedef unsigned short uip_stats_t;

+

+/**

+ * Maximum number of TCP connections.

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_MAX_CONNECTIONS 40

+

+/**

+ * Maximum number of listening TCP ports.

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_MAX_LISTENPORTS 40

+

+/**

+ * uIP buffer size.

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_BUFFER_SIZE     1480

+

+/**

+ * CPU byte order.

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_BYTE_ORDER      LITTLE_ENDIAN

+

+/**

+ * Logging on or off

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_LOGGING         0

+

+/**

+ * UDP support on or off

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_UDP             0

+

+/**

+ * UDP checksums on or off

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_UDP_CHECKSUMS   1

+

+/**

+ * uIP statistics on or off

+ *

+ * \hideinitializer

+ */

+#define UIP_CONF_STATISTICS      1

+

+/* Here we include the header file for the application(s) we use in

+   our project. */

+/*#include "smtp.h"*/

+/*#include "hello-world.h"*/

+/*#include "telnetd.h"*/

+#include "webserver.h"

+/*#include "dhcpc.h"*/

+/*#include "resolv.h"*/

+/*#include "webclient.h"*/

+

+#endif /* __UIP_CONF_H__ */

+

+/** @} */

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip.c
new file mode 100644
index 0000000..d323e99
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip.c
@@ -0,0 +1,1906 @@
+#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/

+

+/**

+ * \defgroup uip The uIP TCP/IP stack

+ * @{

+ *

+ * uIP is an implementation of the TCP/IP protocol stack intended for

+ * small 8-bit and 16-bit microcontrollers.

+ *

+ * uIP provides the necessary protocols for Internet communication,

+ * with a very small code footprint and RAM requirements - the uIP

+ * code size is on the order of a few kilobytes and RAM usage is on

+ * the order of a few hundred bytes.

+ */

+

+/**

+ * \file

+ * The uIP TCP/IP stack code.

+ * \author Adam Dunkels <adam@dunkels.com>

+ */

+

+/*

+ * Copyright (c) 2001-2003, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $

+ *

+ */

+

+/*

+ * uIP is a small implementation of the IP, UDP and TCP protocols (as

+ * well as some basic ICMP stuff). The implementation couples the IP,

+ * UDP, TCP and the application layers very tightly. To keep the size

+ * of the compiled code down, this code frequently uses the goto

+ * statement. While it would be possible to break the uip_process()

+ * function into many smaller functions, this would increase the code

+ * size because of the overhead of parameter passing and the fact that

+ * the optimier would not be as efficient.

+ *

+ * The principle is that we have a small buffer, called the uip_buf,

+ * in which the device driver puts an incoming packet. The TCP/IP

+ * stack parses the headers in the packet, and calls the

+ * application. If the remote host has sent data to the application,

+ * this data is present in the uip_buf and the application read the

+ * data from there. It is up to the application to put this data into

+ * a byte stream if needed. The application will not be fed with data

+ * that is out of sequence.

+ *

+ * If the application whishes to send data to the peer, it should put

+ * its data into the uip_buf. The uip_appdata pointer points to the

+ * first available byte. The TCP/IP stack will calculate the

+ * checksums, and fill in the necessary header fields and finally send

+ * the packet back to the peer.

+*/

+

+#include "uip.h"

+#include "uipopt.h"

+#include "uip_arch.h"

+

+#if UIP_CONF_IPV6

+#include "uip-neighbor.h"

+#endif /* UIP_CONF_IPV6 */

+

+#include <string.h>

+

+/*---------------------------------------------------------------------------*/

+/* Variable definitions. */

+

+

+/* The IP address of this host. If it is defined to be fixed (by

+   setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set

+   here. Otherwise, the address */

+#if UIP_FIXEDADDR > 0

+const uip_ipaddr_t uip_hostaddr =

+  {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),

+   HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};

+const uip_ipaddr_t uip_draddr =

+  {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),

+   HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};

+const uip_ipaddr_t uip_netmask =

+  {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),

+   HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};

+#else

+uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;

+#endif /* UIP_FIXEDADDR */

+

+static const uip_ipaddr_t all_ones_addr =

+#if UIP_CONF_IPV6

+  {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};

+#else /* UIP_CONF_IPV6 */

+  {0xffff,0xffff};

+#endif /* UIP_CONF_IPV6 */

+static const uip_ipaddr_t all_zeroes_addr =

+#if UIP_CONF_IPV6

+  {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};

+#else /* UIP_CONF_IPV6 */

+  {0x0000,0x0000};

+#endif /* UIP_CONF_IPV6 */

+

+#if UIP_FIXEDETHADDR

+const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,

+					  UIP_ETHADDR1,

+					  UIP_ETHADDR2,

+					  UIP_ETHADDR3,

+					  UIP_ETHADDR4,

+					  UIP_ETHADDR5}};

+#else

+struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};

+#endif

+

+#ifndef UIP_CONF_EXTERNAL_BUFFER

+

+#ifdef __ICCARM__

+	#pragma data_alignment=4

+		u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains incoming packets. */

+#else

+	u8_t uip_buf[UIP_BUFSIZE + 2] ALIGN_STRUCT_END; /* The packet buffer that contains incoming packets. */

+#endif

+

+#endif /* UIP_CONF_EXTERNAL_BUFFER */

+

+void *uip_appdata;               /* The uip_appdata pointer points to

+				    application data. */

+void *uip_sappdata;              /* The uip_appdata pointer points to

+				    the application data which is to

+				    be sent. */

+#if UIP_URGDATA > 0

+void *uip_urgdata;               /* The uip_urgdata pointer points to

+   				    urgent data (out-of-band data), if

+   				    present. */

+u16_t uip_urglen, uip_surglen;

+#endif /* UIP_URGDATA > 0 */

+

+u16_t uip_len, uip_slen;

+                             /* The uip_len is either 8 or 16 bits,

+				depending on the maximum packet

+				size. */

+

+u8_t uip_flags;     /* The uip_flags variable is used for

+				communication between the TCP/IP stack

+				and the application program. */

+struct uip_conn *uip_conn;   /* uip_conn always points to the current

+				connection. */

+

+struct uip_conn uip_conns[UIP_CONNS];

+                             /* The uip_conns array holds all TCP

+				connections. */

+u16_t uip_listenports[UIP_LISTENPORTS];

+                             /* The uip_listenports list all currently

+				listning ports. */

+#if UIP_UDP

+struct uip_udp_conn *uip_udp_conn;

+struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];

+#endif /* UIP_UDP */

+

+static u16_t ipid;           /* Ths ipid variable is an increasing

+				number that is used for the IP ID

+				field. */

+

+void uip_setipid(u16_t id) { ipid = id; }

+

+static u8_t iss[4];          /* The iss variable is used for the TCP

+				initial sequence number. */

+

+#if UIP_ACTIVE_OPEN

+static u16_t lastport;       /* Keeps track of the last port used for

+				a new connection. */

+#endif /* UIP_ACTIVE_OPEN */

+

+/* Temporary variables. */

+u8_t uip_acc32[4];

+static u8_t c, opt;

+static u16_t tmp16;

+

+/* Structures and definitions. */

+#define TCP_FIN 0x01

+#define TCP_SYN 0x02

+#define TCP_RST 0x04

+#define TCP_PSH 0x08

+#define TCP_ACK 0x10

+#define TCP_URG 0x20

+#define TCP_CTL 0x3f

+

+#define TCP_OPT_END     0   /* End of TCP options list */

+#define TCP_OPT_NOOP    1   /* "No-operation" TCP option */

+#define TCP_OPT_MSS     2   /* Maximum segment size TCP option */

+

+#define TCP_OPT_MSS_LEN 4   /* Length of TCP MSS option. */

+

+#define ICMP_ECHO_REPLY 0

+#define ICMP_ECHO       8

+

+#define ICMP6_ECHO_REPLY             129

+#define ICMP6_ECHO                   128

+#define ICMP6_NEIGHBOR_SOLICITATION  135

+#define ICMP6_NEIGHBOR_ADVERTISEMENT 136

+

+#define ICMP6_FLAG_S (1 << 6)

+

+#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1

+#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2

+

+

+/* Macros. */

+#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])

+#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])

+#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])

+#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])

+

+

+#if UIP_STATISTICS == 1

+struct uip_stats uip_stat;

+#define UIP_STAT(s) s

+#else

+#define UIP_STAT(s)

+#endif /* UIP_STATISTICS == 1 */

+

+#if UIP_LOGGING == 1

+#include <stdio.h>

+void uip_log(char *msg);

+#define UIP_LOG(m) uip_log(m)

+#else

+#define UIP_LOG(m)

+#endif /* UIP_LOGGING == 1 */

+

+#if ! UIP_ARCH_ADD32

+void

+uip_add32(u8_t *op32, u16_t op16)

+{

+  uip_acc32[3] = op32[3] + (op16 & 0xff);

+  uip_acc32[2] = op32[2] + (op16 >> 8);

+  uip_acc32[1] = op32[1];

+  uip_acc32[0] = op32[0];

+

+  if(uip_acc32[2] < (op16 >> 8)) {

+    ++uip_acc32[1];

+    if(uip_acc32[1] == 0) {

+      ++uip_acc32[0];

+    }

+  }

+

+

+  if(uip_acc32[3] < (op16 & 0xff)) {

+    ++uip_acc32[2];

+    if(uip_acc32[2] == 0) {

+      ++uip_acc32[1];

+      if(uip_acc32[1] == 0) {

+	++uip_acc32[0];

+      }

+    }

+  }

+}

+

+#endif /* UIP_ARCH_ADD32 */

+

+#if ! UIP_ARCH_CHKSUM

+/*---------------------------------------------------------------------------*/

+static u16_t

+chksum(u16_t sum, const u8_t *data, u16_t len)

+{

+  u16_t t;

+  const u8_t *dataptr;

+  const u8_t *last_byte;

+

+  dataptr = data;

+  last_byte = data + len - 1;

+

+  while(dataptr < last_byte) {	/* At least two more bytes */

+    t = (dataptr[0] << 8) + dataptr[1];

+    sum += t;

+    if(sum < t) {

+      sum++;		/* carry */

+    }

+    dataptr += 2;

+  }

+

+  if(dataptr == last_byte) {

+    t = (dataptr[0] << 8) + 0;

+    sum += t;

+    if(sum < t) {

+      sum++;		/* carry */

+    }

+  }

+

+  /* Return sum in host byte order. */

+  return sum;

+}

+/*---------------------------------------------------------------------------*/

+u16_t

+uip_chksum(u16_t *data, u16_t len)

+{

+  return htons(chksum(0, (u8_t *)data, len));

+}

+/*---------------------------------------------------------------------------*/

+#ifndef UIP_ARCH_IPCHKSUM

+u16_t

+uip_ipchksum(void)

+{

+  u16_t sum;

+

+  sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);

+  DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);

+  return (sum == 0) ? 0xffff : htons(sum);

+}

+#endif

+/*---------------------------------------------------------------------------*/

+static u16_t

+upper_layer_chksum(u8_t proto)

+{

+  u16_t upper_layer_len;

+  u16_t sum;

+

+#if UIP_CONF_IPV6

+  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);

+#else /* UIP_CONF_IPV6 */

+  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;

+#endif /* UIP_CONF_IPV6 */

+

+  /* First sum pseudoheader. */

+

+  /* IP protocol and length fields. This addition cannot carry. */

+  sum = upper_layer_len + proto;

+  /* Sum IP source and destination addresses. */

+  sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));

+

+  /* Sum TCP header and data. */

+  sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],

+	       upper_layer_len);

+

+  return (sum == 0) ? 0xffff : htons(sum);

+}

+/*---------------------------------------------------------------------------*/

+#if UIP_CONF_IPV6

+u16_t

+uip_icmp6chksum(void)

+{

+  return upper_layer_chksum(UIP_PROTO_ICMP6);

+

+}

+#endif /* UIP_CONF_IPV6 */

+/*---------------------------------------------------------------------------*/

+u16_t

+uip_tcpchksum(void)

+{

+  return upper_layer_chksum(UIP_PROTO_TCP);

+}

+/*---------------------------------------------------------------------------*/

+#if UIP_UDP_CHECKSUMS

+u16_t

+uip_udpchksum(void)

+{

+  return upper_layer_chksum(UIP_PROTO_UDP);

+}

+#endif /* UIP_UDP_CHECKSUMS */

+#endif /* UIP_ARCH_CHKSUM */

+/*---------------------------------------------------------------------------*/

+void

+uip_init(void)

+{

+  for(c = 0; c < UIP_LISTENPORTS; ++c) {

+    uip_listenports[c] = 0;

+  }

+  for(c = 0; c < UIP_CONNS; ++c) {

+    uip_conns[c].tcpstateflags = UIP_CLOSED;

+  }

+#if UIP_ACTIVE_OPEN

+  lastport = 1024;

+#endif /* UIP_ACTIVE_OPEN */

+

+#if UIP_UDP

+  for(c = 0; c < UIP_UDP_CONNS; ++c) {

+    uip_udp_conns[c].lport = 0;

+  }

+#endif /* UIP_UDP */

+

+

+  /* IPv4 initialization. */

+#if UIP_FIXEDADDR == 0

+  /*  uip_hostaddr[0] = uip_hostaddr[1] = 0;*/

+#endif /* UIP_FIXEDADDR */

+

+}

+/*---------------------------------------------------------------------------*/

+#if UIP_ACTIVE_OPEN

+struct uip_conn *

+uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)

+{

+  register struct uip_conn *conn, *cconn;

+

+  /* Find an unused local port. */

+ again:

+  ++lastport;

+

+  if(lastport >= 32000) {

+    lastport = 4096;

+  }

+

+  /* Check if this port is already in use, and if so try to find

+     another one. */

+  for(c = 0; c < UIP_CONNS; ++c) {

+    conn = &uip_conns[c];

+    if(conn->tcpstateflags != UIP_CLOSED &&

+       conn->lport == htons(lastport)) {

+      goto again;

+    }

+  }

+

+  conn = 0;

+  for(c = 0; c < UIP_CONNS; ++c) {

+    cconn = &uip_conns[c];

+    if(cconn->tcpstateflags == UIP_CLOSED) {

+      conn = cconn;

+      break;

+    }

+    if(cconn->tcpstateflags == UIP_TIME_WAIT) {

+      if(conn == 0 ||

+	 cconn->timer > conn->timer) {

+	conn = cconn;

+      }

+    }

+  }

+

+  if(conn == 0) {

+    return 0;

+  }

+

+  conn->tcpstateflags = UIP_SYN_SENT;

+

+  conn->snd_nxt[0] = iss[0];

+  conn->snd_nxt[1] = iss[1];

+  conn->snd_nxt[2] = iss[2];

+  conn->snd_nxt[3] = iss[3];

+

+  conn->initialmss = conn->mss = UIP_TCP_MSS;

+

+  conn->len = 1;   /* TCP length of the SYN is one. */

+  conn->nrtx = 0;

+  conn->timer = 1; /* Send the SYN next time around. */

+  conn->rto = UIP_RTO;

+  conn->sa = 0;

+  conn->sv = 16;   /* Initial value of the RTT variance. */

+  conn->lport = htons(lastport);

+  conn->rport = rport;

+  uip_ipaddr_copy(&conn->ripaddr, ripaddr);

+

+  return conn;

+}

+#endif /* UIP_ACTIVE_OPEN */

+/*---------------------------------------------------------------------------*/

+#if UIP_UDP

+struct uip_udp_conn *

+uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)

+{

+  register struct uip_udp_conn *conn;

+

+  /* Find an unused local port. */

+ again:

+  ++lastport;

+

+  if(lastport >= 32000) {

+    lastport = 4096;

+  }

+

+  for(c = 0; c < UIP_UDP_CONNS; ++c) {

+    if(uip_udp_conns[c].lport == htons(lastport)) {

+      goto again;

+    }

+  }

+

+

+  conn = 0;

+  for(c = 0; c < UIP_UDP_CONNS; ++c) {

+    if(uip_udp_conns[c].lport == 0) {

+      conn = &uip_udp_conns[c];

+      break;

+    }

+  }

+

+  if(conn == 0) {

+    return 0;

+  }

+

+  conn->lport = HTONS(lastport);

+  conn->rport = rport;

+  if(ripaddr == NULL) {

+    memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));

+  } else {

+    uip_ipaddr_copy(&conn->ripaddr, ripaddr);

+  }

+  conn->ttl = UIP_TTL;

+

+  return conn;

+}

+#endif /* UIP_UDP */

+/*---------------------------------------------------------------------------*/

+void

+uip_unlisten(u16_t port)

+{

+  for(c = 0; c < UIP_LISTENPORTS; ++c) {

+    if(uip_listenports[c] == port) {

+      uip_listenports[c] = 0;

+      return;

+    }

+  }

+}

+/*---------------------------------------------------------------------------*/

+void

+uip_listen(u16_t port)

+{

+  for(c = 0; c < UIP_LISTENPORTS; ++c) {

+    if(uip_listenports[c] == 0) {

+      uip_listenports[c] = port;

+      return;

+    }

+  }

+}

+/*---------------------------------------------------------------------------*/

+/* XXX: IP fragment reassembly: not well-tested. */

+

+#if UIP_REASSEMBLY && !UIP_CONF_IPV6

+#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)

+static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];

+static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];

+static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,

+				    0x0f, 0x07, 0x03, 0x01};

+static u16_t uip_reasslen;

+static u8_t uip_reassflags;

+#define UIP_REASS_FLAG_LASTFRAG 0x01

+static u8_t uip_reasstmr;

+

+#define IP_MF   0x20

+

+static u8_t

+uip_reass(void)

+{

+  u16_t offset, len;

+  u16_t i;

+

+  /* If ip_reasstmr is zero, no packet is present in the buffer, so we

+     write the IP header of the fragment into the reassembly

+     buffer. The timer is updated with the maximum age. */

+  if(uip_reasstmr == 0) {

+    memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);

+    uip_reasstmr = UIP_REASS_MAXAGE;

+    uip_reassflags = 0;

+    /* Clear the bitmap. */

+    memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));

+  }

+

+  /* Check if the incoming fragment matches the one currently present

+     in the reasembly buffer. If so, we proceed with copying the

+     fragment into the buffer. */

+  if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&

+     BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&

+     BUF->destipaddr[0] == FBUF->destipaddr[0] &&

+     BUF->destipaddr[1] == FBUF->destipaddr[1] &&

+     BUF->ipid[0] == FBUF->ipid[0] &&

+     BUF->ipid[1] == FBUF->ipid[1]) {

+

+    len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;

+    offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;

+

+    /* If the offset or the offset + fragment length overflows the

+       reassembly buffer, we discard the entire packet. */

+    if(offset > UIP_REASS_BUFSIZE ||

+       offset + len > UIP_REASS_BUFSIZE) {

+      uip_reasstmr = 0;

+      goto nullreturn;

+    }

+

+    /* Copy the fragment into the reassembly buffer, at the right

+       offset. */

+    memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],

+	   (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),

+	   len);

+

+    /* Update the bitmap. */

+    if(offset / (8 * 8) == (offset + len) / (8 * 8)) {

+      /* If the two endpoints are in the same byte, we only update

+	 that byte. */

+

+      uip_reassbitmap[offset / (8 * 8)] |=

+	     bitmap_bits[(offset / 8 ) & 7] &

+	     ~bitmap_bits[((offset + len) / 8 ) & 7];

+    } else {

+      /* If the two endpoints are in different bytes, we update the

+	 bytes in the endpoints and fill the stuff inbetween with

+	 0xff. */

+      uip_reassbitmap[offset / (8 * 8)] |=

+	bitmap_bits[(offset / 8 ) & 7];

+      for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {

+	uip_reassbitmap[i] = 0xff;

+      }

+      uip_reassbitmap[(offset + len) / (8 * 8)] |=

+	~bitmap_bits[((offset + len) / 8 ) & 7];

+    }

+

+    /* If this fragment has the More Fragments flag set to zero, we

+       know that this is the last fragment, so we can calculate the

+       size of the entire packet. We also set the

+       IP_REASS_FLAG_LASTFRAG flag to indicate that we have received

+       the final fragment. */

+

+    if((BUF->ipoffset[0] & IP_MF) == 0) {

+      uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;

+      uip_reasslen = offset + len;

+    }

+

+    /* Finally, we check if we have a full packet in the buffer. We do

+       this by checking if we have the last fragment and if all bits

+       in the bitmap are set. */

+    if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {

+      /* Check all bytes up to and including all but the last byte in

+	 the bitmap. */

+      for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {

+	if(uip_reassbitmap[i] != 0xff) {

+	  goto nullreturn;

+	}

+      }

+      /* Check the last byte in the bitmap. It should contain just the

+	 right amount of bits. */

+      if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=

+	 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {

+	goto nullreturn;

+      }

+

+      /* If we have come this far, we have a full packet in the

+	 buffer, so we allocate a pbuf and copy the packet into it. We

+	 also reset the timer. */

+      uip_reasstmr = 0;

+      memcpy(BUF, FBUF, uip_reasslen);

+

+      /* Pretend to be a "normal" (i.e., not fragmented) IP packet

+	 from now on. */

+      BUF->ipoffset[0] = BUF->ipoffset[1] = 0;

+      BUF->len[0] = uip_reasslen >> 8;

+      BUF->len[1] = uip_reasslen & 0xff;

+      BUF->ipchksum = 0;

+      BUF->ipchksum = ~(uip_ipchksum());

+

+      return uip_reasslen;

+    }

+  }

+

+ nullreturn:

+  return 0;

+}

+#endif /* UIP_REASSEMBLY */

+/*---------------------------------------------------------------------------*/

+static void

+uip_add_rcv_nxt(u16_t n)

+{

+  uip_add32(uip_conn->rcv_nxt, n);

+  uip_conn->rcv_nxt[0] = uip_acc32[0];

+  uip_conn->rcv_nxt[1] = uip_acc32[1];

+  uip_conn->rcv_nxt[2] = uip_acc32[2];

+  uip_conn->rcv_nxt[3] = uip_acc32[3];

+}

+/*---------------------------------------------------------------------------*/

+void

+uip_process(u8_t flag)

+{

+  register struct uip_conn *uip_connr = uip_conn;

+

+#if UIP_UDP

+  if(flag == UIP_UDP_SEND_CONN) {

+    goto udp_send;

+  }

+#endif /* UIP_UDP */

+

+  uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];

+

+  /* Check if we were invoked because of a poll request for a

+     particular connection. */

+  if(flag == UIP_POLL_REQUEST) {

+    if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&

+       !uip_outstanding(uip_connr)) {

+	uip_flags = UIP_POLL;

+	UIP_APPCALL();

+	goto appsend;

+    }

+    goto drop;

+

+    /* Check if we were invoked because of the perodic timer fireing. */

+  } else if(flag == UIP_TIMER) {

+#if UIP_REASSEMBLY

+    if(uip_reasstmr != 0) {

+      --uip_reasstmr;

+    }

+#endif /* UIP_REASSEMBLY */

+    /* Increase the initial sequence number. */

+    if(++iss[3] == 0) {

+      if(++iss[2] == 0) {

+	if(++iss[1] == 0) {

+	  ++iss[0];

+	}

+      }

+    }

+

+    /* Reset the length variables. */

+    uip_len = 0;

+    uip_slen = 0;

+

+    /* Check if the connection is in a state in which we simply wait

+       for the connection to time out. If so, we increase the

+       connection's timer and remove the connection if it times

+       out. */

+    if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||

+       uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {

+      ++(uip_connr->timer);

+      if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {

+	uip_connr->tcpstateflags = UIP_CLOSED;

+      }

+    } else if(uip_connr->tcpstateflags != UIP_CLOSED) {

+      /* If the connection has outstanding data, we increase the

+	 connection's timer and see if it has reached the RTO value

+	 in which case we retransmit. */

+      if(uip_outstanding(uip_connr)) {

+	  uip_connr->timer = uip_connr->timer - 1;

+	if(uip_connr->timer == 0) {

+	  if(uip_connr->nrtx == UIP_MAXRTX ||

+	     ((uip_connr->tcpstateflags == UIP_SYN_SENT ||

+	       uip_connr->tcpstateflags == UIP_SYN_RCVD) &&

+	      uip_connr->nrtx == UIP_MAXSYNRTX)) {

+	    uip_connr->tcpstateflags = UIP_CLOSED;

+

+	    /* We call UIP_APPCALL() with uip_flags set to

+	       UIP_TIMEDOUT to inform the application that the

+	       connection has timed out. */

+	    uip_flags = UIP_TIMEDOUT;

+	    UIP_APPCALL();

+

+	    /* We also send a reset packet to the remote host. */

+	    BUF->flags = TCP_RST | TCP_ACK;

+	    goto tcp_send_nodata;

+	  }

+

+	  /* Exponential backoff. */

+	  uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?

+					 4:

+					 uip_connr->nrtx);

+	  ++(uip_connr->nrtx);

+

+	  /* Ok, so we need to retransmit. We do this differently

+	     depending on which state we are in. In ESTABLISHED, we

+	     call upon the application so that it may prepare the

+	     data for the retransmit. In SYN_RCVD, we resend the

+	     SYNACK that we sent earlier and in LAST_ACK we have to

+	     retransmit our FINACK. */

+	  UIP_STAT(++uip_stat.tcp.rexmit);

+	  switch(uip_connr->tcpstateflags & UIP_TS_MASK) {

+	  case UIP_SYN_RCVD:

+	    /* In the SYN_RCVD state, we should retransmit our

+               SYNACK. */

+	    goto tcp_send_synack;

+

+#if UIP_ACTIVE_OPEN

+	  case UIP_SYN_SENT:

+	    /* In the SYN_SENT state, we retransmit out SYN. */

+	    BUF->flags = 0;

+	    goto tcp_send_syn;

+#endif /* UIP_ACTIVE_OPEN */

+

+	  case UIP_ESTABLISHED:

+	    /* In the ESTABLISHED state, we call upon the application

+               to do the actual retransmit after which we jump into

+               the code for sending out the packet (the apprexmit

+               label). */

+	    uip_flags = UIP_REXMIT;

+	    UIP_APPCALL();

+	    goto apprexmit;

+

+	  case UIP_FIN_WAIT_1:

+	  case UIP_CLOSING:

+	  case UIP_LAST_ACK:

+	    /* In all these states we should retransmit a FINACK. */

+	    goto tcp_send_finack;

+

+	  }

+	}

+      } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {

+	/* If there was no need for a retransmission, we poll the

+           application for new data. */

+	uip_flags = UIP_POLL;

+	UIP_APPCALL();

+	goto appsend;

+      }

+    }

+    goto drop;

+  }

+#if UIP_UDP

+  if(flag == UIP_UDP_TIMER) {

+    if(uip_udp_conn->lport != 0) {

+      uip_conn = NULL;

+      uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];

+      uip_len = uip_slen = 0;

+      uip_flags = UIP_POLL;

+      UIP_UDP_APPCALL();

+      goto udp_send;

+    } else {

+      goto drop;

+    }

+  }

+#endif

+

+  /* This is where the input processing starts. */

+  UIP_STAT(++uip_stat.ip.recv);

+

+  /* Start of IP input header processing code. */

+

+#if UIP_CONF_IPV6

+  /* Check validity of the IP header. */

+  if((BUF->vtc & 0xf0) != 0x60)  { /* IP version and header length. */

+    UIP_STAT(++uip_stat.ip.drop);

+    UIP_STAT(++uip_stat.ip.vhlerr);

+    UIP_LOG("ipv6: invalid version.");

+    goto drop;

+  }

+#else /* UIP_CONF_IPV6 */

+  /* Check validity of the IP header. */

+  if(BUF->vhl != 0x45)  { /* IP version and header length. */

+    UIP_STAT(++uip_stat.ip.drop);

+    UIP_STAT(++uip_stat.ip.vhlerr);

+    UIP_LOG("ip: invalid version or header length.");

+    goto drop;

+  }

+#endif /* UIP_CONF_IPV6 */

+

+  /* Check the size of the packet. If the size reported to us in

+     uip_len is smaller the size reported in the IP header, we assume

+     that the packet has been corrupted in transit. If the size of

+     uip_len is larger than the size reported in the IP packet header,

+     the packet has been padded and we set uip_len to the correct

+     value.. */

+

+  if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {

+    uip_len = (BUF->len[0] << 8) + BUF->len[1];

+#if UIP_CONF_IPV6

+    uip_len += 40; /* The length reported in the IPv6 header is the

+		      length of the payload that follows the

+		      header. However, uIP uses the uip_len variable

+		      for holding the size of the entire packet,

+		      including the IP header. For IPv4 this is not a

+		      problem as the length field in the IPv4 header

+		      contains the length of the entire packet. But

+		      for IPv6 we need to add the size of the IPv6

+		      header (40 bytes). */

+#endif /* UIP_CONF_IPV6 */

+  } else {

+    UIP_LOG("ip: packet shorter than reported in IP header.");

+    goto drop;

+  }

+

+#if !UIP_CONF_IPV6

+  /* Check the fragment flag. */

+  if((BUF->ipoffset[0] & 0x3f) != 0 ||

+     BUF->ipoffset[1] != 0) {

+#if UIP_REASSEMBLY

+    uip_len = uip_reass();

+    if(uip_len == 0) {

+      goto drop;

+    }

+#else /* UIP_REASSEMBLY */

+    UIP_STAT(++uip_stat.ip.drop);

+    UIP_STAT(++uip_stat.ip.fragerr);

+    UIP_LOG("ip: fragment dropped.");

+    goto drop;

+#endif /* UIP_REASSEMBLY */

+  }

+#endif /* UIP_CONF_IPV6 */

+

+  if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {

+    /* If we are configured to use ping IP address configuration and

+       hasn't been assigned an IP address yet, we accept all ICMP

+       packets. */

+#if UIP_PINGADDRCONF && !UIP_CONF_IPV6

+    if(BUF->proto == UIP_PROTO_ICMP) {

+      UIP_LOG("ip: possible ping config packet received.");

+      goto icmp_input;

+    } else {

+      UIP_LOG("ip: packet dropped since no address assigned.");

+      goto drop;

+    }

+#endif /* UIP_PINGADDRCONF */

+

+  } else {

+    /* If IP broadcast support is configured, we check for a broadcast

+       UDP packet, which may be destined to us. */

+#if UIP_BROADCAST

+    DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());

+    if(BUF->proto == UIP_PROTO_UDP &&

+       uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)

+       /*&&

+	 uip_ipchksum() == 0xffff*/) {

+      goto udp_input;

+    }

+#endif /* UIP_BROADCAST */

+

+    /* Check if the packet is destined for our IP address. */

+#if !UIP_CONF_IPV6

+    if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {

+      UIP_STAT(++uip_stat.ip.drop);

+      goto drop;

+    }

+#else /* UIP_CONF_IPV6 */

+    /* For IPv6, packet reception is a little trickier as we need to

+       make sure that we listen to certain multicast addresses (all

+       hosts multicast address, and the solicited-node multicast

+       address) as well. However, we will cheat here and accept all

+       multicast packets that are sent to the ff02::/16 addresses. */

+    if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&

+       BUF->destipaddr[0] != HTONS(0xff02)) {

+      UIP_STAT(++uip_stat.ip.drop);

+      goto drop;

+    }

+#endif /* UIP_CONF_IPV6 */

+  }

+

+#if !UIP_CONF_IPV6

+  if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header

+				    checksum. */

+    UIP_STAT(++uip_stat.ip.drop);

+    UIP_STAT(++uip_stat.ip.chkerr);

+    UIP_LOG("ip: bad checksum.");

+    goto drop;

+  }

+#endif /* UIP_CONF_IPV6 */

+

+  if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,

+				       proceed with TCP input

+				       processing. */

+    goto tcp_input;

+  }

+

+#if UIP_UDP

+  if(BUF->proto == UIP_PROTO_UDP) {

+    goto udp_input;

+  }

+#endif /* UIP_UDP */

+

+#if !UIP_CONF_IPV6

+  /* ICMPv4 processing code follows. */

+  if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from

+					here. */

+    UIP_STAT(++uip_stat.ip.drop);

+    UIP_STAT(++uip_stat.ip.protoerr);

+    UIP_LOG("ip: neither tcp nor icmp.");

+    goto drop;

+  }

+

+#if UIP_PINGADDRCONF

+ icmp_input:

+#endif /* UIP_PINGADDRCONF */

+  UIP_STAT(++uip_stat.icmp.recv);

+

+  /* ICMP echo (i.e., ping) processing. This is simple, we only change

+     the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP

+     checksum before we return the packet. */

+  if(ICMPBUF->type != ICMP_ECHO) {

+    UIP_STAT(++uip_stat.icmp.drop);

+    UIP_STAT(++uip_stat.icmp.typeerr);

+    UIP_LOG("icmp: not icmp echo.");

+    goto drop;

+  }

+

+  /* If we are configured to use ping IP address assignment, we use

+     the destination IP address of this ping packet and assign it to

+     ourself. */

+#if UIP_PINGADDRCONF

+  if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {

+    uip_hostaddr[0] = BUF->destipaddr[0];

+    uip_hostaddr[1] = BUF->destipaddr[1];

+  }

+#endif /* UIP_PINGADDRCONF */

+

+  ICMPBUF->type = ICMP_ECHO_REPLY;

+

+  if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {

+    ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;

+  } else {

+    ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);

+  }

+

+  /* Swap IP addresses. */

+  uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);

+  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);

+

+  UIP_STAT(++uip_stat.icmp.sent);

+  goto send;

+

+  /* End of IPv4 input header processing code. */

+#else /* !UIP_CONF_IPV6 */

+

+  /* This is IPv6 ICMPv6 processing code. */

+  DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);

+

+  if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from

+					 here. */

+    UIP_STAT(++uip_stat.ip.drop);

+    UIP_STAT(++uip_stat.ip.protoerr);

+    UIP_LOG("ip: neither tcp nor icmp6.");

+    goto drop;

+  }

+

+  UIP_STAT(++uip_stat.icmp.recv);

+

+  /* If we get a neighbor solicitation for our address we should send

+     a neighbor advertisement message back. */

+  if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {

+    if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {

+

+      if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {

+	/* Save the sender's address in our neighbor list. */

+	uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));

+      }

+

+      /* We should now send a neighbor advertisement back to where the

+	 neighbor solicication came from. */

+      ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;

+      ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */

+

+      ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;

+

+      uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);

+      uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);

+      ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;

+      ICMPBUF->options[1] = 1;  /* Options length, 1 = 8 bytes. */

+      memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));

+      ICMPBUF->icmpchksum = 0;

+      ICMPBUF->icmpchksum = ~uip_icmp6chksum();

+      goto send;

+

+    }

+    goto drop;

+  } else if(ICMPBUF->type == ICMP6_ECHO) {

+    /* ICMP echo (i.e., ping) processing. This is simple, we only

+       change the ICMP type from ECHO to ECHO_REPLY and update the

+       ICMP checksum before we return the packet. */

+

+    ICMPBUF->type = ICMP6_ECHO_REPLY;

+

+    uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);

+    uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);

+    ICMPBUF->icmpchksum = 0;

+    ICMPBUF->icmpchksum = ~uip_icmp6chksum();

+

+    UIP_STAT(++uip_stat.icmp.sent);

+    goto send;

+  } else {

+    DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);

+    UIP_STAT(++uip_stat.icmp.drop);

+    UIP_STAT(++uip_stat.icmp.typeerr);

+    UIP_LOG("icmp: unknown ICMP message.");

+    goto drop;

+  }

+

+  /* End of IPv6 ICMP processing. */

+

+#endif /* !UIP_CONF_IPV6 */

+

+#if UIP_UDP

+  /* UDP input processing. */

+ udp_input:

+  /* UDP processing is really just a hack. We don't do anything to the

+     UDP/IP headers, but let the UDP application do all the hard

+     work. If the application sets uip_slen, it has a packet to

+     send. */

+#if UIP_UDP_CHECKSUMS

+  uip_len = uip_len - UIP_IPUDPH_LEN;

+  uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];

+  if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {

+    UIP_STAT(++uip_stat.udp.drop);

+    UIP_STAT(++uip_stat.udp.chkerr);

+    UIP_LOG("udp: bad checksum.");

+    goto drop;

+  }

+#else /* UIP_UDP_CHECKSUMS */

+  uip_len = uip_len - UIP_IPUDPH_LEN;

+#endif /* UIP_UDP_CHECKSUMS */

+

+  /* Demultiplex this UDP packet between the UDP "connections". */

+  for(uip_udp_conn = &uip_udp_conns[0];

+      uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];

+      ++uip_udp_conn) {

+    /* If the local UDP port is non-zero, the connection is considered

+       to be used. If so, the local port number is checked against the

+       destination port number in the received packet. If the two port

+       numbers match, the remote port number is checked if the

+       connection is bound to a remote port. Finally, if the

+       connection is bound to a remote IP address, the source IP

+       address of the packet is checked. */

+    if(uip_udp_conn->lport != 0 &&

+       UDPBUF->destport == uip_udp_conn->lport &&

+       (uip_udp_conn->rport == 0 ||

+        UDPBUF->srcport == uip_udp_conn->rport) &&

+       (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||

+	uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||

+	uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {

+      goto udp_found;

+    }

+  }

+  UIP_LOG("udp: no matching connection found");

+  goto drop;

+

+ udp_found:

+  UIP_STAT(++uip_stat.udp.recv);

+  uip_conn = NULL;

+  uip_flags = UIP_NEWDATA;

+  uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];

+  uip_slen = 0;

+  UIP_UDP_APPCALL();

+ udp_send:

+  if(uip_slen == 0) {

+    goto drop;

+  }

+  uip_len = uip_slen + UIP_IPUDPH_LEN;

+

+#if UIP_CONF_IPV6

+  /* For IPv6, the IP length field does not include the IPv6 IP header

+     length. */

+  BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);

+  BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);

+#else /* UIP_CONF_IPV6 */

+  BUF->len[0] = (uip_len >> 8);

+  BUF->len[1] = (uip_len & 0xff);

+#endif /* UIP_CONF_IPV6 */

+

+  BUF->ttl = uip_udp_conn->ttl;

+  BUF->proto = UIP_PROTO_UDP;

+

+  UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);

+  UDPBUF->udpchksum = 0;

+

+  BUF->srcport  = uip_udp_conn->lport;

+  BUF->destport = uip_udp_conn->rport;

+

+  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);

+  uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);

+

+  uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];

+

+#if UIP_UDP_CHECKSUMS

+  /* Calculate UDP checksum. */

+  UDPBUF->udpchksum = ~(uip_udpchksum());

+  if(UDPBUF->udpchksum == 0) {

+    UDPBUF->udpchksum = 0xffff;

+  }

+#endif /* UIP_UDP_CHECKSUMS */

+  UIP_STAT(++uip_stat.udp.sent);

+  goto ip_send_nolen;

+#endif /* UIP_UDP */

+

+  /* TCP input processing. */

+ tcp_input:

+  UIP_STAT(++uip_stat.tcp.recv);

+

+  /* Start of TCP input header processing code. */

+

+  if(uip_tcpchksum() != 0xffff) {   /* Compute and check the TCP

+				       checksum. */

+    UIP_STAT(++uip_stat.tcp.drop);

+    UIP_STAT(++uip_stat.tcp.chkerr);

+    UIP_LOG("tcp: bad checksum.");

+    goto drop;

+  }

+

+

+  /* Demultiplex this segment. */

+  /* First check any active connections. */

+  for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];

+      ++uip_connr) {

+    if(uip_connr->tcpstateflags != UIP_CLOSED &&

+       BUF->destport == uip_connr->lport &&

+       BUF->srcport == uip_connr->rport &&

+       uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {

+      goto found;

+    }

+  }

+

+  /* If we didn't find and active connection that expected the packet,

+     either this packet is an old duplicate, or this is a SYN packet

+     destined for a connection in LISTEN. If the SYN flag isn't set,

+     it is an old packet and we send a RST. */

+  if((BUF->flags & TCP_CTL) != TCP_SYN) {

+    goto reset;

+  }

+

+  tmp16 = BUF->destport;

+  /* Next, check listening connections. */

+  for(c = 0; c < UIP_LISTENPORTS; ++c) {

+    if(tmp16 == uip_listenports[c])

+      goto found_listen;

+  }

+

+  /* No matching connection found, so we send a RST packet. */

+  UIP_STAT(++uip_stat.tcp.synrst);

+ reset:

+

+  /* We do not send resets in response to resets. */

+  if(BUF->flags & TCP_RST) {

+    goto drop;

+  }

+

+  UIP_STAT(++uip_stat.tcp.rst);

+

+  BUF->flags = TCP_RST | TCP_ACK;

+  uip_len = UIP_IPTCPH_LEN;

+  BUF->tcpoffset = 5 << 4;

+

+  /* Flip the seqno and ackno fields in the TCP header. */

+  c = BUF->seqno[3];

+  BUF->seqno[3] = BUF->ackno[3];

+  BUF->ackno[3] = c;

+

+  c = BUF->seqno[2];

+  BUF->seqno[2] = BUF->ackno[2];

+  BUF->ackno[2] = c;

+

+  c = BUF->seqno[1];

+  BUF->seqno[1] = BUF->ackno[1];

+  BUF->ackno[1] = c;

+

+  c = BUF->seqno[0];

+  BUF->seqno[0] = BUF->ackno[0];

+  BUF->ackno[0] = c;

+

+  /* We also have to increase the sequence number we are

+     acknowledging. If the least significant byte overflowed, we need

+     to propagate the carry to the other bytes as well. */

+  if(++BUF->ackno[3] == 0) {

+    if(++BUF->ackno[2] == 0) {

+      if(++BUF->ackno[1] == 0) {

+	++BUF->ackno[0];

+      }

+    }

+  }

+

+  /* Swap port numbers. */

+  tmp16 = BUF->srcport;

+  BUF->srcport = BUF->destport;

+  BUF->destport = tmp16;

+

+  /* Swap IP addresses. */

+  uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);

+  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);

+

+  /* And send out the RST packet! */

+  goto tcp_send_noconn;

+

+  /* This label will be jumped to if we matched the incoming packet

+     with a connection in LISTEN. In that case, we should create a new

+     connection and send a SYNACK in return. */

+ found_listen:

+  /* First we check if there are any connections avaliable. Unused

+     connections are kept in the same table as used connections, but

+     unused ones have the tcpstate set to CLOSED. Also, connections in

+     TIME_WAIT are kept track of and we'll use the oldest one if no

+     CLOSED connections are found. Thanks to Eddie C. Dost for a very

+     nice algorithm for the TIME_WAIT search. */

+  uip_connr = 0;

+  for(c = 0; c < UIP_CONNS; ++c) {

+    if(uip_conns[c].tcpstateflags == UIP_CLOSED) {

+      uip_connr = &uip_conns[c];

+      break;

+    }

+    if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {

+      if(uip_connr == 0 ||

+	 uip_conns[c].timer > uip_connr->timer) {

+	uip_connr = &uip_conns[c];

+      }

+    }

+  }

+

+  if(uip_connr == 0) {

+    /* All connections are used already, we drop packet and hope that

+       the remote end will retransmit the packet at a time when we

+       have more spare connections. */

+    UIP_STAT(++uip_stat.tcp.syndrop);

+    UIP_LOG("tcp: found no unused connections.");

+    goto drop;

+  }

+  uip_conn = uip_connr;

+

+  /* Fill in the necessary fields for the new connection. */

+  uip_connr->rto = uip_connr->timer = UIP_RTO;

+  uip_connr->sa = 0;

+  uip_connr->sv = 4;

+  uip_connr->nrtx = 0;

+  uip_connr->lport = BUF->destport;

+  uip_connr->rport = BUF->srcport;

+  uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);

+  uip_connr->tcpstateflags = UIP_SYN_RCVD;

+

+  uip_connr->snd_nxt[0] = iss[0];

+  uip_connr->snd_nxt[1] = iss[1];

+  uip_connr->snd_nxt[2] = iss[2];

+  uip_connr->snd_nxt[3] = iss[3];

+  uip_connr->len = 1;

+

+  /* rcv_nxt should be the seqno from the incoming packet + 1. */

+  uip_connr->rcv_nxt[3] = BUF->seqno[3];

+  uip_connr->rcv_nxt[2] = BUF->seqno[2];

+  uip_connr->rcv_nxt[1] = BUF->seqno[1];

+  uip_connr->rcv_nxt[0] = BUF->seqno[0];

+  uip_add_rcv_nxt(1);

+

+  /* Parse the TCP MSS option, if present. */

+  if((BUF->tcpoffset & 0xf0) > 0x50) {

+    for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {

+      opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];

+      if(opt == TCP_OPT_END) {

+	/* End of options. */

+	break;

+      } else if(opt == TCP_OPT_NOOP) {

+	++c;

+	/* NOP option. */

+      } else if(opt == TCP_OPT_MSS &&

+		uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {

+	/* An MSS option with the right option length. */

+	tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |

+	  (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];

+	uip_connr->initialmss = uip_connr->mss =

+	  tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;

+

+	/* And we are done processing options. */

+	break;

+      } else {

+	/* All other options have a length field, so that we easily

+	   can skip past them. */

+	if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {

+	  /* If the length field is zero, the options are malformed

+	     and we don't process them further. */

+	  break;

+	}

+	c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];

+      }

+    }

+  }

+

+  /* Our response will be a SYNACK. */

+#if UIP_ACTIVE_OPEN

+ tcp_send_synack:

+  BUF->flags = TCP_ACK;

+

+ tcp_send_syn:

+  BUF->flags |= TCP_SYN;

+#else /* UIP_ACTIVE_OPEN */

+ tcp_send_synack:

+  BUF->flags = TCP_SYN | TCP_ACK;

+#endif /* UIP_ACTIVE_OPEN */

+

+  /* We send out the TCP Maximum Segment Size option with our

+     SYNACK. */

+  BUF->optdata[0] = TCP_OPT_MSS;

+  BUF->optdata[1] = TCP_OPT_MSS_LEN;

+  BUF->optdata[2] = (UIP_TCP_MSS) / 256;

+  BUF->optdata[3] = (UIP_TCP_MSS) & 255;

+  uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;

+  BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;

+  goto tcp_send;

+

+  /* This label will be jumped to if we found an active connection. */

+ found:

+  uip_conn = uip_connr;

+  uip_flags = 0;

+  /* We do a very naive form of TCP reset processing; we just accept

+     any RST and kill our connection. We should in fact check if the

+     sequence number of this reset is wihtin our advertised window

+     before we accept the reset. */

+  if(BUF->flags & TCP_RST) {

+    uip_connr->tcpstateflags = UIP_CLOSED;

+    UIP_LOG("tcp: got reset, aborting connection.");

+    uip_flags = UIP_ABORT;

+    UIP_APPCALL();

+    goto drop;

+  }

+  /* Calculated the length of the data, if the application has sent

+     any data to us. */

+  c = (BUF->tcpoffset >> 4) << 2;

+  /* uip_len will contain the length of the actual TCP data. This is

+     calculated by subtracing the length of the TCP header (in

+     c) and the length of the IP header (20 bytes). */

+  uip_len = uip_len - c - UIP_IPH_LEN;

+

+  /* First, check if the sequence number of the incoming packet is

+     what we're expecting next. If not, we send out an ACK with the

+     correct numbers in. */

+  if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&

+       ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {

+    if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&

+       (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||

+	BUF->seqno[1] != uip_connr->rcv_nxt[1] ||

+	BUF->seqno[2] != uip_connr->rcv_nxt[2] ||

+	BUF->seqno[3] != uip_connr->rcv_nxt[3])) {

+      goto tcp_send_ack;

+    }

+  }

+

+  /* Next, check if the incoming segment acknowledges any outstanding

+     data. If so, we update the sequence number, reset the length of

+     the outstanding data, calculate RTT estimations, and reset the

+     retransmission timer. */

+  if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {

+    uip_add32(uip_connr->snd_nxt, uip_connr->len);

+

+    if(BUF->ackno[0] == uip_acc32[0] &&

+       BUF->ackno[1] == uip_acc32[1] &&

+       BUF->ackno[2] == uip_acc32[2] &&

+       BUF->ackno[3] == uip_acc32[3]) {

+      /* Update sequence number. */

+      uip_connr->snd_nxt[0] = uip_acc32[0];

+      uip_connr->snd_nxt[1] = uip_acc32[1];

+      uip_connr->snd_nxt[2] = uip_acc32[2];

+      uip_connr->snd_nxt[3] = uip_acc32[3];

+

+

+      /* Do RTT estimation, unless we have done retransmissions. */

+      if(uip_connr->nrtx == 0) {

+	signed char m;

+	m = uip_connr->rto - uip_connr->timer;

+	/* This is taken directly from VJs original code in his paper */

+	m = m - (uip_connr->sa >> 3);

+	uip_connr->sa += m;

+	if(m < 0) {

+	  m = -m;

+	}

+	m = m - (uip_connr->sv >> 2);

+	uip_connr->sv += m;

+	uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;

+

+      }

+      /* Set the acknowledged flag. */

+      uip_flags = UIP_ACKDATA;

+      /* Reset the retransmission timer. */

+      uip_connr->timer = uip_connr->rto;

+

+      /* Reset length of outstanding data. */

+      uip_connr->len = 0;

+    }

+

+  }

+

+  /* Do different things depending on in what state the connection is. */

+  switch(uip_connr->tcpstateflags & UIP_TS_MASK) {

+    /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not

+	implemented, since we force the application to close when the

+	peer sends a FIN (hence the application goes directly from

+	ESTABLISHED to LAST_ACK). */

+  case UIP_SYN_RCVD:

+    /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and

+       we are waiting for an ACK that acknowledges the data we sent

+       out the last time. Therefore, we want to have the UIP_ACKDATA

+       flag set. If so, we enter the ESTABLISHED state. */

+    if(uip_flags & UIP_ACKDATA) {

+      uip_connr->tcpstateflags = UIP_ESTABLISHED;

+      uip_flags = UIP_CONNECTED;

+      uip_connr->len = 0;

+      if(uip_len > 0) {

+        uip_flags |= UIP_NEWDATA;

+        uip_add_rcv_nxt(uip_len);

+      }

+      uip_slen = 0;

+      UIP_APPCALL();

+      goto appsend;

+    }

+    goto drop;

+#if UIP_ACTIVE_OPEN

+  case UIP_SYN_SENT:

+    /* In SYN_SENT, we wait for a SYNACK that is sent in response to

+       our SYN. The rcv_nxt is set to sequence number in the SYNACK

+       plus one, and we send an ACK. We move into the ESTABLISHED

+       state. */

+    if((uip_flags & UIP_ACKDATA) &&

+       (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {

+

+      /* Parse the TCP MSS option, if present. */

+      if((BUF->tcpoffset & 0xf0) > 0x50) {

+	for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {

+	  opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];

+	  if(opt == TCP_OPT_END) {

+	    /* End of options. */

+	    break;

+	  } else if(opt == TCP_OPT_NOOP) {

+	    ++c;

+	    /* NOP option. */

+	  } else if(opt == TCP_OPT_MSS &&

+		    uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {

+	    /* An MSS option with the right option length. */

+	    tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |

+	      uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];

+	    uip_connr->initialmss =

+	      uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;

+

+	    /* And we are done processing options. */

+	    break;

+	  } else {

+	    /* All other options have a length field, so that we easily

+	       can skip past them. */

+	    if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {

+	      /* If the length field is zero, the options are malformed

+		 and we don't process them further. */

+	      break;

+	    }

+	    c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];

+	  }

+	}

+      }

+      uip_connr->tcpstateflags = UIP_ESTABLISHED;

+      uip_connr->rcv_nxt[0] = BUF->seqno[0];

+      uip_connr->rcv_nxt[1] = BUF->seqno[1];

+      uip_connr->rcv_nxt[2] = BUF->seqno[2];

+      uip_connr->rcv_nxt[3] = BUF->seqno[3];

+      uip_add_rcv_nxt(1);

+      uip_flags = UIP_CONNECTED | UIP_NEWDATA;

+      uip_connr->len = 0;

+      uip_len = 0;

+      uip_slen = 0;

+      UIP_APPCALL();

+      goto appsend;

+    }

+    /* Inform the application that the connection failed */

+    uip_flags = UIP_ABORT;

+    UIP_APPCALL();

+    /* The connection is closed after we send the RST */

+    uip_conn->tcpstateflags = UIP_CLOSED;

+    goto reset;

+#endif /* UIP_ACTIVE_OPEN */

+

+  case UIP_ESTABLISHED:

+    /* In the ESTABLISHED state, we call upon the application to feed

+    data into the uip_buf. If the UIP_ACKDATA flag is set, the

+    application should put new data into the buffer, otherwise we are

+    retransmitting an old segment, and the application should put that

+    data into the buffer.

+

+    If the incoming packet is a FIN, we should close the connection on

+    this side as well, and we send out a FIN and enter the LAST_ACK

+    state. We require that there is no outstanding data; otherwise the

+    sequence numbers will be screwed up. */

+

+    if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {

+      if(uip_outstanding(uip_connr)) {

+	goto drop;

+      }

+      uip_add_rcv_nxt(1 + uip_len);

+      uip_flags |= UIP_CLOSE;

+      if(uip_len > 0) {

+	uip_flags |= UIP_NEWDATA;

+      }

+      UIP_APPCALL();

+      uip_connr->len = 1;

+      uip_connr->tcpstateflags = UIP_LAST_ACK;

+      uip_connr->nrtx = 0;

+    tcp_send_finack:

+      BUF->flags = TCP_FIN | TCP_ACK;

+      goto tcp_send_nodata;

+    }

+

+    /* Check the URG flag. If this is set, the segment carries urgent

+       data that we must pass to the application. */

+    if((BUF->flags & TCP_URG) != 0) {

+#if UIP_URGDATA > 0

+      uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];

+      if(uip_urglen > uip_len) {

+	/* There is more urgent data in the next segment to come. */

+	uip_urglen = uip_len;

+      }

+      uip_add_rcv_nxt(uip_urglen);

+      uip_len -= uip_urglen;

+      uip_urgdata = uip_appdata;

+      uip_appdata += uip_urglen;

+    } else {

+      uip_urglen = 0;

+#else /* UIP_URGDATA > 0 */

+      uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);

+      uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];

+#endif /* UIP_URGDATA > 0 */

+    }

+

+    /* If uip_len > 0 we have TCP data in the packet, and we flag this

+       by setting the UIP_NEWDATA flag and update the sequence number

+       we acknowledge. If the application has stopped the dataflow

+       using uip_stop(), we must not accept any data packets from the

+       remote host. */

+    if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {

+      uip_flags |= UIP_NEWDATA;

+      uip_add_rcv_nxt(uip_len);

+    }

+

+    /* Check if the available buffer space advertised by the other end

+       is smaller than the initial MSS for this connection. If so, we

+       set the current MSS to the window size to ensure that the

+       application does not send more data than the other end can

+       handle.

+

+       If the remote host advertises a zero window, we set the MSS to

+       the initial MSS so that the application will send an entire MSS

+       of data. This data will not be acknowledged by the receiver,

+       and the application will retransmit it. This is called the

+       "persistent timer" and uses the retransmission mechanim.

+    */

+    tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];

+    if(tmp16 > uip_connr->initialmss ||

+       tmp16 == 0) {

+      tmp16 = uip_connr->initialmss;

+    }

+    uip_connr->mss = tmp16;

+

+    /* If this packet constitutes an ACK for outstanding data (flagged

+       by the UIP_ACKDATA flag, we should call the application since it

+       might want to send more data. If the incoming packet had data

+       from the peer (as flagged by the UIP_NEWDATA flag), the

+       application must also be notified.

+

+       When the application is called, the global variable uip_len

+       contains the length of the incoming data. The application can

+       access the incoming data through the global pointer

+       uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN

+       bytes into the uip_buf array.

+

+       If the application wishes to send any data, this data should be

+       put into the uip_appdata and the length of the data should be

+       put into uip_len. If the application don't have any data to

+       send, uip_len must be set to 0. */

+    if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {

+      uip_slen = 0;

+      UIP_APPCALL();

+

+    appsend:

+

+      if(uip_flags & UIP_ABORT) {

+	uip_slen = 0;

+	uip_connr->tcpstateflags = UIP_CLOSED;

+	BUF->flags = TCP_RST | TCP_ACK;

+	goto tcp_send_nodata;

+      }

+

+      if(uip_flags & UIP_CLOSE) {

+	uip_slen = 0;

+	uip_connr->len = 1;

+	uip_connr->tcpstateflags = UIP_FIN_WAIT_1;

+	uip_connr->nrtx = 0;

+	BUF->flags = TCP_FIN | TCP_ACK;

+	goto tcp_send_nodata;

+      }

+

+      /* If uip_slen > 0, the application has data to be sent. */

+      if(uip_slen > 0) {

+

+	/* If the connection has acknowledged data, the contents of

+	   the ->len variable should be discarded. */

+	if((uip_flags & UIP_ACKDATA) != 0) {

+	  uip_connr->len = 0;

+	}

+

+	/* If the ->len variable is non-zero the connection has

+	   already data in transit and cannot send anymore right

+	   now. */

+	if(uip_connr->len == 0) {

+

+	  /* The application cannot send more than what is allowed by

+	     the mss (the minumum of the MSS and the available

+	     window). */

+	  if(uip_slen > uip_connr->mss) {

+	    uip_slen = uip_connr->mss;

+	  }

+

+	  /* Remember how much data we send out now so that we know

+	     when everything has been acknowledged. */

+	  uip_connr->len = uip_slen;

+	} else {

+

+	  /* If the application already had unacknowledged data, we

+	     make sure that the application does not send (i.e.,

+	     retransmit) out more than it previously sent out. */

+	  uip_slen = uip_connr->len;

+	}

+      }

+      uip_connr->nrtx = 0;

+    apprexmit:

+      uip_appdata = uip_sappdata;

+

+      /* If the application has data to be sent, or if the incoming

+         packet had new data in it, we must send out a packet. */

+      if(uip_slen > 0 && uip_connr->len > 0) {

+	/* Add the length of the IP and TCP headers. */

+	uip_len = uip_connr->len + UIP_TCPIP_HLEN;

+	/* We always set the ACK flag in response packets. */

+	BUF->flags = TCP_ACK | TCP_PSH;

+	/* Send the packet. */

+	goto tcp_send_noopts;

+      }

+      /* If there is no data to send, just send out a pure ACK if

+	 there is newdata. */

+      if(uip_flags & UIP_NEWDATA) {

+	uip_len = UIP_TCPIP_HLEN;

+	BUF->flags = TCP_ACK;

+	goto tcp_send_noopts;

+      }

+    }

+    goto drop;

+  case UIP_LAST_ACK:

+    /* We can close this connection if the peer has acknowledged our

+       FIN. This is indicated by the UIP_ACKDATA flag. */

+    if(uip_flags & UIP_ACKDATA) {

+      uip_connr->tcpstateflags = UIP_CLOSED;

+      uip_flags = UIP_CLOSE;

+      UIP_APPCALL();

+    }

+    break;

+

+  case UIP_FIN_WAIT_1:

+    /* The application has closed the connection, but the remote host

+       hasn't closed its end yet. Thus we do nothing but wait for a

+       FIN from the other side. */

+    if(uip_len > 0) {

+      uip_add_rcv_nxt(uip_len);

+    }

+    if(BUF->flags & TCP_FIN) {

+      if(uip_flags & UIP_ACKDATA) {

+	uip_connr->tcpstateflags = UIP_TIME_WAIT;

+	uip_connr->timer = 0;

+	uip_connr->len = 0;

+      } else {

+	uip_connr->tcpstateflags = UIP_CLOSING;

+      }

+      uip_add_rcv_nxt(1);

+      uip_flags = UIP_CLOSE;

+      UIP_APPCALL();

+      goto tcp_send_ack;

+    } else if(uip_flags & UIP_ACKDATA) {

+      uip_connr->tcpstateflags = UIP_FIN_WAIT_2;

+      uip_connr->len = 0;

+      goto drop;

+    }

+    if(uip_len > 0) {

+      goto tcp_send_ack;

+    }

+    goto drop;

+

+  case UIP_FIN_WAIT_2:

+    if(uip_len > 0) {

+      uip_add_rcv_nxt(uip_len);

+    }

+    if(BUF->flags & TCP_FIN) {

+      uip_connr->tcpstateflags = UIP_TIME_WAIT;

+      uip_connr->timer = 0;

+      uip_add_rcv_nxt(1);

+      uip_flags = UIP_CLOSE;

+      UIP_APPCALL();

+      goto tcp_send_ack;

+    }

+    if(uip_len > 0) {

+      goto tcp_send_ack;

+    }

+    goto drop;

+

+  case UIP_TIME_WAIT:

+    goto tcp_send_ack;

+

+  case UIP_CLOSING:

+    if(uip_flags & UIP_ACKDATA) {

+      uip_connr->tcpstateflags = UIP_TIME_WAIT;

+      uip_connr->timer = 0;

+    }

+  }

+  goto drop;

+

+

+  /* We jump here when we are ready to send the packet, and just want

+     to set the appropriate TCP sequence numbers in the TCP header. */

+ tcp_send_ack:

+  BUF->flags = TCP_ACK;

+ tcp_send_nodata:

+  uip_len = UIP_IPTCPH_LEN;

+ tcp_send_noopts:

+  BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;

+ tcp_send:

+  /* We're done with the input processing. We are now ready to send a

+     reply. Our job is to fill in all the fields of the TCP and IP

+     headers before calculating the checksum and finally send the

+     packet. */

+  BUF->ackno[0] = uip_connr->rcv_nxt[0];

+  BUF->ackno[1] = uip_connr->rcv_nxt[1];

+  BUF->ackno[2] = uip_connr->rcv_nxt[2];

+  BUF->ackno[3] = uip_connr->rcv_nxt[3];

+

+  BUF->seqno[0] = uip_connr->snd_nxt[0];

+  BUF->seqno[1] = uip_connr->snd_nxt[1];

+  BUF->seqno[2] = uip_connr->snd_nxt[2];

+  BUF->seqno[3] = uip_connr->snd_nxt[3];

+

+  BUF->proto = UIP_PROTO_TCP;

+

+  BUF->srcport  = uip_connr->lport;

+  BUF->destport = uip_connr->rport;

+

+  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);

+  uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);

+

+  if(uip_connr->tcpstateflags & UIP_STOPPED) {

+    /* If the connection has issued uip_stop(), we advertise a zero

+       window so that the remote host will stop sending data. */

+    BUF->wnd[0] = BUF->wnd[1] = 0;

+  } else {

+    BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);

+    BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);

+  }

+

+ tcp_send_noconn:

+  BUF->ttl = UIP_TTL;

+#if UIP_CONF_IPV6

+  /* For IPv6, the IP length field does not include the IPv6 IP header

+     length. */

+  BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);

+  BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);

+#else /* UIP_CONF_IPV6 */

+  BUF->len[0] = (uip_len >> 8);

+  BUF->len[1] = (uip_len & 0xff);

+#endif /* UIP_CONF_IPV6 */

+

+  BUF->urgp[0] = BUF->urgp[1] = 0;

+

+  /* Calculate TCP checksum. */

+  BUF->tcpchksum = 0;

+  BUF->tcpchksum = ~(uip_tcpchksum());

+

+#if UIP_UDP

+ ip_send_nolen:

+#endif /* UIP_UDP */

+

+#if UIP_CONF_IPV6

+  BUF->vtc = 0x60;

+  BUF->tcflow = 0x00;

+  BUF->flow = 0x00;

+#else /* UIP_CONF_IPV6 */

+  BUF->vhl = 0x45;

+  BUF->tos = 0;

+  BUF->ipoffset[0] = BUF->ipoffset[1] = 0;

+  ++ipid;

+  BUF->ipid[0] = ipid >> 8;

+  BUF->ipid[1] = ipid & 0xff;

+  /* Calculate IP checksum. */

+  BUF->ipchksum = 0;

+  BUF->ipchksum = ~(uip_ipchksum());

+  DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());

+#endif /* UIP_CONF_IPV6 */

+

+  UIP_STAT(++uip_stat.tcp.sent);

+ send:

+  DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,

+	       (BUF->len[0] << 8) | BUF->len[1]);

+

+  UIP_STAT(++uip_stat.ip.sent);

+  /* Return and let the caller do the actual transmission. */

+  uip_flags = 0;

+  return;

+ drop:

+  uip_len = 0;

+  uip_flags = 0;

+  return;

+}

+/*---------------------------------------------------------------------------*/

+u16_t

+htons(u16_t val)

+{

+  return HTONS(val);

+}

+/*---------------------------------------------------------------------------*/

+void

+uip_send(const void *data, int len)

+{

+  if(len > 0) {

+    uip_slen = len;

+    if(data != uip_sappdata) {

+      memcpy(uip_sappdata, (data), uip_slen);

+    }

+  }

+}

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip.h
new file mode 100644
index 0000000..82da6fb
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip.h
@@ -0,0 +1,1638 @@
+

+/**

+ * \addtogroup uip

+ * @{

+ */

+

+/**

+ * \file

+ * Header file for the uIP TCP/IP stack.

+ * \author Adam Dunkels <adam@dunkels.com>

+ *

+ * The uIP TCP/IP stack header file contains definitions for a number

+ * of C macros that are used by uIP programs as well as internal uIP

+ * structures, TCP/IP header structures and function declarations.

+ *

+ */

+

+

+/*

+ * Copyright (c) 2001-2003, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $

+ *

+ */

+

+#ifndef __UIP_H__

+#define __UIP_H__

+

+#include "uipopt.h"

+

+/**

+ * Repressentation of an IP address.

+ *

+ */

+typedef u16_t uip_ip4addr_t[2];

+typedef u16_t uip_ip6addr_t[8];

+#if UIP_CONF_IPV6

+typedef uip_ip6addr_t uip_ipaddr_t;

+#else /* UIP_CONF_IPV6 */

+typedef uip_ip4addr_t uip_ipaddr_t;

+#endif /* UIP_CONF_IPV6 */

+

+/*---------------------------------------------------------------------------*/

+/* First, the functions that should be called from the

+ * system. Initialization, the periodic timer and incoming packets are

+ * handled by the following three functions.

+ */

+

+/**

+ * \defgroup uipconffunc uIP configuration functions

+ * @{

+ *

+ * The uIP configuration functions are used for setting run-time

+ * parameters in uIP such as IP addresses.

+ */

+

+/**

+ * Set the IP address of this host.

+ *

+ * The IP address is represented as a 4-byte array where the first

+ * octet of the IP address is put in the first member of the 4-byte

+ * array.

+ *

+ * Example:

+ \code

+

+ uip_ipaddr_t addr;

+

+ uip_ipaddr(&addr, 192,168,1,2);

+ uip_sethostaddr(&addr);

+

+ \endcode

+ * \param addr A pointer to an IP address of type uip_ipaddr_t;

+ *

+ * \sa uip_ipaddr()

+ *

+ * \hideinitializer

+ */

+#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))

+

+/**

+ * Get the IP address of this host.

+ *

+ * The IP address is represented as a 4-byte array where the first

+ * octet of the IP address is put in the first member of the 4-byte

+ * array.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t hostaddr;

+

+ uip_gethostaddr(&hostaddr);

+ \endcode

+ * \param addr A pointer to a uip_ipaddr_t variable that will be

+ * filled in with the currently configured IP address.

+ *

+ * \hideinitializer

+ */

+#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)

+

+/**

+ * Set the default router's IP address.

+ *

+ * \param addr A pointer to a uip_ipaddr_t variable containing the IP

+ * address of the default router.

+ *

+ * \sa uip_ipaddr()

+ *

+ * \hideinitializer

+ */

+#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))

+

+/**

+ * Set the netmask.

+ *

+ * \param addr A pointer to a uip_ipaddr_t variable containing the IP

+ * address of the netmask.

+ *

+ * \sa uip_ipaddr()

+ *

+ * \hideinitializer

+ */

+#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))

+

+

+/**

+ * Get the default router's IP address.

+ *

+ * \param addr A pointer to a uip_ipaddr_t variable that will be

+ * filled in with the IP address of the default router.

+ *

+ * \hideinitializer

+ */

+#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)

+

+/**

+ * Get the netmask.

+ *

+ * \param addr A pointer to a uip_ipaddr_t variable that will be

+ * filled in with the value of the netmask.

+ *

+ * \hideinitializer

+ */

+#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)

+

+/** @} */

+

+/**

+ * \defgroup uipinit uIP initialization functions

+ * @{

+ *

+ * The uIP initialization functions are used for booting uIP.

+ */

+

+/**

+ * uIP initialization function.

+ *

+ * This function should be called at boot up to initilize the uIP

+ * TCP/IP stack.

+ */

+void uip_init(void);

+

+/**

+ * uIP initialization function.

+ *

+ * This function may be used at boot time to set the initial ip_id.

+ */

+void uip_setipid(u16_t id);

+

+/** @} */

+

+/**

+ * \defgroup uipdevfunc uIP device driver functions

+ * @{

+ *

+ * These functions are used by a network device driver for interacting

+ * with uIP.

+ */

+

+/**

+ * Process an incoming packet.

+ *

+ * This function should be called when the device driver has received

+ * a packet from the network. The packet from the device driver must

+ * be present in the uip_buf buffer, and the length of the packet

+ * should be placed in the uip_len variable.

+ *

+ * When the function returns, there may be an outbound packet placed

+ * in the uip_buf packet buffer. If so, the uip_len variable is set to

+ * the length of the packet. If no packet is to be sent out, the

+ * uip_len variable is set to 0.

+ *

+ * The usual way of calling the function is presented by the source

+ * code below.

+ \code

+  uip_len = devicedriver_poll();

+  if(uip_len > 0) {

+    uip_input();

+    if(uip_len > 0) {

+      devicedriver_send();

+    }

+  }

+ \endcode

+ *

+ * \note If you are writing a uIP device driver that needs ARP

+ * (Address Resolution Protocol), e.g., when running uIP over

+ * Ethernet, you will need to call the uIP ARP code before calling

+ * this function:

+ \code

+  #define BUF ((struct uip_eth_hdr *)&uip_buf[0])

+  uip_len = ethernet_devicedrver_poll();

+  if(uip_len > 0) {

+    if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {

+      uip_arp_ipin();

+      uip_input();

+      if(uip_len > 0) {

+        uip_arp_out();

+	ethernet_devicedriver_send();

+      }

+    } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {

+      uip_arp_arpin();

+      if(uip_len > 0) {

+	ethernet_devicedriver_send();

+      }

+    }

+ \endcode

+ *

+ * \hideinitializer

+ */

+#define uip_input()        uip_process(UIP_DATA)

+

+/**

+ * Periodic processing for a connection identified by its number.

+ *

+ * This function does the necessary periodic processing (timers,

+ * polling) for a uIP TCP conneciton, and should be called when the

+ * periodic uIP timer goes off. It should be called for every

+ * connection, regardless of whether they are open of closed.

+ *

+ * When the function returns, it may have an outbound packet waiting

+ * for service in the uIP packet buffer, and if so the uip_len

+ * variable is set to a value larger than zero. The device driver

+ * should be called to send out the packet.

+ *

+ * The ususal way of calling the function is through a for() loop like

+ * this:

+ \code

+  for(i = 0; i < UIP_CONNS; ++i) {

+    uip_periodic(i);

+    if(uip_len > 0) {

+      devicedriver_send();

+    }

+  }

+ \endcode

+ *

+ * \note If you are writing a uIP device driver that needs ARP

+ * (Address Resolution Protocol), e.g., when running uIP over

+ * Ethernet, you will need to call the uip_arp_out() function before

+ * calling the device driver:

+ \code

+  for(i = 0; i < UIP_CONNS; ++i) {

+    uip_periodic(i);

+    if(uip_len > 0) {

+      uip_arp_out();

+      ethernet_devicedriver_send();

+    }

+  }

+ \endcode

+ *

+ * \param conn The number of the connection which is to be periodically polled.

+ *

+ * \hideinitializer

+ */

+#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \

+                                uip_process(UIP_TIMER); } while (0)

+

+/**

+ *

+ *

+ */

+#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)

+

+/**

+ * Perform periodic processing for a connection identified by a pointer

+ * to its structure.

+ *

+ * Same as uip_periodic() but takes a pointer to the actual uip_conn

+ * struct instead of an integer as its argument. This function can be

+ * used to force periodic processing of a specific connection.

+ *

+ * \param conn A pointer to the uip_conn struct for the connection to

+ * be processed.

+ *

+ * \hideinitializer

+ */

+#define uip_periodic_conn(conn) do { uip_conn = conn; \

+                                     uip_process(UIP_TIMER); } while (0)

+

+/**

+ * Reuqest that a particular connection should be polled.

+ *

+ * Similar to uip_periodic_conn() but does not perform any timer

+ * processing. The application is polled for new data.

+ *

+ * \param conn A pointer to the uip_conn struct for the connection to

+ * be processed.

+ *

+ * \hideinitializer

+ */

+#define uip_poll_conn(conn) do { uip_conn = conn; \

+                                 uip_process(UIP_POLL_REQUEST); } while (0)

+

+

+#if UIP_UDP

+/**

+ * Periodic processing for a UDP connection identified by its number.

+ *

+ * This function is essentially the same as uip_periodic(), but for

+ * UDP connections. It is called in a similar fashion as the

+ * uip_periodic() function:

+ \code

+  for(i = 0; i < UIP_UDP_CONNS; i++) {

+    uip_udp_periodic(i);

+    if(uip_len > 0) {

+      devicedriver_send();

+    }

+  }

+ \endcode

+ *

+ * \note As for the uip_periodic() function, special care has to be

+ * taken when using uIP together with ARP and Ethernet:

+ \code

+  for(i = 0; i < UIP_UDP_CONNS; i++) {

+    uip_udp_periodic(i);

+    if(uip_len > 0) {

+      uip_arp_out();

+      ethernet_devicedriver_send();

+    }

+  }

+ \endcode

+ *

+ * \param conn The number of the UDP connection to be processed.

+ *

+ * \hideinitializer

+ */

+#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \

+                                uip_process(UIP_UDP_TIMER); } while (0)

+

+/**

+ * Periodic processing for a UDP connection identified by a pointer to

+ * its structure.

+ *

+ * Same as uip_udp_periodic() but takes a pointer to the actual

+ * uip_conn struct instead of an integer as its argument. This

+ * function can be used to force periodic processing of a specific

+ * connection.

+ *

+ * \param conn A pointer to the uip_udp_conn struct for the connection

+ * to be processed.

+ *

+ * \hideinitializer

+ */

+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \

+                                         uip_process(UIP_UDP_TIMER); } while (0)

+

+

+#endif /* UIP_UDP */

+

+/**

+ * The uIP packet buffer.

+ *

+ * The uip_buf array is used to hold incoming and outgoing

+ * packets. The device driver should place incoming data into this

+ * buffer. When sending data, the device driver should read the link

+ * level headers and the TCP/IP headers from this buffer. The size of

+ * the link level headers is configured by the UIP_LLH_LEN define.

+ *

+ * \note The application data need not be placed in this buffer, so

+ * the device driver must read it from the place pointed to by the

+ * uip_appdata pointer as illustrated by the following example:

+ \code

+ void

+ devicedriver_send(void)

+ {

+    hwsend(&uip_buf[0], UIP_LLH_LEN);

+    if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {

+      hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);

+    } else {

+      hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);

+      hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);

+    }

+ }

+ \endcode

+ */

+#ifndef UIP_CONF_EXTERNAL_BUFFER

+	extern u8_t uip_buf[UIP_BUFSIZE+2];

+#else

+	extern unsigned char *uip_buf;

+#endif

+

+/** @} */

+

+/*---------------------------------------------------------------------------*/

+/* Functions that are used by the uIP application program. Opening and

+ * closing connections, sending and receiving data, etc. is all

+ * handled by the functions below.

+*/

+/**

+ * \defgroup uipappfunc uIP application functions

+ * @{

+ *

+ * Functions used by an application running of top of uIP.

+ */

+

+/**

+ * Start listening to the specified port.

+ *

+ * \note Since this function expects the port number in network byte

+ * order, a conversion using HTONS() or htons() is necessary.

+ *

+ \code

+ uip_listen(HTONS(80));

+ \endcode

+ *

+ * \param port A 16-bit port number in network byte order.

+ */

+void uip_listen(u16_t port);

+

+/**

+ * Stop listening to the specified port.

+ *

+ * \note Since this function expects the port number in network byte

+ * order, a conversion using HTONS() or htons() is necessary.

+ *

+ \code

+ uip_unlisten(HTONS(80));

+ \endcode

+ *

+ * \param port A 16-bit port number in network byte order.

+ */

+void uip_unlisten(u16_t port);

+

+/**

+ * Connect to a remote host using TCP.

+ *

+ * This function is used to start a new connection to the specified

+ * port on the specied host. It allocates a new connection identifier,

+ * sets the connection to the SYN_SENT state and sets the

+ * retransmission timer to 0. This will cause a TCP SYN segment to be

+ * sent out the next time this connection is periodically processed,

+ * which usually is done within 0.5 seconds after the call to

+ * uip_connect().

+ *

+ * \note This function is avaliable only if support for active open

+ * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.

+ *

+ * \note Since this function requires the port number to be in network

+ * byte order, a conversion using HTONS() or htons() is necessary.

+ *

+ \code

+ uip_ipaddr_t ipaddr;

+

+ uip_ipaddr(&ipaddr, 192,168,1,2);

+ uip_connect(&ipaddr, HTONS(80));

+ \endcode

+ *

+ * \param ripaddr The IP address of the remote hot.

+ *

+ * \param port A 16-bit port number in network byte order.

+ *

+ * \return A pointer to the uIP connection identifier for the new connection,

+ * or NULL if no connection could be allocated.

+ *

+ */

+struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);

+

+

+

+/**

+ * \internal

+ *

+ * Check if a connection has outstanding (i.e., unacknowledged) data.

+ *

+ * \param conn A pointer to the uip_conn structure for the connection.

+ *

+ * \hideinitializer

+ */

+#define uip_outstanding(conn) ((conn)->len)

+

+/**

+ * Send data on the current connection.

+ *

+ * This function is used to send out a single segment of TCP

+ * data. Only applications that have been invoked by uIP for event

+ * processing can send data.

+ *

+ * The amount of data that actually is sent out after a call to this

+ * funcion is determined by the maximum amount of data TCP allows. uIP

+ * will automatically crop the data so that only the appropriate

+ * amount of data is sent. The function uip_mss() can be used to query

+ * uIP for the amount of data that actually will be sent.

+ *

+ * \note This function does not guarantee that the sent data will

+ * arrive at the destination. If the data is lost in the network, the

+ * application will be invoked with the uip_rexmit() event being

+ * set. The application will then have to resend the data using this

+ * function.

+ *

+ * \param data A pointer to the data which is to be sent.

+ *

+ * \param len The maximum amount of data bytes to be sent.

+ *

+ * \hideinitializer

+ */

+void uip_send(const void *data, int len);

+

+/**

+ * The length of any incoming data that is currently avaliable (if avaliable)

+ * in the uip_appdata buffer.

+ *

+ * The test function uip_data() must first be used to check if there

+ * is any data available at all.

+ *

+ * \hideinitializer

+ */

+/*void uip_datalen(void);*/

+#define uip_datalen()       uip_len

+

+/**

+ * The length of any out-of-band data (urgent data) that has arrived

+ * on the connection.

+ *

+ * \note The configuration parameter UIP_URGDATA must be set for this

+ * function to be enabled.

+ *

+ * \hideinitializer

+ */

+#define uip_urgdatalen()    uip_urglen

+

+/**

+ * Close the current connection.

+ *

+ * This function will close the current connection in a nice way.

+ *

+ * \hideinitializer

+ */

+#define uip_close()         (uip_flags = UIP_CLOSE)

+

+/**

+ * Abort the current connection.

+ *

+ * This function will abort (reset) the current connection, and is

+ * usually used when an error has occured that prevents using the

+ * uip_close() function.

+ *

+ * \hideinitializer

+ */

+#define uip_abort()         (uip_flags = UIP_ABORT)

+

+/**

+ * Tell the sending host to stop sending data.

+ *

+ * This function will close our receiver's window so that we stop

+ * receiving data for the current connection.

+ *

+ * \hideinitializer

+ */

+#define uip_stop()          (uip_conn->tcpstateflags |= UIP_STOPPED)

+

+/**

+ * Find out if the current connection has been previously stopped with

+ * uip_stop().

+ *

+ * \hideinitializer

+ */

+#define uip_stopped(conn)   ((conn)->tcpstateflags & UIP_STOPPED)

+

+/**

+ * Restart the current connection, if is has previously been stopped

+ * with uip_stop().

+ *

+ * This function will open the receiver's window again so that we

+ * start receiving data for the current connection.

+ *

+ * \hideinitializer

+ */

+#define uip_restart()         do { uip_flags |= UIP_NEWDATA; \

+                                   uip_conn->tcpstateflags &= ~UIP_STOPPED; \

+                              } while(0)

+

+

+/* uIP tests that can be made to determine in what state the current

+   connection is, and what the application function should do. */

+

+/**

+ * Is the current connection a UDP connection?

+ *

+ * This function checks whether the current connection is a UDP connection.

+ *

+ * \hideinitializer

+ *

+ */

+#define uip_udpconnection() (uip_conn == NULL)

+

+/**

+ * Is new incoming data available?

+ *

+ * Will reduce to non-zero if there is new data for the application

+ * present at the uip_appdata pointer. The size of the data is

+ * avaliable through the uip_len variable.

+ *

+ * \hideinitializer

+ */

+#define uip_newdata()   (uip_flags & UIP_NEWDATA)

+

+/**

+ * Has previously sent data been acknowledged?

+ *

+ * Will reduce to non-zero if the previously sent data has been

+ * acknowledged by the remote host. This means that the application

+ * can send new data.

+ *

+ * \hideinitializer

+ */

+#define uip_acked()   (uip_flags & UIP_ACKDATA)

+

+/**

+ * Has the connection just been connected?

+ *

+ * Reduces to non-zero if the current connection has been connected to

+ * a remote host. This will happen both if the connection has been

+ * actively opened (with uip_connect()) or passively opened (with

+ * uip_listen()).

+ *

+ * \hideinitializer

+ */

+#define uip_connected() (uip_flags & UIP_CONNECTED)

+

+/**

+ * Has the connection been closed by the other end?

+ *

+ * Is non-zero if the connection has been closed by the remote

+ * host. The application may then do the necessary clean-ups.

+ *

+ * \hideinitializer

+ */

+#define uip_closed()    (uip_flags & UIP_CLOSE)

+

+/**

+ * Has the connection been aborted by the other end?

+ *

+ * Non-zero if the current connection has been aborted (reset) by the

+ * remote host.

+ *

+ * \hideinitializer

+ */

+#define uip_aborted()    (uip_flags & UIP_ABORT)

+

+/**

+ * Has the connection timed out?

+ *

+ * Non-zero if the current connection has been aborted due to too many

+ * retransmissions.

+ *

+ * \hideinitializer

+ */

+#define uip_timedout()    (uip_flags & UIP_TIMEDOUT)

+

+/**

+ * Do we need to retransmit previously data?

+ *

+ * Reduces to non-zero if the previously sent data has been lost in

+ * the network, and the application should retransmit it. The

+ * application should send the exact same data as it did the last

+ * time, using the uip_send() function.

+ *

+ * \hideinitializer

+ */

+#define uip_rexmit()     (uip_flags & UIP_REXMIT)

+

+/**

+ * Is the connection being polled by uIP?

+ *

+ * Is non-zero if the reason the application is invoked is that the

+ * current connection has been idle for a while and should be

+ * polled.

+ *

+ * The polling event can be used for sending data without having to

+ * wait for the remote host to send data.

+ *

+ * \hideinitializer

+ */

+#define uip_poll()       (uip_flags & UIP_POLL)

+

+/**

+ * Get the initial maxium segment size (MSS) of the current

+ * connection.

+ *

+ * \hideinitializer

+ */

+#define uip_initialmss()             (uip_conn->initialmss)

+

+/**

+ * Get the current maxium segment size that can be sent on the current

+ * connection.

+ *

+ * The current maxiumum segment size that can be sent on the

+ * connection is computed from the receiver's window and the MSS of

+ * the connection (which also is available by calling

+ * uip_initialmss()).

+ *

+ * \hideinitializer

+ */

+#define uip_mss()             (uip_conn->mss)

+

+/**

+ * Set up a new UDP connection.

+ *

+ * This function sets up a new UDP connection. The function will

+ * automatically allocate an unused local port for the new

+ * connection. However, another port can be chosen by using the

+ * uip_udp_bind() call, after the uip_udp_new() function has been

+ * called.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t addr;

+ struct uip_udp_conn *c;

+

+ uip_ipaddr(&addr, 192,168,2,1);

+ c = uip_udp_new(&addr, HTONS(12345));

+ if(c != NULL) {

+   uip_udp_bind(c, HTONS(12344));

+ }

+ \endcode

+ * \param ripaddr The IP address of the remote host.

+ *

+ * \param rport The remote port number in network byte order.

+ *

+ * \return The uip_udp_conn structure for the new connection or NULL

+ * if no connection could be allocated.

+ */

+struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);

+

+/**

+ * Removed a UDP connection.

+ *

+ * \param conn A pointer to the uip_udp_conn structure for the connection.

+ *

+ * \hideinitializer

+ */

+#define uip_udp_remove(conn) (conn)->lport = 0

+

+/**

+ * Bind a UDP connection to a local port.

+ *

+ * \param conn A pointer to the uip_udp_conn structure for the

+ * connection.

+ *

+ * \param port The local port number, in network byte order.

+ *

+ * \hideinitializer

+ */

+#define uip_udp_bind(conn, port) (conn)->lport = port

+

+/**

+ * Send a UDP datagram of length len on the current connection.

+ *

+ * This function can only be called in response to a UDP event (poll

+ * or newdata). The data must be present in the uip_buf buffer, at the

+ * place pointed to by the uip_appdata pointer.

+ *

+ * \param len The length of the data in the uip_buf buffer.

+ *

+ * \hideinitializer

+ */

+#define uip_udp_send(len) uip_send((char *)uip_appdata, len)

+

+/** @} */

+

+/* uIP convenience and converting functions. */

+

+/**

+ * \defgroup uipconvfunc uIP conversion functions

+ * @{

+ *

+ * These functions can be used for converting between different data

+ * formats used by uIP.

+ */

+

+/**

+ * Construct an IP address from four bytes.

+ *

+ * This function constructs an IP address of the type that uIP handles

+ * internally from four bytes. The function is handy for specifying IP

+ * addresses to use with e.g. the uip_connect() function.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr;

+ struct uip_conn *c;

+

+ uip_ipaddr(&ipaddr, 192,168,1,2);

+ c = uip_connect(&ipaddr, HTONS(80));

+ \endcode

+ *

+ * \param addr A pointer to a uip_ipaddr_t variable that will be

+ * filled in with the IP address.

+ *

+ * \param addr0 The first octet of the IP address.

+ * \param addr1 The second octet of the IP address.

+ * \param addr2 The third octet of the IP address.

+ * \param addr3 The forth octet of the IP address.

+ *

+ * \hideinitializer

+ */

+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \

+                     ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \

+                     ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \

+                  } while(0)

+

+/**

+ * Construct an IPv6 address from eight 16-bit words.

+ *

+ * This function constructs an IPv6 address.

+ *

+ * \hideinitializer

+ */

+#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \

+                     ((u16_t *)(addr))[0] = HTONS((addr0)); \

+                     ((u16_t *)(addr))[1] = HTONS((addr1)); \

+                     ((u16_t *)(addr))[2] = HTONS((addr2)); \

+                     ((u16_t *)(addr))[3] = HTONS((addr3)); \

+                     ((u16_t *)(addr))[4] = HTONS((addr4)); \

+                     ((u16_t *)(addr))[5] = HTONS((addr5)); \

+                     ((u16_t *)(addr))[6] = HTONS((addr6)); \

+                     ((u16_t *)(addr))[7] = HTONS((addr7)); \

+                  } while(0)

+

+/**

+ * Copy an IP address to another IP address.

+ *

+ * Copies an IP address from one place to another.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr1, ipaddr2;

+

+ uip_ipaddr(&ipaddr1, 192,16,1,2);

+ uip_ipaddr_copy(&ipaddr2, &ipaddr1);

+ \endcode

+ *

+ * \param dest The destination for the copy.

+ * \param src The source from where to copy.

+ *

+ * \hideinitializer

+ */

+#if !UIP_CONF_IPV6

+#define uip_ipaddr_copy(dest, src) do { \

+                     ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \

+                     ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \

+                  } while(0)

+#else /* !UIP_CONF_IPV6 */

+#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))

+#endif /* !UIP_CONF_IPV6 */

+

+/**

+ * Compare two IP addresses

+ *

+ * Compares two IP addresses.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr1, ipaddr2;

+

+ uip_ipaddr(&ipaddr1, 192,16,1,2);

+ if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {

+    printf("They are the same");

+ }

+ \endcode

+ *

+ * \param addr1 The first IP address.

+ * \param addr2 The second IP address.

+ *

+ * \hideinitializer

+ */

+#if !UIP_CONF_IPV6

+#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \

+				      ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])

+#else /* !UIP_CONF_IPV6 */

+#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)

+#endif /* !UIP_CONF_IPV6 */

+

+/**

+ * Compare two IP addresses with netmasks

+ *

+ * Compares two IP addresses with netmasks. The masks are used to mask

+ * out the bits that are to be compared.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr1, ipaddr2, mask;

+

+ uip_ipaddr(&mask, 255,255,255,0);

+ uip_ipaddr(&ipaddr1, 192,16,1,2);

+ uip_ipaddr(&ipaddr2, 192,16,1,3);

+ if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {

+    printf("They are the same");

+ }

+ \endcode

+ *

+ * \param addr1 The first IP address.

+ * \param addr2 The second IP address.

+ * \param mask The netmask.

+ *

+ * \hideinitializer

+ */

+#define uip_ipaddr_maskcmp(addr1, addr2, mask) \

+                          (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \

+                            (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \

+                           ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \

+                            (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))

+

+

+/**

+ * Mask out the network part of an IP address.

+ *

+ * Masks out the network part of an IP address, given the address and

+ * the netmask.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr1, ipaddr2, netmask;

+

+ uip_ipaddr(&ipaddr1, 192,16,1,2);

+ uip_ipaddr(&netmask, 255,255,255,0);

+ uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);

+ \endcode

+ *

+ * In the example above, the variable "ipaddr2" will contain the IP

+ * address 192.168.1.0.

+ *

+ * \param dest Where the result is to be placed.

+ * \param src The IP address.

+ * \param mask The netmask.

+ *

+ * \hideinitializer

+ */

+#define uip_ipaddr_mask(dest, src, mask) do { \

+                     ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \

+                     ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \

+                  } while(0)

+

+/**

+ * Pick the first octet of an IP address.

+ *

+ * Picks out the first octet of an IP address.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr;

+ u8_t octet;

+

+ uip_ipaddr(&ipaddr, 1,2,3,4);

+ octet = uip_ipaddr1(&ipaddr);

+ \endcode

+ *

+ * In the example above, the variable "octet" will contain the value 1.

+ *

+ * \hideinitializer

+ */

+#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8)

+

+/**

+ * Pick the second octet of an IP address.

+ *

+ * Picks out the second octet of an IP address.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr;

+ u8_t octet;

+

+ uip_ipaddr(&ipaddr, 1,2,3,4);

+ octet = uip_ipaddr2(&ipaddr);

+ \endcode

+ *

+ * In the example above, the variable "octet" will contain the value 2.

+ *

+ * \hideinitializer

+ */

+#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff)

+

+/**

+ * Pick the third octet of an IP address.

+ *

+ * Picks out the third octet of an IP address.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr;

+ u8_t octet;

+

+ uip_ipaddr(&ipaddr, 1,2,3,4);

+ octet = uip_ipaddr3(&ipaddr);

+ \endcode

+ *

+ * In the example above, the variable "octet" will contain the value 3.

+ *

+ * \hideinitializer

+ */

+#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8)

+

+/**

+ * Pick the fourth octet of an IP address.

+ *

+ * Picks out the fourth octet of an IP address.

+ *

+ * Example:

+ \code

+ uip_ipaddr_t ipaddr;

+ u8_t octet;

+

+ uip_ipaddr(&ipaddr, 1,2,3,4);

+ octet = uip_ipaddr4(&ipaddr);

+ \endcode

+ *

+ * In the example above, the variable "octet" will contain the value 4.

+ *

+ * \hideinitializer

+ */

+#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff)

+

+/**

+ * Convert 16-bit quantity from host byte order to network byte order.

+ *

+ * This macro is primarily used for converting constants from host

+ * byte order to network byte order. For converting variables to

+ * network byte order, use the htons() function instead.

+ *

+ * \hideinitializer

+ */

+#ifndef HTONS

+#   if UIP_BYTE_ORDER == UIP_BIG_ENDIAN

+#      define HTONS(n) (n)

+#   else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */

+#      define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))

+#   endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */

+#else

+#error "HTONS already defined!"

+#endif /* HTONS */

+

+/**

+ * Convert 16-bit quantity from host byte order to network byte order.

+ *

+ * This function is primarily used for converting variables from host

+ * byte order to network byte order. For converting constants to

+ * network byte order, use the HTONS() macro instead.

+ */

+#ifndef htons

+u16_t htons(u16_t val);

+#endif /* htons */

+#ifndef ntohs

+#define ntohs htons

+#endif

+

+/** @} */

+

+/**

+ * Pointer to the application data in the packet buffer.

+ *

+ * This pointer points to the application data when the application is

+ * called. If the application wishes to send data, the application may

+ * use this space to write the data into before calling uip_send().

+ */

+extern void *uip_appdata;

+

+#if UIP_URGDATA > 0

+/* u8_t *uip_urgdata:

+ *

+ * This pointer points to any urgent data that has been received. Only

+ * present if compiled with support for urgent data (UIP_URGDATA).

+ */

+extern void *uip_urgdata;

+#endif /* UIP_URGDATA > 0 */

+

+

+/**

+ * \defgroup uipdrivervars Variables used in uIP device drivers

+ * @{

+ *

+ * uIP has a few global variables that are used in device drivers for

+ * uIP.

+ */

+

+/**

+ * The length of the packet in the uip_buf buffer.

+ *

+ * The global variable uip_len holds the length of the packet in the

+ * uip_buf buffer.

+ *

+ * When the network device driver calls the uIP input function,

+ * uip_len should be set to the length of the packet in the uip_buf

+ * buffer.

+ *

+ * When sending packets, the device driver should use the contents of

+ * the uip_len variable to determine the length of the outgoing

+ * packet.

+ *

+ */

+extern u16_t uip_len;

+

+/** @} */

+

+#if UIP_URGDATA > 0

+extern u16_t uip_urglen, uip_surglen;

+#endif /* UIP_URGDATA > 0 */

+

+

+/**

+ * Representation of a uIP TCP connection.

+ *

+ * The uip_conn structure is used for identifying a connection. All

+ * but one field in the structure are to be considered read-only by an

+ * application. The only exception is the appstate field whos purpose

+ * is to let the application store application-specific state (e.g.,

+ * file pointers) for the connection. The type of this field is

+ * configured in the "uipopt.h" header file.

+ */

+struct uip_conn {

+  uip_ipaddr_t ripaddr;   /**< The IP address of the remote host. */

+

+  u16_t lport;        /**< The local TCP port, in network byte order. */

+  u16_t rport;        /**< The local remote TCP port, in network byte

+			 order. */

+

+  u8_t rcv_nxt[4];    /**< The sequence number that we expect to

+			 receive next. */

+  u8_t snd_nxt[4];    /**< The sequence number that was last sent by

+                         us. */

+  u16_t len;          /**< Length of the data that was previously sent. */

+  u16_t mss;          /**< Current maximum segment size for the

+			 connection. */

+  u16_t initialmss;   /**< Initial maximum segment size for the

+			 connection. */

+  u8_t sa;            /**< Retransmission time-out calculation state

+			 variable. */

+  u8_t sv;            /**< Retransmission time-out calculation state

+			 variable. */

+  u8_t rto;           /**< Retransmission time-out. */

+  u8_t tcpstateflags; /**< TCP state and flags. */

+  u8_t timer;         /**< The retransmission timer. */

+  u8_t nrtx;          /**< The number of retransmissions for the last

+			 segment sent. */

+

+  /** The application state. */

+  uip_tcp_appstate_t appstate;

+};

+

+

+/**

+ * Pointer to the current TCP connection.

+ *

+ * The uip_conn pointer can be used to access the current TCP

+ * connection.

+ */

+extern struct uip_conn *uip_conn;

+/* The array containing all uIP connections. */

+extern struct uip_conn uip_conns[UIP_CONNS];

+/**

+ * \addtogroup uiparch

+ * @{

+ */

+

+/**

+ * 4-byte array used for the 32-bit sequence number calculations.

+ */

+extern u8_t uip_acc32[4];

+

+/** @} */

+

+

+#if UIP_UDP

+/**

+ * Representation of a uIP UDP connection.

+ */

+struct uip_udp_conn {

+  uip_ipaddr_t ripaddr;   /**< The IP address of the remote peer. */

+  u16_t lport;        /**< The local port number in network byte order. */

+  u16_t rport;        /**< The remote port number in network byte order. */

+  u8_t  ttl;          /**< Default time-to-live. */

+

+  /** The application state. */

+  uip_udp_appstate_t appstate;

+};

+

+/**

+ * The current UDP connection.

+ */

+extern struct uip_udp_conn *uip_udp_conn;

+extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];

+#endif /* UIP_UDP */

+

+/**

+ * The structure holding the TCP/IP statistics that are gathered if

+ * UIP_STATISTICS is set to 1.

+ *

+ */

+struct uip_stats {

+  struct {

+    uip_stats_t drop;     /**< Number of dropped packets at the IP

+			     layer. */

+    uip_stats_t recv;     /**< Number of received packets at the IP

+			     layer. */

+    uip_stats_t sent;     /**< Number of sent packets at the IP

+			     layer. */

+    uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong

+			     IP version or header length. */

+    uip_stats_t hblenerr; /**< Number of packets dropped due to wrong

+			     IP length, high byte. */

+    uip_stats_t lblenerr; /**< Number of packets dropped due to wrong

+			     IP length, low byte. */

+    uip_stats_t fragerr;  /**< Number of packets dropped since they

+			     were IP fragments. */

+    uip_stats_t chkerr;   /**< Number of packets dropped due to IP

+			     checksum errors. */

+    uip_stats_t protoerr; /**< Number of packets dropped since they

+			     were neither ICMP, UDP nor TCP. */

+  } ip;                   /**< IP statistics. */

+  struct {

+    uip_stats_t drop;     /**< Number of dropped ICMP packets. */

+    uip_stats_t recv;     /**< Number of received ICMP packets. */

+    uip_stats_t sent;     /**< Number of sent ICMP packets. */

+    uip_stats_t typeerr;  /**< Number of ICMP packets with a wrong

+			     type. */

+  } icmp;                 /**< ICMP statistics. */

+  struct {

+    uip_stats_t drop;     /**< Number of dropped TCP segments. */

+    uip_stats_t recv;     /**< Number of recived TCP segments. */

+    uip_stats_t sent;     /**< Number of sent TCP segments. */

+    uip_stats_t chkerr;   /**< Number of TCP segments with a bad

+			     checksum. */

+    uip_stats_t ackerr;   /**< Number of TCP segments with a bad ACK

+			     number. */

+    uip_stats_t rst;      /**< Number of recevied TCP RST (reset) segments. */

+    uip_stats_t rexmit;   /**< Number of retransmitted TCP segments. */

+    uip_stats_t syndrop;  /**< Number of dropped SYNs due to too few

+			     connections was avaliable. */

+    uip_stats_t synrst;   /**< Number of SYNs for closed ports,

+			     triggering a RST. */

+  } tcp;                  /**< TCP statistics. */

+#if UIP_UDP

+  struct {

+    uip_stats_t drop;     /**< Number of dropped UDP segments. */

+    uip_stats_t recv;     /**< Number of recived UDP segments. */

+    uip_stats_t sent;     /**< Number of sent UDP segments. */

+    uip_stats_t chkerr;   /**< Number of UDP segments with a bad

+			     checksum. */

+  } udp;                  /**< UDP statistics. */

+#endif /* UIP_UDP */

+};

+

+/**

+ * The uIP TCP/IP statistics.

+ *

+ * This is the variable in which the uIP TCP/IP statistics are gathered.

+ */

+extern struct uip_stats uip_stat;

+

+

+/*---------------------------------------------------------------------------*/

+/* All the stuff below this point is internal to uIP and should not be

+ * used directly by an application or by a device driver.

+ */

+/*---------------------------------------------------------------------------*/

+/* u8_t uip_flags:

+ *

+ * When the application is called, uip_flags will contain the flags

+ * that are defined in this file. Please read below for more

+ * infomation.

+ */

+extern u8_t uip_flags;

+

+/* The following flags may be set in the global variable uip_flags

+   before calling the application callback. The UIP_ACKDATA,

+   UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time,

+   whereas the others are mutualy exclusive. Note that these flags

+   should *NOT* be accessed directly, but only through the uIP

+   functions/macros. */

+

+#define UIP_ACKDATA   1     /* Signifies that the outstanding data was

+			       acked and the application should send

+			       out new data instead of retransmitting

+			       the last data. */

+#define UIP_NEWDATA   2     /* Flags the fact that the peer has sent

+			       us new data. */

+#define UIP_REXMIT    4     /* Tells the application to retransmit the

+			       data that was last sent. */

+#define UIP_POLL      8     /* Used for polling the application, to

+			       check if the application has data that

+			       it wants to send. */

+#define UIP_CLOSE     16    /* The remote host has closed the

+			       connection, thus the connection has

+			       gone away. Or the application signals

+			       that it wants to close the

+			       connection. */

+#define UIP_ABORT     32    /* The remote host has aborted the

+			       connection, thus the connection has

+			       gone away. Or the application signals

+			       that it wants to abort the

+			       connection. */

+#define UIP_CONNECTED 64    /* We have got a connection from a remote

+                               host and have set up a new connection

+                               for it, or an active connection has

+                               been successfully established. */

+

+#define UIP_TIMEDOUT  128   /* The connection has been aborted due to

+			       too many retransmissions. */

+

+/* uip_process(flag):

+ *

+ * The actual uIP function which does all the work.

+ */

+void uip_process(u8_t flag);

+

+/* The following flags are passed as an argument to the uip_process()

+   function. They are used to distinguish between the two cases where

+   uip_process() is called. It can be called either because we have

+   incoming data that should be processed, or because the periodic

+   timer has fired. These values are never used directly, but only in

+   the macrose defined in this file. */

+

+#define UIP_DATA          1     /* Tells uIP that there is incoming

+				   data in the uip_buf buffer. The

+				   length of the data is stored in the

+				   global variable uip_len. */

+#define UIP_TIMER         2     /* Tells uIP that the periodic timer

+				   has fired. */

+#define UIP_POLL_REQUEST  3     /* Tells uIP that a connection should

+				   be polled. */

+#define UIP_UDP_SEND_CONN 4     /* Tells uIP that a UDP datagram

+				   should be constructed in the

+				   uip_buf buffer. */

+#if UIP_UDP

+#define UIP_UDP_TIMER     5

+#endif /* UIP_UDP */

+

+/* The TCP states used in the uip_conn->tcpstateflags. */

+#define UIP_CLOSED      0

+#define UIP_SYN_RCVD    1

+#define UIP_SYN_SENT    2

+#define UIP_ESTABLISHED 3

+#define UIP_FIN_WAIT_1  4

+#define UIP_FIN_WAIT_2  5

+#define UIP_CLOSING     6

+#define UIP_TIME_WAIT   7

+#define UIP_LAST_ACK    8

+#define UIP_TS_MASK     15

+

+#define UIP_STOPPED      16

+

+/* The TCP and IP headers. */

+

+#ifdef __ICCARM__

+	#pragma pack(1)

+#endif

+

+struct uip_tcpip_hdr {

+#if UIP_CONF_IPV6

+  /* IPv6 header. */

+  u8_t vtc,

+    tcflow;

+  u16_t flow;

+  u8_t len[2];

+  u8_t proto, ttl;

+  uip_ip6addr_t srcipaddr, destipaddr;

+#else /* UIP_CONF_IPV6 */

+  /* IPv4 header. */

+  u8_t vhl,

+    tos,

+    len[2],

+    ipid[2],

+    ipoffset[2],

+    ttl,

+    proto;

+  u16_t ipchksum;

+  u16_t srcipaddr[2],

+    destipaddr[2];

+#endif /* UIP_CONF_IPV6 */

+

+  /* TCP header. */

+  u16_t srcport,

+    destport;

+  u8_t seqno[4],

+    ackno[4],

+    tcpoffset,

+    flags,

+    wnd[2];

+  u16_t tcpchksum;

+  u8_t urgp[2];

+  u8_t optdata[4];

+} PACK_STRUCT_END;

+

+#ifdef __ICCARM__

+	#pragma pack()

+#endif

+

+/* The ICMP and IP headers. */

+#ifdef __ICCARM__

+	#pragma pack(1)

+#endif

+

+struct uip_icmpip_hdr {

+#if UIP_CONF_IPV6

+  /* IPv6 header. */

+  u8_t vtc,

+    tcf;

+  u16_t flow;

+  u8_t len[2];

+  u8_t proto, ttl;

+  uip_ip6addr_t srcipaddr, destipaddr;

+#else /* UIP_CONF_IPV6 */

+  /* IPv4 header. */

+  u8_t vhl,

+    tos,

+    len[2],

+    ipid[2],

+    ipoffset[2],

+    ttl,

+    proto;

+  u16_t ipchksum;

+  u16_t srcipaddr[2],

+    destipaddr[2];

+#endif /* UIP_CONF_IPV6 */

+

+  /* ICMP (echo) header. */

+  u8_t type, icode;

+  u16_t icmpchksum;

+#if !UIP_CONF_IPV6

+  u16_t id, seqno;

+#else /* !UIP_CONF_IPV6 */

+  u8_t flags, reserved1, reserved2, reserved3;

+  u8_t icmp6data[16];

+  u8_t options[1];

+#endif /* !UIP_CONF_IPV6 */

+} PACK_STRUCT_END;

+

+#ifdef __ICCARM__

+	#pragma pack()

+#endif

+

+

+/* The UDP and IP headers. */

+#ifdef __ICCARM__

+	#pragma pack(1)

+#endif

+

+struct uip_udpip_hdr {

+#if UIP_CONF_IPV6

+  /* IPv6 header. */

+  u8_t vtc,

+    tcf;

+  u16_t flow;

+  u8_t len[2];

+  u8_t proto, ttl;

+  uip_ip6addr_t srcipaddr, destipaddr;

+#else /* UIP_CONF_IPV6 */

+  /* IP header. */

+  u8_t vhl,

+    tos,

+    len[2],

+    ipid[2],

+    ipoffset[2],

+    ttl,

+    proto;

+  u16_t ipchksum;

+  u16_t srcipaddr[2],

+    destipaddr[2];

+#endif /* UIP_CONF_IPV6 */

+

+  /* UDP header. */

+  u16_t srcport,

+    destport;

+  u16_t udplen;

+  u16_t udpchksum;

+} PACK_STRUCT_END;

+

+#ifdef __ICCARM__

+	#pragma pack()

+#endif

+

+

+

+/**

+ * The buffer size available for user data in the \ref uip_buf buffer.

+ *

+ * This macro holds the available size for user data in the \ref

+ * uip_buf buffer. The macro is intended to be used for checking

+ * bounds of available user data.

+ *

+ * Example:

+ \code

+ snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);

+ \endcode

+ *

+ * \hideinitializer

+ */

+#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)

+

+

+#define UIP_PROTO_ICMP  1

+#define UIP_PROTO_TCP   6

+#define UIP_PROTO_UDP   17

+#define UIP_PROTO_ICMP6 58

+

+/* Header sizes. */

+#if UIP_CONF_IPV6

+#define UIP_IPH_LEN    40

+#else /* UIP_CONF_IPV6 */

+#define UIP_IPH_LEN    20    /* Size of IP header */

+#endif /* UIP_CONF_IPV6 */

+#define UIP_UDPH_LEN    8    /* Size of UDP header */

+#define UIP_TCPH_LEN   20    /* Size of TCP header */

+#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)    /* Size of IP +

+							  UDP

+							  header */

+#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN)    /* Size of IP +

+							  TCP

+							  header */

+#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN

+

+

+#if UIP_FIXEDADDR

+extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;

+#else /* UIP_FIXEDADDR */

+extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;

+#endif /* UIP_FIXEDADDR */

+

+

+

+/**

+ * Representation of a 48-bit Ethernet address.

+ */

+#ifdef __ICCARM__

+	#pragma pack(1)

+#endif

+

+struct uip_eth_addr {

+  u8_t addr[6];

+} PACK_STRUCT_END;

+

+#ifdef __ICCARM__

+	#pragma pack()

+#endif

+

+/**

+ * Calculate the Internet checksum over a buffer.

+ *

+ * The Internet checksum is the one's complement of the one's

+ * complement sum of all 16-bit words in the buffer.

+ *

+ * See RFC1071.

+ *

+ * \param buf A pointer to the buffer over which the checksum is to be

+ * computed.

+ *

+ * \param len The length of the buffer over which the checksum is to

+ * be computed.

+ *

+ * \return The Internet checksum of the buffer.

+ */

+u16_t uip_chksum(u16_t *buf, u16_t len);

+

+/**

+ * Calculate the IP header checksum of the packet header in uip_buf.

+ *

+ * The IP header checksum is the Internet checksum of the 20 bytes of

+ * the IP header.

+ *

+ * \return The IP header checksum of the IP header in the uip_buf

+ * buffer.

+ */

+u16_t uip_ipchksum(void);

+

+/**

+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.

+ *

+ * The TCP checksum is the Internet checksum of data contents of the

+ * TCP segment, and a pseudo-header as defined in RFC793.

+ *

+ * \return The TCP checksum of the TCP segment in uip_buf and pointed

+ * to by uip_appdata.

+ */

+u16_t uip_tcpchksum(void);

+

+/**

+ * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.

+ *

+ * The UDP checksum is the Internet checksum of data contents of the

+ * UDP segment, and a pseudo-header as defined in RFC768.

+ *

+ * \return The UDP checksum of the UDP segment in uip_buf and pointed

+ * to by uip_appdata.

+ */

+u16_t uip_udpchksum(void);

+

+

+#endif /* __UIP_H__ */

+

+

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arch.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arch.h
new file mode 100644
index 0000000..5ea4578
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arch.h
@@ -0,0 +1,138 @@
+/**

+ * \addtogroup uip

+ * {@

+ */

+

+/**

+ * \defgroup uiparch Architecture specific uIP functions

+ * @{

+ *

+ * The functions in the architecture specific module implement the IP

+ * check sum and 32-bit additions.

+ *

+ * The IP checksum calculation is the most computationally expensive

+ * operation in the TCP/IP stack and it therefore pays off to

+ * implement this in efficient assembler. The purpose of the uip-arch

+ * module is to let the checksum functions to be implemented in

+ * architecture specific assembler.

+ *

+ */

+

+/**

+ * \file

+ * Declarations of architecture specific functions.

+ * \author Adam Dunkels <adam@dunkels.com>

+ */

+

+/*

+ * Copyright (c) 2001, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $

+ *

+ */

+

+#ifndef __UIP_ARCH_H__

+#define __UIP_ARCH_H__

+

+#include "uip.h"

+

+/**

+ * Carry out a 32-bit addition.

+ *

+ * Because not all architectures for which uIP is intended has native

+ * 32-bit arithmetic, uIP uses an external C function for doing the

+ * required 32-bit additions in the TCP protocol processing. This

+ * function should add the two arguments and place the result in the

+ * global variable uip_acc32.

+ *

+ * \note The 32-bit integer pointed to by the op32 parameter and the

+ * result in the uip_acc32 variable are in network byte order (big

+ * endian).

+ *

+ * \param op32 A pointer to a 4-byte array representing a 32-bit

+ * integer in network byte order (big endian).

+ *

+ * \param op16 A 16-bit integer in host byte order.

+ */

+void uip_add32(u8_t *op32, u16_t op16);

+

+/**

+ * Calculate the Internet checksum over a buffer.

+ *

+ * The Internet checksum is the one's complement of the one's

+ * complement sum of all 16-bit words in the buffer.

+ *

+ * See RFC1071.

+ *

+ * \note This function is not called in the current version of uIP,

+ * but future versions might make use of it.

+ *

+ * \param buf A pointer to the buffer over which the checksum is to be

+ * computed.

+ *

+ * \param len The length of the buffer over which the checksum is to

+ * be computed.

+ *

+ * \return The Internet checksum of the buffer.

+ */

+u16_t uip_chksum(u16_t *buf, u16_t len);

+

+/**

+ * Calculate the IP header checksum of the packet header in uip_buf.

+ *

+ * The IP header checksum is the Internet checksum of the 20 bytes of

+ * the IP header.

+ *

+ * \return The IP header checksum of the IP header in the uip_buf

+ * buffer.

+ */

+u16_t uip_ipchksum(void);

+

+/**

+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.

+ *

+ * The TCP checksum is the Internet checksum of data contents of the

+ * TCP segment, and a pseudo-header as defined in RFC793.

+ *

+ * \note The uip_appdata pointer that points to the packet data may

+ * point anywhere in memory, so it is not possible to simply calculate

+ * the Internet checksum of the contents of the uip_buf buffer.

+ *

+ * \return The TCP checksum of the TCP segment in uip_buf and pointed

+ * to by uip_appdata.

+ */

+u16_t uip_tcpchksum(void);

+

+u16_t uip_udpchksum(void);

+

+/** @} */

+/** @} */

+

+#endif /* __UIP_ARCH_H__ */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arp.c b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arp.c
new file mode 100644
index 0000000..44c7975
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arp.c
@@ -0,0 +1,439 @@
+/**

+ * \addtogroup uip

+ * @{

+ */

+

+/**

+ * \defgroup uiparp uIP Address Resolution Protocol

+ * @{

+ *

+ * The Address Resolution Protocol ARP is used for mapping between IP

+ * addresses and link level addresses such as the Ethernet MAC

+ * addresses. ARP uses broadcast queries to ask for the link level

+ * address of a known IP address and the host which is configured with

+ * the IP address for which the query was meant, will respond with its

+ * link level address.

+ *

+ * \note This ARP implementation only supports Ethernet.

+ */

+

+/**

+ * \file

+ * Implementation of the ARP Address Resolution Protocol.

+ * \author Adam Dunkels <adam@dunkels.com>

+ *

+ */

+

+/*

+ * Copyright (c) 2001-2003, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $

+ *

+ */

+

+

+#include "uip_arp.h"

+

+#include <string.h>

+

+#ifdef __ICCARM__

+	#pragma pack(1)

+#endif

+

+struct arp_hdr {

+  struct uip_eth_hdr ethhdr;

+  u16_t hwtype;

+  u16_t protocol;

+  u8_t hwlen;

+  u8_t protolen;

+  u16_t opcode;

+  struct uip_eth_addr shwaddr;

+  u16_t sipaddr[2];

+  struct uip_eth_addr dhwaddr;

+  u16_t dipaddr[2];

+} PACK_STRUCT_END;

+

+#ifdef __ICCARM__

+	#pragma pack()

+#endif

+

+#ifdef __ICCARM__

+	#pragma pack(1)

+#endif

+

+struct ethip_hdr {

+  struct uip_eth_hdr ethhdr;

+  /* IP header. */

+  u8_t vhl,

+    tos,

+    len[2],

+    ipid[2],

+    ipoffset[2],

+    ttl,

+    proto;

+  u16_t ipchksum;

+  u16_t srcipaddr[2],

+    destipaddr[2];

+} PACK_STRUCT_END;

+

+#ifdef __ICCARM__

+	#pragma pack()

+#endif

+

+#define ARP_REQUEST 1

+#define ARP_REPLY   2

+

+#define ARP_HWTYPE_ETH 1

+

+struct arp_entry {

+  u16_t ipaddr[2];

+  struct uip_eth_addr ethaddr;

+  u8_t time;

+};

+

+static const struct uip_eth_addr broadcast_ethaddr =

+  {{0xff,0xff,0xff,0xff,0xff,0xff}};

+static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};

+

+static struct arp_entry arp_table[UIP_ARPTAB_SIZE];

+static u16_t ipaddr[2];

+static u8_t i, c;

+

+static u8_t arptime;

+static u8_t tmpage;

+

+#define BUF   ((struct arp_hdr *)&uip_buf[0])

+#define IPBUF ((struct ethip_hdr *)&uip_buf[0])

+/*-----------------------------------------------------------------------------------*/

+/**

+ * Initialize the ARP module.

+ *

+ */

+/*-----------------------------------------------------------------------------------*/

+void

+uip_arp_init(void)

+{

+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {

+    memset(arp_table[i].ipaddr, 0, 4);

+  }

+}

+/*-----------------------------------------------------------------------------------*/

+/**

+ * Periodic ARP processing function.

+ *

+ * This function performs periodic timer processing in the ARP module

+ * and should be called at regular intervals. The recommended interval

+ * is 10 seconds between the calls.

+ *

+ */

+/*-----------------------------------------------------------------------------------*/

+void

+uip_arp_timer(void)

+{

+  struct arp_entry *tabptr;

+

+  ++arptime;

+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {

+    tabptr = &arp_table[i];

+    if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&

+       arptime - tabptr->time >= UIP_ARP_MAXAGE) {

+      memset(tabptr->ipaddr, 0, 4);

+    }

+  }

+

+}

+/*-----------------------------------------------------------------------------------*/

+static void

+uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)

+{

+  register struct arp_entry *tabptr;

+  /* Walk through the ARP mapping table and try to find an entry to

+     update. If none is found, the IP -> MAC address mapping is

+     inserted in the ARP table. */

+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {

+

+    tabptr = &arp_table[i];

+    /* Only check those entries that are actually in use. */

+    if(tabptr->ipaddr[0] != 0 &&

+       tabptr->ipaddr[1] != 0) {

+

+      /* Check if the source IP address of the incoming packet matches

+         the IP address in this ARP table entry. */

+      if(ipaddr[0] == tabptr->ipaddr[0] &&

+	 ipaddr[1] == tabptr->ipaddr[1]) {

+	

+	/* An old entry found, update this and return. */

+	memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);

+	tabptr->time = arptime;

+

+	return;

+      }

+    }

+  }

+

+  /* If we get here, no existing ARP table entry was found, so we

+     create one. */

+

+  /* First, we try to find an unused entry in the ARP table. */

+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {

+    tabptr = &arp_table[i];

+    if(tabptr->ipaddr[0] == 0 &&

+       tabptr->ipaddr[1] == 0) {

+      break;

+    }

+  }

+

+  /* If no unused entry is found, we try to find the oldest entry and

+     throw it away. */

+  if(i == UIP_ARPTAB_SIZE) {

+    tmpage = 0;

+    c = 0;

+    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {

+      tabptr = &arp_table[i];

+      if(arptime - tabptr->time > tmpage) {

+	tmpage = arptime - tabptr->time;

+	c = i;

+      }

+    }

+    i = c;

+    tabptr = &arp_table[i];

+  }

+

+  /* Now, i is the ARP table entry which we will fill with the new

+     information. */

+  memcpy(tabptr->ipaddr, ipaddr, 4);

+  memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);

+  tabptr->time = arptime;

+}

+/*-----------------------------------------------------------------------------------*/

+/**

+ * ARP processing for incoming IP packets

+ *

+ * This function should be called by the device driver when an IP

+ * packet has been received. The function will check if the address is

+ * in the ARP cache, and if so the ARP cache entry will be

+ * refreshed. If no ARP cache entry was found, a new one is created.

+ *

+ * This function expects an IP packet with a prepended Ethernet header

+ * in the uip_buf[] buffer, and the length of the packet in the global

+ * variable uip_len.

+ */

+/*-----------------------------------------------------------------------------------*/

+#if 1

+void

+uip_arp_ipin(void)

+{

+  uip_len -= sizeof(struct uip_eth_hdr);

+	

+  /* Only insert/update an entry if the source IP address of the

+     incoming IP packet comes from a host on the local network. */

+  if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=

+     (uip_hostaddr[0] & uip_netmask[0])) {

+    return;

+  }

+  if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=

+     (uip_hostaddr[1] & uip_netmask[1])) {

+    return;

+  }

+  uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));

+

+  return;

+}

+#endif /* 0 */

+/*-----------------------------------------------------------------------------------*/

+/**

+ * ARP processing for incoming ARP packets.

+ *

+ * This function should be called by the device driver when an ARP

+ * packet has been received. The function will act differently

+ * depending on the ARP packet type: if it is a reply for a request

+ * that we previously sent out, the ARP cache will be filled in with

+ * the values from the ARP reply. If the incoming ARP packet is an ARP

+ * request for our IP address, an ARP reply packet is created and put

+ * into the uip_buf[] buffer.

+ *

+ * When the function returns, the value of the global variable uip_len

+ * indicates whether the device driver should send out a packet or

+ * not. If uip_len is zero, no packet should be sent. If uip_len is

+ * non-zero, it contains the length of the outbound packet that is

+ * present in the uip_buf[] buffer.

+ *

+ * This function expects an ARP packet with a prepended Ethernet

+ * header in the uip_buf[] buffer, and the length of the packet in the

+ * global variable uip_len.

+ */

+/*-----------------------------------------------------------------------------------*/

+void

+uip_arp_arpin(void)

+{

+

+  if(uip_len < sizeof(struct arp_hdr)) {

+    uip_len = 0;

+    return;

+  }

+  uip_len = 0;

+

+  switch(BUF->opcode) {

+  case HTONS(ARP_REQUEST):

+    /* ARP request. If it asked for our address, we send out a

+       reply. */

+    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {

+      /* First, we register the one who made the request in our ARP

+	 table, since it is likely that we will do more communication

+	 with this host in the future. */

+      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);

+

+      /* The reply opcode is 2. */

+      BUF->opcode = HTONS(2);

+

+      memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);

+      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);

+      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);

+      memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);

+

+      BUF->dipaddr[0] = BUF->sipaddr[0];

+      BUF->dipaddr[1] = BUF->sipaddr[1];

+      BUF->sipaddr[0] = uip_hostaddr[0];

+      BUF->sipaddr[1] = uip_hostaddr[1];

+

+      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);

+      uip_len = sizeof(struct arp_hdr);

+    }

+    break;

+  case HTONS(ARP_REPLY):

+    /* ARP reply. We insert or update the ARP table if it was meant

+       for us. */

+    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {

+      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);

+    }

+    break;

+  }

+

+  return;

+}

+/*-----------------------------------------------------------------------------------*/

+/**

+ * Prepend Ethernet header to an outbound IP packet and see if we need

+ * to send out an ARP request.

+ *

+ * This function should be called before sending out an IP packet. The

+ * function checks the destination IP address of the IP packet to see

+ * what Ethernet MAC address that should be used as a destination MAC

+ * address on the Ethernet.

+ *

+ * If the destination IP address is in the local network (determined

+ * by logical ANDing of netmask and our IP address), the function

+ * checks the ARP cache to see if an entry for the destination IP

+ * address is found. If so, an Ethernet header is prepended and the

+ * function returns. If no ARP cache entry is found for the

+ * destination IP address, the packet in the uip_buf[] is replaced by

+ * an ARP request packet for the IP address. The IP packet is dropped

+ * and it is assumed that they higher level protocols (e.g., TCP)

+ * eventually will retransmit the dropped packet.

+ *

+ * If the destination IP address is not on the local network, the IP

+ * address of the default router is used instead.

+ *

+ * When the function returns, a packet is present in the uip_buf[]

+ * buffer, and the length of the packet is in the global variable

+ * uip_len.

+ */

+/*-----------------------------------------------------------------------------------*/

+void

+uip_arp_out(void)

+{

+  struct arp_entry *tabptr;

+

+  /* Find the destination IP address in the ARP table and construct

+     the Ethernet header. If the destination IP addres isn't on the

+     local network, we use the default router's IP address instead.

+

+     If not ARP table entry is found, we overwrite the original IP

+     packet with an ARP request for the IP address. */

+

+  /* First check if destination is a local broadcast. */

+  if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {

+    memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);

+  } else {

+    /* Check if the destination address is on the local network. */

+    if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {

+      /* Destination address was not on the local network, so we need to

+	 use the default router's IP address instead of the destination

+	 address when determining the MAC address. */

+      uip_ipaddr_copy(ipaddr, uip_draddr);

+    } else {

+      /* Else, we use the destination IP address. */

+      uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);

+    }

+

+    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {

+      tabptr = &arp_table[i];

+      if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {

+	break;

+      }

+    }

+

+    if(i == UIP_ARPTAB_SIZE) {

+      /* The destination address was not in our ARP table, so we

+	 overwrite the IP packet with an ARP request. */

+

+      memset(BUF->ethhdr.dest.addr, 0xff, 6);

+      memset(BUF->dhwaddr.addr, 0x00, 6);

+      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);

+      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);

+

+      uip_ipaddr_copy(BUF->dipaddr, ipaddr);

+      uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);

+      BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */

+      BUF->hwtype = HTONS(ARP_HWTYPE_ETH);

+      BUF->protocol = HTONS(UIP_ETHTYPE_IP);

+      BUF->hwlen = 6;

+      BUF->protolen = 4;

+      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);

+

+      uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];

+

+      uip_len = sizeof(struct arp_hdr);

+      return;

+    }

+

+    /* Build an ethernet header. */

+    memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);

+  }

+  memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);

+

+  IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);

+

+  uip_len += sizeof(struct uip_eth_hdr);

+}

+/*-----------------------------------------------------------------------------------*/

+

+/** @} */

+/** @} */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arp.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arp.h
new file mode 100644
index 0000000..b6b2b66
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uip_arp.h
@@ -0,0 +1,152 @@
+/**

+ * \addtogroup uip

+ * @{

+ */

+

+/**

+ * \addtogroup uiparp

+ * @{

+ */

+

+/**

+ * \file

+ * Macros and definitions for the ARP module.

+ * \author Adam Dunkels <adam@dunkels.com>

+ */

+

+

+/*

+ * Copyright (c) 2001-2003, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $

+ *

+ */

+

+#ifndef __UIP_ARP_H__

+#define __UIP_ARP_H__

+

+#include "uip.h"

+

+

+extern struct uip_eth_addr uip_ethaddr;

+

+/**

+ * The Ethernet header.

+ */

+#ifdef __ICCARM__

+	#pragma pack(1)

+#endif

+

+struct uip_eth_hdr {

+  struct uip_eth_addr dest;

+  struct uip_eth_addr src;

+  u16_t type;

+}PACK_STRUCT_END;

+

+#ifdef __ICCARM__

+	#pragma pack()

+#endif

+

+#define UIP_ETHTYPE_ARP 0x0806

+#define UIP_ETHTYPE_IP  0x0800

+#define UIP_ETHTYPE_IP6 0x86dd

+

+

+/* The uip_arp_init() function must be called before any of the other

+   ARP functions. */

+void uip_arp_init(void);

+

+/* The uip_arp_ipin() function should be called whenever an IP packet

+   arrives from the Ethernet. This function refreshes the ARP table or

+   inserts a new mapping if none exists. The function assumes that an

+   IP packet with an Ethernet header is present in the uip_buf buffer

+   and that the length of the packet is in the uip_len variable. */

+void uip_arp_ipin(void);

+//#define uip_arp_ipin()

+

+/* The uip_arp_arpin() should be called when an ARP packet is received

+   by the Ethernet driver. This function also assumes that the

+   Ethernet frame is present in the uip_buf buffer. When the

+   uip_arp_arpin() function returns, the contents of the uip_buf

+   buffer should be sent out on the Ethernet if the uip_len variable

+   is > 0. */

+void uip_arp_arpin(void);

+

+/* The uip_arp_out() function should be called when an IP packet

+   should be sent out on the Ethernet. This function creates an

+   Ethernet header before the IP header in the uip_buf buffer. The

+   Ethernet header will have the correct Ethernet MAC destination

+   address filled in if an ARP table entry for the destination IP

+   address (or the IP address of the default router) is present. If no

+   such table entry is found, the IP packet is overwritten with an ARP

+   request and we rely on TCP to retransmit the packet that was

+   overwritten. In any case, the uip_len variable holds the length of

+   the Ethernet frame that should be transmitted. */

+void uip_arp_out(void);

+

+/* The uip_arp_timer() function should be called every ten seconds. It

+   is responsible for flushing old entries in the ARP table. */

+void uip_arp_timer(void);

+

+/** @} */

+

+/**

+ * \addtogroup uipconffunc

+ * @{

+ */

+

+

+/**

+ * Specifiy the Ethernet MAC address.

+ *

+ * The ARP code needs to know the MAC address of the Ethernet card in

+ * order to be able to respond to ARP queries and to generate working

+ * Ethernet headers.

+ *

+ * \note This macro only specifies the Ethernet MAC address to the ARP

+ * code. It cannot be used to change the MAC address of the Ethernet

+ * card.

+ *

+ * \param eaddr A pointer to a struct uip_eth_addr containing the

+ * Ethernet MAC address of the Ethernet card.

+ *

+ * \hideinitializer

+ */

+#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \

+                              uip_ethaddr.addr[1] = eaddr.addr[1];\

+                              uip_ethaddr.addr[2] = eaddr.addr[2];\

+                              uip_ethaddr.addr[3] = eaddr.addr[3];\

+                              uip_ethaddr.addr[4] = eaddr.addr[4];\

+                              uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)

+

+/** @} */

+/** @} */

+

+#endif /* __UIP_ARP_H__ */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uipopt.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uipopt.h
new file mode 100644
index 0000000..f7c3e0f
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/uipopt.h
@@ -0,0 +1,539 @@
+/**

+ * \defgroup uipopt Configuration options for uIP

+ * @{

+ *

+ * uIP is configured using the per-project configuration file

+ * uipopt.h. This file contains all compile-time options for uIP and

+ * should be tweaked to match each specific project. The uIP

+ * distribution contains a documented example "uipopt.h" that can be

+ * copied and modified for each project.

+ *

+ * \note Most of the configuration options in the uipopt.h should not

+ * be changed, but rather the per-project uip-conf.h file.

+ */

+

+/**

+ * \file

+ * Configuration options for uIP.

+ * \author Adam Dunkels <adam@dunkels.com>

+ *

+ * This file is used for tweaking various configuration options for

+ * uIP. You should make a copy of this file into one of your project's

+ * directories instead of editing this example "uipopt.h" file that

+ * comes with the uIP distribution.

+ */

+

+/*

+ * Copyright (c) 2001-2003, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack.

+ *

+ * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $

+ *

+ */

+

+#ifndef __UIPOPT_H__

+#define __UIPOPT_H__

+

+#ifndef UIP_LITTLE_ENDIAN

+#define UIP_LITTLE_ENDIAN  3412

+#endif /* UIP_LITTLE_ENDIAN */

+#ifndef UIP_BIG_ENDIAN

+#define UIP_BIG_ENDIAN     1234

+#endif /* UIP_BIG_ENDIAN */

+

+#include "uip-conf.h"

+

+/*------------------------------------------------------------------------------*/

+

+/**

+ * \name Static configuration options

+ * @{

+ *

+ * These configuration options can be used for setting the IP address

+ * settings statically, but only if UIP_FIXEDADDR is set to 1. The

+ * configuration options for a specific node includes IP address,

+ * netmask and default router as well as the Ethernet address. The

+ * netmask, default router and Ethernet address are appliciable only

+ * if uIP should be run over Ethernet.

+ *

+ * All of these should be changed to suit your project.

+*/

+

+/**

+ * Determines if uIP should use a fixed IP address or not.

+ *

+ * If uIP should use a fixed IP address, the settings are set in the

+ * uipopt.h file. If not, the macros uip_sethostaddr(),

+ * uip_setdraddr() and uip_setnetmask() should be used instead.

+ *

+ * \hideinitializer

+ */

+#define UIP_FIXEDADDR    0

+

+/**

+ * Ping IP address asignment.

+ *

+ * uIP uses a "ping" packets for setting its own IP address if this

+ * option is set. If so, uIP will start with an empty IP address and

+ * the destination IP address of the first incoming "ping" (ICMP echo)

+ * packet will be used for setting the hosts IP address.

+ *

+ * \note This works only if UIP_FIXEDADDR is 0.

+ *

+ * \hideinitializer

+ */

+#ifdef UIP_CONF_PINGADDRCONF

+#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF

+#else /* UIP_CONF_PINGADDRCONF */

+#define UIP_PINGADDRCONF 0

+#endif /* UIP_CONF_PINGADDRCONF */

+

+

+/**

+ * Specifies if the uIP ARP module should be compiled with a fixed

+ * Ethernet MAC address or not.

+ *

+ * If this configuration option is 0, the macro uip_setethaddr() can

+ * be used to specify the Ethernet address at run-time.

+ *

+ * \hideinitializer

+ */

+#define UIP_FIXEDETHADDR 0

+

+/** @} */

+/*------------------------------------------------------------------------------*/

+/**

+ * \name IP configuration options

+ * @{

+ *

+ */

+/**

+ * The IP TTL (time to live) of IP packets sent by uIP.

+ *

+ * This should normally not be changed.

+ */

+#define UIP_TTL         64

+

+/**

+ * Turn on support for IP packet reassembly.

+ *

+ * uIP supports reassembly of fragmented IP packets. This features

+ * requires an additonal amount of RAM to hold the reassembly buffer

+ * and the reassembly code size is approximately 700 bytes.  The

+ * reassembly buffer is of the same size as the uip_buf buffer

+ * (configured by UIP_BUFSIZE).

+ *

+ * \note IP packet reassembly is not heavily tested.

+ *

+ * \hideinitializer

+ */

+#define UIP_REASSEMBLY 0

+

+/**

+ * The maximum time an IP fragment should wait in the reassembly

+ * buffer before it is dropped.

+ *

+ */

+#define UIP_REASS_MAXAGE 40

+

+/** @} */

+

+/*------------------------------------------------------------------------------*/

+/**

+ * \name UDP configuration options

+ * @{

+ */

+

+/**

+ * Toggles wether UDP support should be compiled in or not.

+ *

+ * \hideinitializer

+ */

+#ifdef UIP_CONF_UDP

+#define UIP_UDP UIP_CONF_UDP

+#else /* UIP_CONF_UDP */

+#define UIP_UDP           0

+#endif /* UIP_CONF_UDP */

+

+/**

+ * Toggles if UDP checksums should be used or not.

+ *

+ * \note Support for UDP checksums is currently not included in uIP,

+ * so this option has no function.

+ *

+ * \hideinitializer

+ */

+#ifdef UIP_CONF_UDP_CHECKSUMS

+#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS

+#else

+#define UIP_UDP_CHECKSUMS 0

+#endif

+

+/**

+ * The maximum amount of concurrent UDP connections.

+ *

+ * \hideinitializer

+ */

+#ifdef UIP_CONF_UDP_CONNS

+#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS

+#else /* UIP_CONF_UDP_CONNS */

+#define UIP_UDP_CONNS    10

+#endif /* UIP_CONF_UDP_CONNS */

+

+/**

+ * The name of the function that should be called when UDP datagrams arrive.

+ *

+ * \hideinitializer

+ */

+

+

+/** @} */

+/*------------------------------------------------------------------------------*/

+/**

+ * \name TCP configuration options

+ * @{

+ */

+

+/**

+ * Determines if support for opening connections from uIP should be

+ * compiled in.

+ *

+ * If the applications that are running on top of uIP for this project

+ * do not need to open outgoing TCP connections, this configration

+ * option can be turned off to reduce the code size of uIP.

+ *

+ * \hideinitializer

+ */

+#define UIP_ACTIVE_OPEN 1

+

+/**

+ * The maximum number of simultaneously open TCP connections.

+ *

+ * Since the TCP connections are statically allocated, turning this

+ * configuration knob down results in less RAM used. Each TCP

+ * connection requires approximatly 30 bytes of memory.

+ *

+ * \hideinitializer

+ */

+#ifndef UIP_CONF_MAX_CONNECTIONS

+#define UIP_CONNS       10

+#else /* UIP_CONF_MAX_CONNECTIONS */

+#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS

+#endif /* UIP_CONF_MAX_CONNECTIONS */

+

+

+/**

+ * The maximum number of simultaneously listening TCP ports.

+ *

+ * Each listening TCP port requires 2 bytes of memory.

+ *

+ * \hideinitializer

+ */

+#ifndef UIP_CONF_MAX_LISTENPORTS

+#define UIP_LISTENPORTS 20

+#else /* UIP_CONF_MAX_LISTENPORTS */

+#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS

+#endif /* UIP_CONF_MAX_LISTENPORTS */

+

+/**

+ * Determines if support for TCP urgent data notification should be

+ * compiled in.

+ *

+ * Urgent data (out-of-band data) is a rarely used TCP feature that

+ * very seldom would be required.

+ *

+ * \hideinitializer

+ */

+#define UIP_URGDATA      0

+

+/**

+ * The initial retransmission timeout counted in timer pulses.

+ *

+ * This should not be changed.

+ */

+#define UIP_RTO         3

+

+/**

+ * The maximum number of times a segment should be retransmitted

+ * before the connection should be aborted.

+ *

+ * This should not be changed.

+ */

+#define UIP_MAXRTX      8

+

+/**

+ * The maximum number of times a SYN segment should be retransmitted

+ * before a connection request should be deemed to have been

+ * unsuccessful.

+ *

+ * This should not need to be changed.

+ */

+#define UIP_MAXSYNRTX      5

+

+/**

+ * The TCP maximum segment size.

+ *

+ * This is should not be to set to more than

+ * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.

+ */

+#define UIP_TCP_MSS     (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)

+

+/**

+ * The size of the advertised receiver's window.

+ *

+ * Should be set low (i.e., to the size of the uip_buf buffer) is the

+ * application is slow to process incoming data, or high (32768 bytes)

+ * if the application processes data quickly.

+ *

+ * \hideinitializer

+ */

+#ifndef UIP_CONF_RECEIVE_WINDOW

+#define UIP_RECEIVE_WINDOW UIP_TCP_MSS

+#else

+#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW

+#endif

+

+/**

+ * How long a connection should stay in the TIME_WAIT state.

+ *

+ * This configiration option has no real implication, and it should be

+ * left untouched.

+ */

+#define UIP_TIME_WAIT_TIMEOUT 120

+

+

+/** @} */

+/*------------------------------------------------------------------------------*/

+/**

+ * \name ARP configuration options

+ * @{

+ */

+

+/**

+ * The size of the ARP table.

+ *

+ * This option should be set to a larger value if this uIP node will

+ * have many connections from the local network.

+ *

+ * \hideinitializer

+ */

+#ifdef UIP_CONF_ARPTAB_SIZE

+#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE

+#else

+#define UIP_ARPTAB_SIZE 8

+#endif

+

+/**

+ * The maxium age of ARP table entries measured in 10ths of seconds.

+ *

+ * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD

+ * default).

+ */

+#define UIP_ARP_MAXAGE 120

+

+/** @} */

+

+/*------------------------------------------------------------------------------*/

+

+/**

+ * \name General configuration options

+ * @{

+ */

+

+/**

+ * The size of the uIP packet buffer.

+ *

+ * The uIP packet buffer should not be smaller than 60 bytes, and does

+ * not need to be larger than 1500 bytes. Lower size results in lower

+ * TCP throughput, larger size results in higher TCP throughput.

+ *

+ * \hideinitializer

+ */

+#ifndef UIP_CONF_BUFFER_SIZE

+#define UIP_BUFSIZE     1500

+#else /* UIP_CONF_BUFFER_SIZE */

+#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE

+#endif /* UIP_CONF_BUFFER_SIZE */

+

+

+/**

+ * Determines if statistics support should be compiled in.

+ *

+ * The statistics is useful for debugging and to show the user.

+ *

+ * \hideinitializer

+ */

+#ifndef UIP_CONF_STATISTICS

+#define UIP_STATISTICS  0

+#else /* UIP_CONF_STATISTICS */

+#define UIP_STATISTICS UIP_CONF_STATISTICS

+#endif /* UIP_CONF_STATISTICS */

+

+/**

+ * Determines if logging of certain events should be compiled in.

+ *

+ * This is useful mostly for debugging. The function uip_log()

+ * must be implemented to suit the architecture of the project, if

+ * logging is turned on.

+ *

+ * \hideinitializer

+ */

+#ifndef UIP_CONF_LOGGING

+#define UIP_LOGGING     0

+#else /* UIP_CONF_LOGGING */

+#define UIP_LOGGING     UIP_CONF_LOGGING

+#endif /* UIP_CONF_LOGGING */

+

+/**

+ * Broadcast support.

+ *

+ * This flag configures IP broadcast support. This is useful only

+ * together with UDP.

+ *

+ * \hideinitializer

+ *

+ */

+#ifndef UIP_CONF_BROADCAST

+#define UIP_BROADCAST 0

+#else /* UIP_CONF_BROADCAST */

+#define UIP_BROADCAST UIP_CONF_BROADCAST

+#endif /* UIP_CONF_BROADCAST */

+

+/**

+ * Print out a uIP log message.

+ *

+ * This function must be implemented by the module that uses uIP, and

+ * is called by uIP whenever a log message is generated.

+ */

+void uip_log(char *msg);

+

+/**

+ * The link level header length.

+ *

+ * This is the offset into the uip_buf where the IP header can be

+ * found. For Ethernet, this should be set to 14. For SLIP, this

+ * should be set to 0.

+ *

+ * \hideinitializer

+ */

+#ifdef UIP_CONF_LLH_LEN

+#define UIP_LLH_LEN UIP_CONF_LLH_LEN

+#else /* UIP_CONF_LLH_LEN */

+#define UIP_LLH_LEN     14

+#endif /* UIP_CONF_LLH_LEN */

+

+/** @} */

+/*------------------------------------------------------------------------------*/

+/**

+ * \name CPU architecture configuration

+ * @{

+ *

+ * The CPU architecture configuration is where the endianess of the

+ * CPU on which uIP is to be run is specified. Most CPUs today are

+ * little endian, and the most notable exception are the Motorolas

+ * which are big endian. The BYTE_ORDER macro should be changed to

+ * reflect the CPU architecture on which uIP is to be run.

+ */

+

+/**

+ * The byte order of the CPU architecture on which uIP is to be run.

+ *

+ * This option can be either BIG_ENDIAN (Motorola byte order) or

+ * LITTLE_ENDIAN (Intel byte order).

+ *

+ * \hideinitializer

+ */

+#ifdef UIP_CONF_BYTE_ORDER

+#define UIP_BYTE_ORDER     UIP_CONF_BYTE_ORDER

+#else /* UIP_CONF_BYTE_ORDER */

+#define UIP_BYTE_ORDER     UIP_LITTLE_ENDIAN

+#endif /* UIP_CONF_BYTE_ORDER */

+

+/** @} */

+/*------------------------------------------------------------------------------*/

+

+/**

+ * \name Appication specific configurations

+ * @{

+ *

+ * An uIP application is implemented using a single application

+ * function that is called by uIP whenever a TCP/IP event occurs. The

+ * name of this function must be registered with uIP at compile time

+ * using the UIP_APPCALL definition.

+ *

+ * uIP applications can store the application state within the

+ * uip_conn structure by specifying the type of the application

+ * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.

+ *

+ * The file containing the definitions must be included in the

+ * uipopt.h file.

+ *

+ * The following example illustrates how this can look.

+ \code

+

+void httpd_appcall(void);

+#define UIP_APPCALL     httpd_appcall

+

+struct httpd_state {

+  u8_t state;

+  u16_t count;

+  char *dataptr;

+  char *script;

+};

+typedef struct httpd_state uip_tcp_appstate_t

+ \endcode

+ */

+

+/**

+ * \var #define UIP_APPCALL

+ *

+ * The name of the application function that uIP should call in

+ * response to TCP/IP events.

+ *

+ */

+

+/**

+ * \var typedef uip_tcp_appstate_t

+ *

+ * The type of the application state that is to be stored in the

+ * uip_conn structure. This usually is typedef:ed to a struct holding

+ * application state information.

+ */

+

+/**

+ * \var typedef uip_udp_appstate_t

+ *

+ * The type of the application state that is to be stored in the

+ * uip_conn structure. This usually is typedef:ed to a struct holding

+ * application state information.

+ */

+/** @} */

+/** @} */

+

+#endif /* __UIPOPT_H__ */

diff --git a/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/webserver.h b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/webserver.h
new file mode 100644
index 0000000..1acb290
--- /dev/null
+++ b/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/webserver.h
@@ -0,0 +1,49 @@
+/*

+ * Copyright (c) 2002, Adam Dunkels.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above

+ *    copyright notice, this list of conditions and the following

+ *    disclaimer in the documentation and/or other materials provided

+ *    with the distribution.

+ * 3. The name of the author may not be used to endorse or promote

+ *    products derived from this software without specific prior

+ *    written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS

+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY

+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This file is part of the uIP TCP/IP stack

+ *

+ * $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $

+ *

+ */

+#ifndef __WEBSERVER_H__

+#define __WEBSERVER_H__

+

+#include "httpd.h"

+

+typedef struct httpd_state uip_tcp_appstate_t;

+/* UIP_APPCALL: the name of the application function. This function

+   must return void and take no arguments (i.e., C type "void

+   appfunc(void)"). */

+#ifndef UIP_APPCALL

+#define UIP_APPCALL     httpd_appcall

+#endif

+

+

+#endif /* __WEBSERVER_H__ */