[BitCloud] End device's power consumption - Page 1
Forum section: electronics / general

author: danergo
author_rank: Regular Contributor
timestamp: October 22, 2016, 09:34:52 am
content: Hi Guys,How can I make an ED to sleep?I programmed Bitcloud's ED stack into an atmega256RFR2 with some additional codes.CS_END_DEVICE_SLEEP_PERIOD is 60000. So basically ZB stack should be sleeping for a minute.Anyway, I have some timers running @10000ms or so.Power consumption seems always ~15mA@3.3V.But I'd love to see it way lower when the chip is sleeping.So I have two questions:1.) how can I make it sleep?2.) is it possible to have a timer which wakes up the chip, but not the ZB stack itself (for example to initate a measurement and store it for later sending when ZB is active).Thank you,danergo

author: ataradov
author_rank: Super Contributor
timestamp: October 22, 2016, 06:09:44 pm
content: Quote from: danergo on October 22, 2016, 09:34:52 amWhat version of the stack? Older versions required you do to ZDO_SleepReq(), newer versions have a feature called Sleep When Idle. You call SYS_EnableSleepWhenIdle() and device will sleep all the time when there is nothing to do.If you are already doing one of those things, then are you sure if this power consumption does not come from external circuitry on the board?Quote from: danergo on October 22, 2016, 09:34:52 amIt is possible, but not easy. You will have to look though the HAL sleep code and modify it. I'm not even sure what type of modifications may be required without actually going in and doing it.

