OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_LPC1768_GCC_RedSuite/] [src/] [webserver/] [emac.c] - Blame information for rev 581

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 581 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
/* Originally adapted from file written by Andreas Dannenberg.  Supplied with permission. */
55
 
56
/* Kernel includes. */
57
#include "FreeRTOS.h"
58
#include "task.h"
59
#include "semphr.h"
60
 
61
/* Hardware specific includes. */
62
#include "EthDev_LPC17xx.h"
63
 
64
/* Time to wait between each inspection of the link status. */
65
#define emacWAIT_FOR_LINK_TO_ESTABLISH ( 500 / portTICK_RATE_MS )
66
 
67
/* Short delay used in several places during the initialisation process. */
68
#define emacSHORT_DELAY                            ( 2 )
69
 
70
/* Hardware specific bit definitions. */
71
#define emacLINK_ESTABLISHED            ( 0x0001 )
72
#define emacFULL_DUPLEX_ENABLED         ( 0x0004 )
73
#define emac10BASE_T_MODE                       ( 0x0002 )
74
#define emacPINSEL2_VALUE 0x50150105
75
 
76
/* If no buffers are available, then wait this long before looking again.... */
77
#define emacBUFFER_WAIT_DELAY   ( 3 / portTICK_RATE_MS )
78
 
79
/* ...and don't look more than this many times. */
80
#define emacBUFFER_WAIT_ATTEMPTS        ( 30 )
81
 
82
/* Index to the Tx descriptor that is always used first for every Tx.  The second
83
descriptor is then used to re-send in order to speed up the uIP Tx process. */
84
#define emacTX_DESC_INDEX                       ( 0 )
85
 
86
#define PCONP_PCENET    0x40000000
87
/*-----------------------------------------------------------*/
88
 
89
/*
90
 * Configure both the Rx and Tx descriptors during the init process.
91
 */
92
static void prvInitDescriptors( void );
93
 
94
/*
95
 * Setup the IO and peripherals required for Ethernet communication.
96
 */
97
static void prvSetupEMACHardware( void );
98
 
99
/*
100
 * Control the auto negotiate process.
101
 */
102
static void prvConfigurePHY( void );
103
 
104
/*
105
 * Wait for a link to be established, then setup the PHY according to the link
106
 * parameters.
107
 */
108
static long prvSetupLinkStatus( void );
109
 
110
/*
111
 * Search the pool of buffers to find one that is free.  If a buffer is found
112
 * mark it as in use before returning its address.
113
 */
114
static unsigned char *prvGetNextBuffer( void );
115
 
116
/*
117
 * Return an allocated buffer to the pool of free buffers.
118
 */
119
static void prvReturnBuffer( unsigned char *pucBuffer );
120
 
121
/*
122
 * Send lValue to the lPhyReg within the PHY.
123
 */
124
static long prvWritePHY( long lPhyReg, long lValue );
125
 
126
/*
127
 * Read a value from ucPhyReg within the PHY.  *plStatus will be set to
128
 * pdFALSE if there is an error.
129
 */
130
static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus );
131
 
132
/*-----------------------------------------------------------*/
133
 
134
/* The semaphore used to wake the uIP task when data arrives. */
135
extern xSemaphoreHandle xEMACSemaphore;
136
 
137
/* Each ucBufferInUse index corresponds to a position in the pool of buffers.
138
If the index contains a 1 then the buffer within pool is in use, if it
139
contains a 0 then the buffer is free. */
140
static unsigned char ucBufferInUse[ ETH_NUM_BUFFERS ] = { pdFALSE };
141
 
142
/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers
143
allocated within this file. */
144
unsigned char * uip_buf;
145
 
146
/* Store the length of the data being sent so the data can be sent twice.  The
147
value will be set back to 0 once the data has been sent twice. */
148
static unsigned short usSendLen = 0;
149
 
150
/*-----------------------------------------------------------*/
151
 
152
long lEMACInit( void )
153
{
154
long lReturn = pdPASS;
155
unsigned long ulID1, ulID2;
156
 
157
        /* Reset peripherals, configure port pins and registers. */
158
        prvSetupEMACHardware();
159
 
160
        /* Check the PHY part number is as expected. */
161
        ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn );
162
        ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn );
163
        if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) == DP83848C_ID )
164
        {
165
                /* Set the Ethernet MAC Address registers */
166
                LPC_EMAC->SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1;
167
                LPC_EMAC->SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3;
168
                LPC_EMAC->SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5;
169
 
170
                /* Initialize Tx and Rx DMA Descriptors */
171
                prvInitDescriptors();
172
 
173
                /* Receive broadcast and perfect match packets */
174
                LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
175
 
176
                /* Setup the PHY. */
177
                prvConfigurePHY();
178
        }
179
        else
180
        {
181
                lReturn = pdFAIL;
182
        }
