DWM1000 SPI write does not work (but SPI read works)


I want to use a DWM1000 to setup a ranging system with my own board (ModalAI VOXL).
For starters I am trying to get the examples from this repository running: GitHub - Decawave/dwm1001-examples: Simple C examples for Decawave DWM1001 hardware

I am able to read the Device ID of the DWM1001 succesfully, so reading via SPI apparently works.
However, I cannot get it to write anything so far.

I read APS022 and used the check that was suggested in there:

  uint8 dataA[10] = { 1,1,2,3,5,8,13,21 };
  uint8 dataB[10] = { 0,1,2,3,4,5,6,7,8,9 };
  dwt_writetodevice(0x21, 0, 10, &dataA[0]);
  dwt_readfromdevice(0x21, 0 , 10, &dataB[0]);

  int i;
  for (i = 0; i < 10; ++i) {
    printf("%" PRIu8 "\n", dataA[i]);

  for (i = 0; i < 10; ++i) {
    printf("%" PRIu8 "\n", dataB[i]);

  uint8 devIdData[5] = {0,0,0,0,0};
  dwt_readfromdevice(0x00, 0 , 5, &devIdData[0]);

  int j;
  for (j = 0; j < 5; ++j) {
    printf("%" PRIu8 "\n", devIdData[j]);

This returns all 255 from the 0x21 register, so the write did not seem to work.
From the 0x00 register, however, I get the sequence 48, 1, 202, 222, 0, which seems to be correct.

I am using SPI Mode 0 and a frequency of 2000000 Hz (2 MHz).
The cables connecting the VOXL and the DWM1000 are roughly 15cm, so I don’t think this is critical, right?

What can I do to find the cause of the problem?

Okay, I found another thread with the same problem:

For me also the dwt_initialise() function causes the problem. If I don"t call it, writing to SPI works (I also have the problem that Device ID is 0xFFFFFFFF after calling dwt_initialise()).
Why does dwt_initialise() cause this behavior?

But I still have another problem:
This part waits for a frame and checks the SYS_STATUS_ID register to see if a frame was received.

  /* Activate reception immediately. */

  /* Poll for reception of a frame or error/timeout. See NOTE 5 below. */
  while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))

However, dwt_read32bitreg(SYS_STATUS_ID) always returns 0xFFFFFFFF for me, even though no frame was received, which then causes the loop to terminate. Does anyone know why that is?

The first thing to try when troubleshooting SPI is to try lowering the clock speed. That eliminates most (but not all) signal integrity issues.

Any chance you have an oscilloscope handy to check the signals with? The next thing would be to firstly see if there is any data at all on the MOSI line and then double check the timings on the CS, CLK and both data lines.
Also check that the signal path is correct, that the signals are getting to the correct pins on the module.

Basically check the hardware is all good before trying to debug the firmware.

Thanks for the reply.

Let me quickly summarize what’s happening for me:

  1. Writing to SPI did not work initially, but I “resolved” it by not calling dwt_initialise() - if I call it, the Device ID is 0xFFFFFFFF and so is register 0x21. If I do not call it, writing to registers works. This should not be the case, right?

  2. The SYS_STATUS_ID register (0x0F) is 0xFFFFFFFF after the function dwt_rxreset() is called. This also does not seem right. I removed the call, and now I can read the (presumably) correct value of the 0x0F register.

  3. Receiving frames still does not work, because there are RX errors.
    SYS_STATUS_ID is typically something like 0x2801302.
    I don’t really know how to interpret that, but it means that the CLKPLL_LL bit is set to 1, which according to the User Manual indicates an error that should not happen:

Clock PLL Losing Lock. This event status bit is set is set to indicate that the system’s digital
clock PLL is having locking issues. This should not happen in healthy devices operating in
their normal range. Its occurrence may indicate a bad configuration, a faulty part or a
problem in the power or clock inputs to the device. If this bit is set it may be advisable to
turn off the transmitter to avoid sending spurious signals. The CLKPLL_LL bit is cleared by
writing a 1 to it.
Note: The PLLLDT bit in Register file 0x24:00 –EC_CTRL should be set to ensure reliable
operation of this CLKPLL_LL bit.

Do you have any advice on how to resolve these problems?
The SPI clock speed is set to 2 MHz, but I also tried 1 MHz. This should be low enough to work, right?\

I read register 0x24 and it is 0xDEAD0000.
That seems to indicate that the CLKPLL_LL bit is not reliable, but the hex value of register 0x24 also doesn’t seem like a coincidence to me…? I didn’t find anything about that value though.

Edit 2: I realized that I am responsible for setting Bit 2 in register 0x24 in order to make the reading of CLKPLL_LL reliable. I did that, and now the CLKPLL_LL bit is not set anymore, so it seems the problem is somewhere else.