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.

TM4C129ENCPDT locks up, using ethernet, and a soft reset.

Other Parts Discussed in Thread: TM4C129ENCPDT, TM4C1294NCPDT

Hello All, I am wondering if someone has had any experience with the following issue.  I am using a TM4C129ENCPDT, running with a 25Mhz external crystal oscillator.  I am using TivaWare_C_Series-2.1.0.12573 and CCS 6.0.1.00040. The code is running on our own hardware, and I do not have a demo kit to try it out on. 

I have been experiencing a controller lockup, where I can not connect to the board with JTAG after the error occurs.  The following is the code I am running, a simple program that initializes the clock, ethernet, configures the ethernet PHY, toggles a port and then performs a soft reset.  This code is mostly all borrowed from section 10.3 Programming Example, in the Tivaware Peripheral Driver Library User's Guide dated Feb 7, 2014.

If I leave this code running for a while(usually under an hour) it will lock up.  I have already checked the NmiSR, FaultISR and Default ISR handler, and these are not the cause of the lockup, they are never fired.  It also seems that the code locks up in different places, as I have tried instrumenting the code by toggling LEDs at different times, and I have had it lock up in different places.  It seems it is most likely to occur around the call to EMACPHYConfigSet, but it appears to be a bit random.

If I remove the delay between the clock initialization and the rest of the program I no longer get the program to lock up. I am wondering what could be causing the lockup, and why removing the delay could fix it.  A power cycle is needed to get the program to run after it locks up. Any help solving this will be greatly appreciated!

//*****************************************************************************
//
// Ethernet DMA descriptors.
//
// The MAC hardware needs a minimum of 3 receive descriptors to operate. The
// number used will be application-dependent and should be tuned for best
// performance.
//
//*****************************************************************************
#define NUM_TX_DESCRIPTORS 3
#define NUM_RX_DESCRIPTORS 3
tEMACDMADescriptor g_psRxDescriptor[NUM_TX_DESCRIPTORS];
tEMACDMADescriptor g_psTxDescriptor[NUM_RX_DESCRIPTORS];
uint32_t g_ui32RxDescIndex;
uint32_t g_ui32TxDescIndex;
//*****************************************************************************
//
// Transmit and receive buffers. These will typically be allocated within your
// network stack somewhere.
//
//*****************************************************************************
#define RX_BUFFER_SIZE 1536
uint8_t g_ppui8RxBuffer[NUM_RX_DESCRIPTORS][RX_BUFFER_SIZE];

//*****************************************************************************
//
// Read a packet from the DMA receive buffer and return the number of bytes
// read.
//
//*****************************************************************************
int32_t ProcessReceivedPacket(void)
{
    int_fast32_t i32FrameLen;
    //
    // By default, we assume we got a bad frame.
    //
    i32FrameLen = 0;
    //
    // Make sure that we own the receive descriptor.
    //
    if(!(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus & DES0_RX_CTRL_OWN))
    {
        //
        // We own the receive descriptor so check to see if it contains a valid
        // frame.
        //
        if(!(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus &
        DES0_RX_STAT_ERR))
        {
            //
            // We have a valid frame. First check that the "last descriptor"
            // flag is set. We sized the receive buffer such that it can
            // always hold a valid frame so this flag should never be clear at
            // this point but...
            //
            if(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus &
            DES0_RX_STAT_LAST_DESC)
            {
                //
                // What size is the received frame?
                //
                i32FrameLen =
                ((g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus &
                DES0_RX_STAT_FRAME_LENGTH_M) >>
                DES0_RX_STAT_FRAME_LENGTH_S);
                //
                // Pass the received buffer up to the application to handle.
                //
                //ApplicationProcessFrame(i32FrameLen,
                //g_psRxDescriptor[g_ui32RxDescIndex].pvBuffer1);
            }
        }
        //
        // Now that we are finished dealing with this descriptor, hand
        // it back to the hardware. Note that we assume
        // ApplicationProcessFrame() is finished with the buffer at this point
        // so it is safe to reuse.
        //
        g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus =
        DES0_RX_CTRL_OWN;
        //
        // Move on to the next descriptor in the chain.
        //
        g_ui32RxDescIndex++;
        if(g_ui32RxDescIndex == NUM_RX_DESCRIPTORS)
        {
            g_ui32RxDescIndex = 0;
        }
    }
    //
    // Return the Frame Length
    //
    return(i32FrameLen);
}
//*****************************************************************************
//
// The interrupt handler for the Ethernet interrupt.
//
//*****************************************************************************
void EthernetIntHandler(void)
{
    uint32_t ui32Temp;
    //
    // Read and Clear the interrupt.
    //
    ui32Temp = EMACIntStatus(EMAC0_BASE, true);
    EMACIntClear(EMAC0_BASE, ui32Temp);
    //
    // Check to see if an RX Interrupt has occurred.
    //
    if(ui32Temp & EMAC_INT_RECEIVE)
    {
        //
        // Indicate that a packet has been received.
        //
        ProcessReceivedPacket();
    }
}

