Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sleep during twr_nranges_tdma #9

Open
stephenmasih opened this issue Aug 30, 2020 · 6 comments
Open

Sleep during twr_nranges_tdma #9

stephenmasih opened this issue Aug 30, 2020 · 6 comments

Comments

@stephenmasih
Copy link

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_timer_cb_....start_tx_error

please help me resolve this issue.
Thanks

@ncasaril
Copy link
Collaborator

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.

@stephenmasih
Copy link
Author

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()

@ncasaril
Copy link
Collaborator

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.

@stephenmasih
Copy link
Author

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.

@ncasaril
Copy link
Collaborator

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);
}

@stephenmasih
Copy link
Author

stephenmasih commented Sep 21, 2020

i tried working out with your functions, but it still shows up slot_timer_cb_: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..

Screenshot from 2020-09-22 04-29-22

Please help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants