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: DMA software reset of Ethernet MAC DMA Bus Mode register not succeeding.

Part Number: TM4C1292NCPDT

Hi. I am trying to bring to live TM4C1292 with external PHY with RGMII interface.

When EMACPHYConfigSet function gets to EMACReset function it sits in 

while(HWREG(ui32Base + EMAC_O_DMABUSMOD) & EMAC_DMABUSMOD_SWR)
{
}

.

In datasheet it is written: DMA Software Reset The software reset function is driven by this bit. The reset operation is completed only when all resets in all active clock domains are deasserted. It is essential that all the PHY input clocks are present for the software reset completion. The time of the software reset operation depends on the frequency of the slowest active clock.

0: Reset is completed. A value of 0 should be read before reprogramming any MAC registers after a reset.

1: MAC DMA Controller resets the logic and all internal registers of the MAC. It is cleared automatically after the reset operation has completed in all of the MAC clock domains.

I checked that external PHY is generating 50 MHz clock. 

Also , do I understand correctly - "The reset operation is completed only when all resets in all active clock domains are deasserted'' means that no clock should be in reset state?

I also checked that Clock to EMAC and EPHY have not been enabled. SYSCTL.RCGCEMAC register reads 0.

I am using LWip so ethernet initialization is done with lwipinit function seen below

struct netif *
lwIPInit(uint32_t ui32SysClkHz, const uint8_t *pui8MAC, uint32_t ui32IPAddr,
         uint32_t ui32NetMask, uint32_t ui32GWAddr, uint32_t ui32IPMode)
{
    //
    // Check the parameters.
    //
#if LWIP_DHCP && LWIP_AUTOIP
    ASSERT((ui32IPMode == IPADDR_USE_STATIC) ||
           (ui32IPMode == IPADDR_USE_DHCP) ||
           (ui32IPMode == IPADDR_USE_AUTOIP));
#elif LWIP_DHCP
    ASSERT((ui32IPMode == IPADDR_USE_STATIC) ||
           (ui32IPMode == IPADDR_USE_DHCP));
#elif LWIP_AUTOIP
    ASSERT((ui32IPMode == IPADDR_USE_STATIC) ||
           (ui32IPMode == IPADDR_USE_AUTOIP));
#else
    ASSERT(ui32IPMode == IPADDR_USE_STATIC);
#endif

   /*
    *  This is a work-around for EMAC initialization issues found on
    *  the TM4C129 devices. The bug number is:
    *  SDOCM00107378: NDK examples for EK-TM4C1294XL do not work
    *
    *  The following disables the flash pre-fetch (if it is not already disabled).
    *  It is enable within the EMACSnow_emacStart() function.
    */
    bool enablePrefetch = false;
    uint32_t ui32FlashConf;
    ui32FlashConf = HWREG(FLASH_CONF);
    if ((ui32FlashConf & (FLASH_CONF_FPFOFF)) == false) {
        enablePrefetch = true;
        ui32FlashConf &= ~(FLASH_CONF_FPFON);
        ui32FlashConf |= FLASH_CONF_FPFOFF;
        HWREG(FLASH_CONF) = ui32FlashConf;
    }
    
    //
    // Enable the ethernet peripheral.
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
    MAP_SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);

    //
    // Enable the internal PHY if it's present and we're being
    // asked to use it.
    //
    if((EMAC_PHY_CONFIG & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_INTERNAL)
    {
        //
        // We've been asked to configure for use with the internal
        // PHY.  Is it present?
        //
        if(MAP_SysCtlPeripheralPresent(SYSCTL_PERIPH_EPHY0))
        {
            //
            // Yes - enable and reset it.
            //
            MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
            MAP_SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
        }
        else
        {
            //
            // Internal PHY is not present on this part so hang here.
            //
            while(1)
            {
            }
        }
    }

    //
    // Wait for the MAC to come out of reset.
    //
    while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
    {
    }
    
    //
    //    Enable all MII related pins
    //
    // Enable Peripheral Clocks 
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);





    // Configure the GPIO Pin Mux for PG5
    // for EN0TXD1
    MAP_GPIOPinConfigure(GPIO_PG5_EN0TXD1);
    GPIOPinTypeEthernetMII(GPIO_PORTG_BASE, GPIO_PIN_5);



    // Configure the GPIO Pin Mux for PG7
    // for EN0RXDV
    MAP_GPIOPinConfigure(GPIO_PG7_EN0RXDV);
    GPIOPinTypeEthernetMII(GPIO_PORTG_BASE, GPIO_PIN_7);
    
    // Configure the GPIO Pin Mux for PG3
    // for EN0TXEN
    MAP_GPIOPinConfigure(GPIO_PG3_EN0TXEN);
    GPIOPinTypeEthernetMII(GPIO_PORTG_BASE, GPIO_PIN_3);

    // Configure the GPIO Pin Mux for PQ5
    // for EN0RXD0
    MAP_GPIOPinConfigure(GPIO_PQ5_EN0RXD0);
    GPIOPinTypeEthernetMII(GPIO_PORTQ_BASE, GPIO_PIN_5);



    // Configure the GPIO Pin Mux for PG4
    // for EN0TXD0
    MAP_GPIOPinConfigure(GPIO_PG4_EN0TXD0);
    GPIOPinTypeEthernetMII(GPIO_PORTG_BASE, GPIO_PIN_4);



    // Configure the GPIO Pin Mux for PQ6
    // for EN0RXD1
    MAP_GPIOPinConfigure(GPIO_PQ6_EN0RXD1);
    GPIOPinTypeEthernetMII(GPIO_PORTQ_BASE, GPIO_PIN_6);




    
    // Configure the GPIO Pin Mux for PF2
    // for EN0MDC
