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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_STM32F107_GCC_Rowley/] [webserver/] [emac.c] - Blame information for rev 590

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 582 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
/* FreeRTOS includes. */
55
#include "FreeRTOS.h"
56
#include "semphr.h"
57
#include "task.h"
58
#include "emac.h"
59
 
60
/* Library includes. */
61
#include "stm32fxxx_eth.h"
62
#include "stm32f10x_gpio.h"
63
#include "stm32f10x_rcc.h"
64
#include "stm32f10x_nvic.h"
65
 
66
/*-----------------------------------------------------------*/
67
 
68
/* Hardware specifics. */
69
#define uipRCC_MAC_CLOCK                        ( 1UL << 14UL )
70
#define uipRCC_MAC_TX_CLOCK                     ( 1UL << 15UL )
71
#define uipRCC_MAC_RX_CLOCK                     ( 1UL << 16UL )
72
#define uipPHY_ADDRESS                          ( 1 )
73
#define uipENET_IRQ_NUM                         ( 61 )
74
#define uipMODE_MII                                     ( 1UL << 23UL )
75
#define uipREMAP_MAC_IO                         ( 1UL << 21UL )
76
 
77
/* The number of descriptors to chain together for use by the Rx DMA. */
78
#define uipNUM_RX_DESCRIPTORS           4
79
 
80
/* The total number of buffers to be available.  At most (?) there should be
81
one available for each Rx descriptor, one for current use, and one that is
82
in the process of being transmitted. */
83
#define uipNUM_BUFFERS                          ( uipNUM_RX_DESCRIPTORS + 2 )
84
 
85
/* Each buffer is sized to fit an entire Ethernet packet.  This is for
86
simplicity and speed, but could waste RAM. */
87
#define uipMAX_PACKET_SIZE                      1520
88
 
89
/* The field in the descriptor that is unused by this configuration is used to
90
hold the send count.  This is just #defined to a meaningful name. */
91
#define SendCount Buffer2NextDescAddr
92
 
93
/* If no buffers are available, then wait this long before looking again.... */
94
#define uipBUFFER_WAIT_DELAY    ( 3 / portTICK_RATE_MS )
95
 
96
/* ...and don't look more than this many times. */
97
#define uipBUFFER_WAIT_ATTEMPTS ( 30 )
98
 
99
/* Let the DMA know that a new descriptor has been made available to it. */
100
#define prvRxDescriptorAvailable()              ETH_DMA->DMARPDR = 0
101
 
102
/*-----------------------------------------------------------*/
103
 
104
/*
105
 * Configure the IO for Ethernet use.
106
 */
107
static void prvSetupEthGPIO( void );
108
 
109
/*
110
 * Return a pointer to an unused buffer, marking the returned buffer as now
111
 * in use.
112
 */
113
static unsigned char *prvGetNextBuffer( void );
114
 
115
/*-----------------------------------------------------------*/
116
 
117
/* Allocate the Rx descriptors used by the DMA. */
118
static ETH_DMADESCTypeDef  xRxDescriptors[ uipNUM_RX_DESCRIPTORS ] __attribute__((aligned(4)));
119
 
120
/* Allocate the descriptor used for transmitting.  It might be that better
121
performance could be achieved by having more than one Tx descriptor, but
122
in this simple case only one is used. */
123
static volatile ETH_DMADESCTypeDef  xTxDescriptor __attribute__((aligned(4)));
124
 
125
/* Buffers used for receiving and transmitting data. */
126
static unsigned char ucMACBuffers[ uipNUM_BUFFERS ][ uipMAX_PACKET_SIZE ] __attribute__((aligned(4)));
127
 
128
/* Each ucBufferInUse index corresponds to a position in the same index in the
129
ucMACBuffers array.  If the index contains a 1 then the buffer within
130
ucMACBuffers is in use, if it contains a 0 then the buffer is free. */
131
static unsigned char ucBufferInUse[ uipNUM_BUFFERS ] = { 0 };
132
 
133
/* Index to the Rx descriptor to inspect next when looking for a received
134
packet. */
135
static unsigned long ulNextDescriptor;
136
 
137
/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers
138
allocated within this file. */
139
extern unsigned char * uip_buf;
140
 
141
/*-----------------------------------------------------------*/
142
 
