How does SPI know when message is complete?

The DW1000 SPI protocol doesn’t include a length at the beginning of the message. There is a single byte header specifying read/write status, any additional header bytes for subaddressing, and the primary address. So if I write an arbitrary sequence of bytes into, say, register 0x21, which will take any number of bytes up to 41, how does the device know when the message is complete?

Does it just keep accepting bytes and writing them (including any buffer overflow risk) as long as the SPI control line is held low? Does raising the control line back to high signal that the message is complete?

What sort of delay is required after pulling the control line low before sending data and after sending the last data before raising the line back high again? I’ve tried no delay up through 100ms and see how difference in behavior.

I cannot get SPI to work reliably. I can read. For example, I can get ‘DECA0130’ from the first register, but writing basic numerical sequences into 0x21 (which appears to be the recommended register for SPI testing) is extremely sporadic. Sometimes the the data gets in there (as confirmed by a subsequent read) and sometimes it doesn’t…and sometimes it writes some of the sequence but not the entire sequence. It doesn’t matter what baud I set. I have tested two separate DWM1000s from two separate SPI controllers and I’m getting this behavior consistently. It isn’t broken enough to be totally broken (as stated above, I can read fine, and sometimes it writes a few bytes successfully, so it’s configured correctly enough to work some), but it doesn’t work reliably, which is weird (I would expect total failure if I was doing something wrong).

I’m flummoxed. Other than baud rate, polarity, phase (standard SPI parameters), and configuring the single byte header, which is a very simple piece of data to put together, I don’t know what else I have control over.

Could well be a SPI / timing issue.
Please have a look at our debug application note APS022 (attached).

It may also happen because your SPI wires are to long.
Could you tell us with what kind of processor/eval board you’re using to control the DWM1000?

I’m currently working with the PyBoard. I’ve tried two different PyBoards with two different DWM1000s and I’m getting similar behavior across all combinations of boards, so it isn’t an error in an individual device; it’s something systemic, and it isn’t the baud rate because I’ve tried the full range. It isn’t polarity or phase.

I appreciate your feedback, but I doubt it’s wire length (2-4 inches, give or take).

I’ll look at the debug note. Thanks.

I’m going to try to get an Adafruit FT232H going so I can run SPI from my Mac through a different controller instead of the PyBoard, but I don’t see why that should make any difference since I can control other SPI devices from the PyBoard without any trouble. It’s just a shot in the dark.

Hi Again

Would you have written the code yourself or would you have ported one of the example codes we have?
And now you have APS022, maybe check if you have any timeouts and what state the dwm is in

I’m not working with any sample code since I’m using a fairly uncommon device (PyBoard). I’m not sure what APS022 refers to.

How do I check the DWM1000’s state?


Device state and status is all described in aps022 . It was included in the reply yesterday. Otherwise please download it from our website. You’ll find it under UWB systems on

I also suggest you may look at our example code and maybe port it to the pyboard

P. 7 of that APS document says this:

[size=small][font=ArialMT]The programmable SFD register file, USR_SFD at address 0x21 may be used for this and is 401 bytes long.[/font][/size]

[size=small][font=ArialMT]Is that a typo? The other documents says it is 41 bytes long, so I assume 401 is incorrect. Can you confirm?[/font][/size]

Just to sat that your assumption is correct. it’s 41 bytes/octets long, not 401
The typo will be updated in the next release of the document.

Thanks for noting

Hi kwiley,

DW1000 DataSheet describes SPI operaton, please read section:1.3 SPI Host Interface.

Please check the signals on a scope to verify your are sending correct sequences/correct timing to the DW1000.

Hi Kwiley,

I had similar issues. I’m using a PIC16 as a controller.
Some of my boards worked well and some of them had issues. I put a 330p capacitor on MOSI line close to DW1000 and it resolved my issue. Communication is crispy clear since.
PIC is very close to DW so routes of trace are minimal length and straight. Also, I had to pull up SPIPHASE to get communication working with PIC. No other settings worked for me (I tried all setups, 4x in PIC and 4x in DW).
Oh yes, I wrote my own code in PIC ASM and not used any of DW libraries. Also, I’m using DW1000 IC only, not the DWM module. However, I started my project with DWM1000 before designing my own board and 330p capacitor was needed there, too.
I’m not saying it’s the solution but this definitely helped in my cases.


I had similar issues that I cannot get SPI to work reliably. Sometimes, I can get correct values, but sometimes I get all FF. I am using CompuLab IoT board with i.mx7 processor and running with the kernel SPI driver. The CompuLab board is connected to the EVB1000 board as below while all S1 and S2 off.
CompuLab EVB1000
P7-6(CLK) J6-7(CLK)
P7-7(SIMO) J6-8(MOSI)
P7-8(SOMI) J6-5(MISO)
P7-9(CS) J6-9(CS)
P7-14(GND) J6-10(GND)

The following is the readfromspi function used by DW1000 API.

int spi_port // = open("/dev/spidev0.0", O_RDWR); also some other settings
int readfromspi(uint16 headerLength, const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer)
struct spi_ioc_transfer spi_data;
uint32_t length = tx_len + rx_len;

if (spi_port > 0 && length > 0) {
    uint8_t _tx_data[length];
    uint8_t _rx_data[length];
    int rv;

    memcpy(_tx_data, tx_data, tx_len);
    memset(&_tx_data[tx_len], 0, rx_len);
    spi_data.tx_buf = (unsigned long)_tx_data;
    spi_data.rx_buf = (unsigned long)_rx_data;
    spi_data.len = length;
    rv = ioctl(spi_port, SPI_IOC_MESSAGE(1), &spi_data);
    if (rv > 0) {
        memcpy(rx_data, &_rx_data[tx_len], rx_len);
        return DWT_SUCCESS;
return DWT_ERROR;


I used a spectrum analyzer captured the SPI signals and saw sometimes EVB1000 board did not respond so that all ff were obtained.

Hello P.XU,
did u solve your problem? Can you tell me how did you solve that Problem because i have a same.