183
 
184
        /* Check the link status. */
185
        if( lReturn == pdPASS )
186
        {
187
                lReturn = prvSetupLinkStatus();
188
        }
189
 
190
        if( lReturn == pdPASS )
191
        {
192
                /* Initialise uip_buf to ensure it points somewhere valid. */
193
                uip_buf = prvGetNextBuffer();
194
 
195
                /* Reset all interrupts */
196
                LPC_EMAC->IntClear = ( INT_RX_OVERRUN | INT_RX_ERR | INT_RX_FIN | INT_RX_DONE | INT_TX_UNDERRUN | INT_TX_ERR | INT_TX_FIN | INT_TX_DONE | INT_SOFT_INT | INT_WAKEUP );
197
 
198
                /* Enable receive and transmit mode of MAC Ethernet core */
199
                LPC_EMAC->Command |= ( CR_RX_EN | CR_TX_EN );
200
                LPC_EMAC->MAC1 |= MAC1_REC_EN;
201
        }
202
 
203
        return lReturn;
204
}
205
/*-----------------------------------------------------------*/
206
 
207
static unsigned char *prvGetNextBuffer( void )
208
{
209
long x;
210
unsigned char *pucReturn = NULL;
211
unsigned long ulAttempts = 0;
212
 
213
        while( pucReturn == NULL )
214
        {
215
                /* Look through the buffers to find one that is not in use by
216
                anything else. */
217
                for( x = 0; x < ETH_NUM_BUFFERS; x++ )
218
                {
219
                        if( ucBufferInUse[ x ] == pdFALSE )
220
                        {
221
                                ucBufferInUse[ x ] = pdTRUE;
222
                                pucReturn = ( unsigned char * ) ETH_BUF( x );
223
                                break;
224
                        }
225
                }
226
 
227
                /* Was a buffer found? */
228
                if( pucReturn == NULL )
229
                {
230
                        ulAttempts++;
231
 
232
                        if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )
233
                        {
234
                                break;
235
                        }
236
 
237
                        /* Wait then look again. */
238
                        vTaskDelay( emacBUFFER_WAIT_DELAY );
239
                }
240
        }
241
 
242
        return pucReturn;
243
}
244
/*-----------------------------------------------------------*/
245
 
246
static void prvInitDescriptors( void )
247
{
248
long x, lNextBuffer = 0;
249
 
250
        for( x = 0; x < NUM_RX_FRAG; x++ )
251
        {
252
                /* Allocate the next Ethernet buffer to this descriptor. */
253
                RX_DESC_PACKET( x ) = ETH_BUF( lNextBuffer );
254
                RX_DESC_CTRL( x ) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );
255
                RX_STAT_INFO( x ) = 0;
256
                RX_STAT_HASHCRC( x ) = 0;
257
 
258
                /* The Ethernet buffer is now in use. */
259
                ucBufferInUse[ lNextBuffer ] = pdTRUE;
260
                lNextBuffer++;
261
        }
262
 
263
        /* Set EMAC Receive Descriptor Registers. */
264
        LPC_EMAC->RxDescriptor = RX_DESC_BASE;
265
        LPC_EMAC->RxStatus = RX_STAT_BASE;
266
        LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1;
267
 
268
        /* Rx Descriptors Point to 0 */
269
        LPC_EMAC->RxConsumeIndex = 0;
270
 
271
        /* A buffer is not allocated to the Tx descriptors until they are actually
272
        used. */
273
        for( x = 0; x < NUM_TX_FRAG; x++ )
274
        {
275
                TX_DESC_PACKET( x ) = ( unsigned long ) NULL;
276
                TX_DESC_CTRL( x ) = 0;
277
                TX_STAT_INFO( x ) = 0;
278
        }
279
 
280
        /* Set EMAC Transmit Descriptor Registers. */
281
        LPC_EMAC->TxDescriptor = TX_DESC_BASE;
282
        LPC_EMAC->TxStatus = TX_STAT_BASE;
283
        LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1;
284
 
285
        /* Tx Descriptors Point to 0 */
286
        LPC_EMAC->TxProduceIndex = 0;
287
}
288
/*-----------------------------------------------------------*/
289
 
