GENFSK KW41Z LLS3 LLWU exits without wakeup reasons

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

GENFSK KW41Z LLS3 LLWU exits without wakeup reasons

1,327 Views
gerardocatena
Contributor II

Hi,

we are trying to implement a polling receiver using GENFSK. Basically our application is a customization of the FreeRTOS connectivity demo.

The aim is to make the rx device cycling forever between rx peak states and idle low power states:

rx -> idle -> rx -> idle ->rx... and so on.

My application runs in a task and it's main job is to collect events belonging from the GENFSK layer through its notification callback. The application flow is the following:

1- At the beginning the device is disallowed to sleep and perform a RX peak.

2- When the GENFSK notification callback receives a rx timeout event, a local event is bubbled to the application main task.

3- The application main task changes its state and call the PWR_GENFSK_EnterDSM(timeout )) + PWR_AllowDeviceToSleep(); (power mode 7), to make the radio entering in DSM and eventually will make the device enter into deep sleep.

4- When the wake-up event is notified by the GENFSK layer, the PWR_DisallowDeviceToSleep is called, and a local event is bubbled to the main task which will change it status in RX and so on

During the lifetime of this task we experienced systematic blocks. Investigating we found that some times the device exits from LLS3 power down without any reason. This is not depending on the timeout value passed to the PWR_GENFSK_EnterDSM API. If this happens probably the hadler of the power mode 7 fails to put the radio entering into DSM or it fails to put the device in LLS3. The block will be delayed, but it happens in any case, if we synchronize the Radio DSM timeout with the LPTMR timeout. We suspect that when the device fails to go in LLS3 is because the DSM timeout has some invalid values, for a reason currently unknown to us. From this consideration we apply a little "turnaround" which basically invalidate the mPWR_AbsoluteWakeupTimeInDsmTicks variable when the device exits from LLS3 with an invalid reason flag. Before to exit from the  PWR_HandleDeepSleepMode_7 handler, if the device has passed the enterLowPower check, we simply apply this:

...

 PWRLib_LLWU_UpdateWakeupReason();

 PWR_HandleGenfskDsmExit();
 PWRLib_LPTMR_ClockStop();

if(PWRLib_MCU_WakeupReason.AllBits == 0 ) {
             mPWR_AbsoluteWakeupTimeInDsmTicks=mPWR_DSM_InvalidTime_c;

}

....

It works and we tested 4h of working rx. However it will be better to understand why the device fails to enter in DSM. What could be the reason?

Bests,

Gerardo.

Labels (1)
0 Kudos
4 Replies

867 Views
gerardocatena
Contributor II

Hi,

here MKW41Z GENFSK Connectivity Framework: implementing tickless FreeRTOS  I explain how we have implemented the tickless mode of FreeRTOS which should resolve this problem.

Regards,

G.

0 Kudos

868 Views
gerardocatena
Contributor II

Hi,

we are investigating deeper this problem and we want to share some thought.

1- when the device exits from the LLS3, the PWR_HandleDeepSleepMode_7 handler will call PWR_HandleGenfskDsmExit();

2- the PWR_HandleGenfskDsmExit(); will check through the READ_REGISTER_FIELD(RSIM->DSM_CONTROL,RSIM_DSM_CONTROL_GEN_SLEEP_REQUEST) if the device is still in DSM and will adjust the RSIM->GEN_WAKE to DSM_TIMER value + 5 ticks.

We suppose that the  PWR_HandleGenfskDsmExit() API  has the objective of signaling that the device is exited from the DEEP SLEEP to the GENFSK module in the shortest time. But when the device wakes up with an invalid reason equal to zero the RSIM->GEN_WAKE will be incremented forever and the application will never receive a wake-up signal. After the exit from LSS3 with an invalid wake-up reason, the register SMC->PMCTRL has a value of 3 and no abort flag has been set.

So the device enters in deep sleep but suddenly exits, due to some interrupt (probably a systick interrupt). Following the sdk power mode switch example and this article (FreeRTOS in tickless mode and LLS3 ) we found that before to enter in LLS3 the global irq should be disabled. We found inside the PWR_EnterLowPower(void) API the instruction line which disables the interrupts before to enter in DEEP SLEEP mode. If we well understand the OSA_InterruptDisable() it does through FreeRTOS no more than save the PRIMASK and turn off the interrupts. But probably isn't enough to prevent the unwanted behavior.  For this reason we changed the OSA_InterruptDisable() with OSA_DisableIRQGlobal(void) and the related OSA_InterruptEnable(void) with OSA_EnableIRQGlobal(void) and the problem disappeared.

Is it the correct way to face this problem?

Regards

0 Kudos

868 Views
estephania_mart
NXP TechSupport
NXP TechSupport

Hello, 

Something that it's not quite clear, the only desired way of wake-up it's through an Rx event? 

Also, you are using the PWR lib, right? 

Regards, 

Estephania 

0 Kudos

868 Views
gerardocatena
Contributor II

Hello Estephania,

for the moment the wake-up source can be external to the MCU (GPIO/buttons), can be the GENFSK wake-up irq or LPTMR. We are using PWR lib.

The firmware works in this way:

  • Based on the button pressed, I can switch between Rx and Tx mode.
  • If I act on the device to be in Rx mode, it will start to alternate Rx peak followed by a DSM state forever, until I will act again on the device.

The problem is that, when the device is in Rx mode, after a couple of transitions between Rx peak and DSM state, the application will not receive a GENFSK wakeup-event anymore, resulting in a block of the task's state machine that checks the radio events and changes its states based on them.


Our opinion is that systick interrupt prevents the MCU to complete the deep sleep phase.  If the device enters and exits compulsively from the deep sleep without an exit reason, the Power Mode 7 Handler will be called back-to-back, which in turn will call PWR_HandleGenfskDsmExit(). The latter will increment the RSIM->GEN_WAKE register forever. This should be a possible reason of the blocks: simply the GENFSK wakeup irq is never raised. 

Implementing the FreeRTOS runtime statistics we have seen that the idle task takes about the 98% of the processing time. Based on this result we did a better turnaround of the previous one, but is not the definitive solution. We have inserted a little delay into the idle task when it manages the exiting from power down, and for the moment the blocks are avoided.

.....

 if(wakeupReason.Bits.FromKeyBoard)
        {
            KBD_SwitchPressedOnWakeUp();
            PWR_DisallowDeviceToSleep();
        }else if(wakeupReason.AllBits==0){
              OSA_TimeDelay(3);
        }

.....

I think that the definitive solution will be to implement the tickless FreeRTOS mode, but before to take this way It will be better listen your opinion and be sure that we are on the right path.

I hope that this clarifies more the problem.

Thanks,

G.

0 Kudos