DW3000 Fast command error

I’m getting a weird error while trying to port my system over to using the DWM3000.

This is almost certainly a firmware bug on my part but I just can’t track it down so any suggestions as to where to look would be appreciated.

The basic method of operation is:
The ranging code normally sits with the DW3000 in RX mode and is driven off the interrupt line.

When a packet is received it checks the contents of the packet, records the time and sends a reply if required. If no reply is needed then RX is re-enabled immediately. If a reply is needed then it is transmitted using the wait for response option enabled so that the RX re-enables as soon as the transmit is complete. Finally if the received packet is the last one in a range measurement then a higher level callback is triggered to process the results. This callback sets a flag, the background idle loop sees the flag, reads the timestamps saved in memory and calculates range, it doesn’t touch the DW3000 itself.
Transmit complete interrupts are also enabled and are used to record the transmit timestamp values but do nothing else.

When you wish to measure a range the start measurement function returns the device to idle and then sets the appropriate message to be transmitted immediately. Again the wait for response option is enabled when transmitting and at this point the code returns to it’s default interrupt driven, normally receiving mode.

The measurement process is a basic 4 packet TWR exchange (initiator to target, target to initiator, initiator to target, and then a final untimed target to initiator data packet containing time values).

This protocol is fully working on the DW1000 using a custom c++ driver, I’ve since modified it (hacked may be more appropriate given the horrible mix of c and c++ this created) to use the decawave DW3000 driver. The radio is configured to be compatible with a DW1000 based system. From my DW1000 device I can initiate ranges to the DW3000 device, it responds as expected and I get valid ranges.

If I try to initiate ranges from the DW3000 end then the first range succeeds (2 packets sent, 2 received, range calculated) however if I then try to initiate a second range measurement the initial transmit message results in a fast command error interrupt, SYS_STATUS_HI_CMD_ERR_BIT_MASK is set in cbData.status_hi
I have a second DW1000 unit configured with special debug firmware that simply reports all packets seen. This confirms that the initial packet of the second range attempt is not being sent.

Since the code is identical between the first and second range attempts it’s not an issue with the commands issued to start the measurement. This means it must be something to do with the state I’m leaving the device in after the first range cycle.
If I do a full soft reset of my system via the debugger then this repeats, the first range works and then things fail afterwards. I don’t have the hardware reset line connected on the DWM3000 so this is clearly recoverable in software.

Any suggestions as to what I could be doing to cause this situation and how to recover it would be appreciated. And thanks for making it this far into the post :slight_smile:

Hi Andy,

Are you using delayed transmission to send the initial frame?

It could be what is happening is due to an oddity in the DW3000 TX timer: it needs to be set before every TX operation, even if the delay remains constant. Not doing so could result in the DW3000 not being able to send the frame in time. I’m not sure if this results in a CMD_ERR status when using the fast commands.

No, the transmit in question is immediate.

dwt_writetxdata(length+2, message, 0); // add 2 for crc
dwt_writetxfctrl(length+2, 0, 0); // add 2 for crc
dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED); // send and then re-enable Rx

In other operating modes I do use the delayed Tx option but in that situation the timer is always set before enabling transmit. My timing requirements for that mode are tighter in places so I’m getting the basic one working first, the DW3000 code is currently significantly slower than the DW1000. This is expected, the DW1000 driver was written to do the absolute minimum number of SPI cycles needed for the required operation. On the final version I’ll crank the SPI speed up which will help but this is still a prototype with a module hanging off a cable plugged into a connector, the signal quality is pushing it a bit already at 20 MHz. (I did check that dropping it didn’t magically fix things)

I’ve tracked down the cause of the command error bit in the status register. As suspected it was a silly mistake, it was caused by issuing a start Rx command while already in Rx mode.
The background loop had a fail safe that if no packets were received for 30 seconds it re-enabled Rx just in case we had somehow ended up in a state where Rx was disabled. Changing this to be go to idle and then enable Rx fixed that error bit getting set.

The status register is now acting as expected.

edit - All fully working now. Other issues were caused by a stupid bug that caused two different instances of the radio controller being created, one with the correct settings and one with the wrong settings, it was re-configuring the radio to a different channel which is why I couldn’t see the messages.