int main(void)
{ uint32_t ui32SysClock; uint32_t ui32User0, ui32User1, ui32Loop; uint8_t ui8PHYAddr; uint8_t pui8MACAddr[6]; // Make sure the main oscillator is enabled because this is required by // the PHY. The system must have a 25MHz crystal attached to the OSC // pins. The SYSCTL_MOSC_HIGHFREQ parameter is used when the crystal // frequency is 10MHz or higher. HWREG(SYSCTL_MOSCCTL) = SYSCTL_MOSC_HIGHFREQ; ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); //***********This delay BREAKS the program ********************************// ROM_SysCtlDelay(5242880); //*************************************************************************// // // Configure the device pins. // // PK4 is used for Ethernet LEDs. ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); ROM_GPIOPinConfigure(GPIO_PK4_EN0LED0); // // Make the pin(s) be peripheral controlled. // ROM_GPIODirModeSet(GPIO_PORTK_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW); // // Set the pad(s) for standard push-pull operation. // GPIOPadConfigSet(GPIO_PORTK_BASE, GPIO_PIN_4|GPIO_PIN_6, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); // // Read the MAC address from the user registers. // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC // address needed to program the hardware registers, then program the MAC // address into the Ethernet Controller registers. // pui8MACAddr[0] = 0x00; pui8MACAddr[1] = 0x1a; pui8MACAddr[2] = 0xb6; pui8MACAddr[3] = 0x00; pui8MACAddr[4] = 0x64; pui8MACAddr[5] = 0x00; // // 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)) { } // // Configure for use with the internal PHY. // EMACPHYConfigSet(EMAC0_BASE, (EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN | EMAC_PHY_AN_100B_T_FULL_DUPLEX)); // // Reset the MAC to latch the PHY configuration. // EMACReset(EMAC0_BASE); // // Initialize the MAC and set the DMA mode. // EMACInit(EMAC0_BASE, ui32SysClock, EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4, 0); // // Set MAC configuration options. // 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); // Initialize each of the transmit descriptors. Note that we leave the // buffer pointer and size empty and the OWN bit clear here since we have // not set up any transmissions yet. // for(ui32Loop = 0; ui32Loop < NUM_TX_DESCRIPTORS; ui32Loop++) { g_psTxDescriptor[ui32Loop].ui32Count = DES1_TX_CTRL_SADDR_INSERT; g_psTxDescriptor[ui32Loop].DES3.pLink = (ui32Loop == (NUM_TX_DESCRIPTORS - 1)) ? g_psTxDescriptor : &g_psTxDescriptor[ui32Loop + 1]; g_psTxDescriptor[ui32Loop].ui32CtrlStatus = (DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG | DES0_TX_CTRL_INTERRUPT | DES0_TX_CTRL_CHAINED | DES0_TX_CTRL_IP_ALL_CKHSUMS); } // Initialize each of the receive descriptors. We clear the OWN bit here // to make sure that the receiver doesn’t start writing anything // immediately. // for(ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++) { g_psRxDescriptor[ui32Loop].ui32CtrlStatus = 0; g_psRxDescriptor[ui32Loop].ui32Count = (DES1_RX_CTRL_CHAINED | (RX_BUFFER_SIZE << DES1_RX_CTRL_BUFF1_SIZE_S)); g_psRxDescriptor[ui32Loop].pvBuffer1 = g_ppui8RxBuffer[ui32Loop]; g_psRxDescriptor[ui32Loop].DES3.pLink = (ui32Loop == (NUM_RX_DESCRIPTORS - 1)) ? g_psRxDescriptor : &g_psRxDescriptor[ui32Loop + 1]; } // // Set the descriptor pointers in the hardware. // ROM_EMACRxDMADescriptorListSet(EMAC0_BASE, g_psRxDescriptor); ROM_EMACTxDMADescriptorListSet(EMAC0_BASE, g_psTxDescriptor); // // Start from the beginning of both descriptor chains. We actually set // the transmit descriptor index to the last descriptor in the chain // since it will be incremented before use and this means the first // transmission we perform will use the correct descriptor. // g_ui32RxDescIndex = 0; g_ui32TxDescIndex = NUM_TX_DESCRIPTORS - 1; // // Program the hardware with its MAC address (for filtering). // EMACAddrSet(EMAC0_BASE, 0, pui8MACAddr); // // Wait for the link to become active. // while(( EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) & EPHY_BMSR_LINKSTAT) == 0) { } // // 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. // for(ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++) { g_psRxDescriptor[ui32Loop].ui32CtrlStatus |= DES0_RX_CTRL_OWN; } // // Enable the Ethernet MAC transmitter and receiver. // EMACTxEnable(EMAC0_BASE); EMACRxEnable(EMAC0_BASE); // // Enable the Ethernet interrupt. // IntEnable(INT_EMAC0); // // Enable the Ethernet RX Packet interrupt source. // EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE); // // Application main loop continues.... // GPIOInit('K', 6, GPIO_OUTPUT); GPIOSet('K', 6, GPIO_ON);//Toggle LED On ROM_SysCtlDelay(30000000); GPIOSet('K', 6, GPIO_OFF);//Toggle LED Off ROM_SysCtlReset(); while(1) { // // Cannot reach this point in code. // } }

  • Hi Cam, at first please specify all other parameter you missed from:
    Operating system
    IDE version and make (CCS 6.0.1.0040)

    CCS startup (all project files if possible)
    If you can single step program

    if code is not a short snippet insert as file using rich text option of post editor.

    On this forum you can find two sticky, skip the one about USB and read the general troubleshooting point by point and report if all is ok.

    This rule IMHO is violated, your code enable peripheral then immediately program them, this is known failure peripheral need some clock to stabilize. So leave delay init, collect all ROM_SysCtlPeripheralEnable( just after clock stabilization delay wait few cycles then init all peripheral...

    About your code:
    GPIOInit('K', 6, GPIO_OUTPUT);
    GPIOSet('K', 6, GPIO_ON);//Toggle LED On
    ROM_SysCtlDelay(30000000);
    GPIOSet('K', 6, GPIO_OFF);//Toggle LED Off
    ROM_SysCtlReset();
    while(1)
    {
    //
    // Cannot reach this point in code.
    //
    }

    this code is difficult to debug other than single step...
    between Gpioset and sysctlreset addd a delay otherwise it cannot be seen.
    while loop is not reached or it is? add some splecial flashing led inside.

  • In addition to Roberto's sound advice - might it be that function, "ROM_SysCtlDelay(5242880);" either does not reside in your MCU's ROM - or suffers some other, ROM-based limitation?

    Quick/dirty test involves you calling the Flash version of that function.   (you must insure that all necessary source code modules are present)

    Worthwhile too - may be to repeat that call w/far smaller parameter value - and observe if issue lingers.   You should also move that function to another place in your code - and note if it's the function itself - or the location - which causes your issue.

    Note that "best practice" would replace that "blind" delay with an appropriate "read" of the preceding function's "completion state."  

  • Hello Roberto,

    I am having some trouble understanding everything in your post, but I will try to provide any information I am missing.

    I am running CCS 6.0.1.00040 on windows 8, I am using the TI v5.1.6 compiler.

    Linker command file: tm4c129encpdt.cmd

    CCS Startup file:

    //*****************************************************************************
    //
    // startup_ccs.c - Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2012 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    // This is part of revision 9453 of the EK-LM4F120XL Firmware Package.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // External declaration for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    extern void UartDmaIntHandler(void);
    extern void UartDmaErrorHandler(void);
    extern void SPIIntHandler(void);
    extern void EthernetIntHandler(void);
    extern void SysTickIntHandler(void);
    extern void ADCIntHandler(void);
    extern void I2CIntHandler(void);
    
    
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        SysTickIntHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        UartDmaIntHandler,                         // UART0 Rx and Tx
        UartDmaIntHandler,                         // UART1 Rx and Tx
        SPIIntHandler,                          // SSI0 Rx and Tx
        I2CIntHandler,                	        // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        ADCIntHandler,                          // ADC Sequence 0
        ADCIntHandler,   	                    // ADC Sequence 1
        ADCIntHandler,           	            // ADC Sequence 2
        ADCIntHandler,             	            // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                       // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        UartDmaIntHandler,                         // UART2 Rx and Tx
        SPIIntHandler,                          // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        I2CIntHandler, 	                        // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        EthernetIntHandler,                     // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        UartDmaErrorHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        SPIIntHandler,                          // SSI2 Rx and Tx
        SPIIntHandler,                          // SSI3 Rx and Tx
        UartDmaIntHandler,                         // UART3 Rx and Tx
        UartDmaIntHandler,                         // UART4 Rx and Tx
        UartDmaIntHandler,                         // UART5 Rx and Tx
        UartDmaIntHandler,                         // UART6 Rx and Tx
        UartDmaIntHandler,                         // UART7 Rx and Tx
        I2CIntHandler,   	                    // I2C2 Master and Slave
        I2CIntHandler,   	                    // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        I2CIntHandler,  	                    // I2C4 Master and Slave
        I2CIntHandler,    	                    // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        I2CIntHandler,    	                    // I2C6 Master and Slave
        I2CIntHandler,            	            // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        I2CIntHandler,      	                // I2C8 Master and Slave
        I2CIntHandler,     	                    // I2C9 Master and Slave
        IntDefaultHandler                       // GPIO Port T
    };
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }

    I am able to single step through the program, and it runs without any problems that I can see.  The while loop at the end is not executed, the call to ROM_SysCtrlReset() performs a reset of the micro before the while loop is executed.  The LED I am toggling on port K6 does blink when I run the program.  At some point after the program is left to run for a while, it stops blinking, indicating the controller is locked up.

    To clarify, I have put code into the ISRs that blinks another LED, and none of the ISRs were ever fired when the problem occurs. I have also found that if I remove the call to ROM_SysCtlDelay(5242880); that is between the SysCtlClockFreqSet function and the ROM_SysCtlPeripheralEnable() call the problem seems to go away, and the program can run for hours without any lockup seen. The LED is still blinking when I check on it in the morning after leaving it to run overnight.

    I will try adding a delay between the calls to SysCtlPeripheralEnable() and SysCtlPeripheralReset(), and after any other calls to SysCtlPeripheralEnable to see if that might fix the errors. 

    Thanks for your response, I hope that I can get to the bottom of this strange problem with help from this community!

  • Cam Shaw said:
    I am having some trouble understanding everything in your post, but I will try to provide any information I am missing.

     This sound strange but you posted some useful information necessary to try replicate issue.

     I think your code get some way trapped by multiple issue, read the post I was referring, is this one:

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/374640

     We refined many times so check if all listed point are ok to your board.

     Try write a debug code blinking an LED a number of time then do a start (long or short flash) repeating all the time, execute this from FaultISR, IntDefaultHandler with different parameter number to see if cpu stuck or get a fault code.

     To do this debug code don't use function but MACRO, in case of stack failure call never work.

     If you have JTAG connected when processor stop working and is responsive please post value of Fault register listed on post I highlitded to you.

  • Hello CB1, I am currently following your advice of repeated calls to the delay function with smaller values. I will let you know if that seems to fix the issue.

    I first replaced the ROM call to a library call. This did not fix the issue, the controller locked up after this change.

    I have also followed all of Roberto's advice, the only mistake I had that was related to the general troubleshooting guide was not waiting for the peripherals to be ready after enabling them. I have fixed this as the forum suggested by using a while loop to wait for them to be ready,

    I do not believe that the delay after initializing the clock is the actual problem, I believe it exaggerates the actual issue. My suspicion is that there is something happening on the Ethernet bus (from an external source) before it is initialized. I believe that this is what is causing the controller to lock up.

    The problem originally appeared on a much more complicated project, and I have reduced it to this small amount of code to try and pinpoint the cause. The delay in the original program was used for another purpose, I am not actually waiting for the clock to stabilize with that delay. I have a suspicion that I could put the delay at the beginning of main and I will see the same problem, but I have not yet been able to test this theory.

    Any other suggestions while I wait for the latest change to be tested?
  • Cam Shaw said:
     It seems it is most likely to occur around the call to EMACPHYConfigSet, but it appears to be a bit random.

    Have you seen http://processors.wiki.ti.com/index.php/TI-RTOS_TM4C129_Emac_Issues ?.

    Maybe you are suffering similar timing problems around the EMAC configuration.

  • Thanks for letting me know about this Chester, I am not using the TI-RTOS, so I doubt this is the cause of the controller lockup, but I will look into it further, it could be related.

    The Ethernet does function the way it is coded on my project, but the micro locks up once in a while, and it seems to be related to the soft reset more than anything... however if I remove that delay from my code the controller doesn't seem to lock up anymore. I will be running a long term test this weekend to see if that is the actual case, it could be that it just becomes less likely to happen when the delay is removed...
  • Update, I split the delay into 10 different calls and still had a controller lockup.

    NOTE: I get error -2602 when I try to reconnect to the core, so I am unable to see where the controller is locked up at, and am not able to read out any registers.
  • Hi Cam, just two other things:
    1> try reduce clock to 60-70MHz and see if lock again, failure pointed to by Chester caused me and other a nightmare from Network hiccup.
    2> please post silicon revision of your chip (silicon errata known issue)
  • Hello Cam

    So far we have been concentrating on the software, where the post from Chester, cb1 and roberto all seem to indicate the issue may be related to the Prefetch buffer.

    Since you mentioned this in the post, I could not stop but think, that since this is a custom board, is there something with the layout or the board that may be contributing to the cause as well...

    Regards
    Amit
  • Hello Amit, and Community,

    I was starting to think that we were on to something, and that the problem might be hardware related. Then I had my project lock up on a Tiva™ C Series TM4C1294 Connected LaunchPad Evaluation Kit...

    So now I am back to square 1.  This problem is very intermittent seeing as last week I had let the eval board run overnight without an issue, but a weekend of testing had the evaluation board locked up. Restarting the program today I have seen the board lock up multiple times.  

    Is there a way that I might be able to upload my entire project to the community forum so that others could take a look and try to help me find a solution?  I need to get to the bottom of this as soon as possible.

    Here is all the information that I have thus far:

    I am using CCS 6.0.1.00040. I am using the TI v5.1.6 compiler. I have seen this problem on both the TM4C129ENCPDT and the TM1294NCPDT.  I am linking in Tivaware_C_Series-2.1.0.12573 library for the peripheral access functions. I am using an XDS100v2 debugger to connect and download to the target.

    Arm Compiler Settings:

    -mv7M4 --code_state=16 --float_support=FPv4SPD16 --abi=eabi -me --include_path="c:/ti/ccsv6/tools/compiler/arm_5.1.6/include" --include_path="C:/ti/TivaWare_C_Series-2.1.0.12573" -g --gcc --define=ccs="ccs" --define=PART_TM4C1294NCPDT --display_error_number --diag_warning=225 --diag_wrap=off

    Arm Linker Settings:

    -mv7M4 --code_state=16 --float_support=FPv4SPD16 --abi=eabi -me -g --gcc --define=ccs="ccs" --define=PART_TM4C1294NCPDT --display_error_number --diag_warning=225 --diag_wrap=off -z -m"Test_Project.map" --heap_size=0 --stack_size=512 -i"c:/ti/ccsv6/tools/compiler/arm_5.1.6/lib" -i"c:/ti/ccsv6/tools/compiler/arm_5.1.6/include" --reread_libs --warn_sections --display_error_number --diag_wrap=off --xml_link_info="Test_Project_linkInfo.xml" --rom_model

    My project is very simple. It initializes the GPIO ports that are used, the external oscillator,  Ethernet, and configures Ethernet and then performs a soft reset. I toggle a couple of LEDs so that I can see the progress in the program and so that I can see it is still running.

    When the controller locks up the LEDs will stop toggling. This morning it has been locking up with LED D2(PortN0) and D4(Ethernet Link port F0) still lit up, but I have seen random behavior with my own hardware. My own hardware has more LEDs to play with, and I was initially using them to try and focus in on the problem area, but was seeing the controller lock up with different LEDs on indicating that the lockup could happen anywhere in the program.

    I had also implemented a watchdog, but the board was still able to lock up.  (in the latest attempt using the evaluation board I have the watchdog disabled)

    Here is my code, this is what I am running on the evaluation board: (The file testWatchdog.h contains the definitions I have been using for conditional compiles to enable/disable the watchdog, or waiting for peripherals. Watchdog is disabled, but the POTENTIAL_FIX_1 flag is defined.)

    tm4c1294ncpdt.cmd

    /******************************************************************************
     *
     * Default Linker Command file for the Texas Instruments TM4C1294NCPDT
     *
     * This is derived from revision 12770 of the TivaWare Library.
     *
     *****************************************************************************/
    
    --retain=g_pfnVectors
    
    MEMORY
    {
        FLASH (RX) : origin = 0x00000000, length = 0x00100000
        SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    }
    
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* --heap_size=0                                                             */
    /* --stack_size=256                                                          */
    /* --library=rtsv7M4_T_le_eabi.lib                                           */
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > 0x00000000
        .text   :   > FLASH
        .const  :   > FLASH
        .cinit  :   > FLASH
        .pinit  :   > FLASH
        .init_array : > FLASH
    
        .vtable :   > 0x20000000
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM
    }
    
    __STACK_TOP = __stack + 512;
    

    tm4c1294ncpdt_startup_css.c:

    //*****************************************************************************
    //
    // Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Software License Agreement
    //
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // External declarations for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    // To be added by user
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,                      // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        IntDefaultHandler,                      // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        IntDefaultHandler,                      // I2C6 Master and Slave
        IntDefaultHandler,                      // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        IntDefaultHandler,                      // I2C8 Master and Slave
        IntDefaultHandler,                      // I2C9 Master and Slave
        IntDefaultHandler,                      // GPIO Port T
        IntDefaultHandler,                      // Fan 1
        0,                                      // Reserved
    };
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    

    main.c:

    /*
     * main.c
     */
    #include <stdbool.h>
    #include <stdint.h>
    #ifdef PART_TM4C129ENCPDT
        #include "inc/tm4c129encpdt.h"
    #endif //PART_TM4C129ENCPDT
    #ifdef PART_TM4C1294NCPDT
    #include "inc/tm4c1294ncpdt.h"
    #endif
    #include "inc/hw_emac.h"
    //#include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_sysctl.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/emac.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/gpio.h"
    #include "testWatchdog.h"
    
    int32_t ProcessReceivedPacket(void);
    void EthernetIntHandler(void);
    static int32_t PacketTransmit(uint8_t *pui8Buf, int32_t i32BufLen);
    void InitDescriptors(uint32_t ui32Base);
    void InitPorts(void);
    uint32_t InitClock(void);
    void InitEthernet(void);
    void ConfigEthernet(uint32_t clockSpeed);
    
    //*****************************************************************************
    //
    // Ethernet DMA descriptors.
    //
    // The MAC hardware needs a minimum of 3 receive descriptors to operate. The
    // number used will be application-dependent and should be tuned for best
    // performance.
    //
    //*****************************************************************************
    #define NUM_TX_DESCRIPTORS 3
    #define NUM_RX_DESCRIPTORS 3
    tEMACDMADescriptor g_psRxDescriptor[NUM_TX_DESCRIPTORS];
    tEMACDMADescriptor g_psTxDescriptor[NUM_RX_DESCRIPTORS];
    uint32_t g_ui32RxDescIndex;
    uint32_t g_ui32TxDescIndex;
    uint8_t pui8MACAddr[6];
    //*****************************************************************************
    //
    // Transmit and receive buffers. These will typically be allocated within your
    // network stack somewhere.
    //
    //*****************************************************************************
    #define RX_BUFFER_SIZE 1536
    uint8_t g_ppui8RxBuffer[NUM_RX_DESCRIPTORS][RX_BUFFER_SIZE];
    //*****************************************************************************
    //
    // Read a packet from the DMA receive buffer and return the number of bytes
    // read.
    //
    //*****************************************************************************
    int32_t ProcessReceivedPacket(void)
    {
        int_fast32_t i32FrameLen;
        //
        // By default, we assume we got a bad frame.
        //
        i32FrameLen = 0;
        //
        // Make sure that we own the receive descriptor.
        //
        if (!(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus & DES0_RX_CTRL_OWN))
        {
            //
            // We own the receive descriptor so check to see if it contains a valid
            // frame.
            //
            if (!(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus
                    & DES0_RX_STAT_ERR))
            {
                //
                // We have a valid frame. First check that the "last descriptor"
                // flag is set. We sized the receive buffer such that it can
                // always hold a valid frame so this flag should never be clear at
                // this point but...
                //
                if (g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus
                        & DES0_RX_STAT_LAST_DESC)
                {
                    //
                    // What size is the received frame?
                    //
                    i32FrameLen = ((g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus
                                    & DES0_RX_STAT_FRAME_LENGTH_M)
                                    >> DES0_RX_STAT_FRAME_LENGTH_S);
                    //
                    // Pass the received buffer up to the application to handle.
                    //
                    //ApplicationProcessFrame(i32FrameLen, g_psRxDescriptor[g_ui32RxDescIndex].pvBuffer1);
                }
            }
            //
            // Now that we are finished dealing with this descriptor, hand
            // it back to the hardware. Note that we assume
            // ApplicationProcessFrame() is finished with the buffer at this point
            // so it is safe to reuse.
            //
            g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus = DES0_RX_CTRL_OWN;
            //
            // Move on to the next descriptor in the chain.
            //
            g_ui32RxDescIndex++;
            if (g_ui32RxDescIndex == NUM_RX_DESCRIPTORS)
            {
                g_ui32RxDescIndex = 0;
            }
        }
        //
        // Return the Frame Length
        //
        return (i32FrameLen);
    }
    
    //*****************************************************************************
    //
    // The interrupt handler for the Ethernet interrupt.
    //
    //*****************************************************************************
    void EthernetIntHandler(void)
    {
        uint32_t ui32Temp;
        //
        // Read and Clear the interrupt.
        //
        ui32Temp = EMACIntStatus(EMAC0_BASE, true);
        EMACIntClear(EMAC0_BASE, ui32Temp);
        //
        // Check to see if an RX Interrupt has occurred.
        //
        if (ui32Temp & EMAC_INT_RECEIVE)
        {
            //
            // Indicate that a packet has been received.
            //
            ProcessReceivedPacket();
        }
    }
    
    //*****************************************************************************
    //
    // Transmit a packet from the supplied buffer. This function would be called
    // directly by the application. pui8Buf points to the Ethernet frame to send
    // and i32BufLen contains the number of bytes in the frame.
    //
    //*****************************************************************************
    static int32_t PacketTransmit(uint8_t *pui8Buf, int32_t i32BufLen)
    {
        //
        // Wait for the transmit descriptor to free up.
        //
        while (g_psTxDescriptor[g_ui32TxDescIndex].ui32CtrlStatus & DES0_TX_CTRL_OWN)
        {
            //
            // Spin and waste time.
            //
        }
        //
        // Move to the next descriptor.
        //
        g_ui32TxDescIndex++;
        if (g_ui32TxDescIndex == NUM_TX_DESCRIPTORS)
        {
            g_ui32TxDescIndex = 0;
        }
        //
        // Fill in the packet size and pointer, and tell the transmitter to start
        // work.
        //
        g_psTxDescriptor[g_ui32TxDescIndex].ui32Count = (uint32_t) i32BufLen;
        g_psTxDescriptor[g_ui32TxDescIndex].pvBuffer1 = pui8Buf;
        g_psTxDescriptor[g_ui32TxDescIndex].ui32CtrlStatus = (DES0_TX_CTRL_LAST_SEG
                | DES0_TX_CTRL_FIRST_SEG | DES0_TX_CTRL_INTERRUPT
                | DES0_TX_CTRL_IP_ALL_CKHSUMS | DES0_TX_CTRL_CHAINED
                | DES0_TX_CTRL_OWN);
        //
        // Tell the DMA to reacquire the descriptor now that we’ve filled it in.
        // This call is benign if the transmitter hasn’t stalled and checking
        // the state takes longer than just issuing a poll demand so we do this
        // for all packets.
        //
        EMACTxDMAPollDemand(EMAC0_BASE);
        //
        // Return the number of bytes sent.
        //
        return (i32BufLen);
    }
    
    //*****************************************************************************
    //
    // Initialize the transmit and receive DMA descriptors.
    //
    //*****************************************************************************
    void InitDescriptors(uint32_t ui32Base)
    {
        uint32_t ui32Loop;
        //
        // Initialize each of the transmit descriptors. Note that we leave the
        // buffer pointer and size empty and the OWN bit clear here since we have
        // not set up any transmissions yet.
        //
        for (ui32Loop = 0; ui32Loop < NUM_TX_DESCRIPTORS; ui32Loop++)
        {
            g_psTxDescriptor[ui32Loop].ui32Count = DES1_TX_CTRL_SADDR_INSERT;
            g_psTxDescriptor[ui32Loop].DES3.pLink = (ui32Loop == (NUM_TX_DESCRIPTORS - 1)) ? g_psTxDescriptor : &g_psTxDescriptor[ui32Loop + 1];
            g_psTxDescriptor[ui32Loop].ui32CtrlStatus = (DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG | DES0_TX_CTRL_INTERRUPT | DES0_TX_CTRL_CHAINED | DES0_TX_CTRL_IP_ALL_CKHSUMS);
        }
        //
        // Initialize each of the receive descriptors. We clear the OWN bit here
        // to make sure that the receiver doesn’t start writing anything
        // immediately.
        //
        for (ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++)
        {
            g_psRxDescriptor[ui32Loop].ui32CtrlStatus = 0;
            g_psRxDescriptor[ui32Loop].ui32Count = (DES1_RX_CTRL_CHAINED | (RX_BUFFER_SIZE << DES1_RX_CTRL_BUFF1_SIZE_S));
            g_psRxDescriptor[ui32Loop].pvBuffer1 = g_ppui8RxBuffer[ui32Loop];
            g_psRxDescriptor[ui32Loop].DES3.pLink = (ui32Loop == (NUM_RX_DESCRIPTORS - 1)) ?g_psRxDescriptor : &g_psRxDescriptor[ui32Loop + 1];
        }
        //
        // Set the descriptor pointers in the hardware.
        //
        EMACRxDMADescriptorListSet(ui32Base, g_psRxDescriptor);
        EMACTxDMADescriptorListSet(ui32Base, g_psTxDescriptor);
        //
        // Start from the beginning of both descriptor chains. We actually set
        // the transmit descriptor index to the last descriptor in the chain
        // since it will be incremented before use and this means the first
        // transmission we perform will use the correct descriptor.
        //
        g_ui32RxDescIndex = 0;
        g_ui32TxDescIndex = NUM_TX_DESCRIPTORS - 1;
    }
    
    uint32_t InitClock(void)
    {
        return SysCtlClockFreqSet( ( SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480 ), 120000000 );
    }
    
    void InitPorts(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    #ifdef POTENTIAL_FIX_1
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
        {
        }
    #endif
        GPIOPinConfigure(GPIO_PF0_EN0LED0);
        GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_DIR_MODE_HW);
        GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    #ifdef POTENTIAL_FIX_1
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION))
        {
        }
    #endif
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0); //Use Port N0 as an LED Output
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1); //Use Port N1 as an LED Output
    
    }
    
    void InitEthernet(void)
    {
        uint32_t ui32User0, ui32User1;
    
        ui32User0 = 0x00B61A00;
        ui32User1 = 0x00006400;
        //
        // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
        // address needed to program the hardware registers, then program the MAC
        // address into the Ethernet Controller registers.
        //
        pui8MACAddr[0] = ((ui32User0 >> 0) & 0xff);
        pui8MACAddr[1] = ((ui32User0 >> 8) & 0xff);
        pui8MACAddr[2] = ((ui32User0 >> 16) & 0xff);
        pui8MACAddr[3] = ((ui32User1 >> 0) & 0xff);
        pui8MACAddr[4] = ((ui32User1 >> 8) & 0xff);
        pui8MACAddr[5] = ((ui32User1 >> 16) & 0xff);
    
        //
        // Enable and reset the Ethernet modules.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
    #ifdef POTENTIAL_FIX_1
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
        {
        }
    #endif
        SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
    #ifdef POTENTIAL_FIX_1
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0))
        {
        }
    #endif
        SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
        SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
        //
        // Wait for the MAC to be ready.
        //
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
        {
        }
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0))
        {
        }
    }
    
    void ConfigEthernet(uint32_t clockSpeed)
    {
        uint32_t ui32Loop;
        uint8_t ui8PHYAddr;
    
        //
        // Configure for use with the internal PHY.
        //
        ui8PHYAddr = 0;
        EMACPHYConfigSet(EMAC0_BASE, (EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN | EMAC_PHY_AN_100B_T_FULL_DUPLEX));
        //
        // Reset the MAC to latch the PHY configuration.
        //
        EMACReset(EMAC0_BASE);
        //
        // Initialize the MAC and set the DMA mode.
        //
        EMACInit(EMAC0_BASE, clockSpeed, EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4, 0);
        //
        // Set MAC configuration options.
        //
        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);
        //
        // Initialize the Ethernet DMA descriptors.
        //
        InitDescriptors(EMAC0_BASE);
        //
        // Program the hardware with its MAC address (for filtering).
        //
        EMACAddrSet(EMAC0_BASE, 0, pui8MACAddr);
        //
        // Wait for the link to become active.
        //
        while ((EMACPHYRead(EMAC0_BASE, ui8PHYAddr, EPHY_BMSR) & EPHY_BMSR_LINKSTAT) == 0)
        {
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1 );
    #ifdef USE_WATCHDOG
            PetWatchdog();
    #endif
        }
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0 );
    
        //
        // 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.
        //
        for (ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++)
        {
            g_psRxDescriptor[ui32Loop].ui32CtrlStatus |= DES0_RX_CTRL_OWN;
        }
        //
        // Enable the Ethernet MAC transmitter and receiver.
        //
        EMACTxEnable(EMAC0_BASE);
        EMACRxEnable(EMAC0_BASE);
        //
        // Enable the Ethernet interrupt.
        //
        IntEnable(INT_EMAC0);
        //
        // Enable the Ethernet RX Packet interrupt source.
        //
        EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE);
    }
    
    //*****************************************************************************
    //
    // This example demonstrates the use of the Ethernet Controller.
    //
    //*****************************************************************************
    int main(void)
    {
        uint32_t ui32SysClock;
        static volatile uint32_t Reset_Cause = 0;
    
        //
        // Configure the device pins.
        //
        InitPorts();
    
    #ifdef USE_WATCHDOG
        WatchdogInit();
    #endif
        //
        // Run from the PLL at 120 MHz.
        //
        ui32SysClock = InitClock();
        //SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
        //SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
        //SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
        //SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
        //SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0 );
    
        SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
        InitEthernet();
        //SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
        ConfigEthernet(ui32SysClock);
        //SysCtlDelay(20000000);//Half Second
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0 );
        SysCtlDelay(4000000);//100ms
    #ifdef USE_WATCHDOG
        PetWatchdog();
    #endif
    
    #ifdef BLINKER
    #else
    
        Reset_Cause = SysCtlResetCauseGet();
        SysCtlResetCauseClear(Reset_Cause);
        SysCtlReset();
    #endif
    
        while (1)
        {
            //
            // Do main loop things...
            //
            GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_6, GPIO_PIN_6 );
            SysCtlDelay(10000000);//quarter Second
            GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_6, 0 );
            SysCtlDelay(10000000);//quarter Second
        }
    }
    

    testWatchdog.h:

    /*
     * testWatchdog.h
     *
     *  Created on: Jan 26, 2015
     *      Author: cshaw
     */
    
    #ifndef testWATCHDOG_H_
    #define testWATCHDOG_H_
    
    //#define USE_WATCHDOG
    #define POTENTIAL_FIX_1
    //#define BLINKER
    
    extern void WatchdogInit(void);
    extern void PetWatchdog(void);
    extern void WatchdogISR(void);
    
    #endif /* testWATCHDOG_H_ */
    

    testWatchdog.c:

    /*
     * testWatchdog.c
     *
     *  Created on: Jan 26, 2015
     *      Author: cshaw
     */
    #include <stdbool.h>
    #include <stdint.h>
    #ifdef PART_TM4C129ENCPDT
        #include "inc/tm4c129encpdt.h"
    #endif //PART_TM4C129ENCPDT
    #ifdef PART_TM4C1294NCPDT
    #include "inc/tm4c129encpdt.h"
    #endif
    #include "inc/hw_memmap.h"
    #include "inc/hw_sysctl.h"
    #include "driverlib/sysctl.h"
    #include "inc/hw_types.h"
    #include "driverlib/watchdog.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "testWatchdog.h"
    
    void WatchdogInit(void);
    void PetWatchdog(void);
    void WatchdogISR(void);
    
    void WatchdogInit(void)
    {
        //Enable Watchdog timer 1 run mode clock gating control to enable and provide a clock to the watchdog 1 module.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG1);
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_WDOG1))
        {
        }
    
        // Load the reset value
        //
        // Set the period of the watchdog timer to 1 second.
        //
        WatchdogStallEnable(0x40001000);
        WatchdogReloadSet(0x40001000, 0x00F42400);
        IntEnable(INT_WATCHDOG);
        IntMasterEnable();
        WatchdogResetEnable(0x40001000);
        WatchdogEnable(0x40001000);
    }
    
    void PetWatchdog(void)
    {
        // Load the reset value
        WatchdogReloadSet(0x40001000, 0x00F42400);
    }
    
    void WatchdogISR(void)
    {
        while(1)
        {
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0 );
            SysCtlDelay(4000000);
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0 );
            SysCtlDelay(4000000);
        }
    }
    

    Thank you for taking the time to look at this, I am looking forward to any comments that will help me to solve this issue.  I hope we can find a solution quickly!

  • Hello Cam,

    We are tracking a similar issue (same I believe). It seems that clock source for OSCSRC may be the problem (but we need to narrow it down further)

    e2e.ti.com/.../399372

    Regards,
    Amit
  • Thanks for the response Amit.  I have implemented the library change you had suggested and am testing it out on my own hardware as I write this.  I will let you know how it goes.

    Side Note:  I have notice that when I changed targets to the TM4C1294NCPDT device I had forgotten to remap the Ethernet RX interrupt.  It is possible that I was stuck running in an unhandled interrupt when the eval board was locked up during my testing. I am sure this problem still occurs on the eval board though because I have also modified one replacing the TM4C1294 with a TM4C129E, and I did have it lock up with the interrupts correctly mapped in the TM4C129E startup file that was included for that target.

    If you are going to try to replicate my problem use the following for tm4c1294ncpdt_startup_ccs.c

     

    //*****************************************************************************
    //
    // Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Software License Agreement
    //
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // External declarations for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    extern void EthernetIntHandler(void);
    extern void WatchdogISR(void);
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,                      // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        WatchdogISR,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        EthernetIntHandler,                      // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        IntDefaultHandler,                      // I2C6 Master and Slave
        IntDefaultHandler,                      // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        IntDefaultHandler,                      // I2C8 Master and Slave
        IntDefaultHandler,                      // I2C9 Master and Slave
        IntDefaultHandler,                      // GPIO Port T
        IntDefaultHandler,                      // Fan 1
        0,                                      // Reserved
    };
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    

     

  • Hello Cam

    The Interrupt Vector Table will remain the same across the TM4C129 family of devices.

    Regards
    Amit
  • Hello Amit,

    I have been testing the library change that was suggested on this issue, and my hardware has been running overnight without seeing the lockup problem.

    I will test this for the next several days to gain more confidence that the issue has indeed been corrected.  Seeing as this is a problem with a library call will there be a new version of the library coming?  Also, when can I expect to see the updated library available, if it will be released?

    Thanks for your help,

    Cam

  • Hello Cam,

    Yes, the library call will be updated once we get to the root of the problem. Thanks a lot for helping us out testing it with a different application code so that we can cover more ground.

    Regards
    Amit
  • Hello Amit,

    I am trying to understand the impact of the change that you have already suggested as the fix for this issue.  Do I understand correctly when thinking that this change will allow the PIOSC to be used for the system clock until the PLL has stabilized, but that the PLL is indeed used for the system clock as soon as it has stabilized?

    Is this going to be the final fix (assuming testing shows that the failure does not come back)?

    Thanks again,

    Cam

    Edit: Would it not be better practice to enable the MOSC before making a call to the SysCtlClockFreqSet() function, and then to delay for the time that is required for the external oscillator to stabilize?  Would there be a way to programatically determine if the MOSC is stable before calling the SysCtlClockFreqSet() function?

    Thanks

  • Cam Shaw said:
    Would it not be better practice to enable the MOSC before making a call to the SysCtlClockFreqSet() function, and then to delay for the time that is required for the external oscillator to stabilize?  Would there be a way to programatically determine if the MOSC is stable before calling the SysCtlClockFreqSet() function?

    There are the following bits in the Raw Interrupt Status (RIS) register for monitoring the MOSC status:  

    1) The MOSCPUPRIS bit in the which indicates if "Sufficient time has passed for the MOSC to reach the expected frequency".

    2) The MOFRIS bit which indicates if "The MOSCIM bit in the MOSCCTL register is set and the main oscillator has failed".

    In order for the MOFRIS bit to be set, in the MOSCCTL register:

    - The MOSCIM bit must be set (to disable a reboot upon failure)

    - The CVAL bit must be set (to enable Clock Validation for MOSC)

    i.e. looks like MOSC checking could consist of waiting for sufficient time to pass to reach the expected frequency, and that after that time the MOSC isn't indicated as failed.

    From looking at the sysctl.c from TivaWare 2.1.0.12573 noticed that the the SysCtlClockSet() function is checking the MOSCPUPRIS bit, but the SysCtlClockFreqSet() function isn't checking the MOSCPUPRIS bit. Not sure if the reason for the problems.

  • Hello Chester,

    So far all the debug shows that the MOSC stabilization is not the cause. However that has to be included in the function to ensure a correct start up.

    Hello Cam,

    The change ensures that at the time of reset the clock switchover does not cause an issue.

    Regards
    Amit
  • Hello Amit,

    I have had several boards running since I had made the library change that you suggested in order to fix the lockup issue.  I had two demo boards, 1 with a TM4C1294NCPDT, and one that had been modified by us to use a TM4C129ENCPDT, and have two boards with our hardware, with one using a TM4C1294NCPDT and the other using a TM4C129ENCPDT.

    I am running a test program that initializes the GPIO ports we are using, then initializes the clock, sets a port high (connected to an LED), delays for a half a second, initializes ethernet, configures ethernet. Another LED port is set high while waiting for the PHY BMSR bit to clear, and then it is turned off when the bit is set to zero. After that the first LED is turned off, the reset causes are read using SysCtlResetCauseGet() and they are cleared uusing SysCtlResetCauseClear, then SysCtrlReset is called.

    All four of the boards running this code were tested for several days and did not have any lockup issues in that time.  After several days I ended up turning off the demo boards, but I had left our boards running for an entire week.  When I came into the office today the board using the TM4C1294NCPDT was locked up. There are no LEDs lit up on the board indicating that the board locked up early or late in the program.

    Have you found any further problems with the library calls? I have restarted the tests on the demo boards to try to determine if they will lock up if they are left running for a week, and I am looking for more help to resolve whatever might be causing the issue. When I try to connect to the device the debugger reports the following error:

    CORTEX_M4_0: Can't Run Target CPU: (Error -1268 @ 0x1090001) Device is locked up in Hard Fault or in NMI. Reset the device, and retry the operation. If error persists, confirm configuration, power-cycle the board, and/or try more reliable JTAG settings (e.g. lower TCLK). (Emulation package 5.1.507.0)
    CORTEX_M4_0: Flash Programmer: Timed out while writing to Flash memory
    CORTEX_M4_0: GEL: File: C:\Workspace\Projects\PF3100\Test Project Backup\Debug\Test_Project.out: Load failed.

    Does this error give any clues as to where the device might be locked up in the program? 

    If you have any other ideas as to what might need to be modified to avoid this issue please let me know!

    Thanks, Cam

  • Hello Cam,

    On the other thread Hiroyasu reported that the fix is not working for him, so we have asked him to send the device back so that we can check if this is device specific. However they were functionally accessible.

    Since you have ethernet as well in the code, I suspect it to be an issue where the Phy may not have started up. Do you still have the prefetch buffer disable before PHY initialization as part of the code?

    Regards
    Amit
  • Hello Amit,

    I don't have anything in my code that will disable the prefetch buffer.

    This is the ethernet init function:

    void InitEthernet(void)
    {
        uint32_t ui32User0, ui32User1;
        // Read the MAC address from the user registers.
        //
        //    pui8MACAddr[0] = 0x00;
        //    pui8MACAddr[1] = 0x1a;
        //    pui8MACAddr[2] = 0xb6;
        //    pui8MACAddr[3] = 0x00;
        //    pui8MACAddr[4] = 0x64;
        //    pui8MACAddr[5] = 0x00;
        ui32User0 = 0x00B61A00;
        ui32User1 = 0x00006400;
        //
        // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
        // address needed to program the hardware registers, then program the MAC
        // address into the Ethernet Controller registers.
        //
        pui8MACAddr[0] = ((ui32User0 >> 0) & 0xff);
        pui8MACAddr[1] = ((ui32User0 >> 8) & 0xff);
        pui8MACAddr[2] = ((ui32User0 >> 16) & 0xff);
        pui8MACAddr[3] = ((ui32User1 >> 0) & 0xff);
        pui8MACAddr[4] = ((ui32User1 >> 8) & 0xff);
        pui8MACAddr[5] = ((ui32User1 >> 16) & 0xff);
    
        //
        // Enable and reset the Ethernet modules.
        //
        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);
        //
        // Wait for the MAC to be ready.
        //
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
        {
        }
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0))
        {
        }
    }

    And this is the ethernet config function:

    void ConfigEthernet(uint32_t clockSpeed)
    {
        uint32_t ui32Loop;
        uint8_t ui8PHYAddr;
    
        //
        // Configure for use with the internal PHY.
        //
        ui8PHYAddr = 0;
        EMACPHYConfigSet(EMAC0_BASE, (EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN | EMAC_PHY_AN_100B_T_FULL_DUPLEX));
        //
        // Reset the MAC to latch the PHY configuration.
        //
        EMACReset(EMAC0_BASE);
        //
        // Initialize the MAC and set the DMA mode.
        //
        EMACInit(EMAC0_BASE, clockSpeed, EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4, 0);
        //
        // Set MAC configuration options.
        //
        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);
        //
        // Initialize the Ethernet DMA descriptors.
        //
        InitDescriptors(EMAC0_BASE);
        //
        // Program the hardware with its MAC address (for filtering).
        //
        EMACAddrSet(EMAC0_BASE, 0, pui8MACAddr);
        //
        // Wait for the link to become active.
        //
        while ((EMACPHYRead(EMAC0_BASE, ui8PHYAddr, EPHY_BMSR) & EPHY_BMSR_LINKSTAT) == 0)
        {
            GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_PIN_0 );//Write Pin 0 high
        }
        GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0 );//Write Pin 0 low
    
        //
        // 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.
        //
        for (ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++)
        {
            g_psRxDescriptor[ui32Loop].ui32CtrlStatus |= DES0_RX_CTRL_OWN;
        }
        //
        // Enable the Ethernet MAC transmitter and receiver.
        //
        EMACTxEnable(EMAC0_BASE);
        EMACRxEnable(EMAC0_BASE);
        //
        // Enable the Ethernet interrupt.
        //
        IntEnable(INT_EMAC0);
        //
        // Enable the Ethernet RX Packet interrupt source.
        //
        EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE);
    }

    What would I need to do to disable the prefetch, and is there a specific place that I should do it?

    Thanks,

    Cam

  • Hello Cam,

    After System Clock Initialization, but before ethernet initialization write 1 to FLASHCONF.FPFOFF register bit . Once ethernet initialization is done clear the FLASHCONF.FPFOFF

    Regards
    Amit
  • Hello Amit,

    Do you have any estimations as to when the Tivaware libraries will be updated and released? We have rebuilt them with the change you suggested, but have found that there are problems with the SPI driver with the version we rebuilt. It could be due to a compiler setting issue or version issue, but either way it no longer works the same as the version TI released.

    Please let me know when the updated libraries will be available. Thanks!
  • Hello Cam,

    What issue with the SPI Driver. If you can list it out and it indeed is a software library issue, I can see how to get it in the build?

    Regards
    Amit
  • We aren't even sure the problem is coming from SPI, but the point is that with the original Tivaware library the project was working fine, and with the rebuilt Tivaware library (with the single change for clock initialization) the project is no longer working properly. One of my colleagues noticed the problem, so I am not able to describe it here. He is still looking into it.

    What I want to know at this point in time, is when the fixed Tivaware library will be released. Thanks again!

    If we decide to chase this SPI problem further we will likely start a new thread.
  • Hello Cam,

    No formal date but testing is held up for the qs_iot example fixes to cross the 2 week timeline. After that one-two weeks of packaging and release.

    Regards
    Amit
  • (EMAC_MODE_RX_STORE_FORWARD | EMAC_MODE_TX_STORE_FORWARD

                       | EMAC_MODE_TX_THRESHOLD_64_BYTES

                       | EMAC_MODE_RX_THRESHOLD_64_BYTES), 2048); // 2048 was 0

    0? Don't like: Seems plausible watchdog timer may still fire ever receive frame > 2048 bytes and there is no WD timeout (WTO) value REG-22.  Abnormal OR'd  interrupts (tiva-tm4c129.c); The SW continues processing the interrupt and oversize frame might unintentionally lead up to a DMA bus error possibly causing MPU reset or Halt. Seems Tivaware may program registers in conflict with DMA RX-Descriptor returned error status and lwiplib.c improperly handles case oversize frames are received.

    Stop drop and roll if ever on fire and let the other guy resend the frame in absence of a returned frame ACK.

    Tivaware library:
        //
        // Set the maximum receive frame size.  If 0 is passed, this implies
        // that the default maximum frame size should be used so just turn off
        // the override.
         //
        if(ui32RxMaxFrameSize)
        {
            HWREG(ui32Base + EMAC_O_WDOGTO) = ui32RxMaxFrameSize | EMAC_WDOGTO_PWE;
    
            // Set the Watchdog interrupt timeout period WTO >1522 (Giant), Max-frame
            // size 2048 bytes. WDOGTO-PWE bit 16 set enables watchdog timer.
            // RxDES1 bit 31 cleared resets the timer, REG- 61 Page 1581
    
    HWREG(ui32Base + EMAC_O_RXINTWDT) = EMAC_WDOGTO_WTO_G; //2048 } else { HWREG(ui32Base + EMAC_O_WDOGTO) &= ~EMAC_WDOGTO_PWE; //{bitwise not PWE = -65537} }


    Check Dogs bark indicates a giant frame at the front door.

        void
    lwIPEthernetIntHandler(void)
    {
    ~~~~~~~~~~~~~~~~
        //
        // Check if interrupt has set RWT bit 9 (Receive Watchdog timeout).
        // A frame over 2048 bytes will trip the Watchdog timer interrupt.
        // When WTO set period runs out it sets receive interrupt RI. When
        // the DMA engines RDES1[31] has been cleared, the timer is reset.
        // We assume the frame an error, flush FIFO dropping the frame.
        //
        if(ui32Status == EMAC_DMARIS_RWT)
        {
    	  g_ui32AbnormalInts++;
    
    	  UARTprintf(">> RXD-WDOG: Abnormal INTs --->>:%i\r\n", g_ui32AbnormalInts);
    
    	  return;
        }
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`` void tivaif_interrupt(struct netif *psNetif, uint32_t ui32Status) { tStellarisIF *tivaif; ~~~~~ if(ui32Status & EMAC_INT_ABNORMAL_INT) { g_ui32AbnormalInts++; UARTprintf(">> Return: Abnormal INTs --->>:%i\r\n", g_ui32AbnormalInts); // Application don't process abnormal interrupts. Allow the // DMA engine & watchdog timer arbitrate frame issues. // return; }
  • BTW: Be sure to test the WRC bit state, signals the GAP time when it is safe for any back to back writes into WD1 registers. Datasheet states Wdog1 uses ALTCFG clock source therefore requires SW preform this GAP test, prior to asserting WRLS is my guess.

    void PetWatchdog(void)
    {
    // Load the reset value
    WatchdogReloadSet(0x40001000, 0x00F42400);
  • Hi Cam
    We run into exactly the same issue. Our boards occasionally crash at startup. We have a TM4C1294 processor and also use Ethernet.
    If you resolved the problem, what was the root cause?
    Thanks and regards,
    Daniel
  • Hello Daniel,

    After making the changes to the library that were suggested in this issue for the clock initializations, and disabling the prefetch buffer during ethernet initialization, we have no longer seen any issues.

    I believe that this was eventually taken care of in an update to the Tiva driver library.

    Cam