143
portBASE_TYPE xEthInitialise( void )
144
{
145
static ETH_InitTypeDef xEthInit; /* Static so as not to take up too much stack space. */
146
NVIC_InitTypeDef xNVICInit;
147
const unsigned char ucMACAddress[] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
148
portBASE_TYPE xReturn;
149
unsigned long ul;
150
 
151
        /* Start with things in a safe known state. */
152
        ETH_DeInit();
153
        for( ul = 0; ul < uipNUM_RX_DESCRIPTORS; ul++ )
154
        {
155
                ETH_DMARxDescReceiveITConfig( &( xRxDescriptors[ ul ] ), DISABLE );
156
        }
157
 
158
        /* Route clock to the peripheral. */
159
    RCC->AHBENR |= ( uipRCC_MAC_CLOCK | uipRCC_MAC_TX_CLOCK | uipRCC_MAC_RX_CLOCK );
160
 
161
        /* Set the MAC address. */
162
        ETH_MACAddressConfig( ETH_MAC_Address0, ( unsigned char * ) ucMACAddress );
163
 
164
        /* Use MII mode. */
165
    AFIO->MAPR &= ~( uipMODE_MII );
166
 
167
        /* Configure all the GPIO as required for MAC/PHY interfacing. */
168
        prvSetupEthGPIO();
169
 
170
        /* Reset the peripheral. */
171
        ETH_SoftwareReset();
172
        while( ETH_GetSoftwareResetStatus() == SET );
173
 
174
        /* Initialise using the whopping big structure.  Code space could be saved
175
        by making this a const struct, however that would mean changes to the
176
        structure within the library header files could break the code, so for now
177
        just set everything manually at run time. */
178
        xEthInit.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
179
        xEthInit.ETH_Watchdog = ETH_Watchdog_Disable;
180
        xEthInit.ETH_Jabber = ETH_Jabber_Disable;
181
        xEthInit.ETH_JumboFrame = ETH_JumboFrame_Disable;
182
        xEthInit.ETH_InterFrameGap = ETH_InterFrameGap_96Bit;
183
        xEthInit.ETH_CarrierSense = ETH_CarrierSense_Enable;
184
        xEthInit.ETH_Speed = ETH_Speed_10M;
185
        xEthInit.ETH_ReceiveOwn = ETH_ReceiveOwn_Disable;
186
        xEthInit.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
187
        xEthInit.ETH_Mode = ETH_Mode_HalfDuplex;
188
        xEthInit.ETH_ChecksumOffload = ETH_ChecksumOffload_Disable;
189
        xEthInit.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
190
        xEthInit.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
191
        xEthInit.ETH_BackOffLimit = ETH_BackOffLimit_10;
192
        xEthInit.ETH_DeferralCheck = ETH_DeferralCheck_Disable;
193
        xEthInit.ETH_ReceiveAll = ETH_ReceiveAll_Enable;
194
        xEthInit.ETH_SourceAddrFilter = ETH_SourceAddrFilter_Disable;
195
        xEthInit.ETH_PassControlFrames = ETH_PassControlFrames_ForwardPassedAddrFilter;
196
        xEthInit.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable;
197
        xEthInit.ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal;
198
        xEthInit.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
199
        xEthInit.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
200
        xEthInit.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
201
        xEthInit.ETH_HashTableHigh = 0x0;
202
        xEthInit.ETH_HashTableLow = 0x0;
203
        xEthInit.ETH_PauseTime = 0x0;
204
        xEthInit.ETH_ZeroQuantaPause = ETH_ZeroQuantaPause_Disable;
205
        xEthInit.ETH_PauseLowThreshold = ETH_PauseLowThreshold_Minus4;
206
        xEthInit.ETH_UnicastPauseFrameDetect = ETH_UnicastPauseFrameDetect_Disable;
207
        xEthInit.ETH_ReceiveFlowControl = ETH_ReceiveFlowControl_Disable;
208
        xEthInit.ETH_TransmitFlowControl = ETH_TransmitFlowControl_Disable;
209
        xEthInit.ETH_VLANTagComparison = ETH_VLANTagComparison_16Bit;
210
        xEthInit.ETH_VLANTagIdentifier = 0x0;
211
        xEthInit.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disable;
212
        xEthInit.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
213
        xEthInit.ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Disable;
214
        xEthInit.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
215
        xEthInit.ETH_TransmitThresholdControl = ETH_TransmitThresholdControl_64Bytes;
216
        xEthInit.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
217
        xEthInit.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
218
        xEthInit.ETH_ReceiveThresholdControl = ETH_ReceiveThresholdControl_64Bytes;
219
        xEthInit.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Disable;
220
        xEthInit.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
221
        xEthInit.ETH_FixedBurst = ETH_FixedBurst_Disable;
222
        xEthInit.ETH_RxDMABurstLength = ETH_RxDMABurstLength_1Beat;
223
        xEthInit.ETH_TxDMABurstLength = ETH_TxDMABurstLength_1Beat;
224
        xEthInit.ETH_DescriptorSkipLength = 0x0;
225
        xEthInit.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_1_1;
226
 
227
        xReturn = ETH_Init( &xEthInit, uipPHY_ADDRESS );
228
 
229
        /* Check a link was established. */
230
        if( xReturn != pdFAIL )
231
        {
232
                /* Rx and Tx interrupts are used. */
233
                ETH_DMAITConfig( ETH_DMA_IT_NIS | ETH_DMA_IT_R | ETH_DMA_IT_T, ENABLE );
234
 
235
                /* Only a single Tx descriptor is used.  For now it is set to use an Rx
236
                buffer, but will get updated to point to where ever uip_buf is
237
                pointing prior to its use. */
238
                ETH_DMATxDescChainInit( ( void * ) &xTxDescriptor, ( void * ) ucMACBuffers, 1 );
239
                ETH_DMARxDescChainInit( xRxDescriptors, ( void * ) ucMACBuffers, uipNUM_RX_DESCRIPTORS );
240
                for( ul = 0; ul < uipNUM_RX_DESCRIPTORS; ul++ )
241
                {
242
                        /* Ensure received data generates an interrupt. */
243
                        ETH_DMARxDescReceiveITConfig( &( xRxDescriptors[ ul ] ), ENABLE );
244
 
245
                        /* Fix up the addresses used by the descriptors.
246
                        The way ETH_DMARxDescChainInit() is not compatible with the buffer
247
                        declarations in this file. */
248
                        xRxDescriptors[ ul ].Buffer1Addr = ( unsigned long ) &( ucMACBuffers[ ul ][ 0 ] );
249
 
250
                        /* Mark the buffer used by this descriptor as in use. */
251
            ucBufferInUse[ ul ] = pdTRUE;
252
                }
253
 
254
                /* When receiving data, start at the first descriptor. */
255
                ulNextDescriptor = 0;
256
 
257
                /* Initialise uip_buf to ensure it points somewhere valid. */
258
                uip_buf = prvGetNextBuffer();
259
 
260
                /* SendCount must be initialised to 2 to ensure the Tx descriptor looks
261
                as if its available (as if it has already been sent twice. */
262
        xTxDescriptor.SendCount = 2;
263
 
264
                /* Switch on the interrupts in the NVIC. */
265
                xNVICInit.NVIC_IRQChannel = uipENET_IRQ_NUM;
266
                xNVICInit.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY;
267
                xNVICInit.NVIC_IRQChannelSubPriority = 0;
268
                xNVICInit.NVIC_IRQChannelCmd = ENABLE;
269
                NVIC_Init( &xNVICInit );
270
 
271
                /* Buffers and descriptors are all set up, now enable the MAC. */
272
                ETH_Start();
273
 
274
                /* Let the DMA know there are Rx descriptors available. */
275
                prvRxDescriptorAvailable();
276
        }
277
 
278
        return xReturn;
279
}
280
/*-----------------------------------------------------------*/
281
 
