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

Subversion Repositories openrisc

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

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 char *uip_buf;
97
 
98
/* Buffers into which Rx data is placed. */
99
static unsigned char ucRxBuffers[ emacNUM_RX_BUFFERS ][ UIP_BUFSIZE + ( 4 * emacFRAM_SIZE_BYTES ) ] __attribute__((aligned(4)));
100
 
101
/* The length of the data within each of the Rx buffers. */
102
static unsigned long ulRxLength[ emacNUM_RX_BUFFERS ];
103
 
104
/* Used to keep a track of the number of bytes to transmit. */
105
static unsigned long ulNextTxSpace;
106
 
107
/*-----------------------------------------------------------*/
108
 
109
portBASE_TYPE vInitEMAC( void )
110
{
111
unsigned long ulTemp;
112
portBASE_TYPE xReturn;
113
 
114
        /* Ensure all interrupts are disabled. */
115
        EthernetIntDisable( ETH_BASE, ( ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER | ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER | ETH_INT_RX));
116
 
117
        /* Clear any interrupts that were already pending. */
118
    ulTemp = EthernetIntStatus( ETH_BASE, pdFALSE );
119
    EthernetIntClear( ETH_BASE, ulTemp );
120
 
121
        /* Initialise the MAC and connect. */
122
    EthernetInit( ETH_BASE );
123
    EthernetConfigSet( ETH_BASE, ( ETH_CFG_TX_DPLXEN | ETH_CFG_TX_CRCEN | ETH_CFG_TX_PADEN ) );
124
    EthernetEnable( ETH_BASE );
125
 
126
        /* Mark each Rx buffer as empty. */
127
        for( ulTemp = 0; ulTemp < emacNUM_RX_BUFFERS; ulTemp++ )
128
        {
129
                ulRxLength[ ulTemp ] = 0;
130
        }
131
 
132
        /* Create the queue and task used to defer the MAC processing to the
133
        task level. */
134
        vSemaphoreCreateBinary( xMACInterruptSemaphore );
135
        xSemaphoreTake( xMACInterruptSemaphore, 0 );
136
        xReturn = xTaskCreate( vMACHandleTask, ( signed char * ) "MAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
137
        vTaskDelay( macNEGOTIATE_DELAY );
138
 
139
        /* We are only interested in Rx interrupts. */
140
        IntPrioritySet( INT_ETH, configKERNEL_INTERRUPT_PRIORITY );
141
    IntEnable( INT_ETH );
142
    EthernetIntEnable(ETH_BASE, ETH_INT_RX);
143
 
144
        return xReturn;
145
}
146
/*-----------------------------------------------------------*/
147
 
148
unsigned int uiGetEMACRxData( unsigned char *ucBuffer )
149
{
150
static unsigned long ulNextRxBuffer = 0;
151
unsigned int iLen;
152
 
153
        iLen = ulRxLength[ ulNextRxBuffer ];
154
 
155
        if( iLen != 0 )
156
        {
157
                /* Leave room for the size at the start of the buffer. */
158
                uip_buf = &( ucRxBuffers[ ulNextRxBuffer ][ 2 ] );
159
 
160
                ulRxLength[ ulNextRxBuffer ] = 0;
161
 
162
                ulNextRxBuffer++;
163
                if( ulNextRxBuffer >= emacNUM_RX_BUFFERS )
164
                {
165
                        ulNextRxBuffer = 0;
166
                }
167
        }
168
 
169
    return iLen;
170
}
171
/*-----------------------------------------------------------*/
172
 
173
void vInitialiseSend( void )
174
{
175
        /* Set the index to the first byte to send - skipping over the size
176
        bytes. */
177
        ulNextTxSpace = 2;
178
}
179
/*-----------------------------------------------------------*/
180
 
181
void vIncrementTxLength( unsigned long ulLength )
182
{
183
        ulNextTxSpace += ulLength;
184
}
185
/*-----------------------------------------------------------*/
186
 
187
void vSendBufferToMAC( void )
188
{
189
unsigned long *pulSource;
190
unsigned short * pus;
191
unsigned long ulNextWord;
192
 
193
        /* Locate the data to be send. */
194
        pus = ( unsigned short * ) uip_buf;
195
 
196
        /* Add in the size of the data. */
197
        pus--;
198
        *pus = ulNextTxSpace;
199
 
200
        /* Wait for data to be sent if there is no space immediately. */
201
    while( !EthernetSpaceAvail( ETH_BASE ) )
202
    {
203
                vTaskDelay( macWAIT_SEND_TIME );
204
    }
205
 
206
        pulSource = ( unsigned long * ) pus;
207
 
208
        for( ulNextWord = 0; ulNextWord < ulNextTxSpace; ulNextWord += sizeof( unsigned long ) )
209
        {
210
        HWREG(ETH_BASE + MAC_O_DATA) = *pulSource;
211
                pulSource++;
212
        }
213
 
214
        /* Go. */
215
    HWREG( ETH_BASE + MAC_O_TR ) = MAC_TR_NEWTX;
216
}
217
/*-----------------------------------------------------------*/
218
 
219
void vEMAC_ISR( void )
220
{
221
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
222
unsigned long ulTemp;
223
 
224
        /* Clear the interrupt. */
225
        ulTemp = EthernetIntStatus( ETH_BASE, pdFALSE );
226
        EthernetIntClear( ETH_BASE, ulTemp );
227
 
228
        /* Was it an Rx interrupt? */
229
        if( ulTemp & ETH_INT_RX )
230
        {
231
                xSemaphoreGiveFromISR( xMACInterruptSemaphore, &xHigherPriorityTaskWoken );
232
                EthernetIntDisable( ETH_BASE, ETH_INT_RX );
233
        }
234
 
235
    /* Switch to the uIP task. */
236
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
237
}
238
/*-----------------------------------------------------------*/
239
 
240
void vMACHandleTask( void *pvParameters )
241
{
242
unsigned long ulLen = 0, i;
243
unsigned long ulLength, ulInt;
244
unsigned long *pulBuffer;
245
static unsigned long ulNextRxBuffer = 0;
246
portBASE_TYPE xSwitchRequired = pdFALSE;
247
 
248
        for( ;; )
249
        {
250
                /* Wait for something to do. */
251
                xSemaphoreTake( xMACInterruptSemaphore, portMAX_DELAY );
252
 
253
                while( ( ulInt = ( EthernetIntStatus( ETH_BASE, pdFALSE ) & ETH_INT_RX ) ) != 0 )
254
                {
255
                        ulLength = HWREG( ETH_BASE + MAC_O_DATA );
256
 
257
                        /* Leave room at the start of the buffer for the size. */
258
                        pulBuffer = ( unsigned long * ) &( ucRxBuffers[ ulNextRxBuffer ][ 2 ] );
259
                        *pulBuffer = ( ulLength >> 16 );
260
 
261
                        /* Get the size of the data. */
262
                        pulBuffer = ( unsigned long * ) &( ucRxBuffers[ ulNextRxBuffer ][ 4 ] );
263
                        ulLength &= 0xFFFF;
264
 
265
                        if( ulLength > 4 )
266
                        {
267
                                ulLength -= 4;
268
 
269
                                if( ulLength >= UIP_BUFSIZE )
270
                                {
271
                                        /* The data won't fit in our buffer.  Ensure we don't
272
                                        try to write into the buffer. */
273
                                        ulLength = 0;
274
                                }
275
 
276
                                /* Read out the data into our buffer. */
277
                                for( i = 0; i < ulLength; i += sizeof( unsigned long ) )
278
                                {
279
                                        *pulBuffer = HWREG( ETH_BASE + MAC_O_DATA );
280
                                        pulBuffer++;
281
                                }
282
 
283
                                /* Store the length of the data into the separate array. */
284
                                ulRxLength[ ulNextRxBuffer ] = ulLength;
285
 
286
                                /* Use the next buffer the next time through. */
287
                                ulNextRxBuffer++;
288
                                if( ulNextRxBuffer >= emacNUM_RX_BUFFERS )
289
                                {
290
                                        ulNextRxBuffer = 0;
291
                                }
292
 
293
                                /* Ensure the uIP task is not blocked as data has arrived. */
294
                                xSemaphoreGive( xEMACSemaphore );
295
                        }
296
                }
297
 
298
                EthernetIntEnable( ETH_BASE, ETH_INT_RX );
299
        }
300
}
301
 

powered by: WebSVN 2.1.0

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