cancel
Showing results for 
Search instead for 
Did you mean: 

SPCSetRunMode() does sometimes not return

davedave95
Associate III
Posted on February 14, 2017 at 16:41

My project on the P44L3 runs in RUN1 mode and uses SPCSetRunMode(SPC5_RUNMODE_HALT0) in the idle loop for power saving. The PIT timer runs at 1Khz, so switching to HALT0 mode is typically done 1000 times per second.

In some cases - not sure yet how to reproduce though - the SPCSetRunMode() function does not return, but keeps spinning in the for() loop waiting for I_IMODE or I_IMTC, neither of which ever go high. ME.IS is still 0 in this case.

Are there any known circumstances in which this can happen, or anything I could do to debug this issue?

Thank you,

This discussion has been locked for participation. If you have a question, please start a new topic in order to ask your question
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on February 26, 2017 at 10:19

For future reference: here is a document from NXP with extensive explanation and solutions:

http://www.nxp.com/assets/documents/data/en/engineering-bulletins/EB770.pdf

 

View solution in original post

7 REPLIES 7
davedave95
Associate III
Posted on February 14, 2017 at 19:15

Further investigation shows that S_MTRANS does not switch to 1 after the sequence

  ME.MCTL.R = SPC5_ME_MCTL_MODE(mode) | SPC5_ME_MCTL_KEY;

  ME.MCTL.R = SPC5_ME_MCTL_MODE(mode) | SPC5_ME_MCTL_KEY_INV;

is executed.

No wonder the for() loop never terminates, as the mode switch has not been performed.

I'm however not able to find out *why* the switching failed. The ME registers have the following values right after the switch instructions are executed:

ME IS:00000000

GS:401F00F4

IMTS:00000000

DMTS:00000000

ME:000005FD

To be continued

davedave95
Associate III
Posted on February 14, 2017 at 22:39

Might or might not be related: I incidentally see the machine check IVOR1 happen when doing power saving to HALT0. MCSR machine check syndrom register is then set to 0x08000010, meaning 'bus error on instruction read'.

davedave95
Associate III
Posted on February 15, 2017 at 22:17

It seems that I was hit by two different issues, I'd appreciate any feedback to prove my theory right or wrong:

  • My problem with SPCSetRunMode() not returning increases significantly under high interrupt load. The datasheet section 6.4.2 subsection HALT0 states: 'If there is a HALT0 mode request while an interrupt request is active, the device mode does not change, and an invalid mode interrupt is not generated.'.  I feel the implementation of SPCSetRunMode() does not take this into account: after the mode switch ME.GS.B.S_MTRANS is never checked, and the for() loop never exits.
  • The problem with the bus errors on HALT0 mode transition seems to be related with switching the flash to low power mode in HALT0. If I keep the CFLASH powered up, the problem completely disappears. Are there any circumstances under which the processor can try to run the next instruction when waking up from HALT0, with the CFLASH not being properly woken up in time?
Erwan YVIN
ST Employee
Posted on February 16, 2017 at 09:25

Hello Gert ,

Sorry , for my late answer

Point 2) isright .. it is linked to CFLASH

That's why , you should create some function in SRAM

similar example in STANDBY mode and create your own ld file(user.ld) (note your backupramsection)

i am creating a Change request to add an application example in App Wizard section SPC5Studio

