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.

Timer interrupt works using debugger, but not when booting off flash



I have a project that is using the C6672.  I have a timer interrupt running at 10 uS.  Everything works properly when I'm running my code through the CCS debugger.  When I write my program into an SPI Flash and boot normally, the system appears to hang. 

If I don't setup my timer interrupt, the rest of the code runs properly when booting from flash.  If I then setup the timer again, things hang.

If the timer never worked, even under the debugger, I would keep digging and hope to find where my bug was, but with it working under the debugger, but not when I boot from flash, I'm guessing the gel setup does something extra that I'm not doing for myself that allows the interrupts to work properly.

I'm using the standard C6678 gel file when debugging.  Is there something interrupt specific that the gel file does during Global Default Setup that I need to add to my timer setup?  I'm configuring the PLL the same way the gel file does. 

My timer setup code does the following:

CSL_intcInit (&intcContext);

CSL_intcGlobalNmiEnable ();

CSL_intcGlobalEnable (&state);

CSL_tmrInit (NULL);

memset (&TmrObj, 0, sizeof (CSL_TmrObj));

vectId = CSL_INTC_VECTID_13;

tmrIntcHandle = CSL_intcOpen(&tmrIntcObj, CSL_GEM_TINTHN, &vectId, NULL);

EventRecord.handler = (CSL_IntcEventHandler) &TimerInterruptHandler;

EventRecord.arg     = (void *) CSL_GEM_TINTLN;

CSL_intcPlugEventHandler (tmrIntcHandle, &EventRecord);

CSL_intcHwControl (tmrIntcHandle, CSL_INTC_CMD_EVTENABLE, NULL);

hTmr = CSL_tmrOpen (&TmrObj, IntcInstance, NULL, &status);

CSL_tmrHwSetup (hTmr, &hwSetup);

CSL_tmrHwControl (hTmr, CSL_TMR_CMD_RESET_TIMHI, NULL);

hwSetup.tmrTimerMode = CSL_TMR_TIMMODE_DUAL_UNCHAINED;

CSL_tmrHwSetup (hTmr, &hwSetup);

status = CSL_tmrHwControl (hTmr, CSL_TMR_CMD_LOAD_PRDHI, (void *) &LoadValue);

