]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/ARM7_LPC2368_Rowley/webserver/uIP_Task.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / ARM7_LPC2368_Rowley / webserver / uIP_Task.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 /* Standard includes. */\r
29 #include <string.h>\r
30 \r
31 /* Scheduler includes. */\r
32 #include "FreeRTOS.h"\r
33 #include "task.h"\r
34 #include "semphr.h"\r
35 \r
36 /* uip includes. */\r
37 #include "uip.h"\r
38 #include "uip_arp.h"\r
39 #include "httpd.h"\r
40 #include "timer.h"\r
41 #include "clock-arch.h"\r
42 \r
43 /* Demo includes. */\r
44 #include "emac.h"\r
45 #include "partest.h"\r
46 \r
47 /*-----------------------------------------------------------*/\r
48 \r
49 /* MAC address configuration. */\r
50 #define uipMAC_ADDR0    0x00\r
51 #define uipMAC_ADDR1    0x12\r
52 #define uipMAC_ADDR2    0x13\r
53 #define uipMAC_ADDR3    0x10\r
54 #define uipMAC_ADDR4    0x15\r
55 #define uipMAC_ADDR5    0x11\r
56 \r
57 /* IP address configuration. */\r
58 #define uipIP_ADDR0             192\r
59 #define uipIP_ADDR1             168\r
60 #define uipIP_ADDR2             0\r
61 #define uipIP_ADDR3             200     \r
62 \r
63 /* How long to wait before attempting to connect the MAC again. */\r
64 #define uipINIT_WAIT    200\r
65 \r
66 /* Shortcut to the header within the Rx buffer. */\r
67 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])\r
68 \r
69 /* Standard constant. */\r
70 #define uipTOTAL_FRAME_HEADER_SIZE      54\r
71 \r
72 /*-----------------------------------------------------------*/\r
73 \r
74 /* \r
75  * Send the uIP buffer to the MAC. \r
76  */\r
77 static void prvENET_Send(void);\r
78 \r
79 /*\r
80  * Setup the MAC address in the MAC itself, and in the uIP stack.\r
81  */\r
82 static void prvSetMACAddress( void );\r
83 \r
84 /*\r
85  * Port functions required by the uIP stack.\r
86  */\r
87 void clock_init( void );\r
88 clock_time_t clock_time( void );\r
89 \r
90 /*-----------------------------------------------------------*/\r
91 \r
92 /* The semaphore used by the ISR to wake the uIP task. */\r
93 extern SemaphoreHandle_t xEMACSemaphore;\r
94 \r
95 /*-----------------------------------------------------------*/\r
96 \r
97 void clock_init(void)\r
98 {\r
99         /* This is done when the scheduler starts. */\r
100 }\r
101 /*-----------------------------------------------------------*/\r
102 \r
103 clock_time_t clock_time( void )\r
104 {\r
105         return xTaskGetTickCount();\r
106 }\r
107 /*-----------------------------------------------------------*/\r
108 \r
109 void vuIP_Task( void *pvParameters )\r
110 {\r
111 portBASE_TYPE i;\r
112 uip_ipaddr_t xIPAddr;\r
113 struct timer periodic_timer, arp_timer;\r
114 extern void ( vEMAC_ISR_Wrapper )( void );\r
115 \r
116         /* Create the semaphore used by the ISR to wake this task. */\r
117         vSemaphoreCreateBinary( xEMACSemaphore );\r
118         \r
119         /* Initialise the uIP stack. */\r
120         timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );\r
121         timer_set( &arp_timer, configTICK_RATE_HZ * 10 );\r
122         uip_init();\r
123         uip_ipaddr( xIPAddr, uipIP_ADDR0, uipIP_ADDR1, uipIP_ADDR2, uipIP_ADDR3 );\r
124         uip_sethostaddr( xIPAddr );\r
125         httpd_init();\r
126 \r
127         /* Initialise the MAC. */\r
128         while( Init_EMAC() != pdPASS )\r
129     {\r
130         vTaskDelay( uipINIT_WAIT );\r
131     }\r
132 \r
133         portENTER_CRITICAL();\r
134         {\r
135         IntEnable = INT_RX_DONE;\r
136         VICIntEnable |= 0x00200000;\r
137         VICVectAddr21 = ( long ) vEMAC_ISR_Wrapper;\r
138                 prvSetMACAddress();\r
139         }\r
140         portEXIT_CRITICAL();\r
141         \r
142 \r
143         for( ;; )\r
144         {\r
145                 /* Is there received data ready to be processed? */\r
146                 uip_len = uiGetEMACRxData( uip_buf );\r
147                 \r
148                 if( uip_len > 0 )\r
149                 {\r
150                         /* Standard uIP loop taken from the uIP manual. */\r
151                         if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
152                         {\r
153                                 uip_arp_ipin();\r
154                                 uip_input();\r
155 \r
156                                 /* If the above function invocation resulted in data that \r
157                                 should be sent out on the network, the global variable \r
158                                 uip_len is set to a value > 0. */\r
159                                 if( uip_len > 0 )\r
160                                 {\r
161                                         uip_arp_out();\r
162                                         prvENET_Send();\r
163                                 }\r
164                         }\r
165                         else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
166                         {\r
167                                 uip_arp_arpin();\r
168 \r
169                                 /* If the above function invocation resulted in data that \r
170                                 should be sent out on the network, the global variable \r
171                                 uip_len is set to a value > 0. */\r
172                                 if( uip_len > 0 )\r
173                                 {\r
174                                         prvENET_Send();\r
175                                 }\r
176                         }\r
177                 }\r
178                 else\r
179                 {\r
180                         if( timer_expired( &periodic_timer ) )\r
181                         {\r
182                                 timer_reset( &periodic_timer );\r
183                                 for( i = 0; i < UIP_CONNS; i++ )\r
184                                 {\r
185                                         uip_periodic( i );\r
186         \r
187                                         /* If the above function invocation resulted in data that \r
188                                         should be sent out on the network, the global variable \r
189                                         uip_len is set to a value > 0. */\r
190                                         if( uip_len > 0 )\r
191                                         {\r
192                                                 uip_arp_out();\r
193                                                 prvENET_Send();\r
194                                         }\r
195                                 }       \r
196         \r
197                                 /* Call the ARP timer function every 10 seconds. */\r
198                                 if( timer_expired( &arp_timer ) )\r
199                                 {\r
200                                         timer_reset( &arp_timer );\r
201                                         uip_arp_timer();\r
202                                 }\r
203                         }\r
204                         else\r
205                         {                       \r
206                                 /* We did not receive a packet, and there was no periodic\r
207                                 processing to perform.  Block for a fixed period.  If a packet\r
208                                 is received during this period we will be woken by the ISR\r
209                                 giving us the Semaphore. */\r
210                                 xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );                       \r
211                         }\r
212                 }\r
213         }\r
214 }\r
215 /*-----------------------------------------------------------*/\r
216 \r
217 static void prvENET_Send(void)\r
218 {\r
219     RequestSend();\r
220 \r
221     /* Copy the header into the Tx buffer. */\r
222     CopyToFrame_EMAC( uip_buf, uipTOTAL_FRAME_HEADER_SIZE );\r
223     if( uip_len > uipTOTAL_FRAME_HEADER_SIZE )\r
224     {\r
225         CopyToFrame_EMAC( uip_appdata, ( uip_len - uipTOTAL_FRAME_HEADER_SIZE ) );\r
226     }\r
227 \r
228     DoSend_EMAC( uip_len );\r
229 \r
230     RequestSend();\r
231 \r
232     /* Copy the header into the Tx buffer. */\r
233     CopyToFrame_EMAC( uip_buf, uipTOTAL_FRAME_HEADER_SIZE );\r
234     if( uip_len > uipTOTAL_FRAME_HEADER_SIZE )\r
235     {\r
236         CopyToFrame_EMAC( uip_appdata, ( uip_len - uipTOTAL_FRAME_HEADER_SIZE ) );\r
237     }\r
238 \r
239     DoSend_EMAC( uip_len );\r
240 }\r
241 /*-----------------------------------------------------------*/\r
242 \r
243 static void prvSetMACAddress( void )\r
244 {\r
245 struct uip_eth_addr xAddr;\r
246 \r
247         /* Configure the MAC address in the uIP stack. */\r
248         xAddr.addr[ 0 ] = uipMAC_ADDR0;\r
249         xAddr.addr[ 1 ] = uipMAC_ADDR1;\r
250         xAddr.addr[ 2 ] = uipMAC_ADDR2;\r
251         xAddr.addr[ 3 ] = uipMAC_ADDR3;\r
252         xAddr.addr[ 4 ] = uipMAC_ADDR4;\r
253         xAddr.addr[ 5 ] = uipMAC_ADDR5;\r
254         uip_setethaddr( xAddr );\r
255 }\r
256 /*-----------------------------------------------------------*/\r
257 \r
258 void vApplicationProcessFormInput( char *pcInputString, portBASE_TYPE xInputLength )\r
259 {\r
260 char *c, *pcText;\r
261 static char cMessageForDisplay[ 32 ];\r
262 extern QueueHandle_t xLCDQueue;\r
263 xLCDMessage xLCDMessage;\r
264 \r
265         /* Process the form input sent by the IO page of the served HTML. */\r
266 \r
267         c = strstr( pcInputString, "?" );\r
268     if( c )\r
269     {\r
270                 /* Turn LED's on or off in accordance with the check box status. */\r
271                 if( strstr( c, "LED0=1" ) != NULL )\r
272                 {\r
273                         vParTestSetLED( 5, 0 );\r
274                 }\r
275                 else\r
276                 {\r
277                         vParTestSetLED( 5, 1 );\r
278                 }               \r
279                 \r
280                 if( strstr( c, "LED1=1" ) != NULL )\r
281                 {\r
282                         vParTestSetLED( 6, 0 );\r
283                 }\r
284                 else\r
285                 {\r
286                         vParTestSetLED( 6, 1 );\r
287                 }               \r
288 \r
289                 if( strstr( c, "LED2=1" ) != NULL )\r
290                 {\r
291                         vParTestSetLED( 7, 0 );\r
292                 }\r
293                 else\r
294                 {\r
295                         vParTestSetLED( 7, 1 );\r
296                 }\r
297 \r
298                 /* Find the start of the text to be displayed on the LCD. */\r
299         pcText = strstr( c, "LCD=" );\r
300         pcText += strlen( "LCD=" );\r
301 \r
302         /* Terminate the file name for further processing within uIP. */\r
303         *c = 0x00;\r
304 \r
305         /* Terminate the LCD string. */\r
306         c = strstr( pcText, " " );\r
307         if( c != NULL )\r
308         {\r
309             *c = 0x00;\r
310         }\r
311 \r
312         /* Add required spaces. */\r
313         while( ( c = strstr( pcText, "+" ) ) != NULL )\r
314         {\r
315             *c = ' ';\r
316         }\r
317     \r
318         /* Write the message to the LCD. */\r
319                 strcpy( cMessageForDisplay, pcText );\r
320                 xLCDMessage.xColumn = 0;\r
321                 xLCDMessage.pcMessage = cMessageForDisplay;\r
322         xQueueSend( xLCDQueue, &xLCDMessage, portMAX_DELAY );\r
323     }\r
324 }\r
325 \r