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.

Ethernet Initialization Issues

Part Number: TM4C129ENCPDT

We currently have a system comprised of multiple modules communicating over Ethernet in a half duplex setup. When reconfiguring the system to a full duplex auto negotiation mode, some modules continue to communicate normally while others loss communications.  We found that changing:

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

To this,
//
// Enable and reset the Ethernet modules.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);

Solves our communication issue.

In the the TivaWare Peripheral Driver User Guide (www.ti.com/.../spmu298e.pdf document we found an example on page 203 that shows enabling both peripherals prior to resetting them. However, on page 164, there is the example that shows enable, reset, enable, reset of the peripherals (which is what we changed it too).

Can you clarify what exactly these calls do and how they affect communication?

Thank you,

  • Hello Jacob,

    That is a strange nuance and I checked with our Ethernet expert but he hasn't heard of that having an impact before.

    On our TivaWare examples, we have it set with the two Enable calls first and the two Reset calls afterwards.

    I wonder if the changing of the sequence is hiding some sort of timing issue. In the one example we do the sequence like that, we have a Ready check after the resets.

    It could be that with swapping the order, the SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0); call now happens sooner than the SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0); call and that added timing delay allows the EMAC0 peripheral to be in ready state properly before it is accessed.

    Can you try and use this to see if it works:

        //
        // Enable and reset the Ethernet modules.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
        SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
        SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
    
        //
        // Wait for the MAC to be ready.
        //
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
        {
        }
    

    One other possibility would be the issue is related to the errata ETH#02 and how the the Pre-fetch buffer can impact the Ethernet starting after initialization:

    Before Ethernet Initialization the Flash Prefetch must be turned OFF by writing 1 to FLASHCONF.FPFOFF. After completing Ethernet Initialization, the user code must turn ON the Flash Prefetch by clearing the FLASHCONF.FPFOFF bit to restore system performance.

     

  • Hello Ralph,

    We are currently speculating that it is something regarding the timing but haven't found a way to prove it yet.

    Our code already utilizes the SysCtlPeripheralReady() call which has us stumped.

  • Hello Jacob,

    That the order of APIs matters so much really makes me wonder about the pre-fetch buffer errata I called out. It is possible that shifting the commands around would avoid an issue related to the prefetch buffer. Perhaps try the work around to disable and then enable it and see if that impacts the results.

    Another thing to try would be the following code where the EPHY is not enabled until the EMAC is ready. I really haven't seen a past issue where that was needed but it'd be good to understand if that works and lets the Enable for EPHY occur next without issues.

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

  • Hello Ralph,
     
    We have done some more investigation and have found that when we are able to establish communication, EMACStatusGet returns zero and EMACIntStatus returns that EMAC_INT_TRANSMIT is set (presumabley from a successful transmittion).


    When the communication issues are presenting themselves the EMAC_INT_TRANSMIT bit in EMACIntStatus is clear and EMACStatusGet returns that EMAC_STATUS_TX_NOT_EMPTY, EMAC_STATUS_TFC_STATE_WAITING, and EMAC_STATUS_TRC_STATE_READING are set forever and EthernetIntHandler stops being exectued. Hopefully, this is a bit more specific.

    Note: in both instances the EPHY_STS register reports that auto-negotiation has completed with an active link at 100Mb/s Full Duplex (0x0715)

  • Hi,

    Jacob Charlebois said:
    We currently have a system comprised of multiple modules communicating over Ethernet in a half duplex setup. When reconfiguring the system to a full duplex auto negotiation mode, some modules continue to communicate normally while others loss communications.  We found that changing:

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

    To this,
    //
    // Enable and reset the Ethernet modules.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);

    Solves our communication issue.

    I wonder if you do like below, will it make a difference? The idea is wait until the peripheral is ready after you enable it. 

    SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
    {
    }

    SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0))
    {
    }

    SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);

  • Hi Charles,

    Unfortunately throughout our testing that is an approach that we have attempted and it still failed to communicate. We are continuing to test this and will respond to our original post once we find something insightful.

  • Hello Ralph,

    We have also noticed that the EMACDMARIS registers TS and RS bits are getting stuck saying that the receive DMA state has stopped and that the transmit DMA state is 'running' while waiting for status when the module attempts to transmit for the first time.
    Note: the module should be receiving a packet before its first transmission, so this is insufficient to explain why our receive interrupt never fires.
  • Hi Jacob,

      

    Jacob Charlebois said:
    When reconfiguring the system to a full duplex auto negotiation mode, some modules continue to communicate normally while others loss communications

    I'm going back to your original post and I want to understand your described problem. Below are some tips I hope you can provide that will give us some more insights to the problem. 

      - When you say some modules continue to communicate while others lost communications, can you elaborate if all the modules are running the same firmware and if they are all the same board?

      - How many modules are we talking that are still running and how many lost communication?

      - If you limit the number of modules running on the network will it make a difference? I don't know how many total you have. Suppose you have 10 running with some working and some not, can you reduce the total number to like 4 including the ones that was failing before. Will you see any difference? This is to check if there is any network level issue.

      - Can you change the Ethernet cable on the ones that lost communication? Does it make a difference?

      - Can you run the TivaWare Ethernet example on all the modules? Will you see those that lose communication running your own application continue to lose communication running the TivaWare example? This is to check if the problem is software related. 

      -  Can you run your application on the LaunchPad board? Will you see any communication problem?

      -  Let's suppose you have two modules: module_A and module_B. A is good and B will lose communication.  Can you do a ABA swap test meaning swap the MCU on module_B (the bad board) to module_A (the good board) and swap the MCU on module_A to module_B. Will the bad MCU continue to lose communication? This is to check if there is any board related issue with the module_B. 

      

  • Hello Charles,

    Unfortunately, due to time constraints, we have to move on and have changed the system to forced half duplex until we can come back to this.
    In regards to your questions:
    1. The modules are running different firmware, but all use a shared library for Ethernet communications.
    2. Two of the modules communicate with no problems and three either have no comms or will randomly have or not have comms after a power cycle.
    3. A typical network for us is around 5-10 modules. If the network is reduced to just 2 modules, the behaviour observed does not change.
    4. Changing the cables had no effect.
    5-6. Since we are moving on, I am unable to do these tests at this time.
    7. As stated above, I am currently unable to physically test this at this time. However, there are two modules that are physically identical, but run slightly different firmware. One of them doesn't have the issue, the other does. I'm inclined to believe its a software issue and not a hardware issue (we had two other people verify the issue with there modules and they were having the exact same behaviour).

    Sorry to leave this on such an unsatisfactory note but thank you for the help nonetheless. 

  • Hi Jacob,

      Thanks for your updates. I will mark the post as resolved for the time being. If you have updates in the future, simply just reply to the post and the post will be open for support again.