290
static void prvSetupEMACHardware( void )
291
{
292
unsigned short us;
293
long x, lDummy;
294
 
295
        /* Enable P1 Ethernet Pins. */
296
        LPC_PINCON->PINSEL2 = emacPINSEL2_VALUE;
297
        LPC_PINCON->PINSEL3 = ( LPC_PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005;
298
 
299
        /* Power Up the EMAC controller. */
300
        LPC_SC->PCONP |= PCONP_PCENET;
301
        vTaskDelay( emacSHORT_DELAY );
302
 
303
        /* Reset all EMAC internal modules. */
304
        LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
305
        LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;
306
 
307
        /* A short delay after reset. */
308
        vTaskDelay( emacSHORT_DELAY );
309
 
310
        /* Initialize MAC control registers. */
311
        LPC_EMAC->MAC1 = MAC1_PASS_ALL;
312
        LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
313
        LPC_EMAC->MAXF = ETH_MAX_FLEN;
314
        LPC_EMAC->CLRT = CLRT_DEF;
315
        LPC_EMAC->IPGR = IPGR_DEF;
316
 
317
        /* Enable Reduced MII interface. */
318
        LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;
319
 
320
        /* Reset Reduced MII Logic. */
321
        LPC_EMAC->SUPP = SUPP_RES_RMII;
322
        vTaskDelay( emacSHORT_DELAY );
323
        LPC_EMAC->SUPP = 0;
324
 
325
        /* Put the PHY in reset mode */
326
        prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );
327
        prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );
328
 
329
        /* Wait for hardware reset to end. */
330
        for( x = 0; x < 100; x++ )
331
        {
332
                vTaskDelay( emacSHORT_DELAY * 5 );
333
                us = prvReadPHY( PHY_REG_BMCR, &lDummy );
334
                if( !( us & MCFG_RES_MII ) )
335
                {
336
                        /* Reset complete */
337
                        break;
338
                }
339
        }
340
}
341
/*-----------------------------------------------------------*/
342
 
343
static void prvConfigurePHY( void )
344
{
345
unsigned short us;
346
long x, lDummy;
347
 
348
        /* Auto negotiate the configuration. */
349
        if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) )
350
        {
351
                vTaskDelay( emacSHORT_DELAY * 5 );
352
 
353
                for( x = 0; x < 10; x++ )
354
                {
355
                        us = prvReadPHY( PHY_REG_BMSR, &lDummy );
356
 
357
                        if( us & PHY_AUTO_NEG_COMPLETE )
358
                        {
359
                                break;
360
                        }
361
 
362
                        vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );
363
                }
364
        }
365
}
366
/*-----------------------------------------------------------*/
367
 
368
static long prvSetupLinkStatus( void )
369
{
370
long lReturn = pdFAIL, x;
371
unsigned short usLinkStatus;
372
 
373
        /* Wait with timeout for the link to be established. */
374
        for( x = 0; x < 10; x++ )
375
        {
376
                usLinkStatus = prvReadPHY( PHY_REG_STS, &lReturn );
377
                if( usLinkStatus & emacLINK_ESTABLISHED )
378
                {
379
                        /* Link is established. */
380
                        lReturn = pdPASS;
381
                        break;
382
                }
383
 
384
        vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );
385
        }
386
 
387
        if( lReturn == pdPASS )
388
        {
389
                /* Configure Full/Half Duplex mode. */
390
                if( usLinkStatus & emacFULL_DUPLEX_ENABLED )
391
                {
392
                        /* Full duplex is enabled. */
393
                        LPC_EMAC->MAC2 |= MAC2_FULL_DUP;
394
                        LPC_EMAC->Command |= CR_FULL_DUP;
395
                        LPC_EMAC->IPGT = IPGT_FULL_DUP;
396
                }
397
                else
398
                {
399
                        /* Half duplex mode. */
400
                        LPC_EMAC->IPGT = IPGT_HALF_DUP;
401
                }
402
 
403
                /* Configure 100MBit/10MBit mode. */
404
                if( usLinkStatus & emac10BASE_T_MODE )
405
                {
406
                        /* 10MBit mode. */
407
                        LPC_EMAC->SUPP = 0;
408
                }
409
                else
410
                {
411
                        /* 100MBit mode. */
412
                        LPC_EMAC->SUPP = SUPP_SPEED;
413
                }
414
        }
415
 
416
        return lReturn;
417
}
418
/*-----------------------------------------------------------*/
419
 
420
static void prvReturnBuffer( unsigned char *pucBuffer )
421
{
422
unsigned long ul;
423
 
424
        /* Return a buffer to the pool of free buffers. */
425
        for( ul = 0; ul < ETH_NUM_BUFFERS; ul++ )
426
        {
427
                if( ETH_BUF( ul ) == ( unsigned long ) pucBuffer )
428
                {
429
                        ucBufferInUse[ ul ] = pdFALSE;
430
                        break;
431
                }
432
        }
433
}
434
/*-----------------------------------------------------------*/
435
 
436
unsigned long ulGetEMACRxData( void )
437
{
438
unsigned long ulLen = 0;
439
long lIndex;
440
 
441
        if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex )
442
        {
443
                /* Mark the current buffer as free as uip_buf is going to be set to
444
                the buffer that contains the received data. */
445
                prvReturnBuffer( uip_buf );
446
 
447
                ulLen = ( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3;
448
                uip_buf = ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex );
449
 
450
                /* Allocate a new buffer to the descriptor. */
451
        RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex ) = ( unsigned long ) prvGetNextBuffer();
