QN908X Stack Timer/RTC FR not waking MCU from Deep Sleep (0)

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

QN908X Stack Timer/RTC FR not waking MCU from Deep Sleep (0)

1,988 Views
joseraffucci
Contributor IV

I'm having trouble getting the RTC Free-Run interrupt to wake up the MCU when I go into DS0.   Seems to work ok when just sleeping. 

Note:  I am using a digital clock as my XTAL32K source which I suspect may be a factor.  Clock input is on pin XTAL32_IN/PB01.  XTAL32_OUT/PB02 is floating. 

pastedImage_1.png

I've set up a test that sets up an LP timer that toggles an led at 10Hz.  BLE is disabled and all other tasks are shut down. 

pastedImage_2.png

Callback:

pastedImage_3.png

Is there anything about the architecture that would cause this behavior for a digital 32K clock source?  I'm going to switch over to use the internal oscillator to see if I can get my test to work with it next.  One thing I noticed today is that this is occurring while I have the debugger active so it may be a stack/setup issue rather than a hardware one.

The freerun timer is enabled and the interrupt and wakeup bits are set:

pastedImage_4.png

After a wakeup event, the reason correctly identifies that a TMR event occurred:

pastedImage_5.png

But the wakeup is actually coming from the BLE_LLTimer and not the TMR.  The MCU wakes up roughly every 10s and not 100ms as expected.

Any ideas on what might be going on?

0 Kudos
16 Replies

1,491 Views
joseraffucci
Contributor IV

I've narrowed down the problem using only demo code so hopefully someone at NXP can shed some light.  This test uses the power_profiling sample project and a QN9080-DK 1.2 board.

I created a low power millisecond interval timer with a 200ms interval.  The timer callback toggles the blue LED. The timer is started when the button is pressed so that PD0 is active.  I bumped the number of timers in app_config.h to make sure I wasn't running out of them.

I expect the MCU to go into PD0 and wake up periodically to toggle the LED.  This does not happen.  The MCU goes into power down and stays there, even with the debugger connected.

My changes to power_profiling.c:

169,178d168
< static tmrTimerID_t mLedTimerId = gTmrInvalidTimerID_c;
< static void LedTimerCallback(void * pParam);
<
< static void LedTimerCallback(void * pParam)
< {
<     (void) pParam;
<
<     Led3Toggle(); // blue
< }
<
188,189d177
<     mLedTimerId = TMR_AllocateTimer();
<
222,223d209
<    TMR_StopTimer(mLedTimerId);
<
234,242c220,221
<
<                 //Blink Blue LED when in PD0.  Interrupt toggles.
<                 TMR_StartLowPowerTimer(mLedTimerId,
<                                        gTmrLowPowerIntervalMillisTimer_c,
<                                        200,
<                                        LedTimerCallback,
<                                        NULL);
<
<                 mPowerState = 1;
---
>                 Led3On(); // blue                
>                 mPowerState = 1;                

0 Kudos

1,491 Views
joseraffucci
Contributor IV

The timer works as I expect it to when I disable the BLE stack initialization.  LED blinks and I can see that the MCU is going in and out of DS mode.  Unfortunately BLE_Init() is behind the library interface and I can't debug any further.

pastedImage_1.png

Can you kick this back to your developers?  I need a workaround soon.

0 Kudos

1,491 Views
estephania_mart
NXP TechSupport
NXP TechSupport

Hello, 

I have checked the information you are sharing and the procedure you are following with the screenshots shared, The structure of the software you are using, seems to be of an old one. Are you using the latest SDK? 


pastedImage_1.png

If I leave the BLE_Init and BleApp_Init in the code, it works as expected. 

Regards, 
Estephania 

0 Kudos

1,491 Views
joseraffucci
Contributor IV

Code is straight out of examples in

SKD_2.2_QN90X

0 Kudos

1,491 Views
estephania_mart
NXP TechSupport
NXP TechSupport

Hello, 

But which date release of the MCUXpresso SDK are you using ? You can check as well the version of the library you are using in the information of the release notes.

0 Kudos

1,491 Views
joseraffucci
Contributor IV

There is more than one 2.2 SDK released?

This is the only date I could find in the release notes document.  It makes no mention of an SDK version past 2.0.0.

pastedImage_1.png

0 Kudos

1,491 Views
estephania_mart
NXP TechSupport
NXP TechSupport

Hello, 

The SDK 2.2 refers mostly to the driver packages, you need to check and compare the information regarding the Bluetooth LE libraries and version. 

0 Kudos

1,491 Views
joseraffucci
Contributor IV

I am resurrecting this issue.   A year later and using the latest 2.2.1 SDK (bluetooth_1.5.5 / framework_5.6.5).

It is still an issue.

Why does the LP Timer not fire when in PD0?

Edit:  Using the power_profiling free rtos wireless example project in IAR.

Slightly simpler code changes attached:

146,154d145
< static tmrTimerID_t mLedTimerId = gTmrInvalidTimerID_c;
< static void LedTimerCallback(void * pParam);
<
< static void LedTimerCallback(void * pParam)
< {
<     (void) pParam;
<     Led3Toggle(); // blue
< }
<
167,168d157
<     mLedTimerId = TMR_AllocateTimer();
<     
216,222d204
<
<                 //Blink Blue LED when in PD0.  Interrupt toggles.
<                 TMR_StartLowPowerTimer(mLedTimerId,
<                                        gTmrLowPowerIntervalMillisTimer_c,
<                                        400,
<                                        LedTimerCallback,
<                                        NULL);
226d207
<                 TMR_StopTimer(mLedTimerId);
0 Kudos