282
static unsigned char *prvGetNextBuffer( void )
283
{
284
portBASE_TYPE x;
285
unsigned char *ucReturn = NULL;
286
unsigned long ulAttempts = 0;
287
 
288
        while( ucReturn == NULL )
289
        {
290
                /* Look through the buffers to find one that is not in use by
291
                anything else. */
292
                for( x = 0; x < uipNUM_BUFFERS; x++ )
293
                {
294
                        if( ucBufferInUse[ x ] == pdFALSE )
295
                        {
296
                                ucBufferInUse[ x ] = pdTRUE;
297
                                ucReturn = &( ucMACBuffers[ x ][ 0 ] );
298
                                break;
299
                        }
300
                }
301
 
302
                /* Was a buffer found? */
303
                if( ucReturn == NULL )
304
                {
305
                        ulAttempts++;
306
 
307
                        if( ulAttempts >= uipBUFFER_WAIT_ATTEMPTS )
308
                        {
309
                                break;
310
                        }
311
 
312
                        /* Wait then look again. */
313
                        vTaskDelay( uipBUFFER_WAIT_DELAY );
314
                }
315
        }
316
 
317
        return ucReturn;
318
}
319
/*-----------------------------------------------------------*/
320
 
321
unsigned short usGetMACRxData( void )
322
{
323
unsigned short usReturn;
324
 
325
        if( ( xRxDescriptors[ ulNextDescriptor ].Status & ETH_DMARxDesc_ES ) != 0 )
326
        {
327
                /* Error in Rx.  Discard the frame and give it back to the DMA. */
328
                xRxDescriptors[ ulNextDescriptor ].Status = ETH_DMARxDesc_OWN;
329
                prvRxDescriptorAvailable();
330
 
331
                /* No data to return. */
332
                usReturn = 0UL;
333
 
334
                /* Start from the next descriptor the next time this function is called. */
335
                ulNextDescriptor++;
336
                if( ulNextDescriptor >= uipNUM_RX_DESCRIPTORS )
337
                {
338
                        ulNextDescriptor = 0UL;
339
                }
340
        }
341
        else if( ( xRxDescriptors[ ulNextDescriptor ].Status & ETH_DMARxDesc_OWN ) == 0 )
342
        {
343
                /* Mark the current buffer as free as uip_buf is going to be set to
344
                the buffer that contains the received data. */
345
                vReturnBuffer( uip_buf );
346
 
347
                /* Get the received data length from the top 2 bytes of the Status
348
                word and the data itself. */
349
                usReturn = ( unsigned short ) ( ( xRxDescriptors[ ulNextDescriptor ].Status & ETH_DMARxDesc_FL ) >> 16UL );
350
                uip_buf = ( unsigned char * ) ( xRxDescriptors[ ulNextDescriptor ].Buffer1Addr );
351
 
352
                /* Allocate a new buffer to the descriptor. */
353
                xRxDescriptors[ ulNextDescriptor ].Buffer1Addr = ( unsigned long ) prvGetNextBuffer();
354
 
355
                /* Give the descriptor back to the DMA. */
356
                xRxDescriptors[ ulNextDescriptor ].Status = ETH_DMARxDesc_OWN;
357
                prvRxDescriptorAvailable();
358
 
359
                /* Start from the next descriptor the next time this function is called. */
360
                ulNextDescriptor++;
361
                if( ulNextDescriptor >= uipNUM_RX_DESCRIPTORS )
362
                {
363
                        ulNextDescriptor = 0UL;
364
                }
365
        }
366
        else
367
        {
368
                /* No received data at all. */
369
                usReturn = 0UL;
370
        }
371
 
372
        return usReturn;
373
}
374
/*-----------------------------------------------------------*/
375
 