//WE USE SPI
    MAP_GPIOPinConfigure(GPIO_PF2_EN0MDC);
    GPIOPinTypeEthernetMII(GPIO_PORTF_BASE, GPIO_PIN_2);

    // Configure the GPIO Pin Mux for PF3
    // for EN0MDIO
//WE USE SPI
    MAP_GPIOPinConfigure(GPIO_PF3_EN0MDIO);
    GPIOPinTypeEthernetMII(GPIO_PORTF_BASE, GPIO_PIN_3);    

    
    
    
    
    
    
    //
    // Configure for use with whichever PHY the user requires.
    //   

    MAP_EMACPHYConfigSet(EMAC0_BASE, EMAC_PHY_TYPE_EXTERNAL_RMII);
    

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


    //
    // Set MAC configuration options.
    //
    MAP_EMACConfigSet(EMAC0_BASE, (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_MODE_RX_STORE_FORWARD |
                       EMAC_MODE_TX_STORE_FORWARD |
                       EMAC_MODE_TX_THRESHOLD_64_BYTES |
                       EMAC_MODE_RX_THRESHOLD_64_BYTES), 0);

    
    
    
    
    
    
    
    
    //
    // Program the hardware with its MAC address (for filtering).
    //
    MAP_EMACAddrSet(EMAC0_BASE, 0, (uint8_t *)pui8MAC);

    //
    // Save the network configuration for later use by the private
    // initialization.
    //
    g_ui32IPMode = ui32IPMode;
    g_ui32IPAddr = ui32IPAddr;
    g_ui32NetMask = ui32NetMask;
    g_ui32GWAddr = ui32GWAddr;

    //
    // Initialize lwIP.  The remainder of initialization is done immediately if
    // not using a RTOS and it is deferred to the TCP/IP thread's context if
    // using a RTOS.
    //
#if NO_SYS
    lwIPPrivateInit(0);
#else
    tcpip_init(lwIPPrivateInit, 0);
#endif
    
    /*
    * Turns ON the prefetch buffer if it was disabled in EMACSnow_NIMUInit
    */
    if (enablePrefetch == true) {
        ui32FlashConf = HWREG(FLASH_CONF);
        ui32FlashConf &= ~(FLASH_CONF_FPFOFF);
        ui32FlashConf |= FLASH_CONF_FPFON;
        HWREG(FLASH_CONF) = ui32FlashConf;
    }
    
	return &g_sNetIF;
}

  • I added 

    MAP_GPIOPinConfigure(GPIO_PM4_EN0RREF_CLK);
    GPIOPinTypeEthernetMII(GPIO_PORTM_BASE, GPIO_PIN_4);

    and now it just crashes whenever I use EMACPHYRead

    I will continue to investigate but maybe some who has used external PHY with RMII can give me some example?

  • Hi Karlis,

    In the lwipopts.h file, did you change to #define EMAC_PHY_CONFIG EMAC_PHY_TYPE_EXTERNAL_RMII? What might have happened is that the EMAC_PHY_CONFIG as currently defined by default is to use the EMAC_PHY_TYPE_INTERNAL. In line 50 of your posted code, it is check if the internal PHY is to be used. Since the EMAC_PHY_CONFIG in the lwipopts.h uses the internal PHY, it makes the if-clause true and hence enables the internal PHY at line 61.

    This post at the very end by Joseph may be helpful. He is able to get the RMII working. 

    https://e2e.ti.com/support/microcontrollers/other/f/908/p/559297/2162933?tisearch=e2e-quicksearch&keymatch=EMAC_PHY_TYPE_EXTERNAL_RMII#pi320995=5 

  • Hi. Thanks for reply.

    I actually noticed what was wrong. After I added lines about REF clk I forgot to call lwipinit....

    Anyway  - I still can't get any incoming frames of ethernet on TM4C. With oscilloscope I see that there indeed is frames coming and 50 MHz clock is also there. 

    What is the first registers which I should check, just be sure that physical layer is working correctly? I checked the EMAC0RXCNTGB register, but it shows 0 count for bad and good frames :/ ..

    RMII is set up correctly in registers- I checked that clock is enabled and RMII is chosen.

    Of course I get nothing on tivaif_receive() too..Any advice? Thanks

  • Hi Karlis,

      I wonder if the CLKEN in the EMACC register is set to enable EN0RREF_CLK and if the INT bit is set in the EPHYIM register. Unfortunately, we don't have any examples to illustrate RMII and there are very few posts in the forum talking about it. If you can get it to work, please let us know the tips that will greatly benefit the forum who are looking for the same solution. 

  • Karlis Tucs77 said:
    Anyway  - I still can't get any incoming frames of ethernet on TM4C. With oscilloscope I see that there indeed is frames coming and 50 MHz clock is also there. 

    Are your aware after DMA reset the EMAC0 has to be reconfigured? How is your SW checking for DMA BUS fault interrupt? Bus fault interrupt occurs via the internal EMAC0. Well I can tell you even with a internal PHY the DMA Busfault condition never recovers with LWIP1.4.1 even via complete configuration settings being passed into the handler.  

  • Hi Karlis,

      While I do not have more ideas and tips to offer other than my last suggestions, I do like to find out from you if you have made some progress. Please share with us your findings if you have any. I hope your findings will benefit people who plan to use RMII. 

  • Hi Karlis,

      I have not heard back from you. Hope you have made some progress. I will close the thread for now. If you have some update that you would like to share with us you can just write back to reopen this thread.