452
 
453
                /* Move the consume index onto the next position, ensuring it wraps to
454
                the beginning at the appropriate place. */
455
                lIndex = LPC_EMAC->RxConsumeIndex;
456
 
457
                lIndex++;
458
                if( lIndex >= NUM_RX_FRAG )
459
                {
460
                        lIndex = 0;
461
                }
462
 
463
                LPC_EMAC->RxConsumeIndex = lIndex;
464
        }
465
 
466
        return ulLen;
467
}
468
/*-----------------------------------------------------------*/
469
 
470
void vSendEMACTxData( unsigned short usTxDataLen )
471
{
472
unsigned long ulAttempts = 0UL;
473
 
474
        /* Check to see if the Tx descriptor is free, indicated by its buffer being
475
        NULL. */
476
        while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL )
477
        {
478
                /* Wait for the Tx descriptor to become available. */
479
                vTaskDelay( emacBUFFER_WAIT_DELAY );
480
 
481
                ulAttempts++;
482
                if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS )
483
                {
484
                        /* Something has gone wrong as the Tx descriptor is still in use.
485
                        Clear it down manually, the data it was sending will probably be
486
                        lost. */
487
                        prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
488
                        break;
489
                }
490
        }
491
 
492
        /* Setup the Tx descriptor for transmission.  Remember the length of the
493
        data being sent so the second descriptor can be used to send it again from
494
        within the ISR. */
495
        usSendLen = usTxDataLen;
496
        TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf;
497
        TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT );
498
        LPC_EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 );
499
 
500
        /* uip_buf is being sent by the Tx descriptor.  Allocate a new buffer. */
501
        uip_buf = prvGetNextBuffer();
502
}
503
/*-----------------------------------------------------------*/
504
 
505
static long prvWritePHY( long lPhyReg, long lValue )
506
{
507
const long lMaxTime = 10;
508
long x;
509
 
510
        LPC_EMAC->MADR = DP83848C_DEF_ADR | lPhyReg;
511
        LPC_EMAC->MWTD = lValue;
512
 
513
        x = 0;
514
        for( x = 0; x < lMaxTime; x++ )
515
        {
516
                if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 )
517
                {
518
                        /* Operation has finished. */
519
                        break;
520
                }
521
 
522
                vTaskDelay( emacSHORT_DELAY );
523
        }
524
 
525
        if( x < lMaxTime )
526
        {
527
                return pdPASS;
528
        }
529
        else
530
        {
531
                return pdFAIL;
532
        }
533
}
534
/*-----------------------------------------------------------*/
535
 
536
static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus )
537
{
538
long x;
539
const long lMaxTime = 10;
540
 
541
        LPC_EMAC->MADR = DP83848C_DEF_ADR | ucPhyReg;
542
        LPC_EMAC->MCMD = MCMD_READ;
543
 
544
        for( x = 0; x < lMaxTime; x++ )
545
        {
546
                /* Operation has finished. */
547
                if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 )
548
                {
549
                        break;
550
                }
551
 
552
                vTaskDelay( emacSHORT_DELAY );
553
        }
554
 
555
        LPC_EMAC->MCMD = 0;
556
 
557
        if( x >= lMaxTime )
558
        {
559
                *plStatus = pdFAIL;
560
        }
561
 
562
        return( LPC_EMAC->MRDD );
563
}
564
/*-----------------------------------------------------------*/
565
 
566
void vEMAC_ISR( void )
567
{
568
unsigned long ulStatus;
569
long lHigherPriorityTaskWoken = pdFALSE;
570
 
571
        ulStatus = LPC_EMAC->IntStatus;
572
 
573
        /* Clear the interrupt. */
574
        LPC_EMAC->IntClear = ulStatus;
575
 
576
        if( ulStatus & INT_RX_DONE )
577
        {
578
                /* Ensure the uIP task is not blocked as data has arrived. */
579
                xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );
580
        }
581
 
582
        if( ulStatus & INT_TX_DONE )
583
        {
584
                if( usSendLen > 0 )
585
                {
586
                        /* Send the data again, using the second descriptor.  As there are
587
                        only two descriptors the index is set back to 0. */
588
                        TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );
589
                        TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );
590
                        LPC_EMAC->TxProduceIndex = ( emacTX_DESC_INDEX );
591
 
592
                        /* This is the second Tx so set usSendLen to 0 to indicate that the
593
                        Tx descriptors will be free again. */
594
                        usSendLen = 0UL;
595
                }
596
                else
597
                {
598
                        /* The Tx buffer is no longer required. */
599
                        prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
600
            TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;
601
                }
602
        }
603
 
604
        portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
605
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.