DWM3001CDK 1:2 SS‑TWR Ranging: Second Anchor Fails RX Frame Checksum

I’m using the DWM3001CDK boards in a 1 (Tag–Initiator) : N (Anchor–Responder) setup. My goal is for the Tag board to measure distances to each Anchor and then send those distance values to a smartphone over BLE for trilateration.

I’m following this open‑source project and, for measurement convenience, plan to assign different device IDs to Tag and Anchor so I can build separate prebuilt binaries for each:

While 1:1 communication works perfectly, as soon as I switch to 1:2 the second board fails to complete its distance measurement. The logs show the RESP message is sent correctly, but on the INIT side I see:

[00:00:21.539,520] <inf> SIT_DISTANCE: Test: 03a000f7 & 00004000
[00:00:21.539,672] <wrn> SIT_DISTANCE: sit_checkReceivedMessage() no 'RX Frame Checksum Good'
[00:00:21.539,733] <wrn> SIT_DISTANCE: sit_checkReceivedMessage() reg1 = 0x03a000f7 ; reg2 = 0x038000f7 ; removed =  0x00200000
[00:00:21.539,825] <err> SIT_DISTANCE: sit_checkReceivedIdFinalMsg(1, header) fail
[00:00:21.539,855] <wrn> SIT_Module: Something is wrong

From inspecting the code, it seems the bitwise AND between the received status register and DWT_INT_RXFCG_BIT_MASK is never true:

waitForSysStatus(&l_status_reg, NULL,
    (DWT_INT_RXFCG_BIT_MASK | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR), 0);

I don’t have much UWB experience, so I’m finding it hard to debug. Any hints or pointers would be greatly appreciated.

For reference, here are my build‑time settings (see lib/sit/sit.c in the repo):

#if defined(CONFIG_DEVICE_INITF)
    device_settings.device_type = initiator;
    device_settings.initiator   = 1;
    device_settings.responder   = 101;
    device_settings.devices     = 2;
#elif defined(CONFIG_DEVICE_RESPF)
    device_settings.device_type = responder;
    device_settings.initiator   = 0;
    device_settings.responder   = 0;
#else
    LOG_ERR("Define DEVICE_INITF or DEVICE_RESPF");
#endif
device_settings.measurement_type = ss_twr;
device_settings.state            = measurement;
device_settings.deviceID         = CONFIG_DEVICE_ID;
device_type                      = device_settings.device_type;

Thank you in advance for any advice!

The “good” status register comes out as 0x03806ff7, whereas the problematic one is 0x03a000f7. Digging deeper, I found the following key difference:

  • Difference:
    • In the normal case, both the RXFCG (0x4000) and RXFR (0x2000) bits are set, indicating that the preamble and CRC checks both passed.
    • In the failing case, the RXPTO (0x200000) flag is set, which means a “preamble timeout” occurred.

In other words, on the second device (ID 101) the preamble isn’t being detected correctly, so DWT_INT_RXPTO_BIT_MASK is triggered and the code never even reaches the CRC stage—hence the failure.


I’m not sure whether this is a timing/delay issue or a misconfiguration of those flags. I’ve already tried increasing these values without any change:

sit_set_rx_after_tx_delay(DS_RESP_TX_TO_FINAL_RX_DLY_UUS);
sit_set_rx_timeout(DS_FINAL_RX_TIMEOUT + 2000);
sit_set_preamble_detection_timeout(DS_PRE_TIMEOUT + …);