376
void vSendMACData( unsigned short usDataLen )
377
{
378
unsigned long ulAttempts = 0UL;
379
 
380
        /* Check to see if the Tx descriptor is free.  The check against <2 is to
381
        ensure the buffer has been sent twice and in so doing preventing a race
382
        condition with the DMA on the ETH_DMATxDesc_OWN bit. */
383
        while( ( xTxDescriptor.SendCount < 2 ) && ( xTxDescriptor.Status & ETH_DMATxDesc_OWN ) == ETH_DMATxDesc_OWN )
384
        {
385
                /* Wait for the Tx descriptor to become available. */
386
                vTaskDelay( uipBUFFER_WAIT_DELAY );
387
 
388
                ulAttempts++;
389
                if( ulAttempts > uipBUFFER_WAIT_ATTEMPTS )
390
                {
391
                        /* Something has gone wrong as the Tx descriptor is still in use.
392
                        Clear it down manually, the data it was sending will probably be
393
                        lost. */
394
                        xTxDescriptor.Status &= ~ETH_DMATxDesc_OWN;
395
                        vReturnBuffer( ( unsigned char * ) xTxDescriptor.Buffer1Addr );
396
                        break;
397
                }
398
        }
399
 
400
        /* Setup the Tx descriptor for transmission. */
401
        xTxDescriptor.SendCount = 0;
402
        xTxDescriptor.Buffer1Addr = ( unsigned long ) uip_buf;
403
        xTxDescriptor.ControlBufferSize = ( unsigned long ) usDataLen;
404
        xTxDescriptor.Status = ETH_DMATxDesc_OWN | ETH_DMATxDesc_LS | ETH_DMATxDesc_FS | ETH_DMATxDesc_TER | ETH_DMATxDesc_TCH | ETH_DMATxDesc_IC;
405
        ETH_DMA->DMASR = ETH_DMASR_TBUS;
406
        ETH_DMA->DMATPDR = 0;
407
 
408
        /* uip_buf is being sent by the Tx descriptor.  Allocate a new buffer. */
409
        uip_buf = prvGetNextBuffer();
410
}
411
/*-----------------------------------------------------------*/
412
 
