ENET on K70

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ENET on K70

1,065 Views
john71
Senior Contributor I

I have TWR-K70F120M + TWR-SER. 

The question - how to configure ENET and PHY?

The PHY on TWR-SER board is KSZ8041NL. I did the following settins

void enet_start_mii(int phy_addr)
{
    unsigned int periph_clk_mhz = 60;
    int data;


    /*FSL: start MII interface*/
    mii_init(0, periph_clk_mhz);
    
    /* Can we talk to the PHY? */
    do
    {
        data = 0xffff;
        mii_read( 0, phy_addr, PHY_PHYIDR1, &data);
    } while( data == 0xffff );
    
    /* Start auto negotiate. */
    mii_write( 0, phy_addr, PHY_BMCR, (PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE) ); 
}

Is it enough for PHY?

For ENET -  I'm not sure how to configure the module. I can configure pins

/* Enable the ENET clock. */
    SIM_SCGC2 |= SIM_SCGC2_ENET1_MASK;
 
    PORTB_PCR0  = PORT_PCR_MUX(4);//GPIO;//RMII0_MDIO/MII0_MDIO
    PORTB_PCR1  = PORT_PCR_MUX(4);//GPIO;//RMII0_MDC/MII0_MDC    

    #if configUSE_MII_MODE
    PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV
    //PORTA_PCR5  = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER
    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
    PORTA_PCR11 = PORT_PCR_MUX(4);//MII0_RXCLK
    PORTA_PCR25 = PORT_PCR_MUX(4);//MII0_TXCLK
    PORTA_PCR9  = PORT_PCR_MUX(4);//MII0_RXD3
    PORTA_PCR10 = PORT_PCR_MUX(4);//MII0_RXD2  
    PORTA_PCR28 = PORT_PCR_MUX(4);//MII0_TXER
    PORTA_PCR24 = PORT_PCR_MUX(4);//MII0_TXD2
    PORTA_PCR26 = PORT_PCR_MUX(4);//MII0_TXD3
    PORTA_PCR27 = PORT_PCR_MUX(4);//MII0_CRS
    PORTA_PCR29 = PORT_PCR_MUX(4);//MII0_COL
    #else
    PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV
    //PORTA_PCR5  = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER
    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 

But I don't know how to configure the registers.
The code provided in enet.c - void enet_init (ENET_CONFIG *config) - seems to be very basic and generic. I'd like to see some good driver for ENET module.

0 Kudos
Reply
5 Replies

744 Views
john71
Senior Contributor I

After some research I came wit the following setup function.

