Differences between RMII and MII.

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

Differences between RMII and MII.

13,624 Views
Masmiseim
Senior Contributor I

Hello,

I have the lwIP-Stack running on a Kinetis K60FX512 with an MII Connected Phy (DM9161A). It is this board here: http://elmicro.com/de/cardk60.html

It runs very good and with impressive speed (I got nearly 100 Mbit receiving with a iPerf).

Now I would like to get lwIP running on

  • The K60DN512 Tower Modul with RMII connected Phy (KSZ8041NL (TWR-Ser-Module))
  • FRDM K64 Board with RMII connected Phy (KSZ8081RNACA)

My driver is not running on this boards. Other Peripherals on the Boards are working (SDIO, Serial Port).

The handling in the driver for MII/RMII I’ve implemented are:

  • Initialized additional Pins for MII usage:
    PORTB->PCR[0]  = PORT_PCR_MUX (4);                            // RMII0_MDIO/MII0_MDIO
    PORTB->PCR[1]  = PORT_PCR_MUX (4);                              // RMII0_MDC/MII0_MDC
    PORTA->PCR[14] = PORT_PCR_MUX (4);            // RMII0_CRS_DV/MII0_RXDV
    // PORTA->PCR[5]  = PORT_PCR_MUX (4);        // RMII0_RXER/MII0_RXER
    PORTA->PCR[12] = PORT_PCR_MUX (4);            // RMII0_RXD1/MII0_RXD1
    PORTA->PCR[13] = PORT_PCR_MUX (4);            // RMII0_RXD0/MII0_RXD0
    PORTA->PCR[15] = PORT_PCR_MUX (4);            // RMII0_TXEN/MII0_TXEN
    PORTA->PCR[16] = PORT_PCR_MUX (4);            // RMII0_TXD0/MII0_TXD0
    PORTA->PCR[17] = PORT_PCR_MUX (4);            // RMII0_TXD1/MII0_TXD1

    if (Interface == MII)
    {
         // Initialize the additional Pins for the MII Interface
         PORTA->PCR[11] = PORT_PCR_MUX(4);//MII0_RXCLK
         PORTA->PCR[25] = PORT_PCR_MUX(4);//MII0_TXCLK
         PORTA->PCR[9]  = PORT_PCR_MUX(4);//MII0_RXD3
         PORTA->PCR[10] = PORT_PCR_MUX(4);//MII0_RXD2 
         PORTA->PCR[28] = PORT_PCR_MUX(4);//MII0_TXER
         PORTA->PCR[24] = PORT_PCR_MUX(4);//MII0_TXD2
         PORTA->PCR[26] = PORT_PCR_MUX(4);//MII0_TXD3
         PORTA->PCR[27] = PORT_PCR_MUX(4);//MII0_CRS
         PORTA->PCR[29] = PORT_PCR_MUX(4);//MII0_COL
    }

  • Set the ENET_RCR_RMII_MODE_MASK-Flag in RCR Register in RMII Mode
    if (this->PhyInterface == RMII)
            ENET->RCR         = ENET_RCR_MAX_FL (1518) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;
    else
            ENET->RCR         = ENET_RCR_MAX_FL (1518) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK;

The MDIO Communication is working. I can start the auto-Negotiation and getting a link. But no package is sent or received. No IRQ occurs.

Any Idea what I have to change in addition?

Thanks and Regards

3 Replies

2,911 Views
mjbcswitzerland
Specialist V

Markus

When using RMII mode you have to be sure that the mode of the PHY and the EMAC remain synchronised since it otherwise may not (will not if not matching) operate.

To do this you can handle the PHY link state change interrupt on the TWR board and, depending on the negotiated settings, set the EMAC mode to match (in the RCR register).

On the FRDM-K64F there is no interrupt line so you need to poll the state to do the same.

In RMII mode the clock must be 50MHz and use the exact same signal for both the PHY and the Kinetis. The FRDM-K64F has this automatcially but in the tower kit you need to be sure that the jumpers on the K60 board and the serial board are correct. See page 9 of http://www.utasker.com/docs/KINETIS/uTaskerV1.4_Kinetis_demo.pdf

Make sure that you use the checksum offloading capabilities of the Kinetis since it greatly improves performance of TCP.