author: danergo
author_rank: Regular Contributor
timestamp: October 23, 2016, 09:32:51 am
content: Quote from: ataradov on October 22, 2016, 06:09:44 pmI'm using Bitcloud 3.2.0, which I believe has this function.Quote from: ataradov on October 22, 2016, 06:09:44 pmThere is not much else mounted on the board except this chip and the sorroundings (antena, balun, etc, what is mentioned in this chip's sheet).I would not expect the rest to consume more than 1mA altogether.Quote from: ataradov on October 22, 2016, 06:09:44 pmCould you guide me a bit in this topic? It might be a material on the net somewhere maybe?The problem is now, that I have 3 buttons handled by an AppTimer. Which would obviously wake up everything in every 50 or 100 ms.I also looked at the docs, becaue I wanted to make it sleep manually, but in this case, all the AppTimers would only fire after CS_END_DEVICE_SLEEP_PERIOD. (which I'd increase as much as I can, for 15 or 30 mins).Also, I found something interesting in the source code of sysIdleHandler.c on line 26-41:"...If an end device wakes up on expiration of CS_SLEEP_PERIOD it pollsits parent, otherwise it doesn't...."It sounds for me that polling only occurs if CS_SLEEP_PERIOD expires. CS_SLEEP_PERIOD means CS_END_DEVICE_SLEEP_PERIOD in here?Anyway what I'd like to do is to make HAL to differentiate it's waking up source:1.) wake up by expiring CS_END_DEVICE_SLEEP_PERIOD timer (and only this one) -> normal wakeup procedure2.) wake up by anything else -> calls wakeup routines but do _not_ wake up the RF.Thanks.

author: ataradov
author_rank: Super Contributor
timestamp: October 23, 2016, 05:43:43 pm
content: Quote from: danergo on October 23, 2016, 09:32:51 amIn this case you need to careful - if you enable this, then you don't have to manually go to sleep, but device will wakeup (briefly) on every hardware timer interrupt (10 ms for default system timer).Quote from: danergo on October 23, 2016, 09:32:51 amHave you ever seen this board to go to low power mode? Can you try to run unmodified WSNDemo and see what numbers do you get?Quote from: danergo on October 23, 2016, 09:32:51 amWhy not pin change interrupts? Your scenario looks 1:1 like WSNDemo.Quote from: danergo on October 23, 2016, 09:32:51 amThere is some mix in terminology. Internally there are 3 types of wakeups:1. Very short (a few us) every 8 seconds - this is because of limited range of the asynchronous timer and it is unavoidable. This is totally transparent to the application.2. MCU wakeup. When external interrupts happen. This one does not wake up the radio, but the stack (parts of it) is awake. You need to manually call ZDO_WakeupReq() or ZDO_SleepReq(), depending on hoe you want to proceed. It sounds like that's exactly what you want and it is already implemented.3. CS_SLEEP_PERIOD - the whole stack and radio wakes up and sends the poll request.Quote from: danergo on October 23, 2016, 09:32:51 amIt already does this. Look at WSNDemo application.

author: danergo
author_rank: Regular Contributor
timestamp: October 23, 2016, 06:34:02 pm
content: Quote from: ataradov on October 23, 2016, 05:43:43 pmIf I put a simple code inside the chip, I can reproduce the low power mode, yes.Quote from: ataradov on October 23, 2016, 05:43:43 pmWSNDemo is not really suitable for this board, since it hasn't got any LEDs on it, and the Buttons might be overlapped with the WSNDemo's outputs, etc.Anyway, I tried to follow WSNDemo's coding structure in my codes. This means that I use Bitcloud at the same way as WSNDemo.Quote from: ataradov on October 23, 2016, 05:43:43 pmThis is the board's specification. Buttons are not tied to INT pins right now.Quote from: ataradov on October 23, 2016, 05:43:43 pmHAL only differentiate between Timers (whichever expires first, apptimer or sleeptimer),and External interrupts.I mean differentiation between apptimers and sleeptimers. Do you believe it's somewhat possible?

author: ataradov
author_rank: Super Contributor
timestamp: October 23, 2016, 06:40:45 pm
content: Quote from: danergo on October 23, 2016, 06:34:02 pmYou can strip all the parts that don't match. The important part is sleep.Your first order of business to make sure that this board can sleep (not even wake up) using BitCloud APIs.Quote from: danergo on October 23, 2016, 06:34:02 pmSome of Pin Change interrupts can wake up the MCU as well. They are actually better than real INT pins.Quote from: danergo on October 23, 2016, 06:34:02 pmApp timers can't wake up the MCU. When you have Sleep When Idle enabled, sleep timer is reprogrammed to wake up at the interval of the first AppTimer, so it appears that AppTimer woke up the system.This is a very complicated system and messing with it can be dangerous and result in some non obvious bugs.

author: danergo
author_rank: Regular Contributor
timestamp: October 23, 2016, 07:49:52 pm
content: Quote from: ataradov on October 23, 2016, 06:40:45 pmUnfortunately, buttons are connected to PD7 and PD6 and PD5. They are not either INTx or PCINTx.Quote from: ataradov on October 23, 2016, 06:40:45 pmTotally agreed.I'll redesign this board, but for now, I'd need to overcome with this.What I'm thinking right now, is to use a custom timer instead of AppTimer which acts like an external interrupt.In this case I would be able to use this: "2. MCU wakeup. When external interrupts happen. This one does not wake up the radio, but the stack (parts of it) is awake. You need to manually call ZDO_WakeupReq() or ZDO_SleepReq(), depending on hoe you want to proceed. It sounds like that's exactly what you want and it is already implemented."This won't be a large hack, and could be done in user code instead of modifying HAL. What do you think?There are only 2 questions:1.) which timer could be used2.) Is my assumption correct that when a timer overflows, it will result as an MCU wakeup?Thank you!

author: ataradov
author_rank: Super Contributor
timestamp: October 23, 2016, 07:53:40 pm
content: Quote from: danergo on October 23, 2016, 07:49:52 pmRegular timers can't be wake up sources, only asynchronous TC2 can. And it is used by the sleep system in BC.You also have WDT. If you are not using it in your normal operation, then you can use that as your timer.

author: danergo
author_rank: Regular Contributor
timestamp: October 23, 2016, 08:01:22 pm
content: Quote from: ataradov on October 23, 2016, 07:53:40 pmGood point!If I use WDT for handling the buttons, is this true?"You need to manually call ZDO_WakeupReq() or ZDO_SleepReq(), depending on hoe you want to proceed."

author: ataradov
author_rank: Super Contributor
timestamp: October 23, 2016, 09:39:00 pm
content: Quote from: danergo on October 23, 2016, 08:01:22 pmYes. Wake up on WDT will look just like wakeup on external interrupt.You don't actually need to write any new code for this, BitCloud has APIs for WDT, including callback mode.You need to remember that every time you go to sleep, poll sleep timer starts counting again, so you need to make sure that you still poll in a timely manner, even if buttons are pressed a lot.

author: danergo
author_rank: Regular Contributor
timestamp: October 24, 2016, 06:58:45 am
content: That sounds perfect.Anyway, todays news:I was able to put the board to sleep by issueing ZDO_SleepReq().Total consumption is less than 1mA after this call.However, is it possible to wakeup the stack but not the radio itself?I have a button event which triggers a change on a display.The display is handled by BC's state machine.So I want to do some actions with the basic microcontroller before actually deciding on the further wakeup/sleep activities.Is it possible to run BCs state machine with a radio sleeping?

author: ataradov
author_rank: Super Contributor
timestamp: October 24, 2016, 03:15:23 pm
content: Quote from: danergo on October 24, 2016, 06:58:45 amIt is possible to wake up the MCU without waking up the stack. That's exactly what happens when you wake up from an interrupt other than sleep timer interrupt (including WDT).Quote from: danergo on October 24, 2016, 06:58:45 amThat's fine. Just do ZDO_WakeupReq() before you use the stack, or ZDO_SleepReq() if you want to go to sleep right away.

author: danergo
author_rank: Regular Contributor
timestamp: October 24, 2016, 04:10:27 pm
content: I might have some misunderstandings here.ZDO_WakeupReq() will make the stack wake up, right?In this case I'll be able to use BC's state machine, but does this also wake up the radio interface, or does not?If it does not wake up the radio, how can I do that?If it does wake up the radio, I guess I can live with it, and I need to call ZDO_SleepReq when I finished updating the screen and so on (basic tasks that doesn't require radio).What I wanted to be 100% sure is that I don't want to wait for shutting down the radio after issueing ZDO_SleepReq (because in this case I hadn't wanted it to be waken up at all. So waiting for it would be an extra consumption for the battery just because I updated the screen with BC's state machine).

author: ataradov
author_rank: Super Contributor
timestamp: October 24, 2016, 04:23:07 pm
content: Quote from: danergo on October 24, 2016, 04:10:27 pmYes.Quote from: danergo on October 24, 2016, 04:10:27 pmYou don't need to wake up the stack to use the state machine. You only need to wake it up if you use any radio-related interfaces.Quote from: danergo on October 24, 2016, 04:10:27 pmYou need to do this anyway, there is no other way to go back to sleep.

author: danergo
author_rank: Regular Contributor
timestamp: October 24, 2016, 04:53:10 pm
content: Thank you, I'm getting now closer and closer.So: after a HW Interrupt (WDT) wakes up the chip, if I call a SYS_PostTask() function it will call my APL_TaskHandler() and don't go back to sleep automatically?During this operation the radio interface is still sleeping, and I'm not gonna get ZDO_WakeUpInd() unless I issue ZDO_WakeupReq(). Right?In this case, I can have an awakened chip, with running BC (with state machine), but powered down radio. To make the whole chip sleeping again, I have to call ZDO_SleepReq() and it will sleep until the next HW interrupt (or CS_END_DEVICE_SLEEP_PERIOD of time). Right?So the point might be to call SYS_PostTask() in the HW interrupt handler to make the ball rolling.

author: ataradov
author_rank: Super Contributor
timestamp: October 24, 2016, 04:56:30 pm
content: Quote from: danergo on October 24, 2016, 04:53:10 pmNo, nothing goes back to sleep.Quote from: danergo on October 24, 2016, 04:53:10 pmI don't think you will ZDO_WakeUpInd() even after ZDO_WakeupReq(), you just get a normal confirmation from ZDO_WakeupReq().ZDO_WakeUpInd() is only called when stack woken up on its own, from a sleep timer.Quote from: danergo on October 24, 2016, 04:53:10 pmCorrect.Quote from: danergo on October 24, 2016, 04:53:10 pmYep, that's the idea.

author: danergo
author_rank: Regular Contributor
timestamp: October 24, 2016, 05:00:56 pm
content: Alex,thank you very much for your efforts and patience.

author: danergo
author_rank: Regular Contributor
timestamp: October 28, 2016, 06:26:50 pm
content: Hello,I don't really have success with the WDT + ZDOSleepReq.It seems if I choose a WDT for 64ms (for buttons), ZDOSleepReq take more time to sleep, and the whole chip will reset before even going to sleep.How long should the ZDOSleepReq take?My initial idea was:Code:ISR(WDT) {handle_buttonsWDTRestartif nothing to do then {ZDOSleepReq}}This keeps restarting with WDT set to 64ms.

author: ataradov
author_rank: Super Contributor
timestamp: October 28, 2016, 06:29:03 pm
content: Quote from: danergo on October 28, 2016, 06:26:50 pmYou can't call BitCloud APIs from interrupt handlers. You need to set a flag (or change the state machine state) and do actual work in the main task handler.Also, show your WDT initialization code. If WDT restarts the system, no WDT restart will help, you need to disable reset bit on the WDT configuration.

author: danergo
author_rank: Regular Contributor
timestamp: October 28, 2016, 06:44:54 pm
content: Auch. I forgot to avoid calling BC's functions from ISR.Wdt reset should be fine, because without the sleep request, it is handling the buttons correctly, without resets. But it consumes power in this case ofc.Thanks, I'll reorganize the whole thing into the state machine.

author: danergo
author_rank: Regular Contributor
timestamp: October 29, 2016, 10:27:20 am
content: Hello,I modified the code to call ZDO_SleepReq inside the statemachine and not in the ISR's callback.However, the chip still keeps restarting. I found that it's not related to WDT however ZDO_SleepReq call.If I disable the SleepReq, chip is not restarting. When enable the SleepReq (on pushing a button), the chip restarts immediately. It seems I'm not using it correctly:Could you confirm this section, please?Code:zdoSleepReq.ZDO_SleepConf = appZdoSleepConf;ZDO_SleepReq(&zdoSleepReq);

author: ataradov
author_rank: Super Contributor
timestamp: October 29, 2016, 05:18:36 pm
content: Is zdoSleepReq a global or static variable?Also, in ISR(WDT) you need to call a function that informs the stack about wakeup. I don't remember exact name, look at any other ISR() inside HAL and you will see it.

author: danergo
author_rank: Regular Contributor
timestamp: October 29, 2016, 09:50:35 pm
content: zdoSleepReq is static right now. Should it be global?zdoStartReq is also static, and it works as inteneded. I've just copied this one.Regarding wakeup for the stack, I've found halPowerOn(...). Shall I call this one? It extists in each ISR routine.However, it will wake up the radio also, which is absolutely not needed in this case (halPowerOn contains TRXPR &= ~(1 << SLPTR)).

author: ataradov
author_rank: Super Contributor
timestamp: October 30, 2016, 12:15:58 am
content: Quote from: danergo on October 29, 2016, 09:50:35 pmIt just needs to stay valid until confirmation callback is called.Quote from: danergo on October 29, 2016, 09:50:35 pmI would look at what else it does. If I'm not mistaken, it also updates system time, which lets application timers expire properly.The radio will be in the TRX_OFF state, so power consumption will be low.

author: danergo
author_rank: Regular Contributor
timestamp: October 30, 2016, 10:59:08 am
content: Quote from: ataradov on October 30, 2016, 12:15:58 amIt was defined in the same file as the zdoSleepReq call and the callback, so it remains valid yes.I now changed that variable to global, but I still get the same restart issues upon calling the sleepreq.My sleep function is this:Code:void appSleep(){zdoSleepReq.ZDO_SleepConf = appZdoSleepConf;ZDO_SleepReq(&zdoSleepReq);}After I realized, that this function is called 2-3 times in a row, I've reorganized the code into the state machine:Code:void appSleep(){appstate = PREPARE_TO_SLEEPpostglobaltask}void appPrepareSleep(){zdoSleepReq.ZDO_SleepConf = appZdoSleepConf;ZDO_SleepReq(&zdoSleepReq);}void appZdoSleepConf(conf){if (ZDO_SUCCESS_STATUS == sleepInfo->status)appstate = APP_SLEEPelseappSleep()}switch(appstate){...case PREPARE_TO_SLEEPappPrepareSleep()case APP_SLEEP...}And I put halWakeupFromIrq(); in the WDTISR's callback function. It was marked as a generic entry point from all external interrupts.However, bad luck. Still keeps restarting when calls sleepreq. Unfortunately, I can't examine ZDO_SleepReq function because it's compiled into the libraries of BC.One more thing: in the makefile I have SLEEP_WHEN_IDLE defined.But in the source code it is not, so in theory, sleeping when idle is turned off, so manual sleep should work.Also, an additional note is that I dump MCUSR after restart every time, and it's always 0. So it's not the WDT which resets the CPU, but some SW bug I guess. (Like division by zero, or something similar).

author: ataradov
author_rank: Super Contributor
timestamp: October 30, 2016, 05:55:58 pm
content: Quote from: danergo on October 30, 2016, 10:59:08 amYou can step through the assembly code to find out what happens. In this case, the "reset" is a 100% jump to NULL. A bit faster way is to put a breakpoint at address 0 and examine the call stack on reset.Quote from: danergo on October 30, 2016, 10:59:08 amCan you elaborate? You can't manually remove system defines (things that start and end with '_'). This will break everything. You need to enable and disable things thorough the config server APIs.Quote from: danergo on October 30, 2016, 10:59:08 amAs I said, it is a jump to NULL, 100%.

author: danergo
author_rank: Regular Contributor
timestamp: October 30, 2016, 06:34:18 pm
content: You are surely right, Alex.I'm observing the asm, and I think I got the problem, but not yet the reason:Code:void appPrepareSleep(void){zdoSleepReq.ZDO_SleepConf = appZdoSleepConf;3a:80 e0ldir24, 0x00; 03c:90 e0ldir25, 0x00; 03e:90 93 00 00sts0x0000, r2542:80 93 00 00sts0x0000, r24ZDO_SleepReq(&zdoSleepReq);46:80 e0ldir24, 0x00; 048:90 e0ldir25, 0x00; 04a:0e 94 00 00call0; 0x0 <APL_TaskHandler>4e:00 c0rjmp.+0; 0x50 <APL_TaskHandler+0x50>What is your opinion last but one line? Calling 0 looks a bad idea, no?I also have this one for the appSleep() function. In this, appPostGlobalTask calls also 0, which is somewhat strange for me too.Code:void appSleep(void){appState = APP_PREPARE_SLEEP;0:85 e0ldir24, 0x05; 52:80 93 00 00sts0x0000, r24appPostGlobalTask();6:0e 94 00 00call0; 0x0 <appSleep>a:08 95retSeems that calling 0 is present in many times in the assembly, around the sleeping functions. Don't know if this is something wierd, or just normal.

author: ataradov
author_rank: Super Contributor
timestamp: October 30, 2016, 06:38:13 pm
content: Quote from: danergo on October 30, 2016, 06:34:18 pmIt is a jump to the next instruction, not 0.Quote from: danergo on October 30, 2016, 06:34:18 pmThis is wrong.Are you disassembling the final ELF file? If you are looking at object files before lining, then having 0s is normal, they are just placeholders and linker will fill those out as as it figures out what goes where.

author: danergo
author_rank: Regular Contributor
timestamp: October 30, 2016, 06:53:01 pm
content: No, I did it with the .o files, sorry.With the ELF, I don't see all the functions. For example I don't see zdoSleepReq at all.Command I used is:Code:avr-objdump -d -S main.elf

author: ataradov
author_rank: Super Contributor
timestamp: October 30, 2016, 06:56:15 pm
content: Quote from: danergo on October 30, 2016, 06:53:01 pmWell, compiler can inline things. In this case zdoSleepReq is only called once, so there is no reason to have as a separate function.Looking at disassembly won't do anything here. You need to single step though the program and find out what instruction causes jump to 0.Or, as I said, put a breakpoint at address 0 and wait for it to hit, then look at a call stack.

author: danergo
author_rank: Regular Contributor
timestamp: October 30, 2016, 07:09:02 pm
content: Alright, thanks.Will do it later, I need to move back onto XplainedPros and Windows, to speed things up.

author: danergo
author_rank: Regular Contributor
timestamp: October 31, 2016, 09:58:20 pm
content: Hello, Alex,So I moved to Windows and to XplainedPro256rfr2. I'm just uploaded WSNDemo (original one) to this board, but somewhy, I'm unable to debug this code with the EDBG.I can step into SYS_RunTask() pretty well, and also, if I put a breakpoint on SYS_RunTask() I get the breakpoint hit each time, so the basic debugging/stepping works fine.However, I never get a breakpoint hit in APL_TaskHandler or any other functions. So technically, I'm unable to continue my investigation.Atmel Studio writes: Running, and I can pause is, and see the ASM codes.Have you experienced something similar?Of course, I'm compiling with -O0 -g3 switches.

author: ataradov
author_rank: Super Contributor
timestamp: October 31, 2016, 10:03:33 pm
content: Well, if it is the default WSNDemo, then it is possible that APL_TaskHandler is not executing.Try setting CS_UID to a non-zero value and see if that helps.

author: danergo
author_rank: Regular Contributor
timestamp: October 31, 2016, 10:08:27 pm
content: Yes, I changed CS_UID to some random value, but didn't help. Still not able to hit the breakpoints.Also, LED0 is not light up on the board (I remember it should visualize something on the Coordinator).Which other source lines would be worth checking with breakpoints?HAL is not needed to be compiled/recompiled, right? I just loaded up the makefile, and changed CS_UID, selected Coordinator_StdlinkSec_MegaRf_Atmega256rfr2_16Mhz_Gcc.Seems processManagerTask is not able to move on. It always processes the first taskId. SYS_taskFlag is always 16. These are in sysTaskManager.c:246.And also, seems restarting constantly. Just put a breakpoint into SYS_SysInit(), and it gets hit in every half second.

author: ataradov
author_rank: Super Contributor
timestamp: October 31, 2016, 10:30:45 pm
content: Quote from: danergo on October 31, 2016, 10:08:27 pmCheck your fuses and disable WDT there.

author: danergo
author_rank: Regular Contributor
timestamp: October 31, 2016, 10:35:37 pm
content: Hm, I think it's not enabled by default on these boards, but I've just double-checked:http://imgur.com/a/aTW22

author: ataradov
author_rank: Super Contributor
timestamp: October 31, 2016, 10:42:03 pm
content: Quote from: danergo on October 31, 2016, 10:35:37 pmBitCloud needs CKDIV8 bit set, but I doubt that it will lead to resets like this.16 is ZDO_TASK_ID. This task posts APL Task after initialization is done.I really don't see what else may be wrong.Also, what do you mean by "It always processes the first taskId. SYS_taskFlag is always 16"? It never actually runs ZDO task?

author: danergo
author_rank: Regular Contributor
timestamp: October 31, 2016, 10:52:50 pm
content: I checked in the CKDIV8 but nothing changed.So the initialization should cause some memory leaks, or something similar, because it has to called many times before the chip reset. I can't even reproduce with stepping, just with continueing.ZDO's code is closed if I'm not mistaken?

author: ataradov
author_rank: Super Contributor
timestamp: October 31, 2016, 10:57:07 pm
content: Quote from: danergo on October 31, 2016, 10:52:50 pmYes, it is, but it does not do anything special, just resets some stuff and posts APL task.But from your description it looks like it never even gets to ZDO, since ZDO task is always posted at initialization and is cleared after the first call.So it looks like it is busy calling some HAL task handler, which you can debug. Just break in processManagerTask() and step into taskHandlers();

author: danergo
author_rank: Regular Contributor
timestamp: October 31, 2016, 11:05:09 pm
content: Quote from: ataradov on October 31, 2016, 10:57:07 pmThat's the sad thing. I can step into that function but it results in some ASM code.That could be because taskId there is always 1. It's just can't get out of that. It breaks the loop, and then starts again with taskId == 1 in the next iteration. (which is not the reset yet, anyway).Maybe the precompiled libs are not matching with these newly compiled components?

author: ataradov
author_rank: Super Contributor
timestamp: October 31, 2016, 11:12:22 pm
content: Ok, taskId == 1 means that it executes MAC_PHY_HWD_TaskHandler(). See if you have access to a variable called '__handlers' and if you do, what value does it have?Do you have different hardware? At this point I strongly suspect 16 MHz crystal to be broken somehow.

author: ataradov
author_rank: Super Contributor
timestamp: November 01, 2016, 01:43:00 am
content: Quote from: ataradov on October 31, 2016, 11:12:22 pmActually, I'm wrong here. taskId == 1 is HAL and you have the code for this. I think HAL may be compiled with debug info disabled by default, but even if you don't want to recompile it, you can still look at relevant variables to see if you can spot anything.

author: danergo
author_rank: Regular Contributor
timestamp: November 01, 2016, 09:10:17 am
content: Hello,I've recompiled HAL libraries with debug symbols.Now the processManagerTask is stuck in taskId == 4 which is ZDO layer's task handler.I'm attaching a screenshot:http://imgur.com/a/5YaVPYou can see, taskId is 4, and what are those 0x0 addresses in 9,10,11 slot? I assume they are okay, but everything is suscpicious now for me.Also, taskId 1 is for HAL, why is the Studio not grabbing up the HAL's sources? It should be some magic trick to include them somehow? I added halTaskManager.c as a link.My result: after taskId#4, next breakpoint is SYS_SysInit();Tried with a different board with the same results.How can I detect the last address before reset in AS7 debugger?

author: danergo
author_rank: Regular Contributor
timestamp: November 01, 2016, 09:57:12 am
content: Okay, I have some generic compiler issue, I guess.On Linux, I build WSNDemo, and it works after uploading to the target.On Windows same WSNDemo compiled from the same source keeps resetting.Linux avr-gcc: avr-gcc (AVR_8_bit_GNU_Toolchain_3.4.5_1522) 4.8.1Windows avr-gcc: avr-gcc (AVR_8_bit_GNU_Toolchain_3.5.4_1709) 4.9.2I don't think it's worth going further. I installed a brand new fresh AS7, XplainedPros are simply not working with this new compiler. Maybe they are not compatible with AS any more.Is avr-gdb working under Linux? I don't want to burn more time if it's not possible.Or where could I download previous version of avr-gcc for Windows? On Atmel's site it's not available.Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: November 01, 2016, 09:39:04 pm
content: Quote from: danergo on November 01, 2016, 09:57:12 amI'm not aware of any compiler issues like that, which does not mean that they don't exist.But that would be something I investigate, because it may be relevant to your problem. On Windows compiler removes something important that WSNDemo works. On Linux it may remove something important that your program does not work.Quote from: danergo on November 01, 2016, 09:57:12 amNo idea, never used it.Quote from: danergo on November 01, 2016, 09:57:12 amHere they arehttp://www.atmel.com/tools/studioarchive.aspx

author: danergo
author_rank: Regular Contributor
timestamp: December 19, 2016, 08:08:05 pm
content: Hello!I'm back from some other activities.Still struggling with this topic though. Wasn't able to make a solid debuggable configuration either on Win7 (AS6, AS7), either on Linux (avr-gdb, avarice).This is fair for now, I went back to some 'manual' debugging (measuring voltages, looking on the screen, etc).So my current state is that I disabled button handling with WDT (buttons are not working at the moment), and I put the device into sleep mode with sleepreq.However the symptoms are back: after power on, take about 2 secs to go to sleep, this is fine, but while sleeping after58minutesseconds(!) the whole device restarts.It seems something wakes up the device from sleep and then something happens that not handled properly.What is waking up my device from sleep? AppTimers are stopped, interrupts are not arriving).

author: ataradov
author_rank: Super Contributor
timestamp: December 19, 2016, 08:44:11 pm
content: Start with monitoring the value of HAL_ReadResetReason(). It will tell you the source of reset. Device will have to quickly wake up every 8 seconds to count system time, even if all application timers are stopped (unless you explicitly disabled this functionality).It is quite possible that you have some NULL pointer that is being called, and it appears as reset.

author: danergo
author_rank: Regular Contributor
timestamp: December 19, 2016, 08:47:05 pm
content: This looks quite reasonable. Now after I disabled every possible timers, adc-s and everything, interval is 8 seconds exactly (measured with a stopwatch).I'll try to read HAL_ReadResetReason() and post here. Thanks! (Y)

author: ataradov
author_rank: Super Contributor
timestamp: December 19, 2016, 08:54:35 pm
content: 8 second interval is formed by functions in halSleepTimerClock.c. You don't need to change anything there, it all works as expected, but you may start investigations from there.And I'd say it is almost 100% that you have some NULL pointer called.

author: danergo
author_rank: Regular Contributor
timestamp: December 19, 2016, 09:13:26 pm
content: Wow, that's kind of interesting! ResetReason is 0x4. Which is BROWN_OUT_RESET.How is that even possible? Powering via USB.Extra info: I have an H-bridge around the controller. Similar to this one on the right:http://letsmakerobots.com/files/userpics/u4631/H-bro.jpgQ1-Q4 are shorted and connected to PB4Q2-Q3 are shorted and connected to PB5.Maybe HAL does something at wakeup which causes some short-circuit, and BOD resets the whole stuff?

author: ataradov
author_rank: Super Contributor
timestamp: December 19, 2016, 09:15:24 pm
content: What is your BOD threshold setting? Do you have proper bypass capacitors?

author: danergo
author_rank: Regular Contributor
timestamp: December 19, 2016, 09:23:06 pm
content: BOD is default, 1.8V.Capacitors? I have on DVDDs, and on DEVDDs, also on EVDD and on AVDD.Going to be battery powered, so no large capacitor on the powerline. Do you think I supposed to apply one for the USB case?Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: December 19, 2016, 09:26:20 pm
content: I think you are fine, but just in case, check power lines with the oscilloscope. It is possible that you are doing something bad with GPIOs on wake up. Like shorting two outputs, or something similar.It is also possible that reset reason is incorrect, however, I used this function a lot and it never failed.Try to disable BOD. If you have problems with power supply, then device is most likely to reset, but reset reason will be different.

author: danergo
author_rank: Regular Contributor
timestamp: December 19, 2016, 09:44:02 pm
content: Will try disabling it soon.This solved the continuous resetsQuote from: ataradov on December 19, 2016, 09:26:20 pmHow can I control what to do on these kind of wakeups?In theory, only the stack checks something, and goes back to sleep asap. In my understanding.So basically I have no chance to control anything after this wakeup I guess.

author: ataradov
author_rank: Super Contributor
timestamp: December 19, 2016, 09:51:10 pm
content: It would be interesting to see where execution gets after the wake up. It is possible that something in the hardware misconfigured in a way that conflicts with sleep. I'm not sure if it is even possible, just a thought. May be a way some peripherals are connected and configured. Can you post MCU-related part of the schematic?

author: danergo
author_rank: Regular Contributor
timestamp: December 19, 2016, 10:03:22 pm
content: Yes, it's here for some time:

author: ataradov
author_rank: Super Contributor
timestamp: December 19, 2016, 10:11:06 pm
content: That looks fine to me. I'd check all power supply rails with the scope anyway, just in case.

author: danergo
author_rank: Regular Contributor
timestamp: December 20, 2016, 08:59:22 pm
content: Hello!Thank you, I'm proceeding now at least.But now I got some issue again, after sleeping goes fine, I'm trying to wake it up again (on ISR).I have an ISR routine with HAL_RegisterIrq.In the IRQ handler I callCode:SYS_PostTask(BSP_TASK_ID);This should make the state machine run, right? Power consumption not increasing when raising this INT, so I believe state machine doesn't start for somewhy.(Consumption only increase after 1minute which is exactly CS_END_DEVICE_SLEEP_PERIOD.)

author: ataradov
author_rank: Super Contributor
timestamp: December 20, 2016, 09:02:19 pm
content: What IRQ and other parameters do you use in HAL_RegisterIrq?Also, you are posing BSP task. It will wake up the MCU, but application task will not run, of course.

author: danergo
author_rank: Regular Contributor
timestamp: December 20, 2016, 09:12:48 pm
content: Yes, I know, it's okay:IRQ reg:Code:HAL_RegisterIrq(INT4, IRQ_FALLING_EDGE, IRQ_Handler);BSP's handler after getting its task, will call an application function named "appButtonPressed".In this function I call HAL_OpenI2cPacket which would change the LCD display data, but in this case, LCD data is not changing at all before CS_END_DEVICE_SLEEP_PERIOD.So there could be 2 cases:1.) BSP's task handler is not getting called after SYS_PostTask.2.) BSP's task handler called, but HAL_OpenI2cPacket won't run for some other reasons which I'm not yet aware of.Anyway it's an interesting extra info, that I also have "appWakeup" in "appButtonPressed" which basically:Code:void appWakeup() {appState = WAKEUP;SYS_PostTask(APL_TASK_ID);}...case WAKEUP:zdoWakeUpReq.ZDO_WakeUpConf = appZdoWakeUpConf;ZDO_WakeUpReq(&zdoWakeUpReq);break;...static void appZdoWakeUpConf(ZDO_WakeUpConf_t *confirmInfo) {if (ZDO_SUCCESS_STATUS == confirmInfo->status){appState = APP_IN_NETWORK_STATE;appPostGlobalTask();}else{appWakeUp();}}So I'd totally assume that not just the SM but also the radio should be waking up for these combination