1,491 Views
joseraffucci
Contributor IV

I eventually figured out how to get the FR interrupts to fire on the last 2.2.0 SDK.  There were differences between the two 2.2.0 released that I overlooked.

You will need to tell the PWRLib to allow the timer and interrupts to work:


/* Enable RTC_FR clock and interrupt wakeup from PD0 */
#define cPWR_EnableLpTmrRunning         1
#define cPWR_EnablePD0RtcInterrupt      1

It will tick at at least this interval:

//Default wakeup interval from PD0
#define cPWR_DeepSleepDurationMs        2u * 1000u

You also need to set the RTC_FR interrupt priority to 0 prior to entering PD0.  Refer to the file (power_mode_switch.c) in this thread for a simplified example.

0 Kudos

1,491 Views
wang_barry
Contributor III

Hello,
I meet the same issue about how to trigger FR interrupts at PD0.

"You also need to set the RTC_FR interrupt priority to 0 prior to entering PD0" is mean to set NVIC_SetPriority(RTC_FR_IRQn,0) before entering PD0?

0 Kudos

1,491 Views
joseraffucci
Contributor IV

Correct.  Set it to 0 prior to entering PD0 and restore to the correct priority on wakeup.

0 Kudos

1,491 Views
joseraffucci
Contributor IV

I found an answer to one of my questions.  The MCU gets lost when I don't define the handler because the ram and flash vectors are getting mixed up.

The examples do in fact set up RTC_FR_IRQHandler  because of a bug in the SDK.

When the system is coming up, the timers are initialized in TMR_Init():

pastedImage_3.png

 StackTimer_Init() overrides and enables the RTC_FR interrupt so that the stack timer handler is used:

pastedImage_4.png

The abstraction layer eventually calls InstallIRQHandler where the new handler is installed.  Note that the vector table is then moved to RAM:

pastedImage_5.png

After initialization, I eventually go into DS(0) in POWER_EnterPowerDown().  On my very first wakeup event,  the vector table pointer is restored  to _Vectors:

pastedImage_1.png

Unfortunately, you can see that in startup_QN908XC.s _Vectors is defined as the flash vector table.

pastedImage_2.png

...oops!

I'm guessing what's needed is something like:

Index: fsl_power.c
===================================================================
--- fsl_power.c    (revision 20178)
+++ fsl_power.c    (working copy)
@@ -352,9 +352,30 @@
 #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) || (defined(__VFP_FP__) && !defined(__SOFTFP__))
     SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access */
 #endif
+#if defined(__CC_ARM)
+    extern uint32_t Image$$VECTOR_ROM$$Base[];
+    extern uint32_t Image$$VECTOR_RAM$$Base[];
+    extern uint32_t Image$$RW_m_data$$Base[];

-    SCB->VTOR = (uint32_t)&__Vectors;
+#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
+#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
+#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
+#elif defined(__ICCARM__)
+    extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
+    extern uint32_t __VECTOR_TABLE[];
+    extern uint32_t __VECTOR_RAM[];
+#elif defined(__GNUC__)
+    extern uint32_t __VECTOR_TABLE[];
+    extern uint32_t __VECTOR_RAM[];
+    extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
+    uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
+#endif /* defined(__CC_ARM) */
+    //SCB->VTOR = (uint32_t)&__Vectors;

+    /* Point the VTOR to the position of vector table */
+    SCB->VTOR = (uint32_t)__VECTOR_RAM;
+
+
     /* All registers in NVIC are lost, restore from backup values */
     NVIC->ISER[0U] = backISER[0U];
     NVIC->ISER[1U] = backISER[1U];

In any event, this still does not answer why I'm not waking up when the RTC fires.  It doesn't really have anything to do with the vector table, right?

0 Kudos

1,491 Views
joseraffucci
Contributor IV

I started poking around and saw that BLE was not disabled in PMU_CTRL0:

pastedImage_1.png

When I flip this bit on, my led starts to blink as expected.

It looks like there's some sort of conflict with the low power timer and the BLE hardware somewhere.

0 Kudos

1,491 Views
joseraffucci
Contributor IV

One more data point for today...

I have found that I do in fact get FR interrupts.  They're just not getting handled the way I expect.

In TMR_Init, a call is made ot StackTimer_Init which should override the vector for FR interrupts.

pastedImage_2.png

StackTimer_Init:

...

pastedImage_5.png

On a hunch, I created a default handler:

pastedImage_6.png

And found that after a wakeup from DS, it gets called!  It is not getting overwritten by StackTimer_ISR.

pastedImage_1.png

And when I don't create the default handler, the MCU doesn't know who to call after a wakeup!

pastedImage_1.png

The RTC FR count is well above the threshold so it's clearly not responding to that as a wakeup trigger.

pastedImage_7.png

So I'm left with 2 slightly more specific questions:

1.  Why on earth is my interrupt vector getting trashed when I wake up from DS?

2.  Why is the FR interrupt not waking up the MCU?  (see previous posts for RTC config, I believe it's set up correctly).

0 Kudos

1,491 Views
estephania_mart
NXP TechSupport
NXP TechSupport

Hello Jose, 

I will strongly recommend the flow of the code in our available examples and use them as a base, you can check there that you need to add the handlers, please verify in the board.c file and look for the RTC_FR_IRQHandler

About the RTC free running, again, I will ask you to check the available demos as the timer manager already sets and configures that. 

Regards, 
Estephania 

0 Kudos

1,491 Views
joseraffucci
Contributor IV

Retesting using the internal 32k oscillator and the results are the same.  It looks like the digital clock isn't the issue.

0 Kudos