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.

Compiler/TMS320F28069M: Going Into Limp Mode and Don't Know Why

Part Number: TMS320F28069M
Other Parts Discussed in Thread: C2000WARE

Tool/software: TI C/C++ Compiler

Dear Support:

I have been working on trying to move code that is running out of on-chip FLASH and have it run out of RAM to make it run faster. In the process of making changes go the linker .cmd file to do so, I managed to get my project to get into some funky mode where I could no longer recover.  From searching through previous forum submissions, I found this previous post:

https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/298295?Why-does-our-project-CCS-5-4-F28069-now-have-its-PLL-go-into-limp-mode-

which this unfortunate soul ran into a similar problem, bu never got an answer or resolution.  I found a similar fix to my problem, but would really like to know what the heck is going on vs having to rebuild the project from scratch to fix this.  Can you tell me how modifying the linker .cmd file can put you into a state where your project is non-recoverable by going into limp mode (whatever that means) and requires you to trash the project and come up with a new project that no longer goes into limp mode?  

I have wasted a couple of days on this problem and have yet to figure out what the heck is going on other than not messing with the linker .cmd file to not go into this mode.  I made changes to a .c file in my project like the following:

#pragma CODE_SECTION( xmit_spi, "ramfuncs" );
#pragma CODE_SECTION( rcvr_spi, "ramfuncs" );
#pragma CODE_SECTION( rcvr_spi_m, "ramfuncs" );
#pragma CODE_SECTION( rcvr_datablock, "ramfuncs" );
#pragma CODE_SECTION( disk_read, "ramfuncs" );

where I was trying move these routines (that are designated by the 1st argument in parenthesis) into a section "ramfuncs" in the linker command file and then doing the following in my linker .cmd file:

ramfuncs : LOAD = FLASHD,
RUN = RAML0,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0

to run my code out of RAM instead of FLASH.  But more importantly, somehow introducing the #pragma statements above got my project in some weird mode where when I tired to download the code it would go into limp mode and as a result of making a call to:

InitSysCtrl();

which eventually calls this routine:

InitPll( DSP28_PLLCR, DSP28_DIVSEL );

which takes me to the following routine:

if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
{
      EALLOW;
// OSCCLKSRC1 failure detected. PLL running in limp mode.
// Re-enable missing clock logic.
     SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
     EDIS;
// Replace this line with a call to an appropriate
// SystemShutdown(); function.
     __asm(" ESTOP0"); // Uncomment for debugging purposes
}

where the asm instruction gets called and the project no longer works - i.e., clock routines no longer work and the nothing from the console output ).  And since this is non-recoverable, I have to trash the project and start over again.

All as a result of screwing with the linker .cmd file to move code that was running out of FLASH into running out of RAM - pretty bizarre. More importantly, once I get into this mode it is pretty much non-recoverable.  From what I found, I have to trash the project and start over and hope that I have an easy way of doing getting back to where I started - bummer.  Any idea as to what I am doing wrong to get into this mode and when doing so, is there a way of recovering vs just trashing the project?  Please advise.

Thanks,
Tim

  • Tim,

    From what you have described it sounds like you are missing the memcpy() functions in your application. This function is a memory copy that copies intended tasks from flash to ram. Note that the CODE_SECTION pragma of the C compiler is used to create a separately linkable section for flash initialization function (page 13). You will still need to perform a memcpy() to actually copy the defined sections into RAM.

    Pleasse look through the guide, below, and our flash examples in C2000Ware for more information and examples on how to create flash applications.

    An example is shown on pages 13-15 of the appnote on running application from flash: www.ti.com/.../spra958l.pdf

    Regards,
    Ozino
  • Hey Ozino:

    Thanks for your response.  I understand that it may have something to do with copying code from FLASH to RAM correctly, but confused as to why going back to my original project which has everything in FLASH no longer works.  It looks like once I get into this limp mode, I cannot recover by taking out the changes that I made to get me into this mode. 

    Can you tell me how you get into limp mode and when you do, what is the proper way of getting out of this mode?

    Thanks,
    Tim

  • Tim,

    With regards to the limp mode, i've linked to a document that explains the respect actions to take regarding the boot modes (page 24). I have asked to have this post redirected to experts more familiar with this mode.

    www.ti.com/.../spru722c.pdf

    Regards,
    Ozino
  • The PLL issues a limp mode clock when the i/p clock to the PLL has vanished. One potential reason for this could be switching to the crystal oscillator when it has not stabilized completely. Do you use a crystal oscillator in your design?

    What version of C2000ware are you using? Please try C2000Ware_2_00_00_02, which was released only a few days ago. The function to switch to the XTAL OSC has the requisite delay to ensure proper startup of the crystal osc.

    Also, what you perceive to be the "limp mode" may not be limp mode at all. If your code switches the clock source, could you please re-run the experiment without switching clocks at all?