author: ataradov
author_rank: Super Contributor
timestamp: December 20, 2016, 09:16:53 pm
content: The system can only wake up on level from INT 4-7. See Table 12-1 in the datasheet. And specifically note 3 after the table.

author: danergo
author_rank: Regular Contributor
timestamp: December 20, 2016, 09:32:59 pm
content: what a silly amateur mistake of mine... thanks.I'm handling a rotary encoder with INT4 and INT5 which needed EDGE interrupts, I'm gonna deepdive to see how do they work with only level INTs.There are so many things to take care of when going on battery!

author: ataradov
author_rank: Super Contributor
timestamp: December 20, 2016, 09:40:03 pm
content: Given that the only supported level is low, it may be hard or impossible. Those hardware interrupts are annoying. Pin change interrupts work way better.

author: danergo
author_rank: Regular Contributor
timestamp: December 20, 2016, 10:12:32 pm
content: You must definitely be right, yes.Anyway I'd need to redesign this board for sure. There are too many hackish solutions now, not just this level INTS but also buttons with WDT which is far not that good either.Thank you very much Alexru,Merry Xmas to all forum readers!

author: danergo
author_rank: Regular Contributor
timestamp: January 21, 2017, 05:02:15 pm
content: Hello again!I'm back with a brand new, redesigned PCB, which has its buttons connected to the INT pins, and its rotary to the INT2-3, which is able to wakeup the MCU from sleep even on edge interrupt.I also reverted all the hackish code parts with watchdog, and timers, so now I should have a fully functioning sleeping device.But my observations shows something else:1.) If I use SYS_EnableSleepWhenIdle() the device simply doesn't sleep. (consumes 15.3mA @3.3V)2.) If I try to sleep it manually (ZDO_SleepReq without sleepwhenidle), it goes into sleep (less than 0.5mA @3.3V), this is what I wanted, but after a few seconds (usually 2-4) it resets.I'm investigating now the cause of reset.But it's very interesting that sleepwhenidle is simply not working. What could prevent that? I have only long-lasting timers (10 sec, 1 minute) - for testing, they will be increased to 10 - 20 minutes later.I'd expect that in this case, sleepwhenidle should sleep for 9 seconds than wake up for the timer @10s, do its stuff, and go back to sleep until the next 10s. Am I wrong?Thanks!Cheers

