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.

(CC2538) Wake-up from LPM2 doesn't work after spending more than 1 second in sleep mode

Other Parts Discussed in Thread: CC2538

  • Platform: Windows 7
  • Hardware: CC2538EM with SmartRF06
  • IDE: CCS v6.0.1
  • Compiler: GNU v4.7.4 (Linaro)
  • Example from the Foundation Firmware: sleepmode_timer.c

Hello everyone,

  • The problem: If I use the GNU compiler to compile the sleepmode_timer.c example (using startup-gcc.c I attached below), the CC2538 crashes and doesn't go further in the code when it wakes-up from the LPM2 if, and only if, it spends more that 1 second in the LMP2 mode. 

For example, setting an interval of 30000 works fine:

SleepModeTimerCompareSet(ui32Val + 30000);

but with an interval of 40000 the program crashes after exiting the LPM2 mode:

SleepModeTimerCompareSet(ui32Val + 40000);

I verified that many times and it is reproducible. 

However if I set the system to enter in LPM1 instead of LPM2, there is no such problem no matter the sleep interval.

I know that exiting from the LPM2 requires more power. Maybe this can explain that. But when I compile the code with the TI compiler instead of the GNU there is no such problem (if someone ask me why I use the GNU instead of the TI compiler it is because I encountered this problem while I'm playing with Contiki-OS and I managed to compile this latter in CCS only with the GNU compiler). 

Here I reproduced the same problem but with the Foundation Firmware which exonerate completely Contiki from producing this problem (although this latter is respecting strictly the procedure specified in the datasheet for exiting the LPM2 mode). 

Below are the summary of the compilation and linker commands for the GNU compiler while building the sleepmode_timer.c example of the Foundation Firmware:

GNU Comiler:

-mcpu=cortex-m3 -mthumb -mfloat-abi=soft -I"c:/ti/ccsv6/tools/compiler/gcc-arm-none-eabi-4_7-2013q3/arm-none-eabi/include" -I"D:/install/dev/TI/CC2538_Foundation_Firmware/cc2538_foundation_firmware_1_0_1_0/driverlib/cc2538/inc" -I"D:/install/dev/TI/CC2538_Foundation_Firmware/cc2538_foundation_firmware_1_0_1_0/driverlib/cc2538/source" -I"D:/install/dev/TI/CC2538_Foundation_Firmware/cc2538_foundation_firmware_1_0_1_0/driverlib/cc2538/examples/utils" -g -gstrict-dwarf -Wall

GNU Linker:

-mthumb -g -gstrict-dwarf -Wall -Wl,-Map,"SleepmodeTimer_Test.map" -nostartfiles -Wl,--gc-sections -mcpu=cortex-m3

Further notes: On a custom board with the CC2538 chip running Contiki-OS, I encountered this problem but with a small sleep interval (>250ms). After a lot of trials and sweating I finally managed to increase this sleep interval to 500ms without breaking the program after exiting the LPM2: I put bigger capacitors on the DCOUPL pins (instead of 1uF I put 3.2uF on both pins 32 and 56).

Is it possible that somehow these capacitors are discharged so deeply when we set longer sleep interval that the digital regulator cannot start properly after exiting the LPM2 mode? How could we fix this while using the GNU compiler? 

Thanks in advance for your patience reading me and I hope someone can help me with this.

Best regards,

Darko

  • It is a good practice to formulate and collect all information about a problem. After I posted my question I found the problem myself!

    I was looking on the linker script I used with the GNU Linker when noticed that a small part of the script is missing (compared to the original from the contiki-os when we set to use the LPM2 mode). Indead, since the linker script is generated automatically when we build a contiki example, I used one which doesn't take in account that the begging of the SRAM is a 'non-retention' RAM, and this space was used to save the state of the program before entering the LPM2 mode. But this memory is lost when the chip goes in LPM2, and it is now evident that we cannot wake-up properly from the LPM2 mode in this condition.

    The retention SRAM starts from the address 0x20004000 and this needs to be specified in the linker script.