⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enet_freertos.c

📁 freescale k40/k60 freertos-uip 例程
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -