]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/SuperH_SH7216_Renesas/RTOSDemo/webserver/EMAC.c
Minor updates and change version number for V7.5.0 release.
[freertos] / FreeRTOS / Demo / SuperH_SH7216_Renesas / RTOSDemo / webserver / EMAC.c
1 /*\r
2     FreeRTOS V7.5.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
3 \r
4     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
5 \r
6     ***************************************************************************\r
7      *                                                                       *\r
8      *    FreeRTOS provides completely free yet professionally developed,    *\r
9      *    robust, strictly quality controlled, supported, and cross          *\r
10      *    platform software that has become a de facto standard.             *\r
11      *                                                                       *\r
12      *    Help yourself get started quickly and support the FreeRTOS         *\r
13      *    project by purchasing a FreeRTOS tutorial book, reference          *\r
14      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
15      *                                                                       *\r
16      *    Thank you!                                                         *\r
17      *                                                                       *\r
18     ***************************************************************************\r
19 \r
20     This file is part of the FreeRTOS distribution.\r
21 \r
22     FreeRTOS is free software; you can redistribute it and/or modify it under\r
23     the terms of the GNU General Public License (version 2) as published by the\r
24     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
25 \r
26     >>! NOTE: The modification to the GPL is included to allow you to distribute\r
27     >>! a combined work that includes FreeRTOS without being obliged to provide\r
28     >>! the source code for proprietary components outside of the FreeRTOS\r
29     >>! kernel.\r
30 \r
31     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
32     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
33     FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
34     link: http://www.freertos.org/a00114.html\r
35 \r
36     1 tab == 4 spaces!\r
37 \r
38     ***************************************************************************\r
39      *                                                                       *\r
40      *    Having a problem?  Start by reading the FAQ "My application does   *\r
41      *    not run, what could be wrong?"                                     *\r
42      *                                                                       *\r
43      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
44      *                                                                       *\r
45     ***************************************************************************\r
46 \r
47     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
48     license and Real Time Engineers Ltd. contact details.\r
49 \r
50     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
51     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
52     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
53 \r
54     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
55     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
56     licenses offer ticketed support, indemnification and middleware.\r
57 \r
58     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
59     engineered and independently SIL3 certified version for use in safety and\r
60     mission critical applications that require provable dependability.\r
61 \r
62     1 tab == 4 spaces!\r
63 */\r
64 \r
65 /* Hardware specific includes. */\r
66 #include "iodefine.h"\r
67 #include "typedefine.h"\r
68 #include "hwEthernet.h"\r
69 #include "hwEthernetPhy.h"\r
70 \r
71 /* FreeRTOS includes. */\r
72 #include "FreeRTOS.h"\r
73 #include "task.h"\r
74 #include "semphr.h"\r
75 \r
76 /* uIP includes. */\r
77 #include "net/uip.h"\r
78 \r
79 /* The time to wait between attempts to obtain a free buffer. */\r
80 #define emacBUFFER_WAIT_DELAY_ms                ( 3 / portTICK_RATE_MS )\r
81 \r
82 /* The number of times emacBUFFER_WAIT_DELAY_ms should be waited before giving\r
83 up on attempting to obtain a free buffer all together. */\r
84 #define emacBUFFER_WAIT_ATTEMPTS        ( 30 )\r
85 \r
86 /* The number of Rx descriptors. */\r
87 #define emacNUM_RX_DESCRIPTORS  3\r
88 \r
89 /* The number of Tx descriptors.  When using uIP there is not point in having\r
90 more than two. */\r
91 #define emacNUM_TX_BUFFERS      2\r
92 \r
93 /* The total number of EMAC buffers to allocate. */\r
94 #define emacNUM_BUFFERS         ( emacNUM_RX_DESCRIPTORS + emacNUM_TX_BUFFERS )\r
95 \r
96 /* The time to wait for the Tx descriptor to become free. */\r
97 #define emacTX_WAIT_DELAY_ms ( 10 / portTICK_RATE_MS )\r
98 \r
99 /* The total number of times to wait emacTX_WAIT_DELAY_ms for the Tx descriptor to\r
100 become free. */\r
101 #define emacTX_WAIT_ATTEMPTS ( 5 )\r
102 \r
103 /* Only Rx end and Tx end interrupts are used by this driver. */\r
104 #define emacTX_END_INTERRUPT    ( 1UL << 21UL )\r
105 #define emacRX_END_INTERRUPT    ( 1UL << 18UL )\r
106 \r
107 /*-----------------------------------------------------------*/\r
108 \r
109 /* The buffers and descriptors themselves. */\r
110 #pragma section RX_DESCR\r
111         ethfifo xRxDescriptors[ emacNUM_RX_DESCRIPTORS ];\r
112 #pragma section TX_DESCR\r
113         ethfifo xTxDescriptors[ emacNUM_TX_BUFFERS ];\r
114 #pragma section _ETHERNET_BUFFERS\r
115         char xEthernetBuffers[ emacNUM_BUFFERS ][ UIP_BUFSIZE ];\r
116 #pragma section\r
117 \r
118 /* Used to indicate which buffers are free and which are in use.  If an index\r
119 contains 0 then the corresponding buffer in xEthernetBuffers is free, otherwise \r
120 the buffer is in use or about to be used. */\r
121 static unsigned char ucBufferInUse[ emacNUM_BUFFERS ];\r
122 \r
123 /*-----------------------------------------------------------*/\r
124 \r
125 /*\r
126  * Initialise both the Rx and Tx descriptors.\r
127  */\r
128 static void prvInitialiseDescriptors( void );\r
129 \r
130 /*\r
131  * Return a pointer to a free buffer within xEthernetBuffers.\r
132  */\r
133 static unsigned char *prvGetNextBuffer( void );\r
134 \r
135 /*\r
136  * Return a buffer to the list of free buffers.\r
137  */\r
138 static void prvReturnBuffer( unsigned char *pucBuffer );\r
139 \r
140 /*\r
141  * Examine the status of the next Rx FIFO to see if it contains new data.\r
142  */\r
143 static unsigned long prvCheckRxFifoStatus( void );\r
144 \r
145 /*\r
146  * Setup the microcontroller for communication with the PHY.\r
147  */\r
148 static void prvSetupPortPinsAndReset( void );\r
149 \r
150 /*\r
151  * Configure the Ethernet interface peripherals.\r
152  */\r
153 static void prvConfigureEtherCAndEDMAC( void );\r
154 \r
155 /*\r
156  * Something has gone wrong with the descriptor usage.  Reset all the buffers\r
157  * and descriptors.\r
158  */\r
159 static void prvResetEverything( void );\r
160 \r
161 /*-----------------------------------------------------------*/\r
162 \r
163 /* Points to the Rx descriptor currently in use. */\r
164 static ethfifo *xCurrentRxDesc = NULL;\r
165 \r
166 /* The buffer used by the uIP stack to both receive and send.  This points to\r
167 one of the Ethernet buffers when its actually in use. */\r
168 unsigned char *uip_buf = NULL;\r
169 \r
170 /*-----------------------------------------------------------*/\r
171 \r
172 void vInitEmac( void )\r
173 {\r
174         /* Setup the SH hardware for MII communications. */\r
175         prvSetupPortPinsAndReset();\r
176         \r
177         /* Set the Rx and Tx descriptors into their initial state. */\r
178         prvInitialiseDescriptors();\r
179 \r
180         /* Set the MAC address into the ETHERC */\r
181         EtherC.MAHR =   ( ( unsigned long ) configMAC_ADDR0 << 24UL ) | \r
182                                         ( ( unsigned long ) configMAC_ADDR1 << 16UL ) | \r
183                                         ( ( unsigned long ) configMAC_ADDR2 << 8UL ) | \r
184                                         ( unsigned long ) configMAC_ADDR3;\r
185                                         \r
186         EtherC.MALR.BIT.MA = ( ( unsigned long ) configMAC_ADDR4 << 8UL ) |\r
187                                                  ( unsigned long ) configMAC_ADDR5;\r
188 \r
189         /* Perform rest of interface hardware configuration. */\r
190         prvConfigureEtherCAndEDMAC();\r
191         \r
192         /* Nothing received yet, so uip_buf points nowhere. */\r
193         uip_buf = NULL;\r
194 \r
195         /* Initialize the PHY */\r
196         phyReset();\r
197 }\r
198 /*-----------------------------------------------------------*/\r
199 \r
200 void vEMACWrite( void )\r
201 {\r
202 long x;\r
203 \r
204         /* Wait until the second transmission of the last packet has completed. */\r
205         for( x = 0; x < emacTX_WAIT_ATTEMPTS; x++ )\r
206         {\r
207                 if( ( xTxDescriptors[ 1 ].status & ACT ) != 0 )\r
208                 {\r
209                         /* Descriptor is still active. */\r
210                         vTaskDelay( emacTX_WAIT_DELAY_ms );\r
211                 }\r
212                 else\r
213                 {\r
214                         break;\r
215                 }\r
216         }\r
217         \r
218         /* Is the descriptor free after waiting for it? */\r
219         if( ( xTxDescriptors[ 1 ].status & ACT ) != 0 )\r
220         {\r
221                 /* Something has gone wrong. */\r
222                 prvResetEverything();\r
223         }\r
224         \r
225         /* Setup both descriptors to transmit the frame. */\r
226         xTxDescriptors[ 0 ].buf_p = ( char * ) uip_buf;\r
227         xTxDescriptors[ 0 ].bufsize = uip_len;  \r
228         xTxDescriptors[ 1 ].buf_p = ( char * ) uip_buf;\r
229         xTxDescriptors[ 1 ].bufsize = uip_len;\r
230 \r
231         /* uip_buf is being sent by the Tx descriptor.  Allocate a new buffer\r
232         for use by the stack. */\r
233         uip_buf = prvGetNextBuffer();\r
234 \r
235         /* Clear previous settings and go. */\r
236         xTxDescriptors[0].status &= ~( FP1 | FP0 );\r
237         xTxDescriptors[0].status |= ( FP1 | FP0 | ACT );\r
238         xTxDescriptors[1].status &= ~( FP1 | FP0 );\r
239         xTxDescriptors[1].status |= ( FP1 | FP0 | ACT );\r
240 \r
241         EDMAC.EDTRR.LONG = 0x00000001;\r
242 }\r
243 /*-----------------------------------------------------------*/\r
244 \r
245 unsigned long ulEMACRead( void )\r
246 {\r
247 unsigned long ulBytesReceived;\r
248 \r
249         ulBytesReceived = prvCheckRxFifoStatus();\r
250 \r
251         if( ulBytesReceived > 0 )\r
252         {\r
253                 xCurrentRxDesc->status &= ~( FP1 | FP0 );\r
254                 xCurrentRxDesc->status |= ACT;                  \r
255 \r
256                 if( EDMAC.EDRRR.LONG == 0x00000000L )\r
257                 {\r
258                         /* Restart Ethernet if it has stopped */\r
259                         EDMAC.EDRRR.LONG = 0x00000001L;\r
260                 }\r
261 \r
262                 /* Mark the pxDescriptor buffer as free as uip_buf is going to be set to\r
263                 the buffer that contains the received data. */\r
264                 prvReturnBuffer( uip_buf );\r
265                 \r
266                 uip_buf = ( void * ) xCurrentRxDesc->buf_p;\r
267 \r
268                 /* Move onto the next buffer in the ring. */\r
269                 xCurrentRxDesc = xCurrentRxDesc->next;\r
270         }\r
271 \r
272         return ulBytesReceived;\r
273 }\r
274 /*-----------------------------------------------------------*/\r
275 \r
276 long lEMACWaitForLink( void )\r
277 {\r
278 long lReturn;\r
279 \r
280         /* Set the link status. */\r
281         switch( phyStatus() )\r
282         {\r
283                 /* Half duplex link */\r
284                 case PHY_LINK_100H:\r
285                 case PHY_LINK_10H:\r
286                                                                 EtherC.ECMR.BIT.DM = 0;\r
287                                                                 lReturn = pdPASS;\r
288                                                                 break;\r
289 \r
290                 /* Full duplex link */\r
291                 case PHY_LINK_100F:\r
292                 case PHY_LINK_10F:\r
293                                                                 EtherC.ECMR.BIT.DM = 1;\r
294                                                                 lReturn = pdPASS;\r
295                                                                 break;\r
296 \r
297                 default:\r
298                                                                 lReturn = pdFAIL;\r
299                                                                 break;\r
300         }\r
301 \r
302         if( lReturn == pdPASS )\r
303         {\r
304                 /* Enable receive and transmit. */\r
305                 EtherC.ECMR.BIT.RE = 1;\r
306                 EtherC.ECMR.BIT.TE = 1;\r
307 \r
308                 /* Enable EDMAC receive */\r
309                 EDMAC.EDRRR.LONG = 0x1;\r
310         }\r
311         \r
312         return lReturn;\r
313 }\r
314 /*-----------------------------------------------------------*/\r
315 \r
316 static void prvInitialiseDescriptors( void )\r
317 {\r
318 ethfifo *pxDescriptor;\r
319 long x;\r
320 \r
321         for( x = 0; x < emacNUM_BUFFERS; x++ )\r
322         {\r
323                 /* Ensure none of the buffers are shown as in use at the start. */\r
324                 ucBufferInUse[ x ] = pdFALSE;\r
325         }\r
326 \r
327         /* Initialise the Rx descriptors. */\r
328         for( x = 0; x < emacNUM_RX_DESCRIPTORS; x++ )\r
329         {\r
330                 pxDescriptor = &( xRxDescriptors[ x ] );\r
331                 pxDescriptor->buf_p = &( xEthernetBuffers[ x ][ 0 ] );\r
332 \r
333                 pxDescriptor->bufsize = UIP_BUFSIZE;\r
334                 pxDescriptor->size = 0;\r
335                 pxDescriptor->status = ACT;\r
336                 pxDescriptor->next = &xRxDescriptors[ x + 1 ];  \r
337                 \r
338                 /* Mark this buffer as in use. */\r
339                 ucBufferInUse[ x ] = pdTRUE;\r
340         }\r
341 \r
342         /* The last descriptor points back to the start. */\r
343         pxDescriptor->status |= DL;\r
344         pxDescriptor->next = &xRxDescriptors[ 0 ];\r
345         \r
346         /* Initialise the Tx descriptors. */\r
347         for( x = 0; x < emacNUM_TX_BUFFERS; x++ )\r
348         {\r
349                 pxDescriptor = &( xTxDescriptors[ x ] );\r
350                 \r
351                 /* A buffer is not allocated to the Tx descriptor until a send is\r
352                 actually required. */\r
353                 pxDescriptor->buf_p = NULL;\r
354 \r
355                 pxDescriptor->bufsize = UIP_BUFSIZE;\r
356                 pxDescriptor->size = 0;\r
357                 pxDescriptor->status = 0;\r
358                 pxDescriptor->next = &xTxDescriptors[ x + 1 ];  \r
359         }\r
360 \r
361         /* The last descriptor points back to the start. */\r
362         pxDescriptor->status |= DL;\r
363         pxDescriptor->next = &( xTxDescriptors[ 0 ] );\r
364         \r
365         /* Use the first Rx descriptor to start with. */\r
366         xCurrentRxDesc = &( xRxDescriptors[ 0 ] );\r
367 }\r
368 /*-----------------------------------------------------------*/\r
369 \r
370 static unsigned char *prvGetNextBuffer( void )\r
371 {\r
372 long x;\r
373 unsigned char *pucReturn = NULL;\r
374 unsigned long ulAttempts = 0;\r
375 \r
376         while( pucReturn == NULL )\r
377         {\r
378                 /* Look through the buffers to find one that is not in use by\r
379                 anything else. */\r
380                 for( x = 0; x < emacNUM_BUFFERS; x++ )\r
381                 {\r
382                         if( ucBufferInUse[ x ] == pdFALSE )\r
383                         {\r
384                                 ucBufferInUse[ x ] = pdTRUE;\r
385                                 pucReturn = ( unsigned char * ) &( xEthernetBuffers[ x ][ 0 ] );\r
386                                 break;\r
387                         }\r
388                 }\r
389 \r
390                 /* Was a buffer found? */\r
391                 if( pucReturn == NULL )\r
392                 {\r
393                         ulAttempts++;\r
394 \r
395                         if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )\r
396                         {\r
397                                 break;\r
398                         }\r
399 \r
400                         /* Wait then look again. */\r
401                         vTaskDelay( emacBUFFER_WAIT_DELAY_ms );\r
402                 }\r
403         }\r
404 \r
405         return pucReturn;\r
406 }\r
407 /*-----------------------------------------------------------*/\r
408 \r
409 static void prvReturnBuffer( unsigned char *pucBuffer )\r
410 {\r
411 unsigned long ul;\r
412 \r
413         /* Return a buffer to the pool of free buffers. */\r
414         for( ul = 0; ul < emacNUM_BUFFERS; ul++ )\r
415         {\r
416                 if( &( xEthernetBuffers[ ul ][ 0 ] ) == ( void * ) pucBuffer )\r
417                 {\r
418                         ucBufferInUse[ ul ] = pdFALSE;\r
419                         break;\r
420                 }\r
421         }\r
422 }\r
423 /*-----------------------------------------------------------*/\r
424 \r
425 static void prvResetEverything( void )\r
426 {\r
427         /* Temporary code just to see if this gets called.  This function has not\r
428         been implemented. */\r
429         portDISABLE_INTERRUPTS();\r
430         for( ;; );\r
431 }\r
432 /*-----------------------------------------------------------*/\r
433 \r
434 static unsigned long prvCheckRxFifoStatus( void )\r
435 {\r
436 unsigned long ulReturn = 0;\r
437 \r
438         if( ( xCurrentRxDesc->status & ACT ) != 0 )\r
439         {\r
440                 /* Current descriptor is still active. */\r
441         }\r
442         else if( ( xCurrentRxDesc->status & FE ) != 0 )\r
443         {\r
444                 /* Frame error.  Clear the error. */\r
445                 xCurrentRxDesc->status &= ~( FP1 | FP0 | FE );\r
446                 xCurrentRxDesc->status &= ~( RMAF | RRF | RTLF | RTSF | PRE | CERF );\r
447                 xCurrentRxDesc->status |= ACT;\r
448                 xCurrentRxDesc = xCurrentRxDesc->next;\r
449 \r
450                 if( EDMAC.EDRRR.LONG == 0x00000000UL )\r
451                 {\r
452                         /* Restart Ethernet if it has stopped. */\r
453                         EDMAC.EDRRR.LONG = 0x00000001UL;\r
454                 }       \r
455         }\r
456         else\r
457         {\r
458                 /* The descriptor contains a frame.  Because of the size of the buffers\r
459                 the frame should always be complete. */\r
460                 if( (xCurrentRxDesc->status & FP0) == FP0 )\r
461                 {\r
462                         ulReturn = xCurrentRxDesc->size;\r
463                 }\r
464                 else\r
465                 {\r
466                         /* Do not expect to get here. */\r
467                         prvResetEverything();\r
468                 }\r
469         }\r
470         \r
471         return ulReturn;\r
472 }\r
473 /*-----------------------------------------------------------*/\r
474 \r
475 static void prvSetupPortPinsAndReset( void )\r
476 {\r
477         /* Initialisation code taken from Renesas example project. */\r
478         \r
479         PFC.PACRL4.BIT.PA12MD = 0x7;            /* Set TX_CLK input      (EtherC) */\r
480         PFC.PACRL3.BIT.PA11MD = 0x7;            /* Set TX_EN output      (EtherC) */\r
481         PFC.PACRL3.BIT.PA10MD = 0x7;            /* Set MII_TXD0 output   (EtherC) */\r
482         PFC.PACRL3.BIT.PA9MD  = 0x7;            /* Set MII_TXD1 output   (EtherC) */\r
483         PFC.PACRL3.BIT.PA8MD  = 0x7;            /* Set MII_TXD2 output   (EtherC) */\r
484         PFC.PACRL2.BIT.PA7MD  = 0x7;            /* Set MII_TXD3 output   (EtherC) */\r
485         PFC.PACRL2.BIT.PA6MD  = 0x7;            /* Set TX_ER output      (EtherC) */\r
486         PFC.PDCRH4.BIT.PD31MD = 0x7;            /* Set RX_DV input       (EtherC) */\r
487         PFC.PDCRH4.BIT.PD30MD = 0x7;            /* Set RX_ER input       (EtherC) */\r
488         PFC.PDCRH4.BIT.PD29MD = 0x7;            /* Set MII_RXD3 input    (EtherC) */\r
489         PFC.PDCRH4.BIT.PD28MD = 0x7;            /* Set MII_RXD2 input    (EtherC) */\r
490         PFC.PDCRH3.BIT.PD27MD = 0x7;            /* Set MII_RXD1 input    (EtherC) */\r
491         PFC.PDCRH3.BIT.PD26MD = 0x7;            /* Set MII_RXD0 input    (EtherC) */\r
492         PFC.PDCRH3.BIT.PD25MD = 0x7;            /* Set RX_CLK input      (EtherC) */\r
493         PFC.PDCRH3.BIT.PD24MD = 0x7;            /* Set CRS input         (EtherC) */\r
494         PFC.PDCRH2.BIT.PD23MD = 0x7;            /* Set COL input         (EtherC) */\r
495         PFC.PDCRH2.BIT.PD22MD = 0x7;            /* Set WOL output        (EtherC) */\r
496         PFC.PDCRH2.BIT.PD21MD = 0x7;            /* Set EXOUT output      (EtherC) */\r
497         PFC.PDCRH2.BIT.PD20MD = 0x7;            /* Set MDC output        (EtherC) */\r
498         PFC.PDCRH1.BIT.PD19MD = 0x7;            /* Set LINKSTA input     (EtherC) */\r
499         PFC.PDCRH1.BIT.PD18MD = 0x7;            /* Set MDIO input/output (EtherC) */\r
500         \r
501         STB.CR4.BIT._ETHER = 0x0;       \r
502         EDMAC.EDMR.BIT.SWR = 1; \r
503         \r
504         /* Crude wait for reset to complete. */\r
505         vTaskDelay( 500 / portTICK_RATE_MS );   \r
506 }\r
507 /*-----------------------------------------------------------*/\r
508 \r
509 static void prvConfigureEtherCAndEDMAC( void )\r
510 {\r
511         /* Initialisation code taken from Renesas example project. */\r
512         \r
513         /* TODO:    Check   bit 5   */\r
514         EtherC.ECSR.LONG = 0x00000037;                          /* Clear all EtherC statuS BFR, PSRTO, LCHNG, MPD, ICD */\r
515 \r
516         /* TODO:    Check   bit 5   */\r
517         EtherC.ECSIPR.LONG = 0x00000020;                        /* Disable EtherC status change interrupt */\r
518         EtherC.RFLR.LONG = 1518;                                        /* Ether payload is 1500+ CRC */\r
519         EtherC.IPGR.LONG = 0x00000014;                          /* Intergap is 96-bit time */\r
520 \r
521         /* EDMAC */\r
522         EDMAC.EESR.LONG = 0x47FF0F9F;                           /* Clear all EtherC and EDMAC status bits */\r
523         EDMAC.RDLAR = ( void * ) xCurrentRxDesc;        /* Initialaize Rx Descriptor List Address */\r
524         EDMAC.TDLAR = &( xTxDescriptors[ 0 ] );         /* Initialaize Tx Descriptor List Address */\r
525         EDMAC.TRSCER.LONG = 0x00000000;                         /* Copy-back status is RFE & TFE only   */\r
526         EDMAC.TFTR.LONG = 0x00000000;                           /* Threshold of Tx_FIFO */\r
527         EDMAC.FDR.LONG = 0x00000000;                            /* Transmit fifo & receive fifo is 256 bytes */\r
528         EDMAC.RMCR.LONG = 0x00000003;                           /* Receive function is normal mode(continued) */\r
529 \r
530         /* Set the EDMAC interrupt priority - the interrupt priority must be\r
531         configKERNEL_INTERRUPT_PRIORITY no matter which peripheral is used to \r
532         generate the tick interrupt. */\r
533         INTC.IPR19.BIT._EDMAC = portKERNEL_INTERRUPT_PRIORITY;\r
534         EDMAC.EESIPR.LONG = emacTX_END_INTERRUPT | emacRX_END_INTERRUPT;        /* Enable Rx and Tx end interrupts. */\r
535 \r
536         /* Clear the interrupt flag. */\r
537         CMT0.CMCSR.BIT.CMF = 0;\r
538 }\r
539 /*-----------------------------------------------------------*/\r
540 \r
541 void vEMAC_ISR_Handler( void )\r
542 {\r
543 unsigned long ul = EDMAC.EESR.LONG;\r
544 long lHigherPriorityTaskWoken = pdFALSE;\r
545 extern xSemaphoreHandle xEMACSemaphore;\r
546 static long ulTxEndInts = 0;\r
547 \r
548         /* Has a Tx end occurred? */\r
549         if( ul & emacTX_END_INTERRUPT )\r
550         {\r
551                 ++ulTxEndInts;\r
552                 if( ulTxEndInts >= 2 )\r
553                 {\r
554                         /* Only return the buffer to the pool once both Txes have completed. */\r
555                         prvReturnBuffer( ( void * ) xTxDescriptors[ 0 ].buf_p );\r
556                         ulTxEndInts = 0;\r
557                 }\r
558                 EDMAC.EESR.LONG = emacTX_END_INTERRUPT;\r
559         }\r
560 \r
561         /* Has an Rx end occurred? */\r
562         if( ul & emacRX_END_INTERRUPT )\r
563         {\r
564                 /* Make sure the Ethernet task is not blocked waiting for a packet. */\r
565                 xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );\r
566                 portYIELD_FROM_ISR( lHigherPriorityTaskWoken );\r
567                 EDMAC.EESR.LONG = emacRX_END_INTERRUPT;\r
568         }\r
569 }\r