413
static void prvSetupEthGPIO( void )
414
{
415
GPIO_InitTypeDef xEthInit;
416
 
417
        /* Remap MAC IO. */
418
        AFIO->MAPR |=  ( uipREMAP_MAC_IO );
419
 
420
        /* Set PA2, PA8, PB5, PB8, PB11, PB12, PB13, PC1 and PC2 for Ethernet
421
        interfacing. */
422
        xEthInit.GPIO_Pin = GPIO_Pin_2;/* | GPIO_Pin_8; This should be set when the 25MHz is generated by MCO. */
423
        xEthInit.GPIO_Speed = GPIO_Speed_50MHz;
424
        xEthInit.GPIO_Mode = GPIO_Mode_AF_PP;
425
        GPIO_Init( GPIOA, &xEthInit );
426
 
427
        xEthInit.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; /*5*/
428
        GPIO_Init( GPIOB, &xEthInit );
429
 
430
        xEthInit.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
431
        GPIO_Init( GPIOC, &xEthInit );
432
 
433
 
434
        /* Configure PA0, PA1, PA3, PB10, PC3, PD8, PD9, PD10, PD11 and PD12 as
435
        inputs. */
436
        xEthInit.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3;
437
        xEthInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;
438
        GPIO_Init( GPIOA, &xEthInit );
439
 
440
        xEthInit.GPIO_Pin = GPIO_Pin_10;
441
        GPIO_Init( GPIOB, &xEthInit );
442
 
443
        xEthInit.GPIO_Pin = GPIO_Pin_3;
444
        GPIO_Init( GPIOC, &xEthInit );
445
 
446
        xEthInit.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
447
        GPIO_Init( GPIOD, &xEthInit );
448
}
449
/*-----------------------------------------------------------*/
450
 
451
void vReturnBuffer( unsigned char *pucBuffer )
452
{
453
unsigned long ul;
454
 
455
        /* Mark a buffer as free for use. */
456
        for( ul = 0; ul < uipNUM_BUFFERS; ul++ )
457
        {
458
                if( ucMACBuffers[ ul ] == pucBuffer )
459
                {
460
                        ucBufferInUse[ ul ] = pdFALSE;
461
                        break;
462
                }
463
        }
464
}
465
/*-----------------------------------------------------------*/
466
 
467
void vMAC_ISR( void )
468
{
469
unsigned long ulStatus;
470
extern xSemaphoreHandle xEMACSemaphore;
471
long xHigherPriorityTaskWoken = pdFALSE;
472
 
473
        /* What caused the interrupt? */
474
        ulStatus = ETH_DMA->DMASR;
475
 
476
        /* Clear everything before leaving. */
477
    ETH_DMA->DMASR = ulStatus;
478
 
479
        if( ulStatus & ETH_DMA_IT_R )
480
        {
481
                /* Data was received.  Ensure the uIP task is not blocked as data has
482
                arrived. */
483
                xSemaphoreGiveFromISR( xEMACSemaphore, &xHigherPriorityTaskWoken );
484
        }
485
 
486
        if( ulStatus & ETH_DMA_IT_T )
487
        {
488
                /* Data was transmitted. */
489
                if( xTxDescriptor.SendCount == 0 )
490
                {
491
                        /* Send again! */
492
                        ( xTxDescriptor.SendCount )++;
493
 
494
                        xTxDescriptor.Status = ETH_DMATxDesc_OWN | ETH_DMATxDesc_LS | ETH_DMATxDesc_FS | ETH_DMATxDesc_TER | ETH_DMATxDesc_TCH | ETH_DMATxDesc_IC;
495
                        ETH_DMA->DMASR = ETH_DMASR_TBUS;
496
                        ETH_DMA->DMATPDR = 0;
497
                }
498
                else
499
                {
500
                        /* The Tx buffer is no longer required. */
501
                        vReturnBuffer( ( unsigned char * ) xTxDescriptor.Buffer1Addr );
502
                }
503
        }
504
 
505
        /* If xSemaphoreGiveFromISR() unblocked a task, and the unblocked task has
506
        a higher priority than the currently executing task, then
507
        xHigherPriorityTaskWoken will have been set to pdTRUE and this ISR should
508
        return directly to the higher priority unblocked task. */
509
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
510
}
511
 

powered by: WebSVN 2.1.0

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