Went to bed exhausted last night.  I’m really having a lot of trouble getting the ranging to work.  So far I can send and receive packets.  I think I can send packets after a fixed delay, but I can’t seem to receive them correctly.

Some of my problems are clearly just not understanding how to configure the chip for the subset of stuff I need to do.  Then there are illogical behaviors, and frankly — chip bugs.

Status bits are set in the wrong chronological order.

This sequence of trace messages shows the problem.  I’m joining battle here at the point when one TS has sent a “ranging init” packet to the other.  A ranging-init packet is the “serve” in the ping-pong game of packet exchanges between the two peers).  After sending that packet the radio goes to sleep, an I’d expect to get notification of the packet having been finally sent, but in fact I get told (very reasonably) that the radio has woken up: (SYS_STATUS_SLP2INIT); that the clock has locked up OK: ( SYS_STATUS_CPLOCK); that a packet preamble has been successfuly decoded (SYS_STATUS_RXPRD ); that the clock has lost lock again (SYS_STATUS_CLKPLL_LL ); and that the rest of the packet timed out (SYS_STATUS_RXSFDTO).  All of this gets reported at a higher level in the DW IRQ handler as a “receive error” (DWT_SIG_RX_ERROR)

After all that is said and done I get to hear that my original transmission has completed (DWT_SIG_TX_DONE).  This bizarre sequence makes it difficult to build a rational state-machine, and indeed my code (and I actually) get’s confused and hangs up.

(25931) ranger_rxcallback DWT_SIG_RX_ERROR
SYS_STATUS_IRQS SYS_STATUS_CPLOCK SYS_STATUS_RXPRD SYS_STATUS_SLP2INIT SYS_STATUS_CLKPLL_LL SYS_STATUS_RXSFDTO
LISTENING_FOR_RANGE_INIT_RESPONSE
(25932) ranger_txcallback DWT_SIG_TX_DONE

It isn’t even possible to reply to every ranging-init packet

The technique for measuring time of flight is to note the value of a 40-bit timer as a ranging-init packet leaves the antenna.  The peer receiver gets the packet, and hangs onto it for an agreed amount of time before sending it back to the sender.  Believe it or not, that’s a relatively long time – 150ms.  When it gets back to the original sender’s antenna, the clock is read again, the tx and rx times compared and range calculations happen.
Buried deep with the chip is a very fast clock that time stamps the packets going out.  The clock is only 40 bits wide, and so it wraps around quite often.   Each bit in the 40-bit timer represents 16 psecs, so the counter wraps every 16 * 2^40 = 17 seconds.   The timer keeps running all the time and is never zeroed, so if the transmit time is expected to wrap before the reply might conceivably arrive, then the whole operation is aborted.   This results in the confusing message “too late”. Of course restarting the ranging sequence burns power.

WAIT_TX_RESP_DONE
(2839) listener_rxcallback DWT_SIG_RX_ERROR
SYS_STATUS_IRQS SYS_STATUS_CPLOCK SYS_STATUS_RXPRD SYS_STATUS_SLP2INIT SYS_STATUS_CLKPLL_LL SYS_STATUS_RXSFDTO
LISTENING_FOR_RANGE_INIT_RQ
(2840) listener_rxcallback DWT_SIG_RX_ERROR
SYS_STATUS_IRQS SYS_STATUS_CPLOCK SYS_STATUS_RXPRD SYS_STATUS_SLP2INIT SYS_STATUS_CLKPLL_LL SYS_STATUS_RXSFDTO
LISTENING_FOR_RANGE_INIT_RQ
too late

Chip is buggy

There are clearly undocumented issues with the chip, that are only revealed in the code.  I’m not sure that I have actually hit these bugs yet, but I decided to use their IRQ handler which appears to contain fixes for the bugs, albeit with a lot of extra “interrupts off” handling code.  
//fix for bug 622 – LDE done flag gets latched on a bad frame
// bug 634 – overrun overwrites the frame info data… so both frames should be discarded
//bug 627 workaround – clear the AAT bit if the ACK request bit in the FC is not set

Leave a Reply