mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Tidy up Ethernet driver.
This commit is contained in:
parent
b92dd21bc5
commit
0cc071f88a
|
@ -55,7 +55,9 @@
|
|||
/* Demo application includes. */
|
||||
#include "partest.h"
|
||||
|
||||
#define partstFIRST_IO ( ( unsigned portLONG ) 0x04 )
|
||||
#define partstFIRST_IO ( ( unsigned long ) 0x04 )
|
||||
#define partstFIO2_BITS ( ( unsigned long ) 0x0000007C )
|
||||
#define partstFIO1_BITS ( ( unsigned long ) 0xB0000000 )
|
||||
#define partstNUM_LEDS ( 5 )
|
||||
#define partstALL_OUTPUTS_OFF ( ( unsigned portLONG ) 0xff )
|
||||
|
||||
|
@ -65,13 +67,13 @@
|
|||
|
||||
void vParTestInitialise( void )
|
||||
{
|
||||
PINSEL10 = 0;
|
||||
FIO2DIR = 0x000000FF;
|
||||
FIO2MASK = 0x00000000;
|
||||
FIO2CLR = 0xFF;
|
||||
SCS |= (1<<0); //fast mode for port 0 and 1
|
||||
/* LEDs on ports 1 and 2 to output. */
|
||||
FIO2DIR = partstFIO2_BITS;
|
||||
FIO1DIR = partstFIO1_BITS;
|
||||
|
||||
FIO2CLR = partstALL_OUTPUTS_OFF;
|
||||
/* Start will all LEDs off. */
|
||||
FIO1CLR = partstFIO1_BITS;
|
||||
FIO2CLR = partstFIO2_BITS;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
<Project>
|
||||
<ProjectSessionItem path="RTOSDemo" name="unnamed" />
|
||||
<ProjectSessionItem path="RTOSDemo;RTOSDemo" name="unnamed" />
|
||||
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files" name="unnamed" />
|
||||
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;Common Demo Tasks" name="unnamed" />
|
||||
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;FreeRTOS" name="unnamed" />
|
||||
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;WEB Server" name="unnamed" />
|
||||
</Project>
|
||||
<Register1>
|
||||
<RegisterWindow openNodes="CPU;CPU/xPSR;CPU/CFBP;CPU/CFBP/CONTROL[0];CPU/CFBP/CONTROL[1]" binaryNodes="" unsignedNodes="" visibleGroups="CPU" decimalNodes="" octalNodes="" asciiNodes="" />
|
||||
|
@ -52,12 +48,7 @@
|
|||
<Watches active="0" update="Never" />
|
||||
</Watch4>
|
||||
<Files>
|
||||
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\emac.c" y="523" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\emac.c" left="0" selected="0" name="unnamed" top="489" />
|
||||
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" y="172" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" left="0" selected="1" name="unnamed" top="355" />
|
||||
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\uIP_Task.c" y="166" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\uIP_Task.c" left="0" selected="0" name="unnamed" top="138" />
|
||||
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="8" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\EthDev_LPC17xx.h" y="277" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver\EthDev_LPC17xx.h" left="0" selected="0" name="unnamed" top="13" />
|
||||
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Source\queue.c" y="1049" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Source\queue.c" left="0" selected="0" name="unnamed" top="1027" />
|
||||
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\Common\Minimal\integer.c" y="155" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\Common\Minimal\integer.c" left="0" selected="0" name="unnamed" top="133" />
|
||||
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="28" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" y="15" path="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\main.c" left="0" selected="1" name="unnamed" top="10" />
|
||||
</Files>
|
||||
<ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="Amontec JTAGkey" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_GCC_Rowley\webserver" fileDialogDefaultFilter="*.*" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
|
||||
</session>
|
||||
|
|
|
@ -165,8 +165,6 @@ static void vLCDTask( void *pvParameters );
|
|||
/* The queue used to send messages to the LCD task. */
|
||||
xQueueHandle xLCDQueue;
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int main( void )
|
||||
|
@ -186,7 +184,6 @@ long l;
|
|||
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
|
||||
vStartQueuePeekTasks();
|
||||
vStartRecursiveMutexTasks();
|
||||
|
||||
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
|
||||
|
||||
/* Create the uIP task. The WEB server runs in this task. */
|
||||
|
@ -356,10 +353,8 @@ void prvSetupHardware( void )
|
|||
/* Setup the peripheral bus to be the same as the PLL output (64 MHz). */
|
||||
PCLKSEL0 = 0x05555555;
|
||||
|
||||
/* Configure LED GPIOs as outputs. */
|
||||
FIO2DIR = 0xff;
|
||||
FIO2CLR = 0xff;
|
||||
FIO2MASK = 0;
|
||||
/* Configure the LEDs. */
|
||||
vParTestInitialise();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -90,20 +90,22 @@ typedef struct {
|
|||
EthDev_STATUS (*LinkChk) (void);
|
||||
} EthDev_IOB;
|
||||
|
||||
// prototypes
|
||||
portBASE_TYPE Init_EMAC(void);
|
||||
unsigned short ReadFrameBE_EMAC(void);
|
||||
void CopyToFrame_EMAC(void *Source, unsigned int Size);
|
||||
void CopyFromFrame_EMAC(void *Dest, unsigned short Size);
|
||||
void DummyReadFrame_EMAC(unsigned short Size);
|
||||
unsigned short StartReadFrame(void);
|
||||
void EndReadFrame(void);
|
||||
unsigned int CheckFrameReceived(void);
|
||||
void RequestSend(void);
|
||||
unsigned int Rdy4Tx(void);
|
||||
void DoSend_EMAC(unsigned short FrameSize);
|
||||
void vEMACWaitForInput( void );
|
||||
|
||||
/*
|
||||
* Look for received data. If data is found then uip_buf is assigned to the
|
||||
* new data and the length of the data is returned. If no data is found then
|
||||
* uip_buf is not updated and 0 is returned.
|
||||
*/
|
||||
unsigned long ulGetEMACRxData( void );
|
||||
|
||||
/*
|
||||
* Send usTxDataLen bytes from uip_buf.
|
||||
*/
|
||||
void vSendEMACTxData( unsigned short usTxDataLen );
|
||||
|
||||
/*
|
||||
* Prepare the Ethernet hardware ready for TCP/IP comms.
|
||||
*/
|
||||
long lEMACInit(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,34 +1,76 @@
|
|||
/******************************************************************
|
||||
***** *****
|
||||
***** Ver.: 1.0 *****
|
||||
***** Date: 07/05/2001 *****
|
||||
***** Auth: Andreas Dannenberg *****
|
||||
***** HTWK Leipzig *****
|
||||
***** university of applied sciences *****
|
||||
***** Germany *****
|
||||
***** Func: ethernet packet-driver for use with LAN- *****
|
||||
***** controller CS8900 from Crystal/Cirrus Logic *****
|
||||
***** *****
|
||||
***** Keil: Module modified for use with Philips *****
|
||||
***** LPC2378 EMAC Ethernet controller *****
|
||||
***** *****
|
||||
******************************************************************/
|
||||
/*
|
||||
FreeRTOS.org V5.3.1 - Copyright (C) 2003-2009 Richard Barry.
|
||||
|
||||
/* Adapted from file originally written by Andreas Dannenberg. Supplied with permission. */
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License (version 2) as published
|
||||
by the Free Software Foundation and modified by the FreeRTOS exception.
|
||||
**NOTE** The exception to the GPL is included to allow you to distribute a
|
||||
combined work that includes FreeRTOS.org without being obliged to provide
|
||||
the source code for any proprietary components. Alternative commercial
|
||||
license and support terms are also available upon request. See the
|
||||
licensing section of http://www.FreeRTOS.org for full details.
|
||||
|
||||
FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
|
||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* This is a concise, step by step, 'hands on' guide that describes both *
|
||||
* general multitasking concepts and FreeRTOS specifics. It presents and *
|
||||
* explains numerous examples that are written using the FreeRTOS API. *
|
||||
* Full source code for all the examples is provided in an accompanying *
|
||||
* .zip file. *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||
contact details.
|
||||
|
||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||
critical systems.
|
||||
|
||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||
licensing and training services.
|
||||
*/
|
||||
|
||||
/* Originally adapted from file written by Andreas Dannenberg. Supplied with permission. */
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Hardware specific includes. */
|
||||
#include "LPC17xx_defs.h"
|
||||
#include "EthDev_LPC17xx.h"
|
||||
|
||||
#define emacPINSEL2_VALUE 0x50150105
|
||||
|
||||
/* Time to wait between each inspection of the link status. */
|
||||
#define emacWAIT_FOR_LINK_TO_ESTABLISH ( 500 / portTICK_RATE_MS )
|
||||
|
||||
/* Short delay used in several places during the initialisation process. */
|
||||
#define emacSHORT_DELAY ( 2 )
|
||||
|
||||
/* Hardware specific bit definitions. */
|
||||
#define emacLINK_ESTABLISHED ( 0x0001 )
|
||||
#define emacFULL_DUPLEX_ENABLED ( 0x0004 )
|
||||
#define emac10BASE_T_MODE ( 0x0002 )
|
||||
#define emacPINSEL2_VALUE 0x50150105
|
||||
|
||||
/* If no buffers are available, then wait this long before looking again.... */
|
||||
#define emacBUFFER_WAIT_DELAY ( 3 / portTICK_RATE_MS )
|
||||
|
@ -36,24 +78,63 @@
|
|||
/* ...and don't look more than this many times. */
|
||||
#define emacBUFFER_WAIT_ATTEMPTS ( 30 )
|
||||
|
||||
/* Index to the Tx descriptor that is always used first for every Tx. The second
|
||||
descriptor is then used to re-send in order to speed up the uIP Tx process. */
|
||||
#define emacTX_DESC_INDEX ( 0 )
|
||||
|
||||
/* The semaphore used to wake the uIP task when data arives. */
|
||||
extern xSemaphoreHandle xEMACSemaphore;
|
||||
|
||||
static unsigned short *rptr;
|
||||
static unsigned short *tptr;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Configure both the Rx and Tx descriptors during the init process.
|
||||
*/
|
||||
static void prvInitDescriptors( void );
|
||||
|
||||
/*
|
||||
* Setup the IO and peripherals required for Ethernet communication.
|
||||
*/
|
||||
static void prvSetupEMACHardware( void );
|
||||
|
||||
/*
|
||||
* Control the auto negotiate process.
|
||||
*/
|
||||
static void prvConfigurePHY( void );
|
||||
|
||||
/*
|
||||
* Wait for a link to be established, then setup the PHY according to the link
|
||||
* parameters.
|
||||
*/
|
||||
static long prvSetupLinkStatus( void );
|
||||
|
||||
/*
|
||||
* Search the pool of buffers to find one that is free. If a buffer is found
|
||||
* mark it as in use before returning its address.
|
||||
*/
|
||||
static unsigned char *prvGetNextBuffer( void );
|
||||
|
||||
/*
|
||||
* Return an allocated buffer to the pool of free buffers.
|
||||
*/
|
||||
static void prvReturnBuffer( unsigned char *pucBuffer );
|
||||
|
||||
/* Each ucBufferInUse index corresponds to a position in the same index in the
|
||||
ucMACBuffers array. If the index contains a 1 then the buffer within
|
||||
ucMACBuffers is in use, if it contains a 0 then the buffer is free. */
|
||||
/*
|
||||
* Send lValue to the lPhyReg within the PHY.
|
||||
*/
|
||||
static long prvWritePHY( long lPhyReg, long lValue );
|
||||
|
||||
/*
|
||||
* Read a value from ucPhyReg within the PHY. *plStatus will be set to
|
||||
* pdFALSE if there is an error.
|
||||
*/
|
||||
static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The semaphore used to wake the uIP task when data arrives. */
|
||||
extern xSemaphoreHandle xEMACSemaphore;
|
||||
|
||||
/* Each ucBufferInUse index corresponds to a position in the pool of buffers.
|
||||
If the index contains a 1 then the buffer within pool is in use, if it
|
||||
contains a 0 then the buffer is free. */
|
||||
static unsigned char ucBufferInUse[ ETH_NUM_BUFFERS ] = { pdFALSE };
|
||||
|
||||
/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers
|
||||
|
@ -66,64 +147,59 @@ static unsigned short usSendLen = 0;
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int write_PHY( long lPhyReg, long lValue )
|
||||
long lEMACInit( void )
|
||||
{
|
||||
const long lMaxTime = 10;
|
||||
long x;
|
||||
long lReturn = pdPASS;
|
||||
volatile unsigned long regv, tout;
|
||||
unsigned long ulID1, ulID2;
|
||||
|
||||
MAC_MADR = DP83848C_DEF_ADR | lPhyReg;
|
||||
MAC_MWTD = lValue;
|
||||
/* Reset peripherals, configure port pins and registers. */
|
||||
prvSetupEMACHardware();
|
||||
|
||||
x = 0;
|
||||
for( x = 0; x < lMaxTime; x++ )
|
||||
/* Check the PHY part number is as expected. */
|
||||
ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn );
|
||||
ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn );
|
||||
if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) == DP83848C_ID )
|
||||
{
|
||||
if( ( MAC_MIND & MIND_BUSY ) == 0 )
|
||||
{
|
||||
/* Operation has finished. */
|
||||
break;
|
||||
}
|
||||
/* Set the Ethernet MAC Address registers */
|
||||
MAC_SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1;
|
||||
MAC_SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3;
|
||||
MAC_SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5;
|
||||
|
||||
vTaskDelay( emacSHORT_DELAY );
|
||||
}
|
||||
/* Initialize Tx and Rx DMA Descriptors */
|
||||
prvInitDescriptors();
|
||||
|
||||
if( x < lMaxTime )
|
||||
{
|
||||
return pdPASS;
|
||||
/* Receive broadcast and perfect match packets */
|
||||
MAC_RXFILTERCTRL = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
|
||||
|
||||
/* Setup the PHY. */
|
||||
prvConfigurePHY();
|
||||
}
|
||||
else
|
||||
{
|
||||
return pdFAIL;
|
||||
lReturn = pdFAIL;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
unsigned short read_PHY( unsigned char ucPhyReg, long *plStatus )
|
||||
{
|
||||
long x;
|
||||
const long lMaxTime = 10;
|
||||
|
||||
MAC_MADR = DP83848C_DEF_ADR | ucPhyReg;
|
||||
MAC_MCMD = MCMD_READ;
|
||||
|
||||
for( x = 0; x < lMaxTime; x++ )
|
||||
/* Check the link status. */
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
/* Operation has finished. */
|
||||
if( ( MAC_MIND & MIND_BUSY ) == 0 )
|
||||
lReturn = prvSetupLinkStatus();
|
||||
}
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
break;
|
||||
/* Initialise uip_buf to ensure it points somewhere valid. */
|
||||
uip_buf = prvGetNextBuffer();
|
||||
|
||||
/* Reset all interrupts */
|
||||
MAC_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 );
|
||||
|
||||
/* Enable receive and transmit mode of MAC Ethernet core */
|
||||
MAC_COMMAND |= ( CR_RX_EN | CR_TX_EN );
|
||||
MAC_MAC1 |= MAC1_REC_EN;
|
||||
}
|
||||
|
||||
vTaskDelay( emacSHORT_DELAY );
|
||||
}
|
||||
|
||||
MAC_MCMD = 0;
|
||||
|
||||
if( x >= lMaxTime )
|
||||
{
|
||||
*plStatus = pdFAIL;
|
||||
}
|
||||
|
||||
return( MAC_MRDD );
|
||||
return lReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -246,14 +322,14 @@ long x, lDummy;
|
|||
MAC_SUPP = 0;
|
||||
|
||||
/* Put the PHY in reset mode */
|
||||
write_PHY( PHY_REG_BMCR, MCFG_RES_MII );
|
||||
write_PHY( PHY_REG_BMCR, MCFG_RES_MII );
|
||||
prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );
|
||||
prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );
|
||||
|
||||
/* Wait for hardware reset to end. */
|
||||
for( x = 0; x < 100; x++ )
|
||||
{
|
||||
vTaskDelay( emacSHORT_DELAY * 5 );
|
||||
us = read_PHY( PHY_REG_BMCR, &lDummy );
|
||||
us = prvReadPHY( PHY_REG_BMCR, &lDummy );
|
||||
if( !( us & MCFG_RES_MII ) )
|
||||
{
|
||||
/* Reset complete */
|
||||
|
@ -269,13 +345,13 @@ unsigned short us;
|
|||
long x, lDummy;
|
||||
|
||||
/* Auto negotiate the configuration. */
|
||||
if( write_PHY( PHY_REG_BMCR, PHY_AUTO_NEG ) )
|
||||
if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) )
|
||||
{
|
||||
vTaskDelay( emacSHORT_DELAY * 5 );
|
||||
|
||||
for( x = 0; x < 10; x++ )
|
||||
{
|
||||
us = read_PHY( PHY_REG_BMSR, &lDummy );
|
||||
us = prvReadPHY( PHY_REG_BMSR, &lDummy );
|
||||
|
||||
if( us & PHY_AUTO_NEG_COMPLETE )
|
||||
{
|
||||
|
@ -293,9 +369,10 @@ static long prvSetupLinkStatus( void )
|
|||
long lReturn = pdFAIL, x;
|
||||
unsigned short usLinkStatus;
|
||||
|
||||
/* Wait with timeout for the link to be established. */
|
||||
for( x = 0; x < 10; x++ )
|
||||
{
|
||||
usLinkStatus = read_PHY( PHY_REG_STS, &lReturn );
|
||||
usLinkStatus = prvReadPHY( PHY_REG_STS, &lReturn );
|
||||
if( usLinkStatus & emacLINK_ESTABLISHED )
|
||||
{
|
||||
/* Link is established. */
|
||||
|
@ -339,62 +416,6 @@ unsigned short usLinkStatus;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
long Init_EMAC( void )
|
||||
{
|
||||
long lReturn = pdPASS;
|
||||
volatile unsigned long regv, tout;
|
||||
unsigned long ulID1, ulID2;
|
||||
|
||||
/* Reset peripherals, configure port pins and registers. */
|
||||
prvSetupEMACHardware();
|
||||
|
||||
/* Check if connected to a DP83848C PHY. */
|
||||
ulID1 = read_PHY( PHY_REG_IDR1, &lReturn );
|
||||
ulID2 = read_PHY( PHY_REG_IDR2, &lReturn );
|
||||
if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) == DP83848C_ID )
|
||||
{
|
||||
/* Set the Ethernet MAC Address registers */
|
||||
MAC_SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1;
|
||||
MAC_SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3;
|
||||
MAC_SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5;
|
||||
|
||||
/* Initialize Tx and Rx DMA Descriptors */
|
||||
prvInitDescriptors();
|
||||
|
||||
/* Receive Broadcast and Perfect Match Packets */
|
||||
MAC_RXFILTERCTRL = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
|
||||
|
||||
/* Setup the PHY. */
|
||||
prvConfigurePHY();
|
||||
}
|
||||
else
|
||||
{
|
||||
lReturn = pdFAIL;
|
||||
}
|
||||
|
||||
/* Check the link status. */
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
lReturn = prvSetupLinkStatus();
|
||||
}
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
/* Initialise uip_buf to ensure it points somewhere valid. */
|
||||
uip_buf = prvGetNextBuffer();
|
||||
|
||||
/* Reset all interrupts */
|
||||
MAC_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 );
|
||||
|
||||
/* Enable receive and transmit mode of MAC Ethernet core */
|
||||
MAC_COMMAND |= ( CR_RX_EN | CR_TX_EN );
|
||||
MAC_MAC1 |= MAC1_REC_EN;
|
||||
}
|
||||
|
||||
return lReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvReturnBuffer( unsigned char *pucBuffer )
|
||||
{
|
||||
unsigned long ul;
|
||||
|
@ -480,10 +501,66 @@ unsigned long ulAttempts = 0UL;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static long prvWritePHY( long lPhyReg, long lValue )
|
||||
{
|
||||
const long lMaxTime = 10;
|
||||
long x;
|
||||
|
||||
static char c[ 256 ] = { 0 };
|
||||
static int i = 0;
|
||||
MAC_MADR = DP83848C_DEF_ADR | lPhyReg;
|
||||
MAC_MWTD = lValue;
|
||||
|
||||
x = 0;
|
||||
for( x = 0; x < lMaxTime; x++ )
|
||||
{
|
||||
if( ( MAC_MIND & MIND_BUSY ) == 0 )
|
||||
{
|
||||
/* Operation has finished. */
|
||||
break;
|
||||
}
|
||||
|
||||
vTaskDelay( emacSHORT_DELAY );
|
||||
}
|
||||
|
||||
if( x < lMaxTime )
|
||||
{
|
||||
return pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pdFAIL;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus )
|
||||
{
|
||||
long x;
|
||||
const long lMaxTime = 10;
|
||||
|
||||
MAC_MADR = DP83848C_DEF_ADR | ucPhyReg;
|
||||
MAC_MCMD = MCMD_READ;
|
||||
|
||||
for( x = 0; x < lMaxTime; x++ )
|
||||
{
|
||||
/* Operation has finished. */
|
||||
if( ( MAC_MIND & MIND_BUSY ) == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
vTaskDelay( emacSHORT_DELAY );
|
||||
}
|
||||
|
||||
MAC_MCMD = 0;
|
||||
|
||||
if( x >= lMaxTime )
|
||||
{
|
||||
*plStatus = pdFAIL;
|
||||
}
|
||||
|
||||
return( MAC_MRDD );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vEMAC_ISR( void )
|
||||
{
|
||||
|
@ -505,8 +582,6 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
|||
{
|
||||
if( usSendLen > 0 )
|
||||
{
|
||||
if( i < 255 )
|
||||
c[ i++ ] = 1;
|
||||
/* Send the data again, using the second descriptor. As there are
|
||||
only two descriptors the index is set back to 0. */
|
||||
TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );
|
||||
|
@ -519,9 +594,6 @@ if( i < 255 )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( i < 255 )
|
||||
c[ i++ ] = 1;
|
||||
|
||||
/* The Tx buffer is no longer required. */
|
||||
prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
|
||||
TX_DESC_PACKET( emacTX_DESC_INDEX ) = NULL;
|
||||
|
|
|
@ -137,7 +137,7 @@ extern void ( vEMAC_ISR_Wrapper )( void );
|
|||
vSemaphoreCreateBinary( xEMACSemaphore );
|
||||
|
||||
/* Initialise the MAC. */
|
||||
while( Init_EMAC() != pdPASS )
|
||||
while( lEMACInit() != pdPASS )
|
||||
{
|
||||
vTaskDelay( uipINIT_WAIT );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue