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