]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_LM3S6965_GCC/webserver/uIP_Task.c
Update to V4.3.0 as described in http://www.FreeRTOS.org/History.txt
[freertos] / Demo / CORTEX_LM3S6965_GCC / webserver / uIP_Task.c
1 /*\r
2         FreeRTOS.org V4.3.0 - Copyright (C) 2003-2007 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 #include "lcd_message.h"\r
41 \r
42 /* uip includes. */\r
43 #include "hw_types.h"\r
44 \r
45 #include "uip.h"\r
46 #include "uip_arp.h"\r
47 #include "httpd.h"\r
48 #include "timer.h"\r
49 #include "clock-arch.h"\r
50 #include "hw_ethernet.h"\r
51 #include "ethernet.h"\r
52 #include "hw_memmap.h"\r
53 #include "lmi_flash.h"\r
54 \r
55 /* Demo includes. */\r
56 #include "emac.h"\r
57 #include "partest.h"\r
58 \r
59 /*-----------------------------------------------------------*/\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             9       \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 )( 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         while( vInitEMAC() != pdPASS )\r
132     {\r
133         vTaskDelay( uipINIT_WAIT );\r
134     }\r
135         prvSetMACAddress();     \r
136         \r
137 \r
138         for( ;; )\r
139         {\r
140                 /* Is there received data ready to be processed? */\r
141                 uip_len = uiGetEMACRxData( uip_buf );\r
142                 \r
143                 if( uip_len > 0 )\r
144                 {\r
145                         /* Standard uIP loop taken from the uIP manual. */\r
146 \r
147                         if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
148                         {\r
149                                 uip_arp_ipin();\r
150                                 uip_input();\r
151 \r
152                                 /* If the above function invocation resulted in data that\r
153                                 should be sent out on the network, the global variable\r
154                                 uip_len is set to a value > 0. */\r
155                                 if( uip_len > 0 )\r
156                                 {\r
157                                         uip_arp_out();\r
158                                         prvENET_Send();\r
159                                 }\r
160                         }\r
161                         else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
162                         {\r
163                                 uip_arp_arpin();\r
164 \r
165                                 /* If the above function invocation resulted in data that\r
166                                 should be sent out on the network, the global variable\r
167                                 uip_len is set to a value > 0. */\r
168                                 if( uip_len > 0 )\r
169                                 {\r
170                                         prvENET_Send();\r
171                                 }\r
172                         }\r
173                 }\r
174                 else\r
175                 {\r
176                         if( timer_expired( &periodic_timer ) )\r
177                         {\r
178                                 timer_reset( &periodic_timer );\r
179                                 for( i = 0; i < UIP_CONNS; i++ )\r
180                                 {\r
181                                         uip_periodic( i );\r
182         \r
183                                         /* If the above function invocation resulted in data that\r
184                                         should be sent out on the network, the global variable\r
185                                         uip_len is set to a value > 0. */\r
186                                         if( uip_len > 0 )\r
187                                         {\r
188                                                 uip_arp_out();\r
189                                                 prvENET_Send();\r
190                                         }\r
191                                 }       \r
192         \r
193                                 /* Call the ARP timer function every 10 seconds. */\r
194                                 if( timer_expired( &arp_timer ) )\r
195                                 {\r
196                                         timer_reset( &arp_timer );\r
197                                         uip_arp_timer();\r
198                                 }\r
199                         }\r
200                         else\r
201                         {                       \r
202                                 /* We did not receive a packet, and there was no periodic\r
203                                 processing to perform.  Block for a fixed period.  If a packet\r
204                                 is received during this period we will be woken by the ISR\r
205                                 giving us the Semaphore. */\r
206                                 xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );                       \r
207                         }\r
208                 }\r
209         }\r
210 }\r
211 /*-----------------------------------------------------------*/\r
212 \r
213 static void prvENET_Send(void)\r
214 {\r
215     vInitialiseSend();\r
216     vIncrementTxLength( uip_len );\r
217     vSendBufferToMAC();\r
218 }\r
219 /*-----------------------------------------------------------*/\r
220 \r
221 static void prvSetMACAddress( void )\r
222 {\r
223 unsigned portLONG ulUser0, ulUser1;\r
224 unsigned char pucMACArray[8];\r
225 struct uip_eth_addr xAddr;\r
226 \r
227         /* Get the device MAC address from flash */\r
228     FlashUserGet(&ulUser0, &ulUser1);\r
229 \r
230         /* Convert the MAC address from flash into sequence of bytes. */\r
231     pucMACArray[0] = ((ulUser0 >>  0) & 0xff);\r
232     pucMACArray[1] = ((ulUser0 >>  8) & 0xff);\r
233     pucMACArray[2] = ((ulUser0 >> 16) & 0xff);\r
234     pucMACArray[3] = ((ulUser1 >>  0) & 0xff);\r
235     pucMACArray[4] = ((ulUser1 >>  8) & 0xff);\r
236     pucMACArray[5] = ((ulUser1 >> 16) & 0xff);\r
237 \r
238         /* Program the MAC address. */\r
239     EthernetMACAddrSet(ETH_BASE, pucMACArray);\r
240 \r
241         xAddr.addr[ 0 ] = pucMACArray[0];\r
242         xAddr.addr[ 1 ] = pucMACArray[1];\r
243         xAddr.addr[ 2 ] = pucMACArray[2];\r
244         xAddr.addr[ 3 ] = pucMACArray[3];\r
245         xAddr.addr[ 4 ] = pucMACArray[4];\r
246         xAddr.addr[ 5 ] = pucMACArray[5];\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 xOLEDQueue;\r
256 xOLEDMessage xOLEDMessage;\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 \r
262     if( c )\r
263     {\r
264                 /* Turn LED's on or off in accordance with the check box status. */\r
265                 if( strstr( c, "LED0=1" ) != NULL )\r
266                 {\r
267                         vParTestSetLED( 0, 1 );\r
268                 }\r
269                 else\r
270                 {\r
271                         vParTestSetLED( 0, 0 );\r
272                 }               \r
273                 \r
274                 /* Find the start of the text to be displayed on the LCD. */\r
275         pcText = strstr( c, "LCD=" );\r
276         pcText += strlen( "LCD=" );\r
277 \r
278         /* Terminate the file name for further processing within uIP. */\r
279         *c = 0x00;\r
280 \r
281         /* Terminate the LCD string. */\r
282         c = strstr( pcText, " " );\r
283         if( c != NULL )\r
284         {\r
285             *c = 0x00;\r
286         }\r
287 \r
288         /* Add required spaces. */\r
289         while( ( c = strstr( pcText, "+" ) ) != NULL )\r
290         {\r
291             *c = ' ';\r
292         }\r
293 \r
294         /* Write the message to the LCD. */\r
295                 strcpy( cMessageForDisplay, pcText );\r
296                 xOLEDMessage.pcMessage = cMessageForDisplay;\r
297         xQueueSend( xOLEDQueue, &xOLEDMessage, portMAX_DELAY );\r
298     }\r
299 }\r
300 \r