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