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

Subversion Repositories openrisc

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

Go to most recent revision | 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
/* Kernel includes. */
55
#include "FreeRTOS.h"
56
#include "semphr.h"
57
#include "task.h"
58
 
59
/* Demo includes. */
60
#include "emac.h"
61
 
62
/* uIP includes. */
63
#include "uip.h"
64
 
65
/* Hardware library includes. */
66
#include "hw_types.h"
67
#include "hw_memmap.h"
68
#include "hw_ints.h"
69
#include "hw_ethernet.h"
70
#include "ethernet.h"
71
#include "interrupt.h"
72
 
73
#define emacNUM_RX_BUFFERS              5
74
#define emacFRAM_SIZE_BYTES     2
75
#define macNEGOTIATE_DELAY              2000
76
#define macWAIT_SEND_TIME               ( 10 )
77
 
78
/* The task that handles the MAC peripheral.  This is created at a high
79
priority and is effectively a deferred interrupt handler.  The peripheral
80
handling is deferred to a task to prevent the entire FIFO having to be read
81
from within an ISR. */
82
void vMACHandleTask( void *pvParameters );
83
 
84
/*-----------------------------------------------------------*/
85
 
86
/* The semaphore used to wake the uIP task when data arrives. */
87
xSemaphoreHandle xEMACSemaphore = NULL;
88
 
89
/* The semaphore used to wake the interrupt handler task.  The peripheral
90
is processed at the task level to prevent the need to read the entire FIFO from
91
within the ISR itself. */
92
xSemaphoreHandle xMACInterruptSemaphore = NULL;
93
 
94
/* The buffer used by the uIP stack.  In this case the pointer is used to
95
point to one of the Rx buffers. */
96
unsigned portCHAR *uip_buf;
97
 
98
/* Buffers into which Rx data is placed. */
99
static union
100
{
101
        unsigned portLONG ulJustForAlignment;
102
        unsigned portCHAR ucRxBuffers[ emacNUM_RX_BUFFERS ][ UIP_BUFSIZE + ( 4 * emacFRAM_SIZE_BYTES ) ];
103
} uxRxBuffers;
104
 
105
/* The length of the data within each of the Rx buffers. */
106
static unsigned portLONG ulRxLength[ emacNUM_RX_BUFFERS ];
107
 
108
/* Used to keep a track of the number of bytes to transmit. */
109
static unsigned portLONG ulNextTxSpace;
110
 
111
/*-----------------------------------------------------------*/
112
 
