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.

TM4C1294NCPDT: TivaWare emac.c is using incorrect addresses

Part Number: TM4C1294NCPDT

I'm trying to port a Stellaris project over to Tivaware, and I'm running into a problem with getting lwiplib initialized.  I'm using Tivaware 2.1.4.178.

emac.c, located in TivaWare\driverlib is using incorrect memory locations for the ethernet controller.  According to the datasheet, the ethernet controller starts at 0x400E.C000.  However, emac.c is using the SYSCLT_PERIPH_EPHY0 #define (located in TivaWare\Driverlib\sysctl.h).  SYSCTL_PERIPH_EPHY0 is defined as 0xF000.3000

Here's the function that is causing problems in ema.c

void
EMACPHYConfigSet(uint32_t ui32Base, uint32_t ui32Config)
{
    //
    // Write the Ethernet PHY configuration to the peripheral configuration
    // register.
    //
    HWREG(ui32Base + EMAC_O_PC) = ui32Config;

    //
    // If using the internal PHY, reset it to ensure that new configuration is
    // latched there.
    //
    if((ui32Config & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_INTERNAL)
    {
        SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0))
        {
            //
            // Wait for the PHY reset to complete.
            //
        }

        //
        // Delay a bit longer to ensure that the PHY reset has completed.
        //
        SysCtlDelay(10000);
    }

    //
    // If using an external RMII PHY, we must set 2 bits in the Ethernet MAC
    // Clock Configuration Register.
    //
    if((ui32Config & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_EXTERNAL_RMII)
    {
        //
        // Select and enable the external clock from the RMII PHY.
        //
        HWREG(EMAC0_BASE + EMAC_O_CC) |= EMAC_CC_CLKEN;
    }
    else
    {
        //
        // Disable the external clock.
        //
        HWREG(EMAC0_BASE + EMAC_O_CC) &= ~EMAC_CC_CLKEN;
    }

    //
    // Reset the MAC regardless of whether the PHY connection changed or not.
    //
    EMACReset(EMAC0_BASE);

    SysCtlDelay(1000);
}

All of the SYSCTL_PERIPH #defines are all located in 0xF000.XXXX memory area, which should be reserved, according to the datasheet.

My code is getting hung up in the "wait for PHY reset to complete" spin-wait loop.  

  • Hi, Curtis,

     I don't see anything wrong with the code. The 0x400E.C000 is the base address for the Ethernet (EMAC) Controller. The SysCtlPeripheralReady(SYSCLT_PERIPH_EPHY0 ) is checking if the "PHY" is ready. This is not checking the EMAC ready. Somehow your PHY is not ready but it is not due to any incorrect address.

      The SYSCLT_PERIPH_EPHY0 #define is not an absolute PHY address. It is a more like a mask value.  Please see below code. The SYSCTL_PRBASE is equal to 0x400FEA00. The (ui32Peripheral & 0xff00) >> 8) will be 0xF0003000 & 0xFF00) >> 8) which is 0x30. Once you add the offset to the base the final address is 0x400F_EA30. This is the address to the Ethernet PHY Peripheral Ready register. 

    bool
    SysCtlPeripheralReady(uint32_t ui32Peripheral)
    {
        //
        // Check the arguments.
        //
        ASSERT(_SysCtlPeripheralValid(ui32Peripheral));
    
        //
        // See if this peripheral is ready.
        //
        return(HWREGBITW(SYSCTL_PRBASE + ((ui32Peripheral & 0xff00) >> 8),
                         ui32Peripheral & 0xff));
    }

  • I just came to that same conclusion as well. I initially didn't see all that bit twiddling.
  • I also figured out the problem I was having with the spin-wait call to SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0).  I didn't have the clock setup correctly.

    Configuring the clock with the following code fixed the problem.

      uint32_t SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                        SYSCTL_OSC_MAIN |
                                        SYSCTL_USE_PLL |
                                        SYSCTL_CFG_VCO_480), 120000000);

  • Glad your problem is solved.