Dwt_starttx always returns error when using delay

Dear all,

I am using DWM1000 with TI microcontroller. I have everything working so far, but for some reason when I want to have a delayed TX response for the DS-TWR-RESP example, the DW API always returns a DWT_ERROR.

Let me explain my current setup: I have a TREK1000 node that is reprogrammed for the DS-TWR-INIT example, and a TI microcontroller with my ported drivers. The TI microcontroller runs at 80 MHz, and SPI speed is 20 MHz, which are both faster than TREK microcontroller runs at 72 MHz and SPI speed is 18 MHz (although this is not a true one-on-one comparison of course).

When I run the example, it always returns a DWT_ERROR. So when I read the SYS_STATUS after transmission is triggered I get 0x00802f02. If I check the manual, this means that:
(1) CLK PLL is locked
(2) Preamble is detected
(3) SFD is detected
(4) Leading edge detection is performed
(5) PHY header is detected, and
(6) Data frame is ready.

Then I printed the timestamps of a received poll time, expected transmission time and (for debugging purpose) also the system timestamp just after the dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED);, and shows that the dwt_starttx already throws in an error before the actual transmission.
How could this happen, and what should I improve to fix this? A glimpse of the data (only higher 32 bit are printed):

TX: Response failed.. return code: 00802f02
Received poll time: 407372753
Expected resp time: 408038353
Recorded syst time: 407873832
TX: Response failed.. return code: 00802f02
Received poll time: 657462164
Expected resp time: 658127764
Recorded syst time: 657959886
TX: Response failed.. return code: 00802f02
Received poll time: 907551564
Expected resp time: 908217164
Recorded syst time: 908050362
TX: Response failed.. return code: 00802f02
Received poll time: 1157640953
Expected resp time: 1158306553
Recorded syst time: 1158140794

Maybe it is also good to mention that when I reverse the setup (so TREK node becomes RESP, and TI node INIT) that the POLL message can be correctly received (because it does not use the delayed function), but that the final message (that uses a delayed transmission as well) is also not send.
So the problem is really with the use of the delayed transmission.

Please have a look at the example code ex_03a_tx_wait_resp

But also check the API document itself (attached).
dwt_writetxdata() is described + an example on the usage of it (pg 29)

The API also states:
The dwt_writetxdata() function checks that the sum of txFrameLength and txBufferOffset is less than DW1000’s TX buffer length to avoid messing with DW1000’s other registers and memory. If such an error occurs, the write is not performed and the function returns DWT_ERROR. Otherwise, the functions returns DWT_SUCCESS.

DW1000_Software_API_Guide_rev2p7.pdf (1.5 MB)


I just found out that the TXPUTE (Transmit Power Up Time Error) is raised, so that the timing is too short when trying to send a response after a message is succesfully received.
I am a little confused on what the cause could be, since I have not touched the delay times or conversion factor on both devices:

All DW1000 API commands are exactly the same as the ex_05 examples, and when I already compared the SPI implementations, and it takes CS more time to activate and deactivate (~2 us on TREK, ~5-7 us on TI, so ~8 us more overhead per transfer). The SPI transfer itself is done a little faster (20MHz vs 18 MHz) but in total it generally is a bit slower than TREK. I have already pushed the SPI to the max, so I was wondering what I could do. I can’t imagine that the constraints are set so high that I don’t have time to process it with this microcontroller.

Regarding your suggestions: dwt_writetxdata() does not fail. dwt_starttx() does.
I am already using the example code (ex_05b_ds_twr_resp and ex_05a_ds_twr_init) as stated above.
Furthermore, I read the API document and the DW1000 user manual (3.3 Delayed Transmission). The user manual states:
“The low-order 9 bits of the delayed Transmit value programmed into Register file: 0x0A – Delayed
Send or Receive Time are ignored giving a time resolution of 8 ns, or more precisely 4 ÷ (499.2×10 6 )”.

If I am not mistaken, that would mean the timestamps above could be translated to time with this formula:

Time left before/after deadline = Expected response time - recorded sys time after failed tx

The times that I mentioned in my first post are recorded from the DW1000 example: The received poll time is poll_rx_ts >> 8 from the example, the expected response response time is resp_tx_time and the recorded system time is response from a dwt_readsystimestamphi32() call immediately . So I only use standard DW API calls and have not inserted any of my own code in the while(1) loop of the ex_05b_ds_twr_resp example before the failed ret = dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED); call.

If I use these timestamps, and convert them to human readable timescale it result in following differences:

(1) 408038353 - 407873832 = 164521 cycles => multiplied with 4 ÷ (499.2×10 6 ) = 1.318 ms
(2) 658127764 - 657959886 = 167878 cycles => multiplied with 4 ÷ (499.2×10 6 ) = 1.345 ms
(3) 908217164 - 908050362 = 166802 cycles => multiplied with 4 ÷ (499.2×10 6 ) = 1.336 ms
(4) 1158306553 - 1158140794 = 165759 cycles => multiplied with 4 ÷ (499.2×10 6 ) = 1.328 ms

These timings show that the microcontroller is fast enough and well on time, and that DW1000 should have plenty of time to start the transmission. The User manual is talking about several microseconds to startup the transmitter, which is only a tiny fraction of time that is left according to the calculations above.

But still I get the error code of TXPUTE (Transmit Power Up Time Error). Could you please help me why this is the case?

I also had time to check ex_03a_tx_wait_resp example today. However, that one uses dwt_starttx without delay (so using the DWT_START_TX_IMMEDIATE). I have no problems at all with direct transmissions, but the problems start when using DWT_START_TX_DELAYED (as mentioned above). The examples that I am already using ( ex_05a_ds_twr_init and ex_05b_ds_twr_resp) are therefore most relevant to use I think.

Hi, i’m having the same problem as you describe.
Did you ever manage to solve this?

kind regards,

I did solve it, but I am not sure about the exact problem.
Most of my problems were related to the SPI communication (mostly timing). I had to refactor some of the platform dependent code, but you have to be careful about the time that (e.g.) allocating memory takes or the time between 2 SPI transfers.

As far as I remember changing the RX_RESPONSE_TURNAROUND parameter to a larger value fixed the issue for porting the TREK code. A similar value for the simpler examples should also help you, because it gives your microcontroller more time to respond to a received frame.

Maybe it is good to note that the STM32 has a pretty quick SPI module if you consider the switching time that a microcontroller requires between 2 transfers (the actual data-rate is limited of course to 18 MHZ of course), so it wouldn’t surprise me if your custom microcontroller is actually slower although it might operate at higher data-rate.

My suggestions would be to measure the SPI timings of a TREK node and your custom PCB on an oscilloscope, and compare the two. It will give you great insight regarding the timing.

1 Like

Thanks for your comments and advice. I will definitely try your suggestions.

Hello I have the same problem it doesn’t matter witch cpu I you
the dwm1000 just keep return an error when I call dwt_starttx(DWT_START_TX_DELAYED); ,but most of the time
it just lock
I am using st cpu
how did you solve the problem ?

Hi. Sorry for the delay in replying i’m only just getting back to this project now.

I’m working through it now, i’'l let you know if i find something.
Did you have any luck?

kind regards,

Hello, i have the same problem.
did you solve the problem ?

I search for this topic e this post was very helpful for me, I figured out that my problem was three times defined, two in the init and one in the responder.


I modified those times in 300/500/550 and the code work with 84MHz (CPU).