Open stephenmasih opened 4 years ago
If you're adding sleep you will need to add wakeup before the next operation. But, as the timing of the next range exchange depends on the timer in the decawave running continously it will fail. The timer is stopped during sleep and thus the application will need to resync to the network.
Thanks for your comment. Please let me know if I am understanding it wrong. I have called uwb_wakeup(Udev) if sleeping; In the beginning of slot_cb() in main.c
But the same happens slot_timer_cb....start_tx_error
You mentioned that I should resync to the network upon wake up. Does the timer also automatically activates upon wake up ? Please let me know how should I resync back with master anchor time. Probably after resync I should call nrng_request_delay_start()
The ntwr example sends out a blink every 1s. Every time a node/tag needs to resync you need to receive two of these blinks. So, it'll take about 2s after each sleep to resync to the network. So, unless you're sleeping for 2+s you're actually wasting more energy by sleeping than by not sleeping. What I'm saying is that sleeping is not really a good thing to try to do with this example.
Okay I get it. Can you recommend me an example. I am actually trying to add sleep for 5 seconds using os_time_delay(OS_TICKS_PER_SEC*5) after calling nrng_delay_start() and, uwb_enter_sleep(udev) in slot_cb() itself.
In the beginning of the slot_cb() i have added uwb_wakeup(udev).
Will the resync happen automatically after call of this function ?
If not how to do so ? How can I keep nrng_delay_start() in hold until resync is completely done ?
Thank you for your support.
You need to do a bit more work to tear down the tdma and ccp stacks and then restart them. Something like this:
static void
low_battery_mode(void)
{
tdma = (tdma_instance_t*)uwb_mac_find_cb_inst_ptr(inst, UWBEXT_TDMA);
uwb_ccp_stop(tdma->ccp);
uwb_phy_forcetrxoff(inst);
/* Force timeout */
uwb_set_rx_timeout(inst, 1);
uwb_phy_forcetrxoff(inst);
os_time_delay(1);
uwb_sleep_config(inst);
uwb_enter_sleep(inst);
}
void
resume_uwb(struct uwb_dev *inst)
{
uwb_wakeup(inst);
uwb_mac_config(inst, NULL);
uwb_txrf_config(inst, &inst->config.txrf);
uwb_phy_forcetrxoff(inst);
os_time_delay(1);
tdma = (tdma_instance_t*)uwb_mac_find_cb_inst_ptr(inst, UWBEXT_TDMA);
uwb_ccp_start(tdma->ccp, CCP_ROLE_SLAVE);
}
i tried working out with your functions, but it still shows up slot_timercb:start_tx_error
Please look into this code i used in main.c
static void slot_cb(struct dpl_event ev){ assert(ev); tdma_slot_t slot = (tdma_slot_t ) dpl_event_get_arg(ev); tdma_instance_t tdma = slot->parent; struct uwb_ccp_instance ccp = tdma->ccp; struct uwb_dev udev = tdma->dev_inst; uint16_t idx = slot->idx; struct nrng_instance nrng = (struct nrng_instance )slot->arg;
if (udev->status.sleeping) {
printf("sleeping\n");
resume_uwb(udev);
}
/* Avoid colliding with the ccp in case we've got out of sync */
if (dpl_sem_get_count(&ccp->sem) == 0) {
return;
}
/* Update config if needed */
if (uwb_config_updated) {
uwb_config_updated = false;
uwb_phy_forcetrxoff(udev);
uwb_mac_config(udev, NULL);
uwb_txrf_config(udev, &udev->config.txrf);
return;
}
if (ccp->local_epoch==0 || udev->slot_id == 0xffff) return;
/* Process any newtmgr packages queued up */
if (idx > 6 && idx < (tdma->nslots-6) && (idx%4)==0) {
nmgr_uwb_instance_t *nmgruwb = (nmgr_uwb_instance_t *)uwb_mac_find_cb_inst_ptr(udev, UWBEXT_NMGR_UWB);
assert(nmgruwb);
if (uwb_nmgr_process_tx_queue(nmgruwb, tdma_tx_slot_start(tdma, idx))) {
return;
}
}
if (udev->role&UWB_ROLE_ANCHOR) {
/* Listen for a ranging tag */
uwb_set_delay_start(udev, tdma_rx_slot_start(tdma, idx));
uint16_t timeout = uwb_phy_frame_duration(udev, sizeof(nrng_request_frame_t))
+ nrng->config.rx_timeout_delay;
/* Padded timeout to allow us to receive any nmgr packets too */
uwb_set_rx_timeout(udev, timeout + 0x1000);
nrng_listen(nrng, UWB_BLOCKING);
} else {
/* Range with the anchors */
if (idx%MYNEWT_VAL(NRNG_NTAGS) != udev->slot_id) {
return;
}
/* Range with the anchors */
uint64_t dx_time = tdma_tx_slot_start(tdma, idx) & 0xFFFFFFFFFE00UL;
uint32_t slot_mask = 0;
for (uint16_t i = MYNEWT_VAL(NODE_START_SLOT_ID);
i <= MYNEWT_VAL(NODE_END_SLOT_ID); i++) {
slot_mask |= 1UL << i;
}
if(nrng_request_delay_start(
nrng, UWB_BROADCAST_ADDRESS, dx_time,
DWT_SS_TWR_NRNG, slot_mask, 0).start_tx_error) {
uint32_t utime = os_cputime_ticks_to_usecs(os_cputime_get32());
printf("{\"utime\": %lu,\"msg\": \"slot_timer_cb_%d:start_tx_error\"}\n",
utime,idx);
}
low_battery_mode();
os_time_delay(OS_TICKS_PER_SEC*5);
}
} I have called low_battery_mode() and a delay of 5 seconds exact after nrng_request_delay _start() which is SUCCESS only once. resume_uwb(udev) is called when checked if sleeping. After sometime in the UART Console even the printf stops showing "sleeping" I am also attaching a screenshot for your reference..
Please help.
i am trying to add sleep just like in the example of tdoa_tag / Enter sleep / uwb_phy_forcetrxoff(udev); uwb_phy_rx_reset(udev); uwb_sleep_config(udev); uwb_enter_sleep(udev);
after nrng_complete_cb(struct dpl_event *ev) is called. The code is able get the pan slot_id and compute the distance only for once, after that it shows slot_timercb....start_tx_error
please help me resolve this issue. Thanks