__attribute__ ((section ('.codeinram'))) void gotoStandbyMode(void) {
WKUP.WISR.R = 0x00000008;//Clear interrupt flag
if ((ME.GS.B.S_CURRENTMODE < SPC5_RUNMODE_RUN3)
 || (ME.GS.B.S_CURRENTMODE > SPC5_RUNMODE_RUN0)) {
 if (OSAL_FAILED == halSPCSetRunMode(SPC5_RUNMODE_STANDBY)) {
 SPC5_CLOCK_FAILURE_HOOK();
 }
 }
}
__attribute__ ((section ('.codeinram'))) void gotoRunMode(void)
{
 if (OSAL_FAILED == halSPCSetRunMode(SPC5_RUNMODE_DRUN)) {
 SPC5_CLOCK_FAILURE_HOOK();
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
/*
 SPC5 HAL - Copyright (C) 2013 STMicroelectronics
 Licensed under the Apache License, Version 2.0 (the 'License');
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 https://community.st.com/external-link.jspa?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an 'AS IS' BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/
/*
 * This file is automatically generated and can be overwritten, do no change
 * this file manually.
 */
/*
 * SPC560Dxx memory setup.
 */
__irq_stack_size__ = 0;
__process_stack_size__ = 2048;
MEMORY
{
 flash : org = 0x00000000, len = 256k
 dataflash : org = 0x00800000, len = 64k
 ram : org = 0x40000000, len = 10k
 backupram : org = 0x40002800, len = 2k
}
ENTRY(_reset_address)
/*
 * Derived constants.
 */
__flash_size__ = LENGTH(flash);
__flash_start__ = ORIGIN(flash);
__flash_end__ = ORIGIN(flash) + LENGTH(flash);
__ram_size__ = LENGTH(ram);
__ram_start__ = ORIGIN(ram);
__ram_end__ = ORIGIN(ram) + LENGTH(ram);
__backupram_size__ = LENGTH(backupram);
__backupram_start__ = ORIGIN(backupram);
__backupram_end__ = ORIGIN(backupram) + LENGTH(backupram);

SECTIONS
{
 . = ORIGIN(flash);
 .boot0 : ALIGN(16) SUBALIGN(16)
 {
 . += 0x00000000;
 KEEP(*(.boot))
 KEEP(*(.handlers))
 KEEP(*(.crt0))
 } > flash
 .boot1 : ALIGN(16) SUBALIGN(16)
 {
 /* The vectors table requires a 2kB alignment.*/
 . = ALIGN(0x800);
 KEEP(*(.vectors))
 /* The IVPR register requires a 4kB alignment.*/
 . = ALIGN(0x1000);
 __ivpr_base__ = .;
 KEEP(*(.ivors))
 } > flash
 constructors : ALIGN(4) SUBALIGN(4)
 {
 PROVIDE(__init_array_start = .);
 KEEP(*(SORT(.init_array.*)))
 KEEP(*(.init_array))
 PROVIDE(__init_array_end = .);
 } > flash
 destructors : ALIGN(4) SUBALIGN(4)
 {
 PROVIDE(__fini_array_start = .);
 KEEP(*(.fini_array))
 KEEP(*(SORT(.fini_array.*)))
 PROVIDE(__fini_array_end = .);
 } > flash
 .text_vle : ALIGN(16) SUBALIGN(16)
 {
 *(.text_vle)
 *(.text_vle.*)
 *(.gnu.linkonce.t_vle.*)
 } > flash
 .text : ALIGN(16) SUBALIGN(16)
 {
 *(.text)
 *(.text.*)
 *(.gnu.linkonce.t.*)
 } > flash
 .rodata : ALIGN(16) SUBALIGN(16)
 {
 *(.glue_7t)
 *(.glue_7)
 *(.gcc*)
 *(.rodata)
 *(.rodata.*)
 *(.rodata1)
 } > flash
 .sdata2 : ALIGN(16) SUBALIGN(16)
 {
 __sdata2_start__ = . + 0x8000;
 *(.sdata2)
 *(.sdata2.*)
 *(.gnu.linkonce.s2.*)
 *(.sbss2)
 *(.sbss2.*)
 *(.gnu.linkonce.sb2.*)
 } > flash
 .eh_frame_hdr :
 {
 *(.eh_frame_hdr)
 } > flash
 .eh_frame : ONLY_IF_RO
 {
 *(.eh_frame)
 } > flash
 .romdata : ALIGN(16) SUBALIGN(16)
 {
 __romdata_start__ = .;
 } > flash
 .stacks : ALIGN(16) SUBALIGN(16)
 {
 . = ALIGN(8);
 __irq_stack_base__ = .;
 . += __irq_stack_size__;
 . = ALIGN(8);
 __irq_stack_end__ = .;
 __process_stack_base__ = .;
 __main_thread_stack_base__ = .;
 . += __process_stack_size__;
 . = ALIGN(8);
 __process_stack_end__ = .;
 __main_thread_stack_end__ = .;
 } > ram
 .data : AT(__romdata_start__)
 {
 . = ALIGN(4);
 __data_start__ = .;
 *(.data)
 *(.data.*)
 *(.codeinram)
 *(.gnu.linkonce.d.*)
 __sdata_start__ = . + 0x8000;
 *(.sdata)
 *(.sdata.*)
 *(.gnu.linkonce.s.*)
 __data_end__ = .;
 } > ram
 .sbss :
 {
 __bss_start__ = .;
 *(.sbss)
 *(.sbss.*)
 *(.gnu.linkonce.sb.*)
 *(.scommon)
 } > ram
 .bss :
 {
 *(.bss)
 *(.bss.*)
 *(.gnu.linkonce.b.*)
 *(COMMON)
 __bss_end__ = .;
 } > ram
 
 .standbyram : ALIGN(16) SUBALIGN(16)
 {
 __standbyram_start__ = .;
 *(.standbyram)
 *(.standbyram.*)
 __standbyram_end__ = .;
 } > backupram
 __heap_base__ = __bss_end__;
 __heap_end__ = __ram_end__;
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Best regards

Erwan

Erwan YVIN
ST Employee
Posted on February 16, 2017 at 14:45

Hello Geirt ,

For point 1)

you are right

/* it is recommended to poll S_MTRANS after requesting */
 /* STOP, HALT or STANDBY modes */
 while(1 == ME.GS.B.S_MTRANS)
 { 
 }�?�?�?�?�?

i am creating an ER for this for RLA & HAL

Best regards

Erwan

Posted on February 26, 2017 at 10:19

For future reference: here is a document from NXP with extensive explanation and solutions:

http://www.nxp.com/assets/documents/data/en/engineering-bulletins/EB770.pdf

 
Erwan YVIN
ST Employee
Posted on February 27, 2017 at 09:52

Hello Gert ,

Application Notes for MPC56 (NXP-Freescale) are valid for SPC56 (ST Microlectronics)

Same core

   Best Regards

                Erwan