Regards

Mark

http://www.utasker.com/kinetis.html

0 Kudos

2,911 Views
Masmiseim
Senior Contributor I

Hey Mark,

Thanks for the feedback.

After the Auto-Negotiation is finished (Register 1 – Bit 5 is set), I’m reading the result of the Auto-Negotiation. Sadly this is non-Standard. In case of the DM9161A-Phy it is Register17 – Bit 12-15.

OperationMode GetOperationMode_DM9161A (void)
{
    /*17.15 - 100FDX - 100M Full Duplex Operation Mode

    17.14 - 100HDX - 100M Half Duplex Operation Mode
    17.13 - 10FDX  -  10M Full Duplex Operation Mode
    17.12 - 10HDX  -  10M Half Duplex Operation Mode
    17.3-17.0 - Auto-negotiation Monitor Bits
    1 0 0 0  --> Auto-negotiation completed successfully */

    static const uint16_t OperationModeMask                        = 0xF000;
    static const uint16_t OperationModeShift          = 12;
    static const uint16_t AutoNegotiationComplete_Mask                = 0x04;

    uint16_t DSCSR = 0;
    if (!this->pMII->Read (this->Address, 17, DSCSR))
        return UnknownMode;

    if (DSCSR & AutoNegotiationComplete_Mask)
        return OM_AutoNegotiation;

    switch ((DSCSR & OperationModeMask) >> OperationModeShift)
    {
        case 1:  return 10BaseT_HD;
        case 2:  return 10BaseT_FD;
        case 4:  return 100BaseTX_HD;
        case 8:  return 100BaseTX_FD;
        default:return UnknownMode;
    }
}

With the Result of this function I’m setting the corresponding Flags in RCR and TCR.

if (OperationMode ==100BaseTX_FD || OperationMode == 10BaseT_FD)
{
    // Full duplex
    ENET->RCR &= ~ENET_RCR_DRT_MASK;
    ENET->TCR |= ENET_TCR_FDEN_MASK;
}
else
{
    // half duplex
    ENET->RCR |= ENET_RCR_DRT_MASK;
    ENET->TCR &= (uint32_t)~ENET_TCR_FDEN_MASK;
}

// Setup speed
if (OperationMode == 10BaseT_FD || OperationMode == 10BaseT_HD)
    ENET->RCR |= ENET_RCR_RMII_10T_MASK;                                    // 10Mbps

As I said. This is working perfectly fine for the K60FX512 with DM9161A. Stepping through the code with the two other systems looks also good. I’m getting a link and can read the Operation Mode. But I can’t see any packet which is transferred. And no RX/TX/Error interrupt occurs.

Are there any differences in the EMAC implementation of the different Kinetis-Controllers I have to face with? Are there any differences in the RMII/MII usage I should handle? Do I have to handle the Phys in a different way? The Registers 0-F are covered by IEEE 802.3 Section 2. The only non-Standard-Register I’m using is the one to get the Auto-Negotiation-Result.

Thanks and Regards

Markus

PS: The Jumper on the tower look correct

0 Kudos

2,911 Views
mjbcswitzerland
Specialist V

Markus

I can't think of any other differences at the moment.

I would do the following:

1. Load a reference binary to your boards to ensure that Ethernet works with them. There are versions for the boards here: http://www.utasker.com/SW_Demos.html

2. Once you know that there is no HW configuration problem you can download the uTasker project from

http://www.utasker.com/forum/index.php?topic=1721.msg6164#msg6164

This will work with all boards and its TCP/IP stack has many more features than lwip. It is configured for Kinetis parts/freescale boards so you should find that it is also faster and required less resources.
3. Run the uTasker project in VisualStudio (simulator) so that you can also test the Kinetis Ethernet and PHY operation and compare with the same on HW in case of any problems. This will also allow testing and debugging any Ethernet based protocols and applications since it allows the Kinetis to be simulated in real-time. Compare each step in the simulator with your own code's operation to identify where concrete problems are located.

Regards

Mark

P.S. See the following for an overview (of FRDM-K64F): Re: New Freedom FRDM-K64F board

which also has a FRDM-K64F simulator which operates stand-alone in case you want to quickly try what it can do.