📄 enet_freertos.c
字号:
PORTA_PCR29 = PORT_PCR_MUX(4);//MII0_COL
#else
PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV
#if 0
PORTA_PCR5 = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER
#else
PORTA_PCR5 = (0|PORT_PCR_MUX(1)|PORT_PCR_PE_MASK|!PORT_PCR_PS_MASK);//GPIO pull down
#endif
PORTA_PCR12 = PORT_PCR_MUX(4);//RMII0_RXD1/MII0_RXD1
PORTA_PCR13 = PORT_PCR_MUX(4);//RMII0_RXD0/MII0_RXD0
PORTA_PCR15 = PORT_PCR_MUX(4);//RMII0_TXEN/MII0_TXEN
PORTA_PCR16 = PORT_PCR_MUX(4);//RMII0_TXD0/MII0_TXD0
PORTA_PCR17 = PORT_PCR_MUX(4);//RMII0_TXD1/MII0_TXD1
#endif
/* Can we talk to the PHY? */
do
{
vTaskDelay( enetLINK_DELAY );
usData = 0xffff;
mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &usData );
} while( usData == 0xffff );
/* Start auto negotiate. */
mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
/* Wait for auto negotiate to complete. */
do
{
vTaskDelay( enetLINK_DELAY );
mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &usData );
} while( !( usData & PHY_BMSR_AN_COMPLETE ) );
/* When we get here we have a link - find out what has been negotiated. */
usData = 0;
mii_read( 0, configPHY_ADDRESS, PHY_STATUS, &usData );
/* Clear the Individual and Group Address Hash registers */
ENET_IALR = 0;
ENET_IAUR = 0;
ENET_GALR = 0;
ENET_GAUR = 0;
/* Set the Physical Address for the selected ENET */
enet_set_address( 0, ucMACAddress );
#if configUSE_MII_MODE
/* Various mode/status setup. */
ENET_RCR = ENET_RCR_MAX_FL(configENET_BUFFER_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK;
#else
ENET_RCR = ENET_RCR_MAX_FL(configENET_BUFFER_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;
#endif
/*FSL: clear rx/tx control registers*/
ENET_TCR = 0;
/* Setup half or full duplex. */
if( usData & PHY_DUPLEX_STATUS )
{
/*Full duplex*/
ENET_RCR &= (unsigned portLONG)~ENET_RCR_DRT_MASK;
ENET_TCR |= ENET_TCR_FDEN_MASK;
}
else
{
/*half duplex*/
ENET_RCR |= ENET_RCR_DRT_MASK;
ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK;
}
/* Setup speed */
if( usData & PHY_SPEED_STATUS )
{
/*10Mbps*/
ENET_RCR |= ENET_RCR_RMII_10T_MASK;
}
#if( configUSE_PROMISCUOUS_MODE == 1 )
{
ENET_RCR |= ENET_RCR_PROM_MASK;
}
#endif
#ifdef ENHANCED_BD
ENET_ECR = ENET_ECR_EN1588_MASK;
#else
ENET_ECR = 0;
#endif
/* Set Rx Buffer Size */
ENET_MRBR = (unsigned portSHORT) configENET_BUFFER_SIZE;
/* Point to the start of the circular Rx buffer descriptor queue */
ENET_RDSR = ( unsigned portLONG ) &( xENETRxDescriptors[ 0 ] );
/* Point to the start of the circular Tx buffer descriptor queue */
ENET_TDSR = ( unsigned portLONG ) pxENETTxDescriptor;
/* Clear all ENET interrupt events */
ENET_EIR = ( unsigned portLONG ) -1;
/* Enable interrupts. */
ENET_EIMR = ENET_EIR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_RXB_MASK | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK;
/* Enable the MAC itself. */
ENET_ECR |= ENET_ECR_ETHEREN_MASK;
/* Indicate that there have been empty receive buffers produced */
ENET_RDAR = ENET_RDAR_RDAR_MASK;
#if 0
enet_debug_dump();
#endif
}
/*-----------------------------------------------------------*/
unsigned portLONG ulENETRx( void )
{
unsigned portLONG ulLen = 0UL;
/* Is a buffer ready? */
if( ( xENETRxDescriptors[ uxNextRxBuffer ].status & RX_BD_E ) == 0 )
{
/* Obtain the size of the packet and put it into the "len" variable. */
#ifdef NBUF_LITTLE_ENDIAN
ulLen = __REVSH(xENETRxDescriptors[ uxNextRxBuffer ].length);
uip_buf = (uint8_t *)__REV((uint32_t)xENETRxDescriptors[ uxNextRxBuffer ].data);
//not required by uIP
#ifdef ENHANCED_BD
//__REV(xENETRxDescriptors[ uxNextRxBuffer ].timestamp);
//__REVSH(xENETRxDescriptors[ uxNextRxBuffer ].length_proto_type);
//__REVSH(xENETRxDescriptors[ uxNextRxBuffer ].payload_checksum);
#endif
#else
ulLen = xENETRxDescriptors[ uxNextRxBuffer ].length;
uip_buf = xENETRxDescriptors[ uxNextRxBuffer ].data;
//not required by uIP
#ifdef ENHANCED_BD
//xENETRxDescriptors[ uxNextRxBuffer ].timestamp;
//xENETRxDescriptors[ uxNextRxBuffer ].length_proto_type;
//xENETRxDescriptors[ uxNextRxBuffer ].payload_checksum;
#endif
#endif
//not required by uIP
#ifdef ENHANCED_BD
//xENETRxDescriptors[ uxNextRxBuffer ].ebd_status;
#endif
/* Doing this here could cause corruption! */
xENETRxDescriptors[ uxNextRxBuffer ].status |= RX_BD_E;
portENTER_CRITICAL();
{
uxNextRxBuffer++;
if( uxNextRxBuffer >= configNUM_ENET_RX_BUFFERS )
{
uxNextRxBuffer = 0;
}
}
portEXIT_CRITICAL();
/* Make sure the Tx is not using the next buffer before letting the DMA
know the buffer is available. */
while( xENETRxDescriptors[ uxNextRxBuffer ].data == pxENETTxDescriptor->data )
{
vTaskDelay( enetMINIMAL_DELAY );
}
ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
return ulLen;
}
/*-----------------------------------------------------------*/
void vENETTx( void )
{
/* When we get here the Tx descriptor should show as having completed. */
while( pxENETTxDescriptor->status & TX_BD_R )
{
vTaskDelay( enetMINIMAL_DELAY );
}
portENTER_CRITICAL();
{
#ifdef NBUF_LITTLE_ENDIAN
/* To maintain the zero copy implementation, point the Tx descriptor
to the data from the Rx buffer. */
pxENETTxDescriptor->data = (uint8_t *)__REV((uint32_t)uip_buf);
/* Setup the buffer descriptor for transmission */
pxENETTxDescriptor->length = __REVSH(uip_len);
#else
/* To maintain the zero copy implementation, point the Tx descriptor
to the data from the Rx buffer. */
pxENETTxDescriptor->data = uip_buf;
/* Setup the buffer descriptor for transmission */
pxENETTxDescriptor->length = uip_len;
#endif
#ifdef ENHANCED_BD
pxENETTxDescriptor->bdu = 0x00000000;
pxENETTxDescriptor->ebd_status = TX_BD_INT | TX_BD_TS;// | TX_BD_IINS | TX_BD_PINS;
#endif
/* NB this assumes only one Tx descriptor! */
pxENETTxDescriptor->status = ( TX_BD_R | TX_BD_L | TX_BD_TC | TX_BD_W );
}
portEXIT_CRITICAL();
/* Continue the Tx DMA task (in case it was waiting for a new TxBD) */
ENET_TDAR = ENET_TDAR_TDAR_MASK;
}
/*-----------------------------------------------------------*/
void vENETISRHandler( void )
{
unsigned portLONG ulEvent;
portBASE_TYPE xHighPriorityTaskWoken = pdFALSE;
/* Determine the cause of the interrupt. */
ulEvent = ENET_EIR & ENET_EIMR;
ENET_EIR = ulEvent;
if( ulEvent & ENET_EIR_RXF_MASK )
{
/* A packet has been received. Wake the handler task in case it is
blocked. */
xSemaphoreGiveFromISR( xENETSemaphore, &xHighPriorityTaskWoken );
}
if( ulEvent & ENET_EIR_TXF_MASK )
{
/* The Tx has completed. Mark the data pointer as NULL so the uIP
task knows the Rx buffer to which it was pointing is now free again. */
pxENETTxDescriptor->data = NULL;
}
if (ulEvent & ( ENET_EIR_UN_MASK | ENET_EIR_RL_MASK | ENET_EIR_LC_MASK | ENET_EIR_EBERR_MASK | ENET_EIR_BABT_MASK | ENET_EIR_BABR_MASK | ENET_EIR_EBERR_MASK ) )
{
/* Sledge hammer error handling. */
prvInitialiseENETBuffers();
ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
portEND_SWITCHING_ISR( xHighPriorityTaskWoken );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -