]> git.sur5r.net Git - freertos/blob - Demo/ARM7_LPC2368_Rowley/webserver/uIP_Task.c
6a3b3bee630aa5cf4f0a9fd9037c7d8c2a4a93b9
[freertos] / Demo / ARM7_LPC2368_Rowley / webserver / uIP_Task.c
1 /*\r
2         FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify it \r
7         under the terms of the GNU General Public License (version 2) as published\r
8         by the Free Software Foundation and modified by the FreeRTOS exception.\r
9 \r
10         FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT\r
11         ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \r
12         FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for \r
13         more details.\r
14 \r
15         You should have received a copy of the GNU General Public License along \r
16         with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 \r
17         Temple Place, Suite 330, Boston, MA  02111-1307  USA.\r
18 \r
19         A special exception to the GPL is included to allow you to distribute a \r
20         combined work that includes FreeRTOS.org without being obliged to provide\r
21         the source code for any proprietary components.  See the licensing section\r
22         of http://www.FreeRTOS.org for full details.\r
23 \r
24 \r
25         ***************************************************************************\r
26         *                                                                         *\r
27         * Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *\r
28         *                                                                         *\r
29         * This is a concise, step by step, 'hands on' guide that describes both   *\r
30         * general multitasking concepts and FreeRTOS specifics. It presents and   *\r
31         * explains numerous examples that are written using the FreeRTOS API.     *\r
32         * Full source code for all the examples is provided in an accompanying    *\r
33         * .zip file.                                                              *\r
34         *                                                                         *\r
35         ***************************************************************************\r
36 \r
37         1 tab == 4 spaces!\r
38 \r
39         Please ensure to read the configuration and relevant port sections of the\r
40         online documentation.\r
41 \r
42         http://www.FreeRTOS.org - Documentation, latest information, license and\r
43         contact details.\r
44 \r
45         http://www.SafeRTOS.com - A version that is certified for use in safety\r
46         critical systems.\r
47 \r
48         http://www.OpenRTOS.com - Commercial support, development, porting,\r
49         licensing and training services.\r
50 */\r
51 /* Standard includes. */\r
52 #include <string.h>\r
53 \r
54 /* Scheduler includes. */\r
55 #include "FreeRTOS.h"\r
56 #include "task.h"\r
57 #include "semphr.h"\r
58 \r
59 /* uip includes. */\r
60 #include "uip.h"\r
61 #include "uip_arp.h"\r
62 #include "httpd.h"\r
63 #include "timer.h"\r
64 #include "clock-arch.h"\r
65 \r
66 /* Demo includes. */\r
67 #include "emac.h"\r
68 #include "partest.h"\r
69 \r
70 /*-----------------------------------------------------------*/\r
71 \r
72 /* MAC address configuration. */\r
73 #define uipMAC_ADDR0    0x00\r
74 #define uipMAC_ADDR1    0x12\r
75 #define uipMAC_ADDR2    0x13\r
76 #define uipMAC_ADDR3    0x10\r
77 #define uipMAC_ADDR4    0x15\r
78 #define uipMAC_ADDR5    0x11\r
79 \r
80 /* IP address configuration. */\r
81 #define uipIP_ADDR0             172\r
82 #define uipIP_ADDR1             25\r
83 #define uipIP_ADDR2             218\r
84 #define uipIP_ADDR3             10      \r
85 \r
86 /* How long to wait before attempting to connect the MAC again. */\r
87 #define uipINIT_WAIT    100\r
88 \r
89 /* Shortcut to the header within the Rx buffer. */\r
90 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])\r
91 \r
92 /* Standard constant. */\r
93 #define uipTOTAL_FRAME_HEADER_SIZE      54\r
94 \r
95 /*-----------------------------------------------------------*/\r
96 \r
97 /* \r
98  * Send the uIP buffer to the MAC. \r
99  */\r
100 static void prvENET_Send(void);\r
101 \r
102 /*\r
103  * Setup the MAC address in the MAC itself, and in the uIP stack.\r
104  */\r
105 static void prvSetMACAddress( void );\r
106 \r
107 /*\r
108  * Port functions required by the uIP stack.\r
109  */\r
110 void clock_init( void );\r
111 clock_time_t clock_time( void );\r
112 \r
113 /*-----------------------------------------------------------*/\r
114 \r
115 /* The semaphore used by the ISR to wake the uIP task. */\r
116 extern xSemaphoreHandle xEMACSemaphore;\r
117 \r
118 /*-----------------------------------------------------------*/\r
119 \r
120 void clock_init(void)\r
121 {\r
122         /* This is done when the scheduler starts. */\r
123 }\r
124 /*-----------------------------------------------------------*/\r
125 \r
126 clock_time_t clock_time( void )\r
127 {\r
128         return xTaskGetTickCount();\r
129 }\r
130 /*-----------------------------------------------------------*/\r
131 \r
132 void vuIP_Task( void *pvParameters )\r
133 {\r
134 portBASE_TYPE i;\r
135 uip_ipaddr_t xIPAddr;\r
136 struct timer periodic_timer, arp_timer;\r
137 extern void ( vEMAC_ISR_Wrapper )( void );\r
138 \r
139         /* Create the semaphore used by the ISR to wake this task. */\r
140         vSemaphoreCreateBinary( xEMACSemaphore );\r
141         \r
142         /* Initialise the uIP stack. */\r
143         timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );\r
144         timer_set( &arp_timer, configTICK_RATE_HZ * 10 );\r
145         uip_init();\r
146         uip_ipaddr( xIPAddr, uipIP_ADDR0, uipIP_ADDR1, uipIP_ADDR2, uipIP_ADDR3 );\r
147         uip_sethostaddr( xIPAddr );\r
148         httpd_init();\r
149 \r
150         /* Initialise the MAC. */\r
151         while( Init_EMAC() != pdPASS )\r
152     {\r
153         vTaskDelay( uipINIT_WAIT );\r
154     }\r
155 \r
156         portENTER_CRITICAL();\r
157         {\r
158         IntEnable = INT_RX_DONE;\r
159         VICIntEnable |= 0x00200000;\r
160         VICVectAddr21 = ( portLONG ) vEMAC_ISR_Wrapper;\r
161                 prvSetMACAddress();\r
162         }\r
163         portEXIT_CRITICAL();\r
164         \r
165 \r
166         for( ;; )\r
167         {\r
168                 /* Is there received data ready to be processed? */\r
169                 uip_len = uiGetEMACRxData( uip_buf );\r
170                 \r
171                 if( uip_len > 0 )\r
172                 {\r
173                         /* Standard uIP loop taken from the uIP manual. */\r
174                         if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
175                         {\r
176                                 uip_arp_ipin();\r
177                                 uip_input();\r
178 \r
179                                 /* If the above function invocation resulted in data that \r
180                                 should be sent out on the network, the global variable \r
181                                 uip_len is set to a value > 0. */\r
182                                 if( uip_len > 0 )\r
183                                 {\r
184                                         uip_arp_out();\r
185                                         prvENET_Send();\r
186                                 }\r
187                         }\r
188                         else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
189                         {\r
190                                 uip_arp_arpin();\r
191 \r
192                                 /* If the above function invocation resulted in data that \r
193                                 should be sent out on the network, the global variable \r
194                                 uip_len is set to a value > 0. */\r
195                                 if( uip_len > 0 )\r
196                                 {\r
197                                         prvENET_Send();\r
198                                 }\r
199                         }\r
200                 }\r
201                 else\r
202                 {\r
203                         if( timer_expired( &periodic_timer ) )\r
204                         {\r
205                                 timer_reset( &periodic_timer );\r
206                                 for( i = 0; i < UIP_CONNS; i++ )\r
207                                 {\r
208                                         uip_periodic( i );\r
209         \r
210                                         /* If the above function invocation resulted in data that \r
211                                         should be sent out on the network, the global variable \r
212                                         uip_len is set to a value > 0. */\r
213                                         if( uip_len > 0 )\r
214                                         {\r
215                                                 uip_arp_out();\r
216                                                 prvENET_Send();\r
217                                         }\r
218                                 }       \r
219         \r
220                                 /* Call the ARP timer function every 10 seconds. */\r
221                                 if( timer_expired( &arp_timer ) )\r
222                                 {\r
223                                         timer_reset( &arp_timer );\r
224                                         uip_arp_timer();\r
225                                 }\r
226                         }\r
227                         else\r
228                         {                       \r
229                                 /* We did not receive a packet, and there was no periodic\r
230                                 processing to perform.  Block for a fixed period.  If a packet\r
231                                 is received during this period we will be woken by the ISR\r
232                                 giving us the Semaphore. */\r
233                                 xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );                       \r
234                         }\r
235                 }\r
236         }\r
237 }\r
238 /*-----------------------------------------------------------*/\r
239 \r
240 static void prvENET_Send(void)\r
241 {\r
242     RequestSend();\r
243 \r
244     /* Copy the header into the Tx buffer. */\r
245     CopyToFrame_EMAC( uip_buf, uipTOTAL_FRAME_HEADER_SIZE );\r
246     if( uip_len > uipTOTAL_FRAME_HEADER_SIZE )\r
247     {\r
248         CopyToFrame_EMAC( uip_appdata, ( uip_len - uipTOTAL_FRAME_HEADER_SIZE ) );\r
249     }\r
250 \r
251     DoSend_EMAC( uip_len );\r
252 }\r
253 /*-----------------------------------------------------------*/\r
254 \r
255 static void prvSetMACAddress( void )\r
256 {\r
257 struct uip_eth_addr xAddr;\r
258 \r
259         /* Configure the MAC address in the uIP stack. */\r
260         xAddr.addr[ 0 ] = uipMAC_ADDR0;\r
261         xAddr.addr[ 1 ] = uipMAC_ADDR1;\r
262         xAddr.addr[ 2 ] = uipMAC_ADDR2;\r
263         xAddr.addr[ 3 ] = uipMAC_ADDR3;\r
264         xAddr.addr[ 4 ] = uipMAC_ADDR4;\r
265         xAddr.addr[ 5 ] = uipMAC_ADDR5;\r
266         uip_setethaddr( xAddr );\r
267 }\r
268 /*-----------------------------------------------------------*/\r
269 \r
270 void vApplicationProcessFormInput( portCHAR *pcInputString, portBASE_TYPE xInputLength )\r
271 {\r
272 char *c, *pcText;\r
273 static portCHAR cMessageForDisplay[ 32 ];\r
274 extern xQueueHandle xLCDQueue;\r
275 xLCDMessage xLCDMessage;\r
276 \r
277         /* Process the form input sent by the IO page of the served HTML. */\r
278 \r
279         c = strstr( pcInputString, "?" );\r
280     if( c )\r
281     {\r
282                 /* Turn LED's on or off in accordance with the check box status. */\r
283                 if( strstr( c, "LED0=1" ) != NULL )\r
284                 {\r
285                         vParTestSetLED( 5, 0 );\r
286                 }\r
287                 else\r
288                 {\r
289                         vParTestSetLED( 5, 1 );\r
290                 }               \r
291                 \r
292                 if( strstr( c, "LED1=1" ) != NULL )\r
293                 {\r
294                         vParTestSetLED( 6, 0 );\r
295                 }\r
296                 else\r
297                 {\r
298                         vParTestSetLED( 6, 1 );\r
299                 }               \r
300 \r
301                 if( strstr( c, "LED2=1" ) != NULL )\r
302                 {\r
303                         vParTestSetLED( 7, 0 );\r
304                 }\r
305                 else\r
306                 {\r
307                         vParTestSetLED( 7, 1 );\r
308                 }\r
309 \r
310                 /* Find the start of the text to be displayed on the LCD. */\r
311         pcText = strstr( c, "LCD=" );\r
312         pcText += strlen( "LCD=" );\r
313 \r
314         /* Terminate the file name for further processing within uIP. */\r
315         *c = 0x00;\r
316 \r
317         /* Terminate the LCD string. */\r
318         c = strstr( pcText, " " );\r
319         if( c != NULL )\r
320         {\r
321             *c = 0x00;\r
322         }\r
323 \r
324         /* Add required spaces. */\r
325         while( ( c = strstr( pcText, "+" ) ) != NULL )\r
326         {\r
327             *c = ' ';\r
328         }\r
329     \r
330         /* Write the message to the LCD. */\r
331                 strcpy( cMessageForDisplay, pcText );\r
332                 xLCDMessage.xColumn = 0;\r
333                 xLCDMessage.pcMessage = cMessageForDisplay;\r
334         xQueueSend( xLCDQueue, &xLCDMessage, portMAX_DELAY );\r
335     }\r
336 }\r
337 \r