author: ataradov
author_rank: Super Contributor
timestamp: January 21, 2017, 07:41:59 pm
content: Stack has its own timers, some of them are pretty fast. Sleep when idle reduces average power consumption, but current consumption is very pulsed, so multimeter may get confused. I recommend powering device though a small (1-10 Ohm) resistor and measure a voltage drop across this resistor with an oscilloscope.It is also possible that device is actually awake because of something else going on. I would check that pending task mask is 0 at some point and sleep is actually requested. This all should be located in the open part of the stack.Sleep When Idle is not a replacement for full sleep, it is an attempt to reduce power consumption of an active device.Also, I don't think that sleep when idle disables the radio, since it needs to be able to wake up on the radio interrupt. But I may be wrong here.

author: danergo
author_rank: Regular Contributor
timestamp: January 22, 2017, 05:32:35 pm
content: Thanks for these valuable infos, ataradov!Anyway, I chosed managing the power manually. It's more exact.So I did some further tests, which is interesting:1.) After configuring the sleep and wakeup calls, I uploaded the firmware onto xplainedpro, and it can sleep tight. On pressing its button (PE4, INT4) it 'wakes' up, executes the ISR, and goes back to sleep (I have one button on the same pin, so no firmware mod was needed). If I call ZDO_WakeUpReq, the whole stack comes back awake. This whole process is definitely measureable with a multimeter: 15-16mA awake, 1-2mA sleep. (Just wanted to show you that my firmware shouldn't do anything harmful, it can sleep qutie well).This is great, I believe that this firmware is getting to the point.2.) However, afterwards, I uploaded the exact same fw to my board: after going to sleep, it resets in 2-3 seconds. Going to sleep works great. It happens exactly the same time on my board and on the xplainedpro. However, for some reason, my board gets rebooted every time after sleep. I think I don't have watchdog enabled on my board (fuses: E:FE, H:99, L:EF). Also, reset is not scheduled exactly. Sometimes it needs 0.5s, and sometimes it takes 3 seconds. But it surely reset.Now, the thing is that since this doesn't happen on the xplained, I nee to have some issue on my board. It has some external circuits of course, but none of them should raise a reset.I'll check the reset reason, and post it here.So, very interesting: HAL_ReadResetReason() returns 0x04 which is BROWN_OUT_RESET.I had this before. But now I checked the power line with a scope, and nothing happens on the powerline. Not a small glitch. I can disable BOD for sure, but what causes it to fire when the chip is sleeping?And what is much more interesting, why is that not happening on the xplained? (its fuses: E:FE, H:91, L:F7)

