Device not waking properly when using Bitcloud to sleep manually - Page 1
Forum section: electronics / general

author: temasp
author_rank: Newbie
timestamp: May 03, 2018, 07:08:11 pm
content: I'm using Bitcloud SDK 3.3.0 with the Atmel SAM R21 Xplained Pro Evaluation board. I'm trying to go to sleep and wake up after CS_END_DEVICE_SLEEP_PERIOD time period (20 seconds for me).Note that I've sucessfully gotten automatic sleep working, using SYS_EnableSleepWhenIdle() - the device sleeps and wakes properly. However I'm attempting to manage sleeping manually, which I can't get working. I call SYS_DisableSleepWhenIdle() in my initialization function so that Bitcloud sleep-when-idle feature is disabled.The device goes to sleep OK, but on wakeup it executes briefly but eventually hangs. My code snippets are below. Notice in ZDO_WakeUpInd() I call SYS_PostTask(APL_TASK_ID) to get running again after waking up.My problem is, I call SYS_PostTask(APL_TASK_ID) in ZDO_WakeUpInd(), but my task handler APL_TaskHandler() never gets called after waking up.After waking up, I traced through processManagerTask() (in sysTaskManager.c) in the debugger, and I noticed that the task handlers for tasks 3, 2, and 0 get called, in that order. These handlers are NWK_TaskHandler, MAC_HWI_TaskHandler, and MAC_PHY_HWD_TaskHandler, respectively. After calling MAC_PHY_HWD_TaskHandler, the software hangs forever.When the software hangs, I pressed the Pause button in the debugger, and here is the call stack:AS7_ATSAMR21G18A.elf! halDelayUs Line: 38762656AS7_ATSAMR21G18A.elf! HAL_Delay Line: 38762656AS7_ATSAMR21G18A.elf! PHY_SetTrxStateReq Line: 38762656AS7_ATSAMR21G18A.elf! executeDataReq Line: 38762656AS7_ATSAMR21G18A.elf! machwdTxFrameReqHandler Line: 38762656AS7_ATSAMR21G18A.elf! MAC_PHY_HWD_TaskHandler Line: 38762656> AS7_ATSAMR21G18A.elf! processManagerTask Line: 261AS7_ATSAMR21G18A.elf! SYS_RunTask Line: 200AS7_ATSAMR21G18A.elf! main Line: 1125Anyone else have similar trouble? Why is it hanging? Is it hanging in halDelayUs, as the call stack indicates? halDelayUs is a simple function that delays for a few microseconds.Perhaps there is some other function I should call in ZDO_WakeUpInd() to wake up the device, although I'm doing what the Bitcloud documentation and samples say to do.Here are my code snippets. They match the Bitcloud documentation and the few samples I've found.// This is called from APL_TaskHandler() to attempt to go to sleep.void goToSleep(void){zdoSleepReq.ZDO_SleepConf = ZDO_SleepConf;ZDO_SleepReq(&zdoSleepReq);}void ZDO_SleepConf(ZDO_SleepConf_t *conf){if (ZDO_SUCCESS_STATUS == conf->status){// Note that we get actually get here, so I know that the device goes to sleep.// The device is going to sleep.// ZDO_WakeUpInd() will be called by the stack when the device wakes up.}else{// The device is busy. Call SYS_PostTask(APL_TASK_ID) which will cause APL_TaskHandler() to call goToSleep() to try sleeping again.appState = APP_SLEEPING_STATE; // In this state we attempt to sleep.SYS_PostTask(APL_TASK_ID);}}void ZDO_WakeUpInd(void){// This function is called when the device wakes up.// On an end device CS_END_DEVICE_SLEEP_PERIOD determines the duration of the sleep period.if (appState == APP_SLEEPING_STATE){// As recommended in the Bitcloud guide, post a task to get us running again.// Note that we get actually get here, so I know that the device is waking up.appState = APP_RUNNING_STATE; // go to the RUNNING stateSYS_PostTask(APL_TASK_ID);// Even though I post a task above, APL_TaskHandler() never gets called.}}Can anyone offer advice, or point me to a working example of manual sleeping using Bitcloud?Thanks in advance for your help,Tim M

author: ataradov
author_rank: Super Contributor
timestamp: May 03, 2018, 08:17:18 pm
content: What you are doing looks correct.I would debug halDelayUs() and see what exactly happens. It relies on timer/counter to do the delay, so if something is wrong with the timer, it will not work. So at least check that TC is enabled and counting.

author: temasp
author_rank: Newbie
timestamp: May 04, 2018, 07:04:16 pm
content: I checked and discovered that, after waking up, the timer/counter (TC3) used in halDelayUs() is disabled (the enable bit in CTRLA register is zero) and thus the counter is not counting. So that's the problem. But what would cause TC3 to be disabled? Any ideas on how I can debug this further?Remember I'm attemping to control sleep manually. I call SYS_DisableSleepWhenIdle() in my initialization function, and I go to sleep by calling ZDO_SleepReq(). In ZDO_WakeUpInd(), I simply post a task to change state and get us running again.Do I need to call ZDO_WakeUpReq() to properly wake up the stack? The Bitcloud documentation says that ZDO_WakeUpReq() is used when waking up by external interrupt - I'm not using an interrupt. I wake up by timer (using CS_END_DEVICE_SLEEP_PERIOD as the sleep time).By the way, when I'm awake, I use one app timer that I start using HAL_StartAppTimer(). I configure it as a one-shot timer, and this timer is not in use when I'm sleeping. Do you suppose my timer is somehow interfering with TC3 used by halDelayUs()?I tried using automatic sleep, and it worked. It's manual sleep that's giving me trouble.Any ideas on how to fix the problem of TC3 getting disabled?Thanks,Tim M

author: ataradov
author_rank: Super Contributor
timestamp: May 04, 2018, 08:29:53 pm
content: There is nothing you are doing wrong in your code. It is either some stack bug, or some other issue.I would try straightforward debugging of the open part of the HAL. Trace all functions that are known to enable/disable TC3 (halStartAppClock, halStopAppClock).Start with halPowerOff() and everything that follows. Just setting breakpoints on halStartAppClock() and halStopAppClock() will probably tell a lot.I'm not involved in wireless stuff anymore, so I don't have access to the latest source code and I'm slowly getting out of the loop of known issues, etc. So the

author: temasp
author_rank: Newbie
timestamp: May 07, 2018, 05:44:49 pm
content: Alex,Could my problem be caused by the makefile I'm using? I use Makefile_All_SamR21_Atsamr21g18a_Rf233_16Mhz_Gcc (which includes ../../../../BitCloud/lib/Makerules_Atsamr21g18a_Gcc). This makefile is supposed to work for all configurations (Coordinator, Router, or EndDevice).I need an end device, so I configure this in code as follows:sleepPeriod = 20000L; // sleep period, 20 secondsrxOnWhenIdle = false;deviceType = DEVICE_TYPE_END_DEVICE;CS_WriteParameter(CS_DEVICE_TYPE_ID, &deviceType);CS_WriteParameter(CS_RX_ON_WHEN_IDLE_ID, &rxOnWhenIdle);CS_WriteParameter(CS_END_DEVICE_SLEEP_PERIOD_ID, &sleepPeriod);SYS_DisableSleepWhenIdle();I'm assuming that my code snippet above configures my board as an end device with sleep when idle disabled.But I noticed in the makefile _SLEEP_WHEN_IDLE_ is defined. Do I have to delete _SLEEP_WHEN_IDLE_ from the makefile? Or is it good enough to use SYS_DisableSleepWhenIdle()? Do I have to edit the makefile at all?Thanks,Tim M

author: ataradov
author_rank: Super Contributor
timestamp: May 07, 2018, 05:51:54 pm
content: I don't think it has anything to do with the way you build things.Don't delete any defines from included makefiles. Defines that look like _XXX_ are automatically generated based on the way the library was built and must be preserved. _SLEEP_WHEN_IDLE_ means that corresponding library supports this feature, you can't change this without rebuilding the whole library.You are running into some bug, which you need to debug.BTW, do you see the same behavior on the stock WSNDemo application?

author: temasp
author_rank: Newbie
timestamp: May 07, 2018, 08:35:45 pm
content: Alex,The WSNDemo application uses automatic sleeping (it calls SYS_EnableSleepWhenIdle()), and it works. Automatic sleeping works in my application too. It's manual sleeping that's giving me trouble.This is a silly question, but how do I set breakpoints in halStartAppClock() and halStopAppClock()? These functions are part of the compiled Bitcloud library, and Atmel Studio won't allow me to set breakpoints in these functions.Thanks for your help,Tim M

author: ataradov
author_rank: Super Contributor
timestamp: May 07, 2018, 09:10:31 pm
content: You can compile HAL yourself (using Makefiles). By default it is probably built without debugging information.But the easiest way to to look in the map file (or run arm-none-eabi-nm on the *.elf file) for the addresses of those functions and set breakpoints in the disassembly view on the corresponding addresses.

author: temasp
author_rank: Newbie
timestamp: May 08, 2018, 09:05:34 pm
content: I did some debugging and this is what I see.halPowerOff() prepares the device for sleep. A call to halStopAppClock() is made. Most of the sleep preparation is done only if sleepWhenIdleEnabled is true, including setting mcuSleep flag to true.halWakeupHandler() is called when the sleep time has elasped and the device is waking up. The problem in halWakeupHandler() is halStartAppClock() is called only if the mcuSleep flag is true. But mcuSleep flag is set true in halPowerOff() only if sleepWhenIdleEnabled is true, which it's not because I'm in manual sleep mode. So the app clock is never re-enabled.It seems to me that the sleep preparation in halPowerOff() should also be done when in manual sleep mode (i.e. sleepWhenIdleEnabled is false). I could try to change the source code and recompile the HAL library, but I don't fully understand the code and I might make things worse.Do other people have manual sleeping working? I can't believe I'm the first to encounter this problem. It seems that anyone who tries manual sleep will have the same problem. Does anyone have a working example of manual sleep that I could download?Thanks,Tim M

author: ataradov
author_rank: Super Contributor
timestamp: May 08, 2018, 09:13:26 pm
content: Sleep When Idle is a relatively new feature, and it is used by default in all new projects and it is possible that manual control has issues. you can probably find older versions of the stack, where it was not the case, but I don't remember what happened first sleep when idle or R21 support. Official tech support will be your best bet here.I'm not sure that you want to rely on BitCloud if you don't have a huge project, spare yourself a lot of pain.