void ENET_Init(ENET_InitTypeDef enet_init_struct)
 {
    int usData;
    
    /* Enable the ENET clock. */
    SIM_SCGC2 |= SIM_SCGC2_ENET1_MASK;
    
    /*FSL: allow concurrent access to MPU controller. Example: ENET uDMA to SRAM, otherwise bus error*/
    MPU_CESR = 0;
    
    ENET_BDInit();
    
    ENET_ECR = ENET_ECR_RESET_MASK;
     
    for( usData = 0; usData < 10; usData++ )
    {
        asm( "NOP" );
    }
    
    mii_init(0, 60);  //bus freq = 60Mhz
    
    #if USER_IRQs_ENA
    enable_irq(INT_ENET_Transmit); //ENET_Transmit_IRQn
    enable_irq(INT_ENET_Receive);  //ENET_Receive_IRQn
    enable_irq(INT_ENET_Error);  //ENET_Error_IRQn
    #endif
    
    if(enet_init_struct.ENET_TxIsr != NULL)
    {
        ENET_ISR[ENET_TXF_ISR] = enet_init_struct.ENET_TxIsr;
    }
    if(enet_init_struct.ENET_RxIsr != NULL)
    {
        ENET_ISR[ENET_RXF_ISR] = enet_init_struct.ENET_RxIsr;
    }
    if(enet_init_struct.ENET_1588Isr != NULL)
    {
        ENET_ISR[ENET_1588_ISR] = enet_init_struct.ENET_1588Isr;
    }
    if(enet_init_struct.ENET_ErrIsr != NULL)
    {
        ENET_ISR[ENET_ERR_ISR] = enet_init_struct.ENET_ErrIsr;
    }
     
    PORTB_PCR0  = PORT_PCR_MUX(4);//GPIO;//RMII0_MDIO/MII0_MDIO
    PORTB_PCR1  = PORT_PCR_MUX(4);//GPIO;//RMII0_MDC/MII0_MDC    

    #if MII_MODE
    PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV
    //PORTA_PCR5  = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER
    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
    PORTA_PCR11 = PORT_PCR_MUX(4);//MII0_RXCLK
    PORTA_PCR25 = PORT_PCR_MUX(4);//MII0_TXCLK
    PORTA_PCR9  = PORT_PCR_MUX(4);//MII0_RXD3
    PORTA_PCR10 = PORT_PCR_MUX(4);//MII0_RXD2  
    PORTA_PCR28 = PORT_PCR_MUX(4);//MII0_TXER
    PORTA_PCR24 = PORT_PCR_MUX(4);//MII0_TXD2
    PORTA_PCR26 = PORT_PCR_MUX(4);//MII0_TXD3
    PORTA_PCR27 = PORT_PCR_MUX(4);//MII0_CRS
    PORTA_PCR29 = PORT_PCR_MUX(4);//MII0_COL
    #else  //RMII MODE
    PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV
    //PORTA_PCR5  = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER
    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   
    
    do
    {
        ENET_Delay( ENET_LINK_DELAY );
        usData = 0xffff;
        mii_read(0, CFG_PHY_ADDRESS, PHY_PHYIDR1, &usData );   
    } while( usData == 0xffff );
    
    #ifdef ENET_PRINT_PHY_INFO
    mii_read(0, CFG_PHY_ADDRESS, PHY_PHYIDR2, &usData );
    mii_read(0, CFG_PHY_ADDRESS, PHY_ANLPAR, &usData );
    mii_read(0, CFG_PHY_ADDRESS, PHY_ANLPARNP, &usData );
    mii_read(0, CFG_PHY_ADDRESS, PHY_PHYSTS, &usData );
    mii_read(0, CFG_PHY_ADDRESS, PHY_MICR, &usData );
    mii_read(0, CFG_PHY_ADDRESS, PHY_MISR, &usData );
    #endif
    
    /* Start auto negotiate. */
    mii_write( 0, CFG_PHY_ADDRESS, PHY_BMCR, (PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE) );
  

    //for debug
    mii_read(0, CFG_PHY_ADDRESS, PHY_BMCR, &usData );
  
    do
    {
         ENET_Delay( ENET_LINK_DELAY );
         mii_read(0, CFG_PHY_ADDRESS, PHY_BMSR, &usData );
    } while( !( usData & PHY_BMSR_AN_COMPLETE ) );


    //#ifdef ENET_PRINT_PHY_INFO
    mii_read(0, CFG_PHY_ADDRESS, PHY_STATUS, &usData );
    //#endif
   
    ENET_IALR = 0;
    ENET_IAUR = 0;
    ENET_GALR = 0;
    ENET_GAUR = 0;
    
    enet_set_address(0, enet_init_struct.ENET_MacAddress);
    
    ENET_RCR = ENET_RCR_MAX_FL(CFG_ENET_MAX_PACKET_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;
    
    #if RMII_MODE
    ENET_RCR/*(ch)*/ |= ENET_RCR_RMII_MODE_MASK;
      
    /*only set speed in RMII mode*/
    if( config->speed == MII_10BASET )
    {
       ENET_RCR/*(ch)*/ |= ENET_RCR_RMII_10T_MASK;
    }
    #endif /*no need to configure MAC MII interface*/
    
    ENET_TCR = 0;
    
    if( usData & PHY_DUPLEX_STATUS )
    {
        ENET_RCR &= (uint32)~ENET_RCR_DRT_MASK;
        ENET_TCR |= ENET_TCR_FDEN_MASK;
    }
    else
    {
        ENET_RCR |= ENET_RCR_DRT_MASK;
        ENET_TCR &= (uint32)~ENET_TCR_FDEN_MASK;
    }
    
    if( usData & PHY_SPEED_STATUS )
    {
        //10Mbps
        ENET_RCR |= ENET_RCR_RMII_10T_MASK;
    }

    ENET_ECR = 0;
    ENET_MRBR = (unsigned short) CFG_ENET_RX_BUFFER_SIZE;

    ENET_RDSR = ( uint32 ) &( xENETRxDescriptors[ 0 ] );

    ENET_TDSR = ( uint32 ) xENETTxDescriptors;

    ENET_EIR = ( uint32 ) -1;

    ENET_EIMR = 0
            | ENET_EIMR_RXF_MASK  
            | ENET_EIMR_TXF_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
            | ENET_EIMR_RXB_MASK
            ;

    ENET_ECR |= ENET_ECR_ETHEREN_MASK;

    ENET_RDAR = ENET_RDAR_RDAR_MASK;
 }

It stuck at 

do
    {
         ENET_Delay( ENET_LINK_DELAY );
         mii_read(0, CFG_PHY_ADDRESS, PHY_BMSR, &usData );
    } while( !( usData & PHY_BMSR_AN_COMPLETE ) );

But in the previous line mii_read(0, CFG_PHY_ADDRESS, PHY_BMCR, &usData );  I get the correct value.

0 Kudos
Reply

744 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

The TWR-SER Ethernet PHY KSZ8041NL supports both RMII and MII interface, while the TWR-K70F120M board doesn't connect MII pins to PCI interface. Please check below TWR-K70F120M board schematics with MII pins "DNP":

pastedImage_1.png

So, the TWR-K70F120M board doesn't support MII interface with TWR-SER board.

Thank you for the attention.


Have a great day,
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

744 Views
john71
Senior Contributor I

I see. Actually I set jumpers for RMII mode.

0 Kudos
Reply

744 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

I would recommend customer to refer NXP MQX Software example about TWR-K70F120M RMII Ethernet application.

And the FNET TCP/IP stack also provides TWR-K70F120M RMII example application demo.

Please check those examples about Ethernet PHY initialization code.

Wish it helps.


Have a great day,
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

744 Views
john71
Senior Contributor I

Thank you.I've successfully ported FNET stack with a great support of  Andrey.

0 Kudos
Reply