author: ataradov
author_rank: Super Contributor
timestamp: January 22, 2017, 08:04:23 pm
content: Why do you have different fuses between the boards? Are you sure they don't set different BOD levels, for example? I would use AS to generate fuse values you want.

author: danergo
author_rank: Regular Contributor
timestamp: January 22, 2017, 08:15:30 pm
content: BOD levels are set through EFUSE0..2, which was set to the same for both boards.Other differences was the EESAVE (preserve eeprom on erasing) and one board was set to fast rising power, while the other is set to slow rising one.fast rising power 16K CK 14CK + 4.1 ms,slowly rising power 16K CK 14CK + 65 msI think they shouldn't do anything bad with BODBut you are absolutely right that setting them to exactly same should normally decrease possible faults.

author: danergo
author_rank: Regular Contributor
timestamp: January 23, 2017, 03:39:20 pm
content: Hello,I've got two new questions. (should I use a new thread? they both belong here technically)1. What is the required behaviour after CS_SLEEP_PERIOD on EDs? Do they have to call ZdoWakeUpReq for the stack to sync with the C, or I can use ZdoSleepReq immediately?2. My device needs to wakeup after x minutes, where x varies by time. My intention is to set CS_SLEEP_PERIOD to 60000, and on each iteration I'll be able to decide eiter going back to sleep, or waking up.Is this the right approach here?Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: January 23, 2017, 05:17:01 pm
content: Quote from: danergo on January 23, 2017, 03:39:20 pmYou need to make sure that ED checks in at least every CS_SLEEP_PERIOD ms. You can either just do it on CS_SLEEP_PERIOD intervals, or you can keep track of time since the last check in, and then do noting on CS_SLEEP_PERIOD. The idea here is to make sure that parent does not think that device has left for good and does not free the corresponding entry.Quote from: danergo on January 23, 2017, 03:39:20 pmYes, as long as parent has the same sleep interval set.

