If there is a faster, simplier way to calculate congruent modulo, I'd love to see.
I 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.
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:
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:
(*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:
sp.sleepTime = 5000;
sp.startPoll = halSleepControl.startPoll;
sp.callback = originalWakeupCallback;
SYS_Sleep(&sp);
What am I doing wrong?
HAL_WakeUpCallback_t is already a pointer, so do something like this:
static HAL_WakeUpCallback_t originalWakeupCallback = 0;
originalWakeupCallback = halSleepControl.callback;
And then "originalWakeupCallback(halSleepControl.startPoll);" or "sp.callback = originalWakeupCallback;".
Many thanks, works like a charm.
Hello!
Just for curiosity:
what is the difference between the below functions?
1.) halGetTimeOfSleepTimer
2.) halGetSystemTimeUs
3.) halGetTimeOfAppTimer
Without looking into the code, so may be somewhat inaccurate.
1.) halGetTimeOfSleepTimer
Gets timer value of the asynchronous timer. The only one running in sleep mode.
2.) halGetSystemTimeUs
This is a very accurate (us) version of halGetTimeOfAppTimer.
3.) halGetTimeOfAppTimer
Wall 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.
Hello,
I'm trying to calculate some sleeping variables, but I'm
.
Why happens this:
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
#endif
I 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.
Hello,
I'm trying to calculate some sleeping variables, but I'm .
Why happens this:
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
#endif
I 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.
It seems some odd compiler optimalization. If I explicitly cast b to uint32_t, it's working.
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!
Hello!
And now the final question of this topic
While 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!
1.) Is this buffering mechanism implemented in the APS layer, or I need to take care of it from the app layer?
It is implemented on the parent device.
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)?
After devices wakes up and sends Poll Request.
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).
Deep 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.
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.
Yes, fair enough.
Thank you!
Hello!
How many messages can the Coordinator buffer for sleeping nodes?
Is it defined somewhere?
Thanks!
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.
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_DataInd
2. ZDO_WakeupInd
or
1. ZDO_WakeupInd
2. 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!
Do you know, for how long is BitCloud storing these messages?
Indefinitely 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.
1. ZDO_WakeupInd
2. APS_DataInd
This. There will be no indications of any sort if stack is sleeping.
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.
Well, you will get to indications, what's the problem?
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.
Well, you will get to indications, what's the problem?
Well, 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!
This is quite my own problem, just wanted to let you know.
Well, 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.
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?
I believe it will be discarded.
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.
Yes, any device that can be a parent implements this buffer.