]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_LM3Sxxxx_IAR_Keil/webserver/uIP_Task.c
0b83dd4097c930b2ea788a454e687018be1b5f66
[freertos] / FreeRTOS / Demo / CORTEX_LM3Sxxxx_IAR_Keil / webserver / uIP_Task.c
1 /*\r
2  * FreeRTOS Kernel V10.2.1\r
3  * Copyright (C) 2019 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.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 /* Standard includes. */\r
28 #include <string.h>\r
29 \r
30 /* Scheduler includes. */\r
31 #include "FreeRTOS.h"\r
32 #include "task.h"\r
33 #include "semphr.h"\r
34 \r
35 /* uip includes. */\r
36 #include "hw_types.h"\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 #include "hw_ethernet.h"\r
43 #include "ethernet.h"\r
44 #include "hw_memmap.h"\r
45 #include "lmi_flash.h"\r
46 #include "sysctl.h"\r
47 \r
48 /* Demo includes. */\r
49 #include "emac.h"\r
50 #include "partest.h"\r
51 #include "lcd_message.h"\r
52 \r
53 struct timer {\r
54   clock_time_t start;\r
55   clock_time_t interval;\r
56 };\r
57 \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             19      \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 SemaphoreHandle_t 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 /* Define clock functions here to avoid header file name clash between uIP\r
108 and the Luminary Micro driver library. */\r
109 clock_time_t clock_time( void )\r
110 {\r
111         return xTaskGetTickCount();\r
112 }\r
113 extern void timer_set(struct timer *t, clock_time_t interval);\r
114 extern int timer_expired(struct timer *t);\r
115 extern void timer_reset(struct timer *t);\r
116 \r
117 \r
118 \r
119 \r
120 void vuIP_Task( void *pvParameters )\r
121 {\r
122 portBASE_TYPE i;\r
123 uip_ipaddr_t xIPAddr;\r
124 struct timer periodic_timer, arp_timer;\r
125 extern void ( vEMAC_ISR )( void );\r
126 \r
127         /* Enable/Reset the Ethernet Controller */\r
128         SysCtlPeripheralEnable( SYSCTL_PERIPH_ETH );\r
129         SysCtlPeripheralReset( SYSCTL_PERIPH_ETH );\r
130 \r
131         /* Create the semaphore used by the ISR to wake this task. */\r
132         vSemaphoreCreateBinary( xEMACSemaphore );\r
133         \r
134         /* Initialise the uIP stack. */\r
135         timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );\r
136         timer_set( &arp_timer, configTICK_RATE_HZ * 10 );\r
137         uip_init();\r
138         uip_ipaddr( xIPAddr, uipIP_ADDR0, uipIP_ADDR1, uipIP_ADDR2, uipIP_ADDR3 );\r
139         uip_sethostaddr( xIPAddr );\r
140         httpd_init();\r
141 \r
142         while( vInitEMAC() != pdPASS )\r
143     {\r
144         vTaskDelay( uipINIT_WAIT );\r
145     }\r
146         prvSetMACAddress();     \r
147         \r
148 \r
149         for( ;; )\r
150         {\r
151                 /* Is there received data ready to be processed? */\r
152                 uip_len = uiGetEMACRxData( uip_buf );\r
153                 \r
154                 if( uip_len > 0 )\r
155                 {\r
156                         /* Standard uIP loop taken from the uIP manual. */\r
157 \r
158                         if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
159                         {\r
160                                 uip_arp_ipin();\r
161                                 uip_input();\r
162 \r
163                                 /* If the above function invocation resulted in data that\r
164                                 should be sent out on the network, the global variable\r
165                                 uip_len is set to a value > 0. */\r
166                                 if( uip_len > 0 )\r
167                                 {\r
168                                         uip_arp_out();\r
169                                         prvENET_Send();\r
170                                 }\r
171                         }\r
172                         else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
173                         {\r
174                                 uip_arp_arpin();\r
175 \r
176                                 /* If the above function invocation resulted in data that\r
177                                 should be sent out on the network, the global variable\r
178                                 uip_len is set to a value > 0. */\r
179                                 if( uip_len > 0 )\r
180                                 {\r
181                                         prvENET_Send();\r
182                                 }\r
183                         }\r
184                 }\r
185                 else\r
186                 {\r
187                         if( timer_expired( &periodic_timer ) )\r
188                         {\r
189                                 timer_reset( &periodic_timer );\r
190                                 for( i = 0; i < UIP_CONNS; i++ )\r
191                                 {\r
192                                         uip_periodic( i );\r
193         \r
194                                         /* If the above function invocation resulted in data that\r
195                                         should be sent out on the network, the global variable\r
196                                         uip_len is set to a value > 0. */\r
197                                         if( uip_len > 0 )\r
198                                         {\r
199                                                 uip_arp_out();\r
200                                                 prvENET_Send();\r
201                                         }\r
202                                 }       \r
203         \r
204                                 /* Call the ARP timer function every 10 seconds. */\r
205                                 if( timer_expired( &arp_timer ) )\r
206                                 {\r
207                                         timer_reset( &arp_timer );\r
208                                         uip_arp_timer();\r
209                                 }\r
210                         }\r
211                         else\r
212                         {                       \r
213                                 /* We did not receive a packet, and there was no periodic\r
214                                 processing to perform.  Block for a fixed period.  If a packet\r
215                                 is received during this period we will be woken by the ISR\r
216                                 giving us the Semaphore. */\r
217                                 xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );                       \r
218                         }\r
219                 }\r
220         }\r
221 }\r
222 /*-----------------------------------------------------------*/\r
223 \r
224 static void prvENET_Send(void)\r
225 {\r
226         vInitialiseSend();\r
227         vIncrementTxLength( uip_len );\r
228         vSendBufferToMAC();\r
229 }\r
230 /*-----------------------------------------------------------*/\r
231 \r
232 static void prvSetMACAddress( void )\r
233 {\r
234 unsigned long ulUser0, ulUser1;\r
235 unsigned char pucMACArray[8];\r
236 struct uip_eth_addr xAddr;\r
237 \r
238         /* Get the device MAC address from flash */\r
239     FlashUserGet(&ulUser0, &ulUser1);\r
240 \r
241         /* Convert the MAC address from flash into sequence of bytes. */\r
242     pucMACArray[0] = ((ulUser0 >>  0) & 0xff);\r
243     pucMACArray[1] = ((ulUser0 >>  8) & 0xff);\r
244     pucMACArray[2] = ((ulUser0 >> 16) & 0xff);\r
245     pucMACArray[3] = ((ulUser1 >>  0) & 0xff);\r
246     pucMACArray[4] = ((ulUser1 >>  8) & 0xff);\r
247     pucMACArray[5] = ((ulUser1 >> 16) & 0xff);\r
248 \r
249         /* Program the MAC address. */\r
250     EthernetMACAddrSet(ETH_BASE, pucMACArray);\r
251 \r
252         xAddr.addr[ 0 ] = pucMACArray[0];\r
253         xAddr.addr[ 1 ] = pucMACArray[1];\r
254         xAddr.addr[ 2 ] = pucMACArray[2];\r
255         xAddr.addr[ 3 ] = pucMACArray[3];\r
256         xAddr.addr[ 4 ] = pucMACArray[4];\r
257         xAddr.addr[ 5 ] = pucMACArray[5];\r
258         uip_setethaddr( xAddr );\r
259 }\r
260 /*-----------------------------------------------------------*/\r
261 \r
262 void vApplicationProcessFormInput( char *pcInputString, portBASE_TYPE xInputLength )\r
263 {\r
264 char *c, *pcText;\r
265 static char cMessageForDisplay[ 32 ];\r
266 extern QueueHandle_t xOLEDQueue;\r
267 xOLEDMessage xOLEDMessage;\r
268 \r
269         /* Process the form input sent by the IO page of the served HTML. */\r
270 \r
271         c = strstr( pcInputString, "?" );\r
272 \r
273     if( c )\r
274     {\r
275                 /* Turn LED's on or off in accordance with the check box status. */\r
276                 if( strstr( c, "LED0=1" ) != NULL )\r
277                 {\r
278                         vParTestSetLED( 0, 1 );\r
279                 }\r
280                 else\r
281                 {\r
282                         vParTestSetLED( 0, 0 );\r
283                 }               \r
284                 \r
285                 /* Find the start of the text to be displayed on the LCD. */\r
286         pcText = strstr( c, "LCD=" );\r
287         pcText += strlen( "LCD=" );\r
288 \r
289         /* Terminate the file name for further processing within uIP. */\r
290         *c = 0x00;\r
291 \r
292         /* Terminate the LCD string. */\r
293         c = strstr( pcText, " " );\r
294         if( c != NULL )\r
295         {\r
296             *c = 0x00;\r
297         }\r
298 \r
299         /* Add required spaces. */\r
300         while( ( c = strstr( pcText, "+" ) ) != NULL )\r
301         {\r
302             *c = ' ';\r
303         }\r
304 \r
305         /* Write the message to the LCD. */\r
306                 strcpy( cMessageForDisplay, pcText );\r
307                 xOLEDMessage.pcMessage = ( signed char * ) cMessageForDisplay;\r
308         xQueueSend( xOLEDQueue, &xOLEDMessage, portMAX_DELAY );\r
309     }\r
310 }\r
311 \r