]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_LM3Sxxxx_IAR_Keil/webserver/uIP_Task.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / CORTEX_LM3Sxxxx_IAR_Keil / 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 "hw_types.h"\r
38 #include "uip.h"\r
39 #include "uip_arp.h"\r
40 #include "httpd.h"\r
41 #include "timer.h"\r
42 #include "clock-arch.h"\r
43 #include "hw_ethernet.h"\r
44 #include "ethernet.h"\r
45 #include "hw_memmap.h"\r
46 #include "lmi_flash.h"\r
47 #include "sysctl.h"\r
48 \r
49 /* Demo includes. */\r
50 #include "emac.h"\r
51 #include "partest.h"\r
52 #include "lcd_message.h"\r
53 \r
54 struct timer {\r
55   clock_time_t start;\r
56   clock_time_t interval;\r
57 };\r
58 \r
59 \r
60 /*-----------------------------------------------------------*/\r
61 \r
62 /* IP address configuration. */\r
63 #define uipIP_ADDR0             172\r
64 #define uipIP_ADDR1             25\r
65 #define uipIP_ADDR2             218\r
66 #define uipIP_ADDR3             19      \r
67 \r
68 /* How long to wait before attempting to connect the MAC again. */\r
69 #define uipINIT_WAIT    100\r
70 \r
71 /* Shortcut to the header within the Rx buffer. */\r
72 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])\r
73 \r
74 /* Standard constant. */\r
75 #define uipTOTAL_FRAME_HEADER_SIZE      54\r
76 \r
77 /*-----------------------------------------------------------*/\r
78 \r
79 /*\r
80  * Send the uIP buffer to the MAC.\r
81  */\r
82 static void prvENET_Send(void);\r
83 \r
84 /*\r
85  * Setup the MAC address in the MAC itself, and in the uIP stack.\r
86  */\r
87 static void prvSetMACAddress( void );\r
88 \r
89 /*\r
90  * Port functions required by the uIP stack.\r
91  */\r
92 void clock_init( void );\r
93 clock_time_t clock_time( void );\r
94 \r
95 /*-----------------------------------------------------------*/\r
96 \r
97 /* The semaphore used by the ISR to wake the uIP task. */\r
98 extern SemaphoreHandle_t xEMACSemaphore;\r
99 \r
100 /*-----------------------------------------------------------*/\r
101 \r
102 void clock_init(void)\r
103 {\r
104         /* This is done when the scheduler starts. */\r
105 }\r
106 /*-----------------------------------------------------------*/\r
107 \r
108 /* Define clock functions here to avoid header file name clash between uIP\r
109 and the Luminary Micro driver library. */\r
110 clock_time_t clock_time( void )\r
111 {\r
112         return xTaskGetTickCount();\r
113 }\r
114 extern void timer_set(struct timer *t, clock_time_t interval);\r
115 extern int timer_expired(struct timer *t);\r
116 extern void timer_reset(struct timer *t);\r
117 \r
118 \r
119 \r
120 \r
121 void vuIP_Task( void *pvParameters )\r
122 {\r
123 portBASE_TYPE i;\r
124 uip_ipaddr_t xIPAddr;\r
125 struct timer periodic_timer, arp_timer;\r
126 extern void ( vEMAC_ISR )( void );\r
127 \r
128         /* Enable/Reset the Ethernet Controller */\r
129         SysCtlPeripheralEnable( SYSCTL_PERIPH_ETH );\r
130         SysCtlPeripheralReset( SYSCTL_PERIPH_ETH );\r
131 \r
132         /* Create the semaphore used by the ISR to wake this task. */\r
133         vSemaphoreCreateBinary( xEMACSemaphore );\r
134         \r
135         /* Initialise the uIP stack. */\r
136         timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );\r
137         timer_set( &arp_timer, configTICK_RATE_HZ * 10 );\r
138         uip_init();\r
139         uip_ipaddr( xIPAddr, uipIP_ADDR0, uipIP_ADDR1, uipIP_ADDR2, uipIP_ADDR3 );\r
140         uip_sethostaddr( xIPAddr );\r
141         httpd_init();\r
142 \r
143         while( vInitEMAC() != pdPASS )\r
144     {\r
145         vTaskDelay( uipINIT_WAIT );\r
146     }\r
147         prvSetMACAddress();     \r
148         \r
149 \r
150         for( ;; )\r
151         {\r
152                 /* Is there received data ready to be processed? */\r
153                 uip_len = uiGetEMACRxData( uip_buf );\r
154                 \r
155                 if( uip_len > 0 )\r
156                 {\r
157                         /* Standard uIP loop taken from the uIP manual. */\r
158 \r
159                         if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
160                         {\r
161                                 uip_arp_ipin();\r
162                                 uip_input();\r
163 \r
164                                 /* If the above function invocation resulted in data that\r
165                                 should be sent out on the network, the global variable\r
166                                 uip_len is set to a value > 0. */\r
167                                 if( uip_len > 0 )\r
168                                 {\r
169                                         uip_arp_out();\r
170                                         prvENET_Send();\r
171                                 }\r
172                         }\r
173                         else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
174                         {\r
175                                 uip_arp_arpin();\r
176 \r
177                                 /* If the above function invocation resulted in data that\r
178                                 should be sent out on the network, the global variable\r
179                                 uip_len is set to a value > 0. */\r
180                                 if( uip_len > 0 )\r
181                                 {\r
182                                         prvENET_Send();\r
183                                 }\r
184                         }\r
185                 }\r
186                 else\r
187                 {\r
188                         if( timer_expired( &periodic_timer ) )\r
189                         {\r
190                                 timer_reset( &periodic_timer );\r
191                                 for( i = 0; i < UIP_CONNS; i++ )\r
192                                 {\r
193                                         uip_periodic( i );\r
194         \r
195                                         /* If the above function invocation resulted in data that\r
196                                         should be sent out on the network, the global variable\r
197                                         uip_len is set to a value > 0. */\r
198                                         if( uip_len > 0 )\r
199                                         {\r
200                                                 uip_arp_out();\r
201                                                 prvENET_Send();\r
202                                         }\r
203                                 }       \r
204         \r
205                                 /* Call the ARP timer function every 10 seconds. */\r
206                                 if( timer_expired( &arp_timer ) )\r
207                                 {\r
208                                         timer_reset( &arp_timer );\r
209                                         uip_arp_timer();\r
210                                 }\r
211                         }\r
212                         else\r
213                         {                       \r
214                                 /* We did not receive a packet, and there was no periodic\r
215                                 processing to perform.  Block for a fixed period.  If a packet\r
216                                 is received during this period we will be woken by the ISR\r
217                                 giving us the Semaphore. */\r
218                                 xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );                       \r
219                         }\r
220                 }\r
221         }\r
222 }\r
223 /*-----------------------------------------------------------*/\r
224 \r
225 static void prvENET_Send(void)\r
226 {\r
227         vInitialiseSend();\r
228         vIncrementTxLength( uip_len );\r
229         vSendBufferToMAC();\r
230 }\r
231 /*-----------------------------------------------------------*/\r
232 \r
233 static void prvSetMACAddress( void )\r
234 {\r
235 unsigned long ulUser0, ulUser1;\r
236 unsigned char pucMACArray[8];\r
237 struct uip_eth_addr xAddr;\r
238 \r
239         /* Get the device MAC address from flash */\r
240     FlashUserGet(&ulUser0, &ulUser1);\r
241 \r
242         /* Convert the MAC address from flash into sequence of bytes. */\r
243     pucMACArray[0] = ((ulUser0 >>  0) & 0xff);\r
244     pucMACArray[1] = ((ulUser0 >>  8) & 0xff);\r
245     pucMACArray[2] = ((ulUser0 >> 16) & 0xff);\r
246     pucMACArray[3] = ((ulUser1 >>  0) & 0xff);\r
247     pucMACArray[4] = ((ulUser1 >>  8) & 0xff);\r
248     pucMACArray[5] = ((ulUser1 >> 16) & 0xff);\r
249 \r
250         /* Program the MAC address. */\r
251     EthernetMACAddrSet(ETH_BASE, pucMACArray);\r
252 \r
253         xAddr.addr[ 0 ] = pucMACArray[0];\r
254         xAddr.addr[ 1 ] = pucMACArray[1];\r
255         xAddr.addr[ 2 ] = pucMACArray[2];\r
256         xAddr.addr[ 3 ] = pucMACArray[3];\r
257         xAddr.addr[ 4 ] = pucMACArray[4];\r
258         xAddr.addr[ 5 ] = pucMACArray[5];\r
259         uip_setethaddr( xAddr );\r
260 }\r
261 /*-----------------------------------------------------------*/\r
262 \r
263 void vApplicationProcessFormInput( char *pcInputString, portBASE_TYPE xInputLength )\r
264 {\r
265 char *c, *pcText;\r
266 static char cMessageForDisplay[ 32 ];\r
267 extern QueueHandle_t xOLEDQueue;\r
268 xOLEDMessage xOLEDMessage;\r
269 \r
270         /* Process the form input sent by the IO page of the served HTML. */\r
271 \r
272         c = strstr( pcInputString, "?" );\r
273 \r
274     if( c )\r
275     {\r
276                 /* Turn LED's on or off in accordance with the check box status. */\r
277                 if( strstr( c, "LED0=1" ) != NULL )\r
278                 {\r
279                         vParTestSetLED( 0, 1 );\r
280                 }\r
281                 else\r
282                 {\r
283                         vParTestSetLED( 0, 0 );\r
284                 }               \r
285                 \r
286                 /* Find the start of the text to be displayed on the LCD. */\r
287         pcText = strstr( c, "LCD=" );\r
288         pcText += strlen( "LCD=" );\r
289 \r
290         /* Terminate the file name for further processing within uIP. */\r
291         *c = 0x00;\r
292 \r
293         /* Terminate the LCD string. */\r
294         c = strstr( pcText, " " );\r
295         if( c != NULL )\r
296         {\r
297             *c = 0x00;\r
298         }\r
299 \r
300         /* Add required spaces. */\r
301         while( ( c = strstr( pcText, "+" ) ) != NULL )\r
302         {\r
303             *c = ' ';\r
304         }\r
305 \r
306         /* Write the message to the LCD. */\r
307                 strcpy( cMessageForDisplay, pcText );\r
308                 xOLEDMessage.pcMessage = ( signed char * ) cMessageForDisplay;\r
309         xQueueSend( xOLEDQueue, &xOLEDMessage, portMAX_DELAY );\r
310     }\r
311 }\r
312 \r