author: danergo
author_rank: Regular Contributor
timestamp: January 23, 2017, 05:24:06 pm
content: Thanks!One point is missing:Quote from: ataradov on January 23, 2017, 05:17:01 pmIf ED is sleeping (no HW INTs are coming) how can it check in? After CS_SLEEP_PERIOD I need to call ZdoWakeUpReq, and send a message to C?(I understand the basic idea, but don't know if stack does the checkin behind the walls after CS_SLEEP_PERIOD.)Sorry. You've already explained this."3. CS_SLEEP_PERIOD - the whole stack and radio wakes up and sends the poll request."So I'd reverse my question.What is the most efficient way to wake up the MCU without radio in every minute? (I'd like to have a sleeping ED, which wakes up periodically, but does rare radio transmission to preserve battery. In this case I'd set CS_SLEEP_PERIOD to a higher number like 30*60*1000).Thank you!

author: ataradov
author_rank: Super Contributor
timestamp: January 23, 2017, 06:59:36 pm
content: Quote from: danergo on January 23, 2017, 05:24:06 pmThere is a way to completely disable automatic checkins. I think you need to use 0 or something like that.The thing to keep in mind is that you need to set appropriate value on the coordinator. It needs to reflect actual check in period. Although if you don't mind that devices sit in tables for a long time, then even that does not matter.

author: danergo
author_rank: Regular Contributor
timestamp: January 23, 2017, 07:45:47 pm
content: Yes. that's cool, I can set 0 for that, but in that case, what would wake up the MCU from sleep?(I think only HW INTs can do that. Shall I use watchdog INT for this purpose?)Oh, and one more thing.After HW interrupt (button press), the MCU wakes up. How can I send it back to sleep? (On ZDO_SleepReq, it returns with code 128 which is ZDO_INVALID_REQUEST_STATUS.)

author: ataradov
author_rank: Super Contributor
timestamp: January 23, 2017, 08:46:02 pm
content: Quote from: danergo on January 23, 2017, 07:45:47 pmThat's more for a case when you know that external events happen at a certain rate. Let's say you have a motion detection sensor, so you know that there is going to be at least one event per day, or something like that. If you don't sure, then just leave a really long wake up time.Quote from: danergo on January 23, 2017, 07:45:47 pmUse SYS_Sleep(). ZDO returns ZDO_INVALID_REQUEST_STATUS because it thinks that it is already sleeping

author: ataradov
author_rank: Super Contributor
timestamp: January 23, 2017, 08:47:07 pm
content: But if you use SYS_Sleep(), then it will overwrite stack's track of time, so you will have to do manual sleep management at this point.

author: danergo
author_rank: Regular Contributor
timestamp: January 23, 2017, 09:07:55 pm
content: That's exactly what I was thinking about in the past few minutes.I'd need to call it with a HAL_Sleep_t structure, which needs a few fields.Could you guide me on how shall I setup these fields?-sleepTime - I need to calculate how much time spent already from the CS_SLEEP_PERIOD, and set it accordingly.-startPoll - true or false?-callback - shall I use my own wakeup callback, or it needs to be set to some internal function?Unfortunately I couldn't find anything in the opened sources.

author: ataradov
author_rank: Super Contributor
timestamp: January 23, 2017, 09:12:55 pm
content: Quote from: danergo on January 23, 2017, 09:07:55 pmCorrect.Quote from: danergo on January 23, 2017, 09:07:55 pmThis value will be passed as an argument of the callback. HAL itself does not care what the value is.Quote from: danergo on January 23, 2017, 09:07:55 pmYour own function with the following prototype: "typedef void (* HAL_WakeUpCallback_t)(bool);"

author: danergo
author_rank: Regular Contributor
timestamp: January 23, 2017, 09:26:22 pm
content: Thanks!Quote from: ataradov on January 23, 2017, 09:12:55 pmHm. I'm thinking on using halTimerControl.remainder for this. Is this a good approach? It's defined as global and seems to hold the remaining time for the sleeptimer to CS_SLEEP_PERIOD.Quote from: ataradov on January 23, 2017, 09:12:55 pmIn this function I would call ZDO_WakeUpReq to behave exactly the same as if CS_SLEEP_PERIOD ellapsed without any HW INT. Right?

author: ataradov
author_rank: Super Contributor
timestamp: January 23, 2017, 09:28:59 pm
content: Quote from: danergo on January 23, 2017, 09:26:22 pmNo. It only holds this value until you start requesting manual sleeps. You need to fully manage sleep yourself. don't rely in any gloabal variables in the stack.Quote from: ataradov on January 23, 2017, 09:12:55 pmI would post a task from this callback and do the real work in the task, but the general idea is correct.

author: danergo
author_rank: Regular Contributor
timestamp: January 24, 2017, 01:25:41 pm
content: Quote from: ataradov on January 23, 2017, 09:28:59 pmShall I avoid ZDO_SleepReq at all? In this case I'd prefer to manually manage the sleeping part.My idea without ZDO_SleepReq (CS_SLEEP_PERIOD set to 5 mins):1.) SYS_Sleep(1 minute)2.) callback in every minute, and decidedo the 1 minute tasks (e.g. increment minute counter)if radio is not needed and checkin is also not needed, SYS_SLEEP(1 minute)if radio or checkin is needed (checkin if minute_counter >= 5), do ZDO_WakeUpReq, and then SYS_Sleep(1 minute)3.) On HW INT, MCU wakeup and decidedo the ISR part, and increment minute counterif radio is not needed and checkin is also not needed, SYS_SLEEP(1 minute)if radio or checkin is needed (checkin if minute_counter >= 5), do ZDO_WakeUpReq, and then SYS_Sleep(1 minute)Q1.) Can I use SYS_Sleep without any previous ZDO_SleepReq?Q2.) After waking up from SYS_Sleep, can I use ZDO_WakeUpReq, or it will return with ZDO_INVALID_REQUEST_STATUS if I didn't do any ZDO_SleepReq before?Q3.) If I use ZDO_WakeUpReq, will it do the checkin to Coordinator automatically, or something else is needed as well?Note: I know that I also have to take into account the durations in ISR and in callback. I'd set CS_SLEEP_PERIOD to 10 minutes to avoid any problems. In this case, ISRs and callbacks can leak 5 minutes of time which is impossible. Thus, this error is not cumulating because minute_counter shall be resetted after checkins.

author: ataradov
author_rank: Super Contributor
timestamp: January 24, 2017, 05:18:50 pm
content: Quote from: danergo on January 24, 2017, 01:25:41 pmI don't think you can. It prepares actual stack infrastructure for work.Quote from: danergo on January 24, 2017, 01:25:41 pmThis is kind of a hack, so I don't know if it will work.Quote from: danergo on January 24, 2017, 01:25:41 pmYes.Quote from: danergo on January 24, 2017, 01:25:41 pmI'm pretty sure that invalid status will be returned.Quote from: danergo on January 24, 2017, 01:25:41 pmIf your sleep was due to ZDO_SleepReq() noting else is needed.It look like the best thing to do is to actually properly wake up every time. This sucks, but the rest of it really depends on experimentation.I was trying to point this out many years ago, but had no luck doing this. This is why I created LwMesh, which does things in a way people can actually use.

author: danergo
author_rank: Regular Contributor
timestamp: January 24, 2017, 10:43:52 pm
content: Quote from: ataradov on January 24, 2017, 05:18:50 pmYepp, but anyway, I was thinking on this a lot in the past few days, and I still believe, that I'd need the MCU without radio for many cases.So, One ultimate question remains: after ZDO_SleepReq, and HW INT arrival, how can I detect the current ellapsed time slept between SleepReq and HW INT? (Maybe with halGetTimeOfSleepTimer?)Or halGetTimeOfSleepTimer is counting all the time, and I can save it's value before sleep, and check after HW INT?Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: January 24, 2017, 10:54:17 pm
content: Quote from: danergo on January 24, 2017, 10:43:52 pmThat's how standard sleep routines do this, so it should work.If you really want to make this work, you can probably do quite a bit by modifying HAL layer. It is not trivial, but doable.

author: danergo
author_rank: Regular Contributor
timestamp: January 25, 2017, 06:31:41 am
content: Hm, why should I modify HAL?halGetTimeOfSleepTimer is accessable from user space, so it's easy to save its value right before sleep, and upon wakeup I can calculate sleep time by a simple math.Or you mean adding a new function to it like halGetTimeSlept, and handle all the calculations inside HAL?

author: ataradov
author_rank: Super Contributor
timestamp: January 25, 2017, 06:33:41 am
content: Quote from: danergo on January 25, 2017, 06:31:41 amI feel like all the other HAL sleep stuff will be in a way. If you can make it work without modifying HAL, then good.

author: danergo
author_rank: Regular Contributor
timestamp: January 25, 2017, 05:59:24 pm
content: I thought that it won't break anything:Possible flows:1.) ZDO_SleepReq->CS_SLEEP_PERIOD->fully awake(checkin)->ZDO_SleepReq2.) ZDO_SleepReq->HWINT->calculate sleep timer->SYS_Sleep->CS_SLEEP_PERIOD-calculated_time->fully awake(checkin)->ZDO_SleepReq3.) ZDO_SleepReq->HWINT->ZDO_WakeUpReq->fully awake(checkin)->ZDO_SleepReq4.) ZDO_SleepReq->HWINT->calculate sleep timer->SYS_Sleep->HWINT->calculate sleep timer->SYS_Sleep->CS_SLEEP_PERIOD-calculated_time->fully awake(checkin)->ZDO_SleepReqIn the above cases I believe the HAL doesn't need to be modified.Maybe, if HWINT is not subscribed by the app layer, it can cause problems. ?How would the line continues:5.) ZDO_SleepReq->HWINT(not published to app)->...?Thanks very much!

