This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1292NCPDT: MAC to MAC connection with RMII interface

Part Number: TM4C1292NCPDT

Tool/software:

Hi,

We are trying to connect the MCU to a Ethernet switch IC with its RMII port. According to the switch IC's datasheet:

The RMII interface only supports RMII MAC mode. When connecting the interface to another MAC,
the RMII pins must be cross-connected in a way that the direction of the control, clock, and data pins matches on
both ends. In this configuration, it is also possible to operate a MAC vs MAC mode

But I am not sure if it is possible for the MCU to work in MAC to MAC connection.

I found a similar thread in the forum:

e2e.ti.com/.../am335x-rmii-direct-connection-between-two-devices

If the MAC design of the MCU is similar to that of AM335, I will be confident that this would work for us. Or do you know if there is any successful case on this?

  • Hi TianLei,

      I think in theory, it is possible. Connecting the MCU to the switch using RMII is supported by the EMAC controller on the TM4C129 MCU. How one MAC talks to another MAC that also connects to the switch through RMII is something to be handled by the switch. I'm not familiar with your switch though. My point is that TM4C129 does not know how other MACs are connected to the switch, whether in RMII or via PHY. 

  • Thanks Charles.

    You mentioned that:

    Connecting the MCU to the switch using RMII is supported by the EMAC controller on the TM4C129 MCU

    that is for sure if the switch can pretend to be a PHY on the other side of RMII.

    What I would like to clarify is that, since the other side of the RMII (the switch side) is not a PHY, but another MAC (the switch cannot work in PHY mode behind the RMII interface), the TX-EN signal from the switch MAC would need to be routed to MCU's EN0RXDV.

    This means, the MCU will have to accept the TX-EN signal from the other MAC as the CRS_DV. Since these two signals are not the same, would the EMAC controller tolerate this?

  • Hi Tianlei,

      Although the below diagram is for RGMII MAC2MAC connection but should be the same for RMII as well. Refer to this app note for MAC2MAC  connection. https://www.ti.com/lit/pdf/sprad07

  • Hi Charles, I will verify this. I can physically loop the Tx0,Tx1,TX_EM back to Rx0,Rx1 and CRS_DV and provide an external 50MHz clock. Theoretically this should work.

  • Hi Charles,

    It's confirmed to work.We have the MCU connected to the switch IC and the MAC-MAC connection on RMII interface is working  perfectly.

    One thing worth mentioning is that the EN0RXER pin must be physically pulled low for RMII interface to work. The datasheet is not correct on this, which says 'RX_ER is an optional standard RMII signal and is not used in this device'.

  • Hi Tianlei,

      Very glad that it works in MAC2MAC. I also learn something new myself. Can you please share your code on configuring EMAC for the RMII interface and perhaps some simple test code that you use to send some data out of RMII. I'd really appreciate it for the benefit of forum community. Thanks. 

  • Here is the code for EMAC configuration. The testing is from a network device who broadcast test packet to the LAN and this device would bounce back the test packet back.

    void
    EthernetRmiiCfg(BYTE* mac)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
        GPIOPinConfigure(GPIO_PG3_EN0TXEN);
        GPIOPinConfigure(GPIO_PG4_EN0TXD0);
        GPIOPinConfigure(GPIO_PG5_EN0TXD1);
        GPIOPinConfigure(GPIO_PG6_EN0RXER);
        GPIOPinConfigure(GPIO_PG7_EN0RXDV);
        GPIOPinTypeEthernetMII(GPIO_PORTG_BASE, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);

        // This is important! No RX without this.
        // PHY does not provide this signal, so MCU has to desert it by itself
        //
        GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_6, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPD);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
        GPIOPinConfigure(GPIO_PQ5_EN0RXD0);
        GPIOPinConfigure(GPIO_PQ6_EN0RXD1);
        GPIOPinTypeEthernetMII(GPIO_PORTQ_BASE,GPIO_PIN_5 |  GPIO_PIN_6);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
        GPIOPinConfigure(GPIO_PM4_EN0RREF_CLK);
        GPIOPinTypeEthernetMII(GPIO_PORTM_BASE,GPIO_PIN_4);

        // Enable and reset the Ethernet modules.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
        SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);

        // Wait for the MAC to be ready.
        //
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0)) {
            WdogTemporyFeed();
        }

        // Configure the interface
        //
        EMACPHYConfigSet(EMAC0_BASE, (EMAC_PHY_TYPE_EXTERNAL_RMII | EMAC_PHY_AN_100B_T_FULL_DUPLEX));

        // Reset the MAC
        //
        EMACReset(EMAC0_BASE);

        // Initialize the MAC and set the DMA mode.
        //
        EMACInit(EMAC0_BASE, SysClock, EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4, 0);

        // Set MAC configuration options.
        //
        EMACConfigSet(EMAC0_BASE, ( EMAC_CONFIG_STRIP_CRC | EMAC_CONFIG_FULL_DUPLEX | EMAC_CONFIG_CHECKSUM_OFFLOAD | EMAC_CONFIG_7BYTE_PREAMBLE |
                                    EMAC_CONFIG_IF_GAP_96BITS |    EMAC_CONFIG_USE_MACADDR0 | EMAC_CONFIG_SA_FROM_DESCRIPTOR |
                                    EMAC_CONFIG_BO_LIMIT_1024 | EMAC_CONFIG_100MBPS),
                                  ( EMAC_MODE_RX_STORE_FORWARD | EMAC_MODE_TX_STORE_FORWARD | EMAC_MODE_TX_THRESHOLD_64_BYTES |
                                    EMAC_MODE_RX_THRESHOLD_64_BYTES), 0);

        // Initialize the Ethernet DMA descriptors.
        //
        InitDescriptors(EMAC0_BASE);

        // Program the hardware with its MAC address (for filtering).
        //
        EMACAddrSet(EMAC0_BASE, 0, mac);

        // Enable the Ethernet RX Packet interrupt source.
        //
        EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE);


        // Set MAC filtering options. We receive all broadcast and multicast
        // packets along with those addressed specifically for us.
        //
        EMACFrameFilterSet(EMAC0_BASE, (EMAC_FRMFILTER_SADDR | EMAC_FRMFILTER_PASS_MULTICAST | EMAC_FRMFILTER_PASS_NO_CTRL));

        // Clear any pending interrupts.
        //
        EMACIntClear(EMAC0_BASE, EMACIntStatus(EMAC0_BASE, false));

        // Mark the receive descriptors as available to the DMA to start
        // the receive processing.
        //
        int i;
        for(i = 0; i < NUM_RX_DESCRIPTORS; i++) {
            g_psRxDescriptor[i].ui32CtrlStatus |= DES0_RX_CTRL_OWN;
        }

        // Enable the Ethernet MAC transmitter and receiver.
        //
        EMACTxEnable(EMAC0_BASE);
        EMACRxEnable(EMAC0_BASE);

        // Enable the Ethernet interrupt.
        //
        IntPrioritySet(INT_EMAC0, ETHERNET_PERIORITY);
        IntEnable(INT_EMAC0);

        // Enable the Ethernet RX Packet interrupt source.
        //
        EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE);
    }

  • Hi Tianlei,

      Thanks so much for sharing. I'm sure it will greatly benefit people in the community who are looking for the same solution. Bravo on the finding that EN0RXER must be pulled low.