What's the best strategy for the initiator in a ToF ranging sequence to implement a timeout?

By the look of official UWB1000 example program on github, after sending the first round of message, the initiator of a ranging sequence waits indefinitely unless certain error related registers got ticked.

This is all dandy and fine for demonstration and proof of concept, but in reality, this clearly doesn’t work, as you need a timeout that, when the respond message from the responder failed to send or sent but failed to be intercepted by the initiator, the initiator could abandon the current round of ranging and start a new one.

So, what’s the best strategy to do it?

I tried to put a counter in the while condition loop:

while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))

Note my actual code was modified whereas this one that I pasted here isn’t, please don’t get confused, this is just a reminder that tells people where I did the modification.

But… it for some reason doesn’t work. I assumed it was that some compilers are pretty intelligent and would “skip” “meaningless” counting process. I am not fond of pursuing that solution any further because that’s a ducttape solution, not the best course of action.

So, can anyone shed any light as to how I should best implement the time out?

Note that I could be entirely mistaken, there could already be a timeout register somewhere just that it doesn’t work in my code after integrated from official example.

Thanks in advance!

My code is all interrupt driven so sitting in a loop waiting wasn’t an option.

The method I used was that I had a processor timer that is used to initiate each round of ranging. After sending the range start message the code sets a flag indicating that we are waiting for a reply.

If a receive interrupt happens the system checks the packet and if it was the expected reply clears that flag since we’ve received the expected message.

The next time the range start timer triggers the first thing we do is check the flag, if it’s not been cleared then the previous range start is reported as failed.

The other option is the DW1000 has a receive timeout option, you can set that before enabling receive mode. It will then disable receive, set a status bit and optionally trigger an interrupt if no packet is received within the specified time.

Or the really simple method, the keyword you want is volatile. If a variable is flagged as volatile the compiler won’t optimise access to it. It’s normally used for hardware registers or variables changed in interrupts since those can change in ways the compiler doesn’t expect but can also be used to prevent empty loops from being optimised out.

Hello Andy, thank you for helping me out as always!

Say, can you recall even if only vaguely the name of that timeout register?

User manual section 7.2.14, Register 0x0C, Receive Frame Wait Timeout Period (RX_FWTO)

Takes a 16 bit value of the required timeout in us (technically units of 1.026 µs). Set the value and enable it by setting RXWTOE in the system configuration register while the system is idle.

1 Like

Thank you Andy, the issue has been resolved perfectly.