author: ataradov
author_rank: Super Contributor
timestamp: January 25, 2017, 06:04:25 pm
content: Quote from: danergo on January 25, 2017, 05:59:24 pmYou will also have to restore wake up callback to the stack one before last wake up (which you don't know). ZDO sets "halSleep.callback = wakeupCallback;" where wakeupCallback() is a static function inside ZDO. So basically you would need to save the value of this pointer before setting your own, and then call it manually when needed.

author: danergo
author_rank: Regular Contributor
timestamp: January 25, 2017, 10:13:46 pm
content: Yes, I'm getting your point.It is easy, I can give it directly to SYS_Sleep, right? (because SYS_Sleep happens only after HWINT)Then after the timeout, it will call ZDO's wakeup fn.If that is interrupted again by a HWINT, after processing the INT, I can still give that pointer to SYS_Sleep. (I dont need a custom callback for SYS_Sleep)ZDO will think that nothing happened, and CS_SLEEP_PERIOD has expired -> will checkin the ED.Am I right here?

author: ataradov
author_rank: Super Contributor
timestamp: January 25, 2017, 10:17:02 pm
content: Quote from: danergo on January 25, 2017, 10:13:46 pmGive what? wakeupCallback is static inside the closed part of the stack, linker will let you use that name.You can get the whole sleep structure saved in HAL and give that to SYS_Sleep() again.

author: danergo
author_rank: Regular Contributor
timestamp: January 26, 2017, 08:47:19 am
content: What I wanted to mark here, is that with this mod, I won't need to createmy owncallback for SYS_Sleep, because I'm giving 'wakeupCallback' to it.If I can count the right time to sleep, 'wakeupCallback' will be called exactly the same time like when no INTs arrived:This is CS_SLEEP_PERIOD ms after the very first ZDO_SleepReq. Afterwards, wakeupCallback will be called and it will take care of checking in and making the ball rolling again in the StateMachine.Thank you very much Alex for your kind help.

author: ataradov
author_rank: Super Contributor
timestamp: January 26, 2017, 08:50:03 am
content: Quote from: danergo on January 26, 2017, 08:47:19 amAnd I was saying that you can't give wakeupCallback to it, it is an internal static function that you have no access to, even to take its address.You can extract this address from the request already created by ZDO and stored in a global variable inside HAL.

author: danergo
author_rank: Regular Contributor
timestamp: January 26, 2017, 08:52:21 am
content: Yes!! Got your point now.Thanks really much.

author: danergo
author_rank: Regular Contributor
timestamp: January 27, 2017, 08:13:15 pm
content: Hello!I've done some research in the HAL's code, and realized that HAL already stores halSleep.callback and halSleep.startPoll in a global variable named 'halSleepControl'.I'm using this now, and works as I thought, without modifying HAL's code.However, what happens, if the IRQ arrives right before CS_SLEEP_PERIOD expired? Let's imagine this situation. In this case, the next calculated time_to_sleep shall be mathematically negative.So it's quite sure that Coordinator will handle this ED as disconnected (I don't know the right expression here).Is it a good approach that before calling SYS_Sleep, I'd check time_to_sleep. If it would be negative, I call halSleep.callback immediately, instead of SYS_Sleep.So, to reverse this question, is it valid to call ZDO's 'wakeupCallback' in case the MCU itself is not sleeping anymore?Of course, if this is valid, I'd also need to set a bit larger CS_SLEEP_PERIOD in the Coordinator to avoid mistique behaviours.Is it okay, to set CS_SLEEP_PERIOD to 10mins in the Coordinator, and 5mins in the ED? In this case ED will checkin before C would judge it as disconnected.Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: January 27, 2017, 08:21:30 pm
content: Quote from: danergo on January 27, 2017, 08:13:15 pmYes, that's exactly what I was suggesting.Quote from: danergo on January 27, 2017, 08:13:15 pmThe chap way is to adjust it so it is not negative, but a small positive value.Quote from: danergo on January 27, 2017, 08:13:15 pmThat may work too, I don't think it will break anything. But keep in mind that wakeupCallback calls ZDO_WakeUpInd(). So you need to handle this properly.Quote from: danergo on January 27, 2017, 08:13:15 pmSure, you can set much higher timeouts, like a whole day or something.

author: danergo
author_rank: Regular Contributor
timestamp: January 28, 2017, 08:17:44 pm
content: Hello!Well, this might be a bit out-of-topic, but somehow relates to here.I'm trying to deal with calculating the sleeping time to the next minute at 0 second. So this is something between 0 and 59999 ms.Hm, that's too easy, mod60000 calculates exactly this. However I can't figure out what am I doing wrong:Code:uint32_t a = 21625 - 26250;uint32_t b = a % 60000U;uint32_t c = 60000U - b;printf("data: a=%d, b=%d, c=%d\n\r", (int)a,(int)b,(int)c);//prints "data: a=-4625, b=-22865, c=17329"I know that printf uses void* pointers and casts them to the defined format.So far, 'a' is alright.However, for 'b', I have no idea. I'd like it to be exactly 55375. (I know about C89's truncate towards zero, but how could I overcome of that in avr-gcc?) Why is b -22865?And well, for 'c', that's alright too.A feel confused of b's current value. Any explanation would be very helpful, I guess.Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: January 28, 2017, 08:22:05 pm
content: Quote from: danergo on January 28, 2017, 08:17:44 pmint is 16 bits on AVR.printf("data: a=%ld, b=%ld, c=%ld\n\r", a, b, c);

author: danergo
author_rank: Regular Contributor
timestamp: January 28, 2017, 08:35:57 pm
content: Ah, first of all.Unfortunately it still has some defect, because now b is 42671. Seems very mistique, but there is a reason for sure.

author: ataradov
author_rank: Super Contributor
timestamp: January 28, 2017, 08:39:19 pm
content: Quote from: danergo on January 28, 2017, 08:35:57 pmYour a is negative, and I'm not sure how % operation is defined for negative numbers. I would try to transfer all this math to positive numbers.

author: danergo
author_rank: Regular Contributor
timestamp: January 28, 2017, 10:13:27 pm
content: Wow, I just have solved this module question by this macro:Code:#define mod(M, N) (M>=0 ? M%N : (N-abs(M%N))%N)or#define mod2(M, N) (M%N>=0 ? M%N : M%N + N)Both produces the same (correct) result, but they look really ugly to me. And besides of that I'm quite sure they will consume a lot of cycles to calculate.If there is a faster, simplier way to calculate congruent modulo, I'd love to see.

author: ataradov
author_rank: Super Contributor
timestamp: January 28, 2017, 11:38:28 pm
content: Quote from: danergo on January 28, 2017, 10:13:27 pmI don't see why you need % at all.Can you restate the goal with sensible variable names? I think all you need to do is compare with 0, and if difference is less than 0, then add 60000 to the next wake up time. Since there is no way you will ever have more than one minute rollover.

author: danergo
author_rank: Regular Contributor
timestamp: February 04, 2017, 10:47:45 pm
content: Hello!I've eliminated all the %-s and now the whole thing started to work very well.I only have one more problem, around saving the original zdo's wakeup callback.I'm doing it like this:Code:static HAL_WakeUpCallback_t* originalWakeupCallback = 0;void sleep() {...zdoSleepReq.ZDO_SleepConf = SleepConf;ZDO_SleepReq(&zdoSleepReq);...}static void SleepConf(ZDO_SleepConf_t *sleepInfo) {...originalWakeupCallback = &halSleepControl.callback;...}And want to use like this:Code:(*originalWakeupCallback)(halSleepControl.startPoll);But does not seem to work. (It seems to stuck in some inner function).To be more exact, after calling it, consumption jumps to around 5mA which is larger than normal MCU awake, and less than radio awake.printf('%d', originalWakeupCallback) prints 2796 which seems a valid address for me at first sight.Also, using it like this prevents the MCU from waking up:Code:sp.sleepTime = 5000;sp.startPoll = halSleepControl.startPoll;sp.callback = originalWakeupCallback;SYS_Sleep(&sp);What am I doing wrong?

author: ataradov
author_rank: Super Contributor
timestamp: February 04, 2017, 11:12:28 pm
content: HAL_WakeUpCallback_t is already a pointer, so do something like this:Code:static HAL_WakeUpCallback_t originalWakeupCallback = 0;originalWakeupCallback = halSleepControl.callback;And then "originalWakeupCallback(halSleepControl.startPoll);" or "sp.callback = originalWakeupCallback;".

author: danergo
author_rank: Regular Contributor
timestamp: February 05, 2017, 07:41:35 am
content: Many thanks, works like a charm.

author: danergo
author_rank: Regular Contributor
timestamp: February 09, 2017, 05:40:02 am
content: Hello!Just for curiosity:what is the difference between the below functions?1.) halGetTimeOfSleepTimer2.) halGetSystemTimeUs3.) halGetTimeOfAppTimer

author: ataradov
author_rank: Super Contributor
timestamp: February 09, 2017, 05:53:22 am
content: Without looking into the code, so may be somewhat inaccurate.Quote from: danergo on February 09, 2017, 05:40:02 amGets timer value of the asynchronous timer. The only one running in sleep mode.Quote from: danergo on February 09, 2017, 05:40:02 amThis is a very accurate (us) version of halGetTimeOfAppTimer.Quote from: danergo on February 09, 2017, 05:40:02 amWall clock timer. Starts at 0 and monotonically increments. The value is in ms. The value is updated based on the sleep timer when device comes out of sleep.

author: danergo
author_rank: Regular Contributor
timestamp: February 12, 2017, 07:58:47 pm
content: Hello,I'm trying to calculate some sleeping variables, but I'm.Why happens this:Code:uint8_t b = 43;uint32_t a = halGetTimeOfSleepTimer() + b * 1000;printf("ST=%ld,A=%ld,B=%d\n\r", halGetTimeOfSleepTimer(), a, b);//prints ST=4781,A=-17755,B=43#endifI assumed that A should be 4781+43*1000 = 47781 which fits perfectly in the range of an uint32_t. At least I thought so.If I set b to 8, it works, for example ST=343,A=8343,B=8.

author: danergo
author_rank: Regular Contributor
timestamp: February 12, 2017, 08:54:10 pm
content: Quote from: danergo on February 12, 2017, 07:58:47 pmIt seems some odd compiler optimalization. If I explicitly cast b to uint32_t, it's working.

author: danergo
author_rank: Regular Contributor
timestamp: February 13, 2017, 01:39:46 pm
content: Hi,A minor detail is still needed for this:After issuing APS_DataReq, with a structure of APS_DataReq_t, I get a callback 'appAPSDataConf'.Is it right to send the node to sleeping in this appAPSDataConf? I mean isn't it too early for the stack to sleep?(sending to sleep means here that I set the statemachine's state, and it will call ZDO_SleepReq in the next step.)Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: February 13, 2017, 04:36:56 pm
content: Quote from: danergo on February 13, 2017, 01:39:46 pmThat's absolutely fine.

author: danergo
author_rank: Regular Contributor
timestamp: February 14, 2017, 09:37:17 am
content: Hello!And now the final question of this topicWhile ED is sleeping, C wants to send something to it (with APS_DataReq). Theoretically, ED will receive it after it wakes up.1.) Is this buffering mechanism implemented in the APS layer, or I need to take care of it from the app layer?2.) Now assuming it is in the APS, when will it send the message? After CS_SLEEP_PERIOD, or after ED wakes up and send something to C (which is much earlier than CS_SLEEP_PERIOD)?And one more thing: when I call ZDO_SleepReq, device should go the deep sleep, right? It's marked that in that mode it consumes less or equal to 700nA, but my measurements show 700uA (measured on the Xplainedpro, and also on my device). It is 1000 times more, is it a mistake in the datasheet, or it's caused by the stack and the sleep timers? (I'm using a pure multimeter at the moment).Thanks a lot!

author: ataradov
author_rank: Super Contributor
timestamp: February 14, 2017, 05:13:44 pm
content: Quote from: danergo on February 14, 2017, 09:37:17 amIt is implemented on the parent device.Quote from: danergo on February 14, 2017, 09:37:17 amAfter devices wakes up and sends Poll Request.Quote from: danergo on February 14, 2017, 09:37:17 amDeep sleep (Power-down mode) is when sleep interval is 0, and no timer is running. The only useful wake up source is external interrupt.If there is preset timer, then device goes into Power-save mode.

author: danergo
author_rank: Regular Contributor
timestamp: February 14, 2017, 09:32:23 pm
content: Quote from: ataradov on February 14, 2017, 05:13:44 pm

author: ataradov
author_rank: Super Contributor
timestamp: February 15, 2017, 06:55:40 am
content: You need to have the stack properly awake and it will send request on its own. I can't keep track of your modifications, so it is hard for me to say what to do exactly. If you are getting the data, then requests are sent.You need to check what else on the board may consume power. Typically MCU sleep works fine.

author: danergo
author_rank: Regular Contributor
timestamp: February 15, 2017, 08:45:03 am
content: Yes, fair enough.Thank you!

author: danergo
author_rank: Regular Contributor
timestamp: February 16, 2017, 06:07:15 pm
content: Hello!How many messages can the Coordinator buffer for sleeping nodes?Is it defined somewhere?Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2017, 06:19:03 pm
content: One per ED, if I'm not mistaken. And that's generous compared to what IEEE standard mandates. According to the standard, the message must be discarded after about 8.5 seconds. But that's really impractical, so all stacks implement longer storage time.

author: danergo
author_rank: Regular Contributor
timestamp: February 16, 2017, 08:06:22 pm
content: Wow, 8.5 seconds is not that practical indeed. The most practical would be to store messages for CS_SLEEP_PERIOD.Do you know, for how long is BitCloud storing these messages?Hm, and what is the command order after waking up on the ED side?1. APS_DataInd2. ZDO_WakeupIndor1. ZDO_WakeupInd2. APS_DataInd?If that is the second case, I'd have to implement some level of buffering in the APS_DataInd, because after wakeup my firmware usually does some radio-related task which results an incoming message into APS_DataInd.Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2017, 08:22:22 pm
content: Quote from: danergo on February 16, 2017, 08:06:22 pmIndefinitely until it is time to kick the device out for not checking in. If I'm not mistaken it is some thing like 1.5*EdSleepPeriod.Quote from: danergo on February 16, 2017, 08:06:22 pmThis. There will be no indications of any sort if stack is sleeping.Quote from: danergo on February 16, 2017, 08:06:22 pmWell, you will get to indications, what's the problem?

author: danergo
author_rank: Regular Contributor
timestamp: February 16, 2017, 08:44:45 pm
content: Quote from: ataradov on February 16, 2017, 08:22:22 pmWell, for processing incoming messages, I'm using the SM. Currently I have a storage for only 1 message in the APS_DataInd. The message is stored until the SM fetches it.Now I have the feeling, that if C has a pending message and it arrives into APS_DataInd (in ED), my app's SM is not yet there, so the pending message will be discarded on the ED side unless I implement some buffering in the APS_DataInd.This is quite my own problem, just wanted to let you know.What is a bit more interesting here, what happens, if C requested to send a new message to ED, while C already has 1 item in its buffer for ED?Is this new message going to be discarded or it will replace the previous pending message?Oh, and one more thing. This message buffering is implemented in the Coordinator and also in the Router, right? So if the ED's 'parent' is not the coordinator itself, it's router will store the message for it.Thanks a lot!

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2017, 09:07:46 pm
content: Quote from: danergo on February 16, 2017, 08:44:45 pmWell, If this is just about SM switching states, then I would not worry, there is no way 2 consecutive DataInds can be called in the same planning cycle, since all other layers involved in delivering messages have their own SMs, plus the now one will have to be received over the air and over SPI. If SM actually takes a long time to process messages, then yes, you need buffering.Quote from: danergo on February 16, 2017, 08:44:45 pmI believe it will be discarded.Quote from: danergo on February 16, 2017, 08:44:45 pmYes, any device that can be a parent implements this buffer.