CSL_tmrHwControl (hTmr, CSL_TMR_CMD_START_TIMHI, (void *) &TimeCountMode);

  • Andrew,

    You need to do everything that the GEL file does, unless you specifically know you can do without it.

    The best choice is to duplicate everything that the GEL file does, then you can start removing things until you find out what is not required. But it is still best to just leave it all in unless you need to avoid powering on modules that are not being used.

    The next best choice is to comment out everything in the GEL file that would get called automatically. This means comment out the contents of all of the On...() callback functions. Then see if your code works. It probably will not. Then you can start putting things back in until you get it working. This at least allows you to be working from the debugger instead of rewriting the SPI Flash each time.

    The worst choice is to get me to guess something for you to try. If I am right and it gets your timer working, there could be something else that is missing that does not show up until later, meaning that the "best choice" should have been used. If I am wrong, then a lot of time passes before you get another guess from someone.

    But if your code works in both cases, it is probably not your code.

    My guess is the timer is not Powered and Clocked and Released from Reset in the PSC module. This is my guess because I had similar problems on a completely different TI processor, the DM8168 or DM8148 (I cannot remember which).

    Good luck.

    Regards,
    RandyP

  • Randy,

    Thanks for the suggestions.  I believe I've duplicated everything from the GEL file, but I'm still not getting my interrupts to work when booting from the flash.  I also tried to comment out all of the GEL file calls and ran the debugger, and I DID get interrupts.

    I know my code is loading off the flash properly (I set a GPIO tied to an LED and can verify it turns ON) but it looks seems when the interrupt occurs, the core hangs up.  I've compared my interrupt setup code to the examples provided.

    I'm at a loss.  Any additional suggestions would be greatly appreciated.

    Andrew.

  • Also, to add information about my problem, I tried a different interrupt, this one based on a GPIO change.  Again, the interrupt functions properly when running in the debugger, but when running off the flash, the core hangs.  This happens with either interrupt enabled (timer or gpio).

     

  • Andrew,

    Either something is not being initialized correctly or some part of your program is not being loaded correctly from Flash. It could be both.

    Initialization confirmation:

    1. In CCS, make a copy of your Target Configuration or edit the existing one or create a new one, which ever you prefer.
    2. Remove the "initialization script" from both CorePacs in the Advanced tab.
    3. Power cycle the board.
    4. Launch the modified Target Configuration.
    5. Connect to CorePac0 and CorePac1.
    6. Load the full image through CorePac0 as you expect it to be loaded by the Bootloader.
    7. Run both CorePacs.
    8. Observe the results.

    It would be best if the program makes no use of CorePac1 for now. Put a "spin" instruction or while (1) at the top of the CorePac1 code, if needed.

    Load confirmation:

    1. Use the memory browser's memory fill feature to fill all memory space with something like 0x55555555.
    2. Load the full image through CorePac0.
    3. Use the memory browser's memory save feature to copy all used memory space to files. Use the linker's output .map file to determine the used memory space.
    4. Use the memory browser's memory fill feature to fill all memory space with the same value, like 0x55555555.
    5. Put a hardware breakpoint at the entry point for your program, usually c_int00.
    6. Set the PC Program Counter at the beginning of the RBL at 0x20B00000.
    7. Run to the hardware breakpoint.
    8. Use the memory browser's memory save feature to copy all used memory space to files. Use the linker's output .map file to determine the used memory space.
    9. Compare the files from #3 and #8. Any differences mean the load was not exactly the same.

    Program debug:

    1. If the program is setup to trigger an interrupt when the GPIO toggles, take control with CCS after loading from Flash and before toggling that GPIO.
    2. Set a breakpoint in the interrupt service routine and at any other places that would make sense to test.
    3. Run, toggle the GPIO, halt the processor.
    4. Look at everything in the interrupt path from the GPIO to the IFR and find out where the break occurred.
    5. Look at where the program is stuck and figure out what is keeping it there.

    Regards,
    RandyP

  • Randy,

    Thank you for your very detailed suggestions.  I've spent most of the morning working through them.  Here is where I stand:

    Initialization confirmation:

    In CCS, I created a new Target Configuration with no initialization scripts.  I am not currently using CorePac1, so I've put it in bypass mode.  I power cycle my board and launch the debugger, connect to CorePac0 and load my .OUT file.  When I run, I get my timer interrupts working properly (I am toggling a GPIO that is connected to an LED in the ISR, so I can put my scope on it and see my 10 uS interrupt).

    Load Confirmation:

    I followed your steps and verified that my debugger load and my flash boot load is identical, as far as my .text, .switch, .cinit, and .const are concerned.  Other areas of memory holding variables do not match.  I believe this verifies that my flash load process is working properly.

    Program Debug:

    I tried booting from the flash, then launching the debugger.  Most of the time I can get in and suspend CorePac0.  I do a CPU Reset and see my program counter return to the RBL at 0x20B00000.  From there I set a HW BP at c_int00 (which is at 0x00802100) and run.  I hit the breakpoint.  I then set a HW BP at my configureTimer routine, and get there too.  Finally, I place a HW BP at _CSL_intcDispatcher (0x008067E0) but never get there.  I go somewhere when the interrupt occurs, just not to the dispatch routine.  If I do all of this on the debugger load, even with no GEL initialization, my HW BP at _CSL_intcDispatcher triggers.

    From what I've figured out, the CSL routines provide a second layer of inderection for handling interrupts.  I haven't figured out where the main interrupt branch table is located.  There must be some main table that the CSL routines write the address of the _CSL_intcDispatcher routine to, that transfers control to it following an interrupt.  I'm guessing that, somehow, that main table isn't getting populated properly when I boot from flash.

    ~ Andrew

  • Additional information:

    I checked the status of the ISTP and in both the debugger and flash boot methods, this register contains 0x00800400.  The contents of the table are different between the two.  When running from the flash boot, I can trigger a HW BP at the INT13 ISFP located at 0x008005A0.  Because the contents of the table have not been written properly, the PC just walks through memory until it hits an "instruction" that branches me out to reserved memory space (0x004B1EB0).

    So, why would instructions running through the debugger fill the Interrupt Service Table one way, and the same instructions when loaded off the flash doesn't write them at all? 

    I booted from flash, then launched the debugger.  I reset the CPU, filled the IST with 0x55555555 and ran to my HW BP at th eINT13 ISFP.  When I broke, the table was still filled with 0x55555555's.

    Doesn't the call to csl_intcInit fill the table with the address of the dispatch routine?  It looks like it calls _CSL_initcIvpSet() then fills the table.  Why situation would cause this not to happen? 

    Next, I'll try to set HW BP's at csl_intcInit and see if, for some reason, I'm not getting there...

    ~ Andrew

  • Andrew,

    When you saved the memory contents from the CCS-load version, I assume you had not yet run any code. Is that correct? The interrupt vector table is usually created at build time and not run time. You can call functions that make changes there, but that is not common, especially if you are instantiating the interrupts in the BIOS .cfg file.

    Take a look at your linker .map file to see what it has placed at 0x00800400 to see if the code should be there. It sounds like the process you use to create your Flash code does not include this section. If that is the case, you will want to review the files that configure the flash code build and see where you need to place this section's name to get it to load into the proper place.

    Regards,
    RandyP

  • Paul,  I think I owe you a beer (if that's your poison).  I was not including a "boot" directive for the section that holds the vector table, so it was not being added to my hex file.  Adding that gives me a working timer interrupt when booting from the flash.

    Thank you so very much.  I only wish I had tried posting my question a few weeks ago.  I can't tell you how much time I've wasted on this.

    ~ Andrew