]> begriffs open source - freertos/blob - Demo/ARM9_STR91X_IAR/webserver/uIP_Task.c
Update to V5.1.2.
[freertos] / Demo / ARM9_STR91X_IAR / webserver / uIP_Task.c
1 /*\r
2         FreeRTOS.org V5.1.2 - Copyright (C) 2003-2009 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     ***************************************************************************\r
28     *                                                                         *\r
29     * Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *\r
30         *                                                                         *\r
31         * This is a concise, step by step, 'hands on' guide that describes both   *\r
32         * general multitasking concepts and FreeRTOS specifics. It presents and   *\r
33         * explains numerous examples that are written using the FreeRTOS API.     *\r
34         * Full source code for all the examples is provided in an accompanying    *\r
35         * .zip file.                                                              *\r
36     *                                                                         *\r
37     ***************************************************************************\r
38     ***************************************************************************\r
39 \r
40         Please ensure to read the configuration and relevant port sections of the\r
41         online documentation.\r
42 \r
43         http://www.FreeRTOS.org - Documentation, latest information, license and \r
44         contact details.\r
45 \r
46         http://www.SafeRTOS.com - A version that is certified for use in safety \r
47         critical systems.\r
48 \r
49         http://www.OpenRTOS.com - Commercial support, development, porting, \r
50         licensing and training services.\r
51 */\r
52 /* Standard includes. */\r
53 #include <string.h>\r
54 \r
55 /* Library includes. */\r
56 #include "91x_lib.h"\r
57 #include "91x_enet.h"\r
58 \r
59 /* Scheduler includes. */\r
60 #include "FreeRTOS.h"\r
61 #include "task.h"\r
62 #include "semphr.h"\r
63 \r
64 /* uip includes. */\r
65 #include "uip.h"\r
66 #include "uip_arp.h"\r
67 #include "httpd.h"\r
68 #include "timer.h"\r
69 #include "clock-arch.h"\r
70 \r
71 /*-----------------------------------------------------------*/\r
72 \r
73 /* MAC address configuration. */\r
74 #define uipMAC_ADDR0    0x00\r
75 #define uipMAC_ADDR1    0x12\r
76 #define uipMAC_ADDR2    0x13\r
77 #define uipMAC_ADDR3    0x14\r
78 #define uipMAC_ADDR4    0x15\r
79 #define uipMAC_ADDR5    0x20\r
80 \r
81 /* IP address configuration. */\r
82 #define uipIP_ADDR0             172\r
83 #define uipIP_ADDR1             25\r
84 #define uipIP_ADDR2             218\r
85 #define uipIP_ADDR3             11      \r
86 \r
87 /* Netmask configuration. */\r
88 #define uipNET_MASK0    255\r
89 #define uipNET_MASK1    255\r
90 #define uipNET_MASK2    255\r
91 #define uipNET_MASK3    0\r
92 \r
93 /* Gateway address configuration. */\r
94 #define uipGATEWAY_ADDR0 172\r
95 #define uipGATEWAY_ADDR1 25\r
96 #define uipGATEWAY_ADDR2 218\r
97 #define uipGATEWAY_ADDR3 1\r
98 \r
99 /* Shortcut to the header within the Rx buffer. */\r
100 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])\r
101 \r
102 /* uIP update frequencies. */\r
103 #define uipMAX_BLOCK_TIME       (configTICK_RATE_HZ / 4)\r
104 \r
105 /* Interrupt status bit definition. */\r
106 #define uipDMI_RX_CURRENT_DONE 0x8000\r
107 \r
108 /* If no buffers are available, then wait this long before looking again. */\r
109 #define uipBUFFER_WAIT_DELAY    ( 10 / portTICK_RATE_MS )\r
110 #define uipBUFFER_WAIT_ATTEMPTS ( 10 )\r
111 \r
112 /* Standard constant. */\r
113 #define uipTOTAL_FRAME_HEADER_SIZE      54\r
114 \r
115 /*-----------------------------------------------------------*/\r
116 \r
117 /*\r
118  * Send the uIP buffer to the MAC.\r
119  */\r
120 static void prvENET_Send(void);\r
121 \r
122 /*\r
123  * Setup the MAC address in the MAC itself, and in the uIP stack.\r
124  */\r
125 static void prvSetMACAddress( void );\r
126 \r
127 /*\r
128  * Used to return a pointer to the next buffer to be used.\r
129  */\r
130 extern unsigned portCHAR *pcGetNextBuffer( void );\r
131 \r
132 /*\r
133  * Port functions required by the uIP stack.\r
134  */\r
135 void clock_init( void );\r
136 clock_time_t clock_time( void );\r
137 \r
138 /*-----------------------------------------------------------*/\r
139 \r
140 /* The semaphore used by the ISR to wake the uIP task. */\r
141 xSemaphoreHandle xSemaphore = NULL;\r
142 \r
143 /*-----------------------------------------------------------*/\r
144 \r
145 void clock_init(void)\r
146 {\r
147         /* This is done when the scheduler starts. */\r
148 }\r
149 /*-----------------------------------------------------------*/\r
150 \r
151 clock_time_t clock_time( void )\r
152 {\r
153         return xTaskGetTickCount();\r
154 }\r
155 /*-----------------------------------------------------------*/\r
156 \r
157 void vuIP_Task( void *pvParameters )\r
158 {\r
159 portBASE_TYPE i;\r
160 uip_ipaddr_t xIPAddr;\r
161 struct timer periodic_timer, arp_timer;\r
162 \r
163         /* Create the semaphore used by the ISR to wake this task. */\r
164         vSemaphoreCreateBinary( xSemaphore );\r
165         \r
166         /* Initialise the uIP stack. */\r
167         timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );\r
168         timer_set( &arp_timer, configTICK_RATE_HZ * 10 );\r
169         uip_init();\r
170         uip_ipaddr( xIPAddr, uipIP_ADDR0, uipIP_ADDR1, uipIP_ADDR2, uipIP_ADDR3 );\r
171         uip_sethostaddr( xIPAddr );\r
172         uip_ipaddr( xIPAddr, uipNET_MASK0, uipNET_MASK1, uipNET_MASK2, uipNET_MASK3 );\r
173         uip_setnetmask( xIPAddr );\r
174         uip_ipaddr( xIPAddr, uipGATEWAY_ADDR0, uipGATEWAY_ADDR1, uipGATEWAY_ADDR2, uipGATEWAY_ADDR3 );\r
175         uip_setdraddr( xIPAddr );       \r
176         httpd_init();\r
177 \r
178         /* Initialise the MAC. */\r
179         ENET_InitClocksGPIO();\r
180         ENET_Init();\r
181         portENTER_CRITICAL();\r
182         {\r
183                 ENET_Start();\r
184                 prvSetMACAddress();\r
185                 VIC_Config( ENET_ITLine, VIC_IRQ, 1 );\r
186                 VIC_ITCmd( ENET_ITLine, ENABLE );       \r
187                 ENET_DMA->ISR = uipDMI_RX_CURRENT_DONE;\r
188                 ENET_DMA->IER = uipDMI_RX_CURRENT_DONE;\r
189         }\r
190         portEXIT_CRITICAL();\r
191         \r
192 \r
193         while(1)\r
194         {\r
195                 /* Is there received data ready to be processed? */\r
196                 uip_len = ENET_HandleRxPkt( uip_buf );\r
197                 \r
198                 if( uip_len > 0 )\r
199                 {\r
200                         /* Standard uIP loop taken from the uIP manual. */\r
201                         if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
202                         {\r
203                                 uip_arp_ipin();\r
204                                 uip_input();\r
205 \r
206                                 /* If the above function invocation resulted in data that\r
207                                 should be sent out on the network, the global variable\r
208                                 uip_len is set to a value > 0. */\r
209                                 if( uip_len > 0 )\r
210                                 {\r
211                                         uip_arp_out();\r
212                                         prvENET_Send();\r
213                                 }\r
214                         }\r
215                         else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
216                         {\r
217                                 uip_arp_arpin();\r
218 \r
219                                 /* If the above function invocation resulted in data that\r
220                                 should be sent out on the network, the global variable\r
221                                 uip_len is set to a value > 0. */\r
222                                 if( uip_len > 0 )\r
223                                 {\r
224                                         prvENET_Send();\r
225                                 }\r
226                         }\r
227                 }\r
228                 else\r
229                 {\r
230                         if( timer_expired( &periodic_timer ) )\r
231                         {\r
232                                 timer_reset( &periodic_timer );\r
233                                 for( i = 0; i < UIP_CONNS; i++ )\r
234                                 {\r
235                                         uip_periodic( i );\r
236         \r
237                                         /* If the above function invocation resulted in data that\r
238                                         should be sent out on the network, the global variable\r
239                                         uip_len is set to a value > 0. */\r
240                                         if( uip_len > 0 )\r
241                                         {\r
242                                                 uip_arp_out();\r
243                                                 prvENET_Send();\r
244                                         }\r
245                                 }       \r
246         \r
247                                 /* Call the ARP timer function every 10 seconds. */\r
248                                 if( timer_expired( &arp_timer ) )\r
249                                 {\r
250                                         timer_reset( &arp_timer );\r
251                                         uip_arp_timer();\r
252                                 }\r
253                         }\r
254                         else\r
255                         {                       \r
256                                 /* We did not receive a packet, and there was no periodic\r
257                                 processing to perform.  Block for a fixed period.  If a packet\r
258                                 is received during this period we will be woken by the ISR\r
259                                 giving us the Semaphore. */\r
260                                 xSemaphoreTake( xSemaphore, configTICK_RATE_HZ / 2 );                   \r
261                         }\r
262                 }\r
263         }\r
264 }\r
265 /*-----------------------------------------------------------*/\r
266 \r
267 static void prvENET_Send(void)\r
268 {\r
269 portBASE_TYPE i;\r
270 static unsigned portCHAR *pcTxData;\r
271 \r
272         /* Get a DMA buffer into which we can write the data to send. */\r
273         for( i = 0; i < uipBUFFER_WAIT_ATTEMPTS; i++ )\r
274         {\r
275                 pcTxData = pcGetNextBuffer();\r
276 \r
277                 if( pcTxData )\r
278                 {\r
279                         break;\r
280                 }\r
281                 else\r
282                 {\r
283                         vTaskDelay( uipBUFFER_WAIT_DELAY );\r
284                 }\r
285         }\r
286         \r
287         if( pcTxData )\r
288         {\r
289                 /* Copy the header into the Tx buffer. */\r
290                 memcpy( ( void * ) pcTxData, ( void * ) uip_buf, uipTOTAL_FRAME_HEADER_SIZE );\r
291                 if( uip_len > uipTOTAL_FRAME_HEADER_SIZE )\r
292                 {\r
293                         memcpy( ( void * ) &( pcTxData[ uipTOTAL_FRAME_HEADER_SIZE ] ), ( void * ) uip_appdata, ( uip_len - uipTOTAL_FRAME_HEADER_SIZE ) );\r
294                 }\r
295 \r
296                 ENET_TxPkt( &pcTxData, uip_len );\r
297         }\r
298 }\r
299 /*-----------------------------------------------------------*/\r
300 \r
301 void ENET_IRQHandler(void)\r
302 {\r
303 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
304 \r
305         /* Give the semaphore in case the uIP task needs waking. */\r
306         xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );\r
307         \r
308         /* Clear the interrupt. */\r
309         ENET_DMA->ISR = uipDMI_RX_CURRENT_DONE;\r
310         \r
311         /* Switch tasks if necessary. */        \r
312         portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );\r
313 }\r
314 /*-----------------------------------------------------------*/\r
315 \r
316 static void prvSetMACAddress( void )\r
317 {\r
318 struct uip_eth_addr xAddr;\r
319 \r
320         /* Configure the MAC address in the uIP stack. */\r
321         xAddr.addr[ 0 ] = uipMAC_ADDR0;\r
322         xAddr.addr[ 1 ] = uipMAC_ADDR1;\r
323         xAddr.addr[ 2 ] = uipMAC_ADDR2;\r
324         xAddr.addr[ 3 ] = uipMAC_ADDR3;\r
325         xAddr.addr[ 4 ] = uipMAC_ADDR4;\r
326         xAddr.addr[ 5 ] = uipMAC_ADDR5;\r
327         uip_setethaddr( xAddr );\r
328 \r
329         /* Write the MAC address to the MAC. */ \r
330         ENET_MAC->MAL = ( uipMAC_ADDR3 << 24 ) | ( uipMAC_ADDR2 << 16 ) | ( uipMAC_ADDR1 << 8 ) | ( uipMAC_ADDR0 );\r
331         ENET_MAC->MAH = ( uipMAC_ADDR5 << 8 ) | ( uipMAC_ADDR4 );\r
332 }\r
333 \r