Any condition that needs to be polled for Accelerated STANDBY Exit? (MPC5748G)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Any condition that needs to be polled for Accelerated STANDBY Exit? (MPC5748G)

Jump to solution
1,906 Views
gvictorio
Contributor III

I have configured the MPC5748G to enter from DRUN into STANDBY, taking care of shutting down clocks for peripherals that were in use, clearing interrupts, disabling 2nd core, etc (anything that would prevent the transition to STANDBY in the 1st place). I also have my wakeup sources configured for a couple CAN Rx pins and activity on an input pin. My intent is also to use the Accelerated Low Power Exit so in ME_DRUN_MC I have the system clock set to the PLL and PLLON and FXOSCON are set.

 

So, entering into STANDBY works... and exit out of it was working, but after moving the following functions (based from the Freescale Eval board examples) early to the __start.s file before ECC, stack and .bss/.data initialization (to reduce boot time) I started having a problem, which only happens if the debugger (Lauterbach) is not connected:

  • memory_config_160mhz
  • crossbar_config
  • bridges_config
  • peri_clock_gating
  • system160mhz

 

Basically when the debugger is not connected (i.e. target connected stand alone) and I let the target enter STANDBY mode, if I trigger a wakeup condition (I/O pin or send CAN msg) the MPC5748G seems to hung somewhere during the startup code. Unfortunately if I reproduce the issue and try to attach with Lauterbach debugger Trace32 gives me a debugging error so it does not allow me to connect to the system (I was hoping to look at registers while on that condition) so I have only been able to debug this by toggling debug pins in different phases of the init sequence.

 

So far I've discovered that when the target HW wakes up from Standby the MC_ME.GS.B.S_FXOSC field is reported as not stable so I added a delay before memory_config_160mhz to make sure that it doesn't continue unless MC_ME.GS.B.S_FXOSC and MC_ME.GS.B.S_PLLON are set but still the target HW is getting stuck somewhere. It takes ~1.86ms to report a stable FXOSC.

 

I tried skipping memory_config_160mhz and system160mhz if the system clock reported in MC_ME.DRUN_MC.B.SYSCLK is already the PLL (since it is supposed to exit from STANDBY using the PLL) but the problem still occurs.

 

It puzzles me that the issue does not occur when the debugger is attached and I run the sequence like that... I don't know if somehow the debugging session is making conditions more stable or adding some delay(s) that allows the STANDBY exit to work correctly. If I move the functions listed above to run after entering main() then things work again.

 

Additional info:

  • PLL is set to 160MHz (based on 16MHz crystal)
  • Execution is from FLASH
  • For STandby configuration, Flash is configured to stay on and No system clock (since they're all reserved):
    • MC_ME.STANDBY_MC.R = 0x0001000F;

 

Questions:

  1. Is there any condition that I need to poll when the code starts before I can continue with normal init process?
  2. Is it safe to assume that the memory and system do not need to be configured for 160MHZ PLL if DRUN was already configured for that before entering STANDBY? Any clarification of what and what should not be re-configured is appreciated.
Labels (1)
1 Solution
1,255 Views
gvictorio
Contributor III

Got a little side-tracked but finally had time to go back to troubleshoot this...

So, by using lukaszadrapa​'s recommendation of the endless loop I was able to attach to the target HW before the problem presented and was able to figure out what was going on.

Problem #1:

The functions I listed in my original post were being called before the Stack and SP (R1) were initialized and basically I was relying in the fact that the functions did not receive any argument and did not declare any local variables so I incorrectly assumed that the stack would not be used... but turns out it is used. The assembly code on function entry uses the stack to save the Link Register (LR), which will later be pulled from the Stack on function exit in order to load the return address to LR before branching to it. The reason why it worked OK on Power On Reset (and with the debugger connected) is because in those cases the R1 register (stack pointer) happens to be initialized to a valid memory location in RAM; but when the target HW wakes up from STANDBY, the R1 register had a random value (garbage) which would be an invalid address (reserved space) hence when trying to use that location as the Stack the MCU would crash.

Solution #1:

I implemented a partial stack initialization before calling the functions from my original post. I only initialize 256 bytes which is way more than what it needs but at least I do not do the full stack initialization until the PLL is setup (and can be done faster).

Problem #2:

On STANDBY exit, after the initialization was done and started configuring peripheral SW drivers within main() I noticed that I was getting another crash when I attempted to write to peripheral registers. After a little bit of debugging I noticed that the module I was trying to configure was not really enabled... if I tried to see the registers with Trace32 it could not read them (which is an indication the module is not enabled) and by that time the MC_ME.PCTL[x].RUN_CFG field had already been setup (before jump to main).

Solution #2:

I suspected that the fact that the external crystal (FXOSC) was disabled during STANDBY maybe needed some stabilization time before the PCTL configuration could really set the configured peripherals to be active on the different run modes, so I added a wait time after exit from STANDBY to wait until the FXOSC and PLL report stable clock before continue the initialization process. Also made sure to execute the PLL/System configuration and trigger the mode transition (to same mode) because otherwise the 160MHz frequency didn't seem to take effect on STANDBY exit, even though the accelerated low power exit is supposed to allow that (per my understanding).

View solution in original post

0 Kudos
5 Replies
1,256 Views
gvictorio
Contributor III

Got a little side-tracked but finally had time to go back to troubleshoot this...

So, by using lukaszadrapa​'s recommendation of the endless loop I was able to attach to the target HW before the problem presented and was able to figure out what was going on.

Problem #1:

The functions I listed in my original post were being called before the Stack and SP (R1) were initialized and basically I was relying in the fact that the functions did not receive any argument and did not declare any local variables so I incorrectly assumed that the stack would not be used... but turns out it is used. The assembly code on function entry uses the stack to save the Link Register (LR), which will later be pulled from the Stack on function exit in order to load the return address to LR before branching to it. The reason why it worked OK on Power On Reset (and with the debugger connected) is because in those cases the R1 register (stack pointer) happens to be initialized to a valid memory location in RAM; but when the target HW wakes up from STANDBY, the R1 register had a random value (garbage) which would be an invalid address (reserved space) hence when trying to use that location as the Stack the MCU would crash.

Solution #1:

I implemented a partial stack initialization before calling the functions from my original post. I only initialize 256 bytes which is way more than what it needs but at least I do not do the full stack initialization until the PLL is setup (and can be done faster).

Problem #2:

On STANDBY exit, after the initialization was done and started configuring peripheral SW drivers within main() I noticed that I was getting another crash when I attempted to write to peripheral registers. After a little bit of debugging I noticed that the module I was trying to configure was not really enabled... if I tried to see the registers with Trace32 it could not read them (which is an indication the module is not enabled) and by that time the MC_ME.PCTL[x].RUN_CFG field had already been setup (before jump to main).

Solution #2:

I suspected that the fact that the external crystal (FXOSC) was disabled during STANDBY maybe needed some stabilization time before the PCTL configuration could really set the configured peripherals to be active on the different run modes, so I added a wait time after exit from STANDBY to wait until the FXOSC and PLL report stable clock before continue the initialization process. Also made sure to execute the PLL/System configuration and trigger the mode transition (to same mode) because otherwise the 160MHz frequency didn't seem to take effect on STANDBY exit, even though the accelerated low power exit is supposed to allow that (per my understanding).

0 Kudos
1,255 Views
neojung
NXP Employee
NXP Employee

Hello Gonzalo,

Currently I faced problem #2 as you described above.

So, do you have any detailed wait time information or simple code?

Best regards,

Neo

0 Kudos
1,255 Views
gvictorio
Contributor III

Hello Neo, sorry I missed your question before... I known chances are you may not have this problem anymore, but for future reference, this is the code that I modified.... based on the memory_config_160mhz() function included with many of NXP examples:

void memory_config_160mhz(void)
{
    /* If waking up (DRUN clock is set to PLL), wait until FXOSC and PLL has been stabilized */
    if (ME_SYSCLK_PLL_PHI_0 == MC_ME.DRUN_MC.B.SYSCLK)
    {
        /* System clock is PLL, so this is a wake up event */

        while (MC_ME.GS.B.S_FXOSC == 0)
        {
            /* Wait for FXOSC to stabilize */
        }

        while (MC_ME.GS.B.S_PLLON == 0)
        {
            /* Wait for PLL to provide stable clock */
        }
    }

... /* Same as NXP sample code */   

     typedef void (*mem_write_code_ptr_t)(uint32_t, uint32_t);
        /* create a new type def: a func pointer called mem_write_code_ptr_t */
        /* which does not return a value (void) */
        /* and will pass two 32 bit unsigned integer values */
        /* (per EABI, the first parameter will be in r3, the second r4) */

    asm (" mbar"); /* Wait for prior code to complete before proceeding. */

    (*((mem_write_code_ptr_t)mem_write_code_vle))
                    /* cast mem_write_code as func ptr */
                    /* "*" de-references func ptr, i.e. converts to func*/
      (PFLASH_PFCR1_VALUE_160MHz, /* which passes integer (in r3) */
      (uint32_t)&PFLASH_PFCR1_REG); /* and address to write integer (in r4) */

...

...

...
}

0 Kudos
1,255 Views
gvictorio
Contributor III

Thanks for your response lukaszadrapa

Since the SWT0 is enabled by default on the MPC5748G (with timeout of 20ms) at some point I was having a problem where the watchdog would reset while initializing the .bss/.data areas (which are big) so back then I changed the startup code to take care of reconfiguring the SWT for a 128ms delay before the .bss/.data initialization (i.e. before jumping to main). So now the startup code has enough time to execute without the watchdog expires even after power-on-reset which runs the first few functions listed in my original post without the PLL configured as DRUN system clock. While connected to a debugging session, I have confirmed that on wake-up events the code executes faster right from exit from STANDBY, which makes sense since the PLL is supposed to be enabled and selected as DRUN system clock automatically (if previously configured for accelerated low power exit before entry to STANDBY, which is the case here).

BTW: One of the steps I do before entering to STANDBY is to disable SWT0 (used by Z4a core) and SWT1 (used for Z2 core), so as far as I know that means that the SWT0 would not be enabled after wake-up from STANDBY, right?.

While I don't think the SWT0 could be the root cause (because of the explanation above), I believe it is a good idea to disable the watchdog and put an endless loop to see if I can attach to the target after a (stand-alone) wake-up and then try to see what's going on with the MCU/SW at that point. I will let you know if I find something out - or if you have any other suggestion (based on my comments above) I'd appreciate that too.

One clarification: In my original post I mentioned that if I "try to attach with Lauterbach debugger Trace32 gives me a debugging error so it does not allow me to connect to the system", but actually it does seem to connect to the target... Trace32 does show "running" in the status bar, but if I try to break the execution to look at register values Trace32 takes a while and at the end shows one of the following errors:

  • debug port problem
  • emulation running
0 Kudos
1,255 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

the only difference between debug mode and standalone mode is that Lauterbach automatically disables watchdog. Of course, I do not consider own scripts.

Where do you disable watchdog? If the watchdog is not disabled, do you refresh it appropriately? If some code is moved to startup files, it is possible that the watchdog initialization is delayed, so it can reset the device before initialization code is reached...

Try to execute this code immediately after startup:

;SWT_0.SR.R = 0xc520;

     e_lis    r12,0xFC05

     e_li    r0,0xC520

     e_stw    r0,0x10(r12)   

;SWT_0.SR.R = 0xd928;

     e_li    r0,0xd928

     e_stw    r0,0x10(r12)   

;SWT_0.CR.R = 0xFF00010A;

     e_lis    r0,0xFF00

     e_or2i    r0,0x010A

     e_stw    r0,0x0(r12)

And one more test I would try:

Immediately after startup, disable the watchdog and enter endless loop. After power-on, just attach debugger and manually move the program counter to next instruction after endless loop and start the application. Enter STANDBY and then wake up the device. If you use standard reset vector as entry point for STANDBY exit, the watchdog will be disabled and endless loop will be entered again. Now you can attach debugger, change the program counter manually again and step the code to see what's wrong. If the problem is related to SW, you should find it now. Otherwise we will have to do deeper investigation...

Regards,

Lukas

0 Kudos