113
portBASE_TYPE vInitEMAC( void )
114
{
115
unsigned long ulTemp;
116
portBASE_TYPE xReturn;
117
 
118
        /* Ensure all interrupts are disabled. */
119
        EthernetIntDisable( ETH_BASE, ( ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER | ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER | ETH_INT_RX));
120
 
121
        /* Clear any interrupts that were already pending. */
122
    ulTemp = EthernetIntStatus( ETH_BASE, pdFALSE );
123
    EthernetIntClear( ETH_BASE, ulTemp );
124
 
125
        /* Initialise the MAC and connect. */
126
    EthernetInit( ETH_BASE );
127
    EthernetConfigSet( ETH_BASE, ( ETH_CFG_TX_DPLXEN | ETH_CFG_TX_CRCEN | ETH_CFG_TX_PADEN ) );
128
    EthernetEnable( ETH_BASE );
129
 
130
        /* Mark each Rx buffer as empty. */
131
        for( ulTemp = 0; ulTemp < emacNUM_RX_BUFFERS; ulTemp++ )
132
        {
133
                ulRxLength[ ulTemp ] = 0;
134
        }
135
 
136
        /* Create the queue and task used to defer the MAC processing to the
137
        task level. */
138
        vSemaphoreCreateBinary( xMACInterruptSemaphore );
139
        xSemaphoreTake( xMACInterruptSemaphore, 0 );
140
        xReturn = xTaskCreate( vMACHandleTask, ( signed portCHAR * ) "MAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
141
        vTaskDelay( macNEGOTIATE_DELAY );
142
 
143
        /* We are only interested in Rx interrupts. */
144
        IntPrioritySet( INT_ETH, configKERNEL_INTERRUPT_PRIORITY );
145
    IntEnable( INT_ETH );
146
    EthernetIntEnable(ETH_BASE, ETH_INT_RX);
147
 
148
        return xReturn;
149
}
150
/*-----------------------------------------------------------*/
151
 
152
unsigned int uiGetEMACRxData( unsigned char *ucBuffer )
153
{
154
static unsigned long ulNextRxBuffer = 0;
155
unsigned int iLen;
156
 
157
        iLen = ulRxLength[ ulNextRxBuffer ];
158
 
159
        if( iLen != 0 )
160
        {
161
                /* Leave room for the size at the start of the buffer. */
162
                uip_buf = &( uxRxBuffers.ucRxBuffers[ ulNextRxBuffer ][ 2 ] );
163
 
164
                ulRxLength[ ulNextRxBuffer ] = 0;
165
 
166
                ulNextRxBuffer++;
167
                if( ulNextRxBuffer >= emacNUM_RX_BUFFERS )
168
                {
169
                        ulNextRxBuffer = 0;
170
                }
171
        }
172
 
173
    return iLen;
174
}
175
/*-----------------------------------------------------------*/
176
 
177
void vInitialiseSend( void )
178
{
179
        /* Set the index to the first byte to send - skipping over the size
180
        bytes. */
181
        ulNextTxSpace = 2;
182
}
183
/*-----------------------------------------------------------*/
184
 
185
void vIncrementTxLength( unsigned portLONG ulLength )
186
{
187
        ulNextTxSpace += ulLength;
188
}
189
/*-----------------------------------------------------------*/
190
 
191
void vSendBufferToMAC( void )
192
{
193
unsigned long *pulSource;
194
unsigned portSHORT * pus;
195
unsigned portLONG ulNextWord;
196
 
197
        /* Locate the data to be send. */
198
        pus = ( unsigned portSHORT * ) uip_buf;
199
 
200
        /* Add in the size of the data. */
201
        pus--;
202
        *pus = ulNextTxSpace;
203
 
204
        /* Wait for data to be sent if there is no space immediately. */
205
    while( !EthernetSpaceAvail( ETH_BASE ) )
206
    {
207
                vTaskDelay( macWAIT_SEND_TIME );
208
    }
209
 
210
        pulSource = ( unsigned portLONG * ) pus;
211
 
212
        for( ulNextWord = 0; ulNextWord < ulNextTxSpace; ulNextWord += sizeof( unsigned portLONG ) )
213
        {
214
        HWREG(ETH_BASE + MAC_O_DATA) = *pulSource;
215
                pulSource++;
216
        }
217
 
218
        /* Go. */
219
    HWREG( ETH_BASE + MAC_O_TR ) = MAC_TR_NEWTX;
220
}
221
/*-----------------------------------------------------------*/
222
 
223
void vEMAC_ISR( void )
224
{
225
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
226
unsigned portLONG ulTemp;
227
 
228
        /* Clear the interrupt. */
229
        ulTemp = EthernetIntStatus( ETH_BASE, pdFALSE );
230
        EthernetIntClear( ETH_BASE, ulTemp );
231
 
232
        /* Was it an Rx interrupt? */
233
        if( ulTemp & ETH_INT_RX )
234
        {
235
                xSemaphoreGiveFromISR( xMACInterruptSemaphore, &xHigherPriorityTaskWoken );
236
                EthernetIntDisable( ETH_BASE, ETH_INT_RX );
237
        }
238
 
239
    /* Switch to the uIP task. */
240
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
241
}
242
/*-----------------------------------------------------------*/
243
 
244
void vMACHandleTask( void *pvParameters )
245
{
246
unsigned long i, ulInt;
247
unsigned portLONG ulLength;
248
unsigned long *pulBuffer;
249
static unsigned portLONG ulNextRxBuffer = 0;
250
 
251
        for( ;; )
252
        {
253
                /* Wait for something to do. */
254
                xSemaphoreTake( xMACInterruptSemaphore, portMAX_DELAY );
255
 
256
                while( ( ulInt = ( EthernetIntStatus( ETH_BASE, pdFALSE ) & ETH_INT_RX ) ) != 0 )
257
                {
258
                        ulLength = HWREG( ETH_BASE + MAC_O_DATA );
259
 
260
                        /* Leave room at the start of the buffer for the size. */
261
                        pulBuffer = ( unsigned long * ) &( uxRxBuffers.ucRxBuffers[ ulNextRxBuffer ][ 2 ] );
262
                        *pulBuffer = ( ulLength >> 16 );
263
 
264
                        /* Get the size of the data. */
265
                        pulBuffer = ( unsigned long * ) &( uxRxBuffers.ucRxBuffers[ ulNextRxBuffer ][ 4 ] );
266
                        ulLength &= 0xFFFF;
267
 
268
                        if( ulLength > 4 )
269
                        {
270
                                ulLength -= 4;
271
 
272
                                if( ulLength >= UIP_BUFSIZE )
273
                                {
274
                                        /* The data won't fit in our buffer.  Ensure we don't
275
                                        try to write into the buffer. */
276
                                        ulLength = 0;
277
                                }
278
 
279
                                /* Read out the data into our buffer. */
280
                                for( i = 0; i < ulLength; i += sizeof( unsigned portLONG ) )
281
                                {
282
                                        *pulBuffer = HWREG( ETH_BASE + MAC_O_DATA );
283
                                        pulBuffer++;
284
                                }
285
 
286
                                /* Store the length of the data into the separate array. */
287
                                ulRxLength[ ulNextRxBuffer ] = ulLength;
288
 
289
                                /* Use the next buffer the next time through. */
290
                                ulNextRxBuffer++;
291
                                if( ulNextRxBuffer >= emacNUM_RX_BUFFERS )
292
                                {
293
                                        ulNextRxBuffer = 0;
294
                                }
295
 
296
                                /* Ensure the uIP task is not blocked as data has arrived. */
297
                                xSemaphoreGive( xEMACSemaphore );
298
                        }
299
                }
300
 
301
                EthernetIntEnable( ETH_BASE, ETH_INT_RX );
302
 
303
                ( void ) ulInt;
304
        }
305
}
306
 

powered by: WebSVN 2.1.0

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