WDOG ignoring refresh when using LPO clock

cancel
Showing results for 
Search instead for 
Did you mean: 

WDOG ignoring refresh when using LPO clock

Jump to solution
6,362 Views
jhollister
Contributor II

MCU: MK20DX128VLH5

Maskset: 1N86B

I'm trying to use the internal watchdog of a Kinetis K20, sourced from the LPO clock. My WDOG refresh operations seem to have no effect when I use the LPO clock, but if I use the Bus clock the refresh works fine. I've boiled my application down to a simple bare-metal C program generated by CodeWarrior, shown below. If PET_THE_DOG == 0, then both bus clock and LPO clock variations cause a reset in a few seconds. If PET_THE_DOG ==1, then the bus clock variation does not reset but the LPO clock variation still does reset.

I've seen some other discussions about a similar problem, but no resolution that's worked for me. Anybody know why the WDOG is treating the refresh differently when I run from the LPO clock?

void delay(int n)

{

  for (; n > 0; --n) {

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  }

}

# define WDOG_LPO_CLOCK 1

# define PET_THE_DOG 1

int main(void)

{

  __asm("CPSID   i"); // Disable interrupts

  // Unlock watchdog for write-once register access

  WDOG_UNLOCK = 0xC520;

  WDOG_UNLOCK = 0xD928;

  #if WDOG_LPO_CLOCK == 1

  // Enable WDOG with 1kHz LPO clock

  WDOG_PRESC = WDOG_PRESC_PRESCVAL(0);

  WDOG_TOVALH = (3000 >> 16);

  WDOG_TOVALL = (3000 & 0xFFFF);

  // STCTRLH : WAITEN=1, STOPEN=1, ALLOWUPDATE=1, CLKSRC=0, WDOGEN=1

  WDOG_STCTRLH = 0x1D1;

  #else

  // Enable WDOG with 21MHz FEI clock

  WDOG_PRESC = WDOG_PRESC_PRESCVAL(3);

  WDOG_TOVALH = (21000000 >> 16);

  WDOG_TOVALL = (21000000 & 0xFFFF);

  // STCTRLH : WAITEN=1, STOPEN=1, ALLOWUPDATE=1, CLKSRC=1, WDOGEN=1

  WDOG_STCTRLH = 0x1D3;

  #endif

  __asm("CPSIE   i"); // Enable interrupts

  // Loop here. Periodically pet the WDOG.

  while(1) {

  #if PET_THE_DOG == 1

  WDOG_REFRESH = 0xA602;

  WDOG_REFRESH = 0xB480;

  #endif

  delay(1000);

  }

}

Labels (1)
Tags (4)
1 Solution
569 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Guys,

This maybe a common issure for using LPO as watchdog clock source. The refresh logic in current watchdog implementation, it will take 2-3 WDOG clock to sync refresh command to watchdog coutner domain. For bus clock as the coutner source, it will be 2-3 bus clock with watchdog prescaler set to 1; however, for LPO, it will be 2-3 LPO clock. You know that it is 2-3 ms, very very long time than bus clock situation.  In your case, the program is keeping issue refresh clock, and refresh logic keeping sync the comand, and finally, there is no refresh command synced to coutner domain, watchdog timeeout. You must refresh watchdog with the interval longer than the sync time, it is the design requirment.

In your case, please try to use delay() function with a larger value, it should work.

Thanks,

Sandy

View solution in original post

25 Replies
463 Views
fredroeber
Contributor II

This is a reply to zhaohuiliu (Sandy).

Sandy, Thanks for suggestions. I have tried more fixes but still the same problem. Power is .3mA in LLS and 3.2mA in VLPS. I want to get VLPS down to close to the LLS level.

One thing I thought was that since this Teensy board has 16MHz oscillator vs 8MHz your boards have then maybe clock circuit was using more power in VLPS. The MCU data sheet said power use much higher for higher frequency crystals. So I redid my code to not use PEE clock mode and to instead use FEE clock mode with the RTC oscillator selected as the external clock source. I verified that MCG_C6_OSCINIT0 now 0 so no 16MHz and no PLL. But there was no change in power use.

As to your suggestion 1 I don't think there is any clock pin output enabled. But I do have things hooked to some pins. Just none that change state. Is there any difference in the GPIO being "static and latched" in LLS and "wakeup" in VLPS? I am feeding VBat and VRegIn from a Lion battery pack that can get up to 4.2V which is maybe a bit high? But the fact that things work in LLS but not VLPS makes me think that isn't the issue. Unless GPIO works different for LLS vs VLPS?

As to your suggestion 3 I have looked through that table on which modules are on in which modes. The only things I have enabled in terms of the clock gates are the LPTimer, RTC, VREF (but it's not enabled) and one UART. And I have tried with LPTimer and UART and GPIO (Ports) all not used at all and turned off. No change in power.

As to your suggestion 4 about how long it runs in VLPS vs RUN mode,I have run versions of code where it goes into VLPS and stays there forever (I have Watchdog turned off). Power doesn't change.

I really appreciate your suggestions as I need to find a solution. Thank you!   Fred

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

HI Fred,

Can you check following:

1. Check out OSC_CR value to see if osc is active in STOP/VLPS mode, disable it may save some power.

2. FEI mode, which will use internal IRC. May be have a lower power data.

3. 4.2V for Vbat is out of spec. Max Vbat is 3.6V in Kinetis datasheet. While Vregin can be from 2.xV to 5.xV. So is that possible to remove the battery and connect MCU VDD these two power PINs  to have a quick check. Be careful when you do the power pin connection for it may damage the chip.

hope this helpful,

Sandy

0 Kudos
463 Views
fredroeber
Contributor II

Sandy, I finally found the problem we were having with the 3mA power use. The Teensy3 board from PJRC that we are using happens to have a small Arm 0 processor chip on it hooked up to the Ezport connections on the main processor (ie the Freescale Kinetis one). That Arm 0 contains a bootloader that can be used to program the main processor (I think the designers idea was to avoid taking up space in Kinetis FLASH memory with a boot loader.

Well, it turned out that VLPW and VLPS stop states left those lines in a state that the Arm 0 processor didn't recognize the low power state and shut itself down so kept drawing power resulting in the current I was seeing. Once I disabled the pins connected to that processor (by changing the port mode on the pins to inputs) that processor shut itself down properly and the 3mA went away. I guess the LLS mode worked because of the way the GPIO pins were set to a "static" state.

So, my the problem of the 3mA extra power use is solved. And I have code that turns off the various modules we use like SPI, ADC, USB and SYSTICK and goes from PEE to PLBI clock mode and then switches to VLPR and then VLPW mode to sleep in low power. On wakeup we go back to PEE clock mode and RUN mode and turn the modules we need back on. It's quite a lot of steps but it's something several of us using this Teensy board and your processor had to do to get reliable operation with no STOPA signals on trying to enter low power.

I now have reliable operation and the watchdog timer running off the LPO keeps running in low power mode so that we can maintain safe operation under all conditions!! Because we sleep in VLPW mode we don't have the lowest power use but it's low enough to get by for now.  I may try to get even lower power use somewhere down the line once I get caught up on other parts of the project I have let slide the past few weeks. Things like trying some other modes like FEE mode running off the RTC 32KHz crystal instead of the high power 16 MHz crystal. You suggested this and I did try it in RUN mode and noted the reduced power use but for now I'm sticking with the PEE mode using the 16 MHz crystal so that I can get an accurate enough 48MHz signal for the USB.

Anyways, just wanted to let you know that with your help and suggestions I finally have things working well enough for out project to be successful. Thanks much!   Fred

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Fred,

Glad to hear that the root caused found. So please let us know when you get any issues using Kinetis MCUs.

Thanks,

Regard,

Sandy

0 Kudos
463 Views
fredroeber
Contributor II

This is a reply to Sandy's last reply to my questions. I did this as a reply to the original post because things were getting too indented with all the posts and replies.

Sandy,I wanted to reply to some issues you raised before I go off and experiment with the others. I wanted to mention that the ELOG system doesn't use any debugger mode. It simply stores the data in RAM while the system is running. I can press a button to trigger an interrupt and get the buffer of events dumped out over the UART0 port where I capture the data and can format it into the time history. I understand that the debugger would change power use.

Also, my initialization function includes the code to make sure all low power modes are ok and that the debugger is disabled :

    /* We need to enable the use of the low power modes we want by setting the

    * PMPROT register. Note, the PMPROT register can only be successfully

    * written once following a system reset so we might as well enable any

    * low power mode.

    */

    SMC_PMPROT = SMC_PMPROT_AVLP | SMC_PMPROT_ALLS | SMC_PMPROT_AVLLS;

    /* Disable JTAG TDO pin since it can cause problems entering LLS mode.

    * This code is from the code for App Note 4470. We disable and pull up

    * Port A pin 2.

    */

    PORTA_PCR2 = PORT_PCR_PE | PORT_PCR_PS;

Sandy, in point 3 you mention that VLPS should wake up in PBE mode. And you wonder where my recovery code to go from PBE to PEE mode is. So, when I use LLS mode I do find that the processor wakes up in PBE mode and I have code in my LLWU functions that return the processor from PBE to PEE. But I didn't think I needed that to go from RUN mode to VLPS and back. In the code I posted earlier that shows how I go into low power mode, line 75 shows an assertion where I make sure that I am in PEE mode when I return. I have the "standard" mcg_mode_check function in my code that returns the current power mode. And assertions are always enabled in my code. And when one fails operation stops immediately and dumps out the event trace and other information. That doesn't happen so I think that is evidence that VLPS comes back in PEE mode. But because of your comment I now realize that I am missing code to go from PBE to PEE if I return from sleep in PBE mode. Because I am never getting into VLPS mode (as indicated by abort signal) I have never had to transition from PBE back to PEE. Thanks for pointing that out!

So, I think I have to follow up on your suggestion in point 6. I now have a feeling that USB must be running and causing problems. USB is one thing I haven't looked at much so I will have to figure it out. I will post back when I make some progress.

Thanks again!!   Fred

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Fred,

Hope you can have a quick test on keeping MCU in VLPS mode more than 1 second, properly 2 seconds. I think you can simply disable LPTimer interrupt to do this trick. There is a scheme in our MCUs to check if it can enter STOP/VLPS mode successfully. If it can not enter STOP/VLPS mode longer than 1 second(1024 LPO clocks), it will be reset by STOP ACKNOWLEDGE ERROR Reset.  This is shown in RCM_SRS1[SACKERR] bit. The reset source for this bit is different among Kinetis devices. I am not sure if your case is related to this and whether USB can cause this issue. 

Please do try this by disable LPTimer interrupt and other wakeup sources, you can leave one gpio to wakeup MCU from VLPS/STOP mode for this test.

Hope this will be helpful.

Thanks,

Sandy

0 Kudos
463 Views
fredroeber
Contributor II

Sandy, I turned off the periodic LPTIMER interrupts and my watchdog. I went into low power mode and didn't come out of it until seconds later when I pressed a button that triggers interrupt. However, when I came back from WFI instruction the STOPA bit was set (same as it has been).

I know that before I turned off my SYSTICK interrupt before going into low power mode that the SYSTICK interrupt used to cause going into low power to abort. As you know, this processor has USB and our application uses it. I saw from my event logs that the USB was generating 1msec interrupts. I think that is probably something that would cause problems with going into low power. I had started trying to figure out how to disable USB for low power mode but haven't figured that out yet. I think I have to figure out how to disable USB and try running that way. But that will have to be a task for tomorrow.

Thanks again. Fred

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Fred,

Make the USB ISR execution time as short as possible, firstly. For example, remove any UART print which takes a very long time.

0 Kudos
463 Views
fredroeber
Contributor II

Hello Sandy, I have been working long hours trying to get VLPS mode to work. I have added code to be able to stop and disable everything before going into low power and was able to go into VLPS mode and wake up without PMCTRL_STOPA set. But my problem is that power use is 3.2mA in VLPS. In LLS mode it's only 300uA. I wanted to get power in VLPS to be near LLS power.

I tried many things to see if I could reduce power. I went into BSP code and my code and took out everything I use so I am using no peripherals. I never even power them up and have verified all the bits in the SIM_SCGCx registers are off. So no USB, UART, ADC, LPTIMER, Watchdog, SPI, RTC. Nothing. And still current is 3.2mA. So, I am wondering if it is because FLASH draws that much current? I am using the code you provided in your March 20th post above which doesn't do anything to change clock speeds/modes -- I enter VLPS from PEE power mode and come back in PBE mode with processor clock at 48 MHz and Flash clock at 24 MHz. Would that cause the power use? Could I use a simple RAM function to turn off the FTFL bit in the SIM_SCGC6 register, do the WFI to sleep and then turn the FTFL back on before returning to FLASH operation?

I really just want to know if you think the Flash memory could be using all this power use as compared to LLS mode. Thank you.  Fred

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Fred,

I think RAM func will be a good point to check out, and meantime you don't have to disable FTFL clock. I don't think flash will draw huge current upto 3 mA in your case. Would you please help to check following items in your case:

1. if any clock pin output enabled when you switch back to RUN mode or in VLPS mode.

2. if external clock crystal or oscillator is always keep on in VLPS mode.

3. pls check RM chapter7 module operation in low power modes table, to check which modules can work in VLPS mode but off in LLS mode, to check the modules may cause the current issue.

4. Is there any pin can be used to check out how long the MCU in VLPS mode and RUN mode. If MCU only in VLPS mode for a very short time, then wakeup, the current may be reasonable. it is better to check out the duration of MCU sleep and wake up.

Hope these helpful,

Sandy

0 Kudos
463 Views
fredroeber
Contributor II

Hi, I've been working with another Freescale engineer the past couple of days (Hy Mai). He very helpfully provided me the same code as above last week and I ran it and found that it didn't work with my HW. After some investigation I found that the BSP SW for the Teensy 3.0 HW I'm using had a startup code error that was causing all my problems. I found the Teensy3 code in the ResetHandler function that was the first thing to run on startup did:

WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;

WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;

WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;

The Freescale "bare metal"  environment code available on the Freescale site had startup code that instead did:

WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;

WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;

WDOG_STCTRLH &= ~WDOG_STCTRLH_WDOGEN;

I changed the Teensy code to match the Freescale code (ie the 3rd line) and then the Watchdog worked with the LPO option. I think the issue is that the original Teensy code changed the watchdog to use the LPO option right away and that somehow caused problems. Just wanted to provide a head's up on that.

I do still find that I'm not entirely pleased with using the LPO to drive the watchdog timer. It seems that even though the LPO keeps running in almost all low power modes, the watchdog doesn't. In particular I'm using LLS mode a lot of the time to reduce battery load by the processor. If something goes wrong with any of the LLS entry/exit code the watchdog is of no use to help reset the processor in order to restore proper operation. That seems unfortunate.

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Fred,

It is true that the WDOG has lots of restrictions while using, but it intends to make sure the correct operations. For your LLS mode case, is that possible to do following workaround? It is to use VLPS mode instead of LLS mode. VLPS mode power is a little higher than LLS mode, but the WDOG is working with LPO clock. You can refer to the datasheet you have about these two power mode consumption. Hope it helpful for your case.

Sandy

0 Kudos
463 Views
fredroeber
Contributor II

Sandy, It is interesting you mentioned trying to use VLPS mode to get the watchdog to work. Hy Mai (another freescale engineer who has been helping me on this too) said yesterday the watchdog wouldn't work in LLS mode. I had told him that maybe I would have to try to use VLPS mode to get the watchdog to work.

Last fall when I worked on getting low power to work with our application I tried to use VLPS mode first. I spent weeks and could never get it to work. I looked for sample code but it seems that MQX doesn't use VLPS mode. It uses VLPR, STOP and LLS for reducing power. Like Hy Mai, you seem very knowledgeable. Do you know of any sample code that shows how to make VLPS mode work?

I'm using a Teensy3 development board with your processor. There is a thread on the Teensy3 forum where a number of us are trying to help each other to get low power working (Forum post) and nobody has had luck getting VLPS to work either.

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Fred,

Hy Mai and I have some internal discussion about your case. It was a pity that our company email system was updated while I relied on it to get the topic status I involved sometime. So i failed to get the issue you met. Hy told me about this, so we suggest you or other user to use VLPS mode instead of LLS mode for WDOG.

Just try following code for VLPS mode entry. Suppose you have stop(); function already. Please help to take care the highlight content about PMPROT register, it is write-once regs, you must make sure all the low power mode you will use to be enabled before you enter certain mode.

Hope it helpful.

volatile uint32 dummyread;

    /* The PMPROT register may have already been written by init code

       If so then this next write is not done since 

       PMPROT is write once after RESET

       allows the MCU to enter the VLPR, VLPW, and VLPS modes.

       If AVLP is already writen to 0

       Stop is entered instead of VLPS*/

    SMC_PMPROT = SMC_PMPROT_AVLP_MASK | SMC_PMPROT_AVLLS_MASK | SMC_PMPROT_ALLS_MASK; 

    /* Set the STOPM field to 0b010 for VLPS mode */

    SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK;

    SMC_PMCTRL |=  SMC_PMCTRL_STOPM(0x2);

    /*wait for write to complete to SMC before stopping core */ 

    dummyread = SMC_PMCTRL;

    dummyread++;

    /* Now execute the stop instruction to go into VLPS */

    stop();

0 Kudos
463 Views
fredroeber
Contributor II

Sandy, I very much appreciate the help from you and Hy Mai. I think using VLPS mode would help if I could get it to work. Last fall I spent several weeks trying to get VLPS mode to work. I was using some low_power_demo.c code from the k20d50m_sc_baremetal example project I found on the Freescale website. It had test code to go in to VLPS mode. But that code was much more complex than the code you show above. The code I was using did a lot of MCG mode changes to go from the normal PEE mode to BLPE. Because of the code you showed me above, I now know that the code I was using was more complicated because it could be used with other low power modes like VLPR. When I was trying to get the code to work back then, I would sometimes get hard faults. And I found that the Freescale MQX RTOS doesn't use VLPS mode at all. There were a group of us users of Teensy3 boards with this Kinetsis processor trying to get VLPS mode to work and none of us could. That is why I used LLS mode.

When I used the code you showed to do the mode switch, the mode did switch and I didn't get any hard faults. I also found that the watchdog did work. But I am having two problems that I am working on now. I will explain my problems but I think I have to check if there might be other forum posts that would help since now my problem with the watchdog is fixed but I have to understand and make VLPS mode work.

My problems with VLPS mode are that it always ends with the SMC_PMCTRL SMC_PMCTRL_STOPA bit set after the WFI instruction finishes when I use VLPS mode. And I don't see the power reduction I expect. When the system is idle normally it draws about 21 mA. When I go into LLS low power mode that drops to .7 mA. I understand that the processor is probably using less than 50 uA in LLS mode but I have other things running like an LCD and other peripherals. But when I use VLPS mode, the current only drops to 8 mA from the 21 mA. This isn't the power savings I need and so I was wondering if it has to do with the abort signal I am seeing (SMC_PMCTRL_STOPA) or whether it's just that more peripherals stay running in VLPS mode than LLS mode.

Sandy, I don't know if there is any thoughts you might have on this. Maybe this should be a new forum thread since my problem with the watchdog timer now seems to be resolved -- use VLPS low power mode with LPO clock and not LLS if you want a watchdog that keeps working/protecting while powered down. Maybe there is already a forum post that addresses this issue. I haven't looked because I have some ideas about things to try that I'm working on. But I will soon.

Thanks again for the help you and Hy Mai have provided!   Fred

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Fred,

SMC_PMCTRL_STOPA means interrupt happens while you are trying to enter any STOP modes. I am wondering if you have some system ticker with interrupt running while you are trying to enter VLPS mode. Active interrupt will abort the entering of STOP mode.  And also you need to make sure the clock monitor is off before you enter STOP modes, if MCG is in any of external clock modes. 

My suggestion on your case:

1. If you can enter VLPR mode, just use stop() function to see if you can enter VLPS mode. In VLPR mode, if user want to enter STOP mode, it is VLPS mode.

2. Disable all interrupts and MCG clock monitor that may impact VLPS mode entry first. If this works, then enable the interrupt one by one to see which interrupt impact the power mode entry.

If possible, please share your MCG/OSC/SMC/PMC related registers settings.

Thanks,

Sandy

0 Kudos
463 Views
fredroeber
Contributor II

Hi Sandy, Thanks for the great explanation and suggestions! Much clearer than what I could puzzle together from reference manual. But I want to show you my code and a trace of what I do because something doesn't make sense. Also, for now I want to try to use the simple code you suggested above that goes right in to VLPS from RUN mode and exits back to that. When I was spending weeks last fall on trying to get VLPS to work I was adjusting the clock settings and trying to go through VLPR mode and had problems with occasional hard faults. I am not seeing that at all now which is great.

So my code that goes into low power mode is:

static void

enter_low_power_mode(void)

{

    /* Declare variable that can be used to force a read of a register

     * without getting a compiler warning that nothing is done with the value.

     */

    volatile uint8_t dummy_read __attribute__ ((unused));

    bool systick_enabled = false;   // True if SYSTICK counter is enabled

    /* Always expect to be in PEE power mode when we start this function */

    assert(mcg_mode_check() == MCG_MODE_PEE);

    /* We want to finish all serial debug output and shut it down before

     * stopping the processor since the UART is disabled in low power modes.

     */

    SL_DEBUG_PRINT("Z");

    if (sl_debug_enabled) {

        Serial1.end();

    }

    ELOG(7, 1, "power enter_low_power", ELOG_ALWAYS);

    /* Make sure clock monitor is off so we don't get spurious reset */

    MCG_C6 &= ~MCG_C6_CME0;

    /* Turn off the SYSTICK timer while we are stopped so that elapsed time

     * interrupts don't happen. We had problems that these interrupts caused

     * aborts from stop mode.

     */

    if (SYST_CSR & SYST_CSR_ENABLE) {

        SYST_CSR &= ~SYST_CSR_ENABLE;

        systick_enabled = true;

    }

    /* We don't want to go to sleep if, since our last check, we have gotten

     * an interrupt indicating that we shouldn't sleep. We do this check in a

     * critical section coupled with going to sleep so we don't miss any

     * interrupts.

     */

    __disable_irq();

    if (power_users == 0) {

        /* Set the power mode control register (PMCTRL) STOPM field to select

         * the VLPS mode.

         */

        SMC_PMCTRL = SMC_PMCTRL_STOPM(0x2);

        /* Wait for write to complete to SMC before stopping core */

        dummy_read = SMC_PMCTRL;

        /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP). We don't

         * want other bits in register (eg SLEEPONEXIT) set.

         */

        SCB_SCR = SCB_SCR_SLEEPDEEP;

        /* WFI instruction will start entry into LLS mode */

        ELOG(7, 2, "power WFI", ELOG_ALWAYS);

        asm("WFI");

        ELOG(7, 3, "power WFI done", ELOG_ALWAYS);

    } else {

        ELOG(7, 4, "power WFI skipped", ELOG_ALWAYS);

    }

    __enable_irq();

    /* Start back up the serial port if needed. Note, output may not actually

     * work right if we have to restore the clock settings until we get that

     * done.

     */

    if (sl_debug_enabled) {

        Serial1.begin(SL_DEBUG_BAUD);

        ELOG(7, 7, "power serial started back up", ELOG_ALWAYS);

    }

    /* When we are using VLPS low power mode, we always exit back to PEE mode.

     */

    assert(mcg_mode_check() == MCG_MODE_PEE);

    /* Turn back on external clock monitor */

    MCG_C6 |= MCG_C6_CME0;

    /* Reset the SysTick counter and enable it to start a new countdown cycle.

     * We stopped it before going into LLS mode.

     */

    if (systick_enabled) {

// TODO We lose all sense of elapsed time doing this. Should we do something

// different? As long as we use the RTC timer for all elapsed time measurements

// that can span power down intervals then things are ok.

        SYST_CVR = 0;

        SYST_CSR |= SYST_CSR_ENABLE;

    }

    /* We should have gone into low power mode and woken up on an interrupt.

     * However, there could have been some issue entering the low power mode

     * in which case an "abort" will be signaled by the STOPA bit in the PMCTRL

     * register. For now we just display a different letter on the debug output

     * to indicate the problem. We expect to see an 'N' printed right after the

     * 'Z' printed at the beginning of this function.

     */

    SL_DEBUG_PRINTLN((SMC_PMCTRL & SMC_PMCTRL_STOPA) ? "A" : "N");

}

When the code runs the debug output is always "ZA" when using VLPS mode. When I change the code to use LLS mode it worked right and showed "ZN" based on the SL_DEBUG_PRINT of Z at the beginning of the routine and A or N at the end based on the PMCTRL_STOPA value.

Now, here is the odd thing. See the ELOG() calls in the code? Those are call to an event tracing system I use in embedded systems like this to see how things are working. Each call saves 4 bytes of data in a circular buffer. These are the first two parms from each call (1 byte each) and a 16 bit timestamp from the RTC_TPR register. After running I can retrieve the event data and print it to show what happened. Here is a piece of the data showing two low power cycles (I have the LPTMR running off LPO set to interrupt every 1/2 second):

     Time      Delta   Event (type, value, description)

   0:069.183   69.183 103    1 serial1 uart0_status_isr enter

   0:069.183        0   2  128 <<data value>>

   0:069.214       31 103    1 serial1 uart0_status_isr enter

   0:069.214        0   2  128 <<data value>>

   0:069.214        0 103    1 serial1 uart0_status_isr enter

   0:069.214        0   2  128 <<data value>>

   0:069.550      336 103    1 serial1 uart0_status_isr enter

   0:069.550        0   2  128 <<data value>>

   0:069.702      153 103    1 serial1 uart0_status_isr enter

   0:069.702        0   2  128 <<data value>>

   0:070.068      366 103    1 serial1 uart0_status_isr enter

   0:070.068        0   2  192 <<data value>>

   0:070.068        0   7    1 power enter_low_power

   0:070.068        0   7    2 power WFI

   0:574.310  504.242   7    3 power WFI done

   0:574.341       31   0    1 sl_time lptmr_isr

   0:574.341        0   7    7 power serial started back up

   0:574.341        0 103    1 serial1 uart0_status_isr enter

   0:574.341        0   2  128 <<data value>>

   0:574.341        0 103    1 serial1 uart0_status_isr enter

   0:574.341        0   2  128 <<data value>>

   0:574.341        0 103    1 serial1 uart0_status_isr enter

   0:574.341        0   2  128 <<data value>>

   0:574.677      336 103    1 serial1 uart0_status_isr enter

   0:574.677        0   2  128 <<data value>>

   0:575.043      366 103    1 serial1 uart0_status_isr enter

   0:575.043        0   2  192 <<data value>>

   0:577.362    2.319 103    1 serial1 uart0_status_isr enter

   0:577.362        0   2  192 <<data value>>

   0:577.362        0 103    1 serial1 uart0_status_isr enter

   0:577.362        0   2  128 <<data value>>

   0:577.545      183 103    1 serial1 uart0_status_isr enter

   0:577.576       31   2  192 <<data value>>

   0:577.576        0   7    1 power enter_low_power

   0:577.576        0   7    2 power WFI

   1:079.498  501.923   7    3 power WFI done

   1:079.498        0   0    1 sl_time lptmr_isr

   1:079.498        0   7    7 power serial started back up

   1:079.498        0 103    1 serial1 uart0_status_isr enter

   1:079.498        0   2  128 <<data value>>

There is a "Delta" time field that shows how long after the previous event the current event happened. The time values are shown in seconds:msec.usec. So the odd thing is that after flushing all the serial data and disabling the UART I do the WFI instruction and it does take 1/2 second till I return. And I return and go into the LPTMR interrupt just as I would expect. But when I get the STOPA value and print it the bit is set. That is what doesn't make sense.

Your suggestion to make sure the SYSTICK timer wasn't ticking was great. Too bad I wasn't talking to you last fall when it took me a few days to realize I had to turn off SYSTICK before going into low power. Before I did that I would return from the WFI instruction with the abort set pretty much right away.

So Sandy, any ideas/suggestions? I know pretty much everything I have the processor doing. The one thing I haven't really looked into much at all is the USB interface. We use it and it works but all the driver SW for it was done by the person who developed and sells the Teensy board we are using. I don't do anything with that driver code relative to low power but it doesn't look like it is causing any interference. I did put ELOG calls in the USB interrupt handler code so would see an event log if we got a USB interrupt.

As I've said before, your advice on this has been great!  Fred

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi Fred,

Would you please help try following things to narrow the issue?

1. Only enable LPTimer running before asm("WFI"); to enter VLPS mode, make sure no LPT isr pending event.

2. For the ELOG buffers, are they in MCU SRAM? or other debugger system? Would you please help to try this case after you POR the system, not running the MCU in debug active mode?

3. After wakeup from STOP/VLPS/LLS mode, MCU should be in PBE mode, but I can't you use any switch function to switch MCU back to PEE mode. Is there anything missing?

4. Set a larger value of LPTimer isr interval, maybe upto several seconds, then you can get a static power mode current, you can check out the STOP/LLS/VLPS mode current.

5. UART print will take lots of time, for example 100kbps, it will take 100us to send out a character. Please take care while using it.

6. Shutdown USB system if possible. It may be a MCU architecture issue if this causes your issue. Not sure, just have a try if possible.

Hope these helpful,

Sandy

0 Kudos
463 Views
zhaohuiliu
NXP Employee
NXP Employee

Hi all,

I have never thought the WDOG would get any one in such a big trouble, but actually, it does!!. Please help to try following code for WDOG refresh. You don't have to use a delay loop to wait to refresh WDOG, just checking the WDOG timer value. For latest Kinetis family device, WDOG may have more clock sources other than bus/LPO, maybe ERCLK. delay loop may be not very good for that case. Another attention is that if you are using early age Kinetis, then don't try to modify the reserved bit of WDOG_STCTRLH[8], it may impact WDOG STOP.VLPS mode behavioral. Please always keep the reserved bit value as the default value!  WDOG is not functional in LLSx/VLLSx modes. the lowest power mode for WDOG to active is VLPS mode.  Hope everyone like this WDOG. Have a nice day!!

Regards,

Sandy

main(){

       wdog_unlock();

       //enable wdog and use LPO clock as counter source

       WDOG_STCTRLH |= WDOG_STCTRLH_WDOGEN_MASK// | WDOG_STCTRLH_CLKSRC_MASK

                    | WDOG_STCTRLH_ALLOWUPDATE_MASK;//x0013;

       //set timer overflow time to 5s with default prescaler value

        WDOG_TOVALH = 0;

        WDOG_TOVALL = 1000;

       

        while(1){

          //make sure to wait 2-3 WDCLK before refresh wdog

          while(WDOG_TMROUTL<2){}

          // printf("%d\n",WDOG_TMROUTL);

           WDOG_REFRESH = 0xA602;

           WDOG_REFRESH = 0xB480;

           //make sure the refresh passed to WDCLK clock domain, after that, counter value should be 0

           while(WDOG_TMROUTL>=2){}

         } 

}

void wdog_unlock(void)

{

  /* NOTE: DO NOT SINGLE STEP THROUGH THIS FUNCTION!!! */

  /* There are timing requirements for the execution of the unlock. If

   * you single step through the code you will cause the CPU to reset.

   */

  /* This sequence must execute within 20 clock cycles, so disable

         * interrupts will keep the code atomic and ensure the timing.

         */

        DisableInterrupts;

  /* Write 0xC520 to the unlock register */

  WDOG_UNLOCK = 0xC520;

  /* Followed by 0xD928 to complete the unlock */

  WDOG_UNLOCK = 0xD928;

  /* Re-enable interrupts now that we are done */

        EnableInterrupts;

}

0 Kudos
463 Views
fredroeber
Contributor II

Wow, have I had an amazing run around with Freescale! I've used their products for years and liked them and had good results with tech support. But on this project I'm developing a safety critical product that HAS TO WORK. And I need a watchdog timer to guarantee that. And using the watchdog with the aux clock doesn't do the trick because our product goes into LLS mode to save power and then the aux clock watchdog stops running. And we are having problems.

So I want to/need to use the LPO with the watchdog. And as I presented above, I've written all the code to do everything suggested by people here but the watchdog never triggers. This is the continual problem I have had with that. Jim said he got some verification code that showed the watchdog worked. BUT, he decided he didn't need to use the LPO option so I'm pretty sure he hasn't verified the LPO option works. So, as far as I can see from this thread nobody has said they got LPO working.

I put in a service request asking for the same code Jim got so I could see if there was anything in that code that I was doing wrong. I referenced this post in the request. Well I got back a response saying "you should use the forum to get an answer to this request". And, ridiculously, once I got the response I could no longer look at my service request or add anything to it. I got "server errors" from Freescale. So I put in a second service request saying "didn't you see that I DID USE the forum and didn't get the info I needed? Could I please get a real answer to my question?? Well, I just got a response to that service request saying:

I checked your thread on community, There is a correct reply marked by you. If you have any question, please follow that thread, I will follow that thread. Thanks a lot for your understanding. Have a nice day.

Thank you for your interest in Freescale Semiconductor products and for the opportunity to serve you.

WOW! So my request for info on this thread is considered my saying my request had been answered and I was all set. Oh, and of course I now can't look at my second support request or add to it since it was "answered". So I'm forced to indicate how pissed off and disappointed I am with Freescale in this public forum rather than going through a more appropriate support request process.

AND I STILL WORRY THAT THE LPO WATCHDOG IS BROKEN SO THIS PROCESSOR CAN"T BE USED IN APPLICATIONS WHERE PROPER OPERATION IS IMPORTANT.

I just wish I could get a copy of the freescale validation code so I can hopefully see something I'm doing wrong. Just in case it will help I'll post the code I wrote for this as I think it does everything right but still doesn't work. I've used a lot of vendors on past projects over the decades including Moto and then Freescale. I've worked with lots of support groups and helped lots of companies improve their product. I have to say I used Energy Micro processors on my last project and their products are great and the company (and support) is awesome. I needed a different feature set for this project so went with Freescale. I'm beginning to think that was a major mistake because it seems the company has a broken support system and possibly problems building working products. I guess I'll have to go back to my Rolodex and resurrect my contacts higher up in the food chain there and try to get some resolution since this support mechanism just isn't working.

Fred

0 Kudos