Difference of CIR (Channel Impulse Response) between Tag and Anchor during ranging in DS-TWR

Hi all,

I’m currently working with the DWM3001CDK and have modified the firmware to capture CIR (Channel Impulse Response) during DS-TWR ranging.
Specifically, I modified dw3000_mcps_mcu.c, and within the function triggered by mcps_rx_cb, I added a routine to extract and send a fixed number of CIR samples (pairs of real and imaginary values) via USB after reception.

With this setup, when I use the CLI commands initf and respf to start a DS-TWR session, I expect each ranging exchange to produce one set of CIR samples along with the ranging result. I have configured the number of CIR samples to 16 in the firmware. After each successful ranging session, report_cb is triggered and both CIR and ranging results are sent over USB.


The question is:

When I test this setup using two terminals — one running initf (tag) and the other respf (anchor) —

  • The tag (initf) side behaves as expected: it outputs 16 CIR samples per ranging session.
  • But the anchor (respf) side outputs 32 CIR samples per session, which seems to indicate that CIR capture is being triggered twice per session.

Since I’m using DS-TWR, I would expect only one reception per device per round.
So my question is:

Why is the anchor capturing CIR data twice per ranging session, while the tag only captures once?

Is this expected behavior under DS-TWR?

Any clarification or insight would be greatly appreciated.

Thanks in advance!

1 Like

In DS-TWR, three messages are exchanged between the tag and anchor:

  1. Tag → Anchor: Poll message (initiates ranging)
  2. Anchor → Tag: Response message
  3. Tag → Anchor: Final message (contains timing information)

So the expected CIR capture behavior should be:

  • Tag side: Receives 1 message (the Response) → 16 CIR samples
  • Anchor side: Receives 2 messages (Poll + Final) → 32 CIR samples

Your observation is actually correct and expected behaviour. The anchor node receives both the initial Poll message and the Final message from the tag, while the tag only receives the Response message from the anchor.

Why this happens:

  • The anchor must receive both the Poll and Final messages to calculate the time-of-flight, as all timestamp information must be captured at least at the Anchor node to perform the distance calculation
  • Your CIR capture routine in mcps_rx_cb is correctly being triggered twice on the anchor side - once for each received message

This is not a bug in your implementation - it’s the normal DS-TWR protocol behaviour. If you only want to capture CIR once per ranging session, you could modify your code to only capture CIR on specific message types (e.g., only Poll messages), or add logic to track and skip subsequent CIR captures within the same ranging session.

Oz

1 Like

Hi OJackson,

Thank you for your reply, and apologies for my late response.

I now understand that in DS-TWR, the anchor receives two messages per ranging session, which explains why CIR capture is triggered twice.

I’m using the DWM3001CDK, and just to confirm my understanding — the CIR I’m capturing is essentially the CIR corresponding to each received packet involved in the ranging process, correct?

I have one more question.
When I switch to SS-TWR mode, the message flow should be:

  1. Tag → Anchor: Initiation
  2. Anchor → Tag: Response

According to the DWM3001CDK SDK Developer Guide, SS-TWR can be configured for ranging.

I tested this and measured CIR in SS-TWR mode, but I still observed the same behavior:

  • Tag: 16 samples per ranging session
  • Anchor: 32 samples per ranging session

In SS-TWR, I would have expected the anchor to receive only one message from the tag, so CIR capture should occur once, not twice.
Could you explain why the anchor is still capturing CIR twice in SS-TWR mode?

Thanks in advance for your insight.

1 Like

Hi @putitomato

That is indeed unexpected behaviour. In true SS-TWR, the anchor should only receive one message (initiation/poll message), so you should only see one CIR capture event.

The fact that you’re still seeing 32 captures is a bit confusing, but it suggests that a few potential unexpected things might be occurring (in no particular order):

Implementation Detail: The DWM3001CDK’s SS-TWR implementation might not be “pure” SS-TWR. Some implementations use a modified SS-TWR that still involves additional message exchanges for improved accuracy or reliability. Check if the SDK documentation mentions any implementation-specific details about their SS-TWR mode. I’m not the person to ask about the specifics of Qorvo’s implementation unfortunately, I just know how UWB works more generally.

Configuration Issue: Verify that SS-TWR is actually being used and not falling back to DS-TWR. You can check this by adding debug prints to identify which message types are being received, checking the actual message flow with a protocol analyser if you’ve got one (I don’t), or maybe examining the ranging session statistics

Is there any chance you could give me a printout of what’s going on? I’m assuming you’re using CLI here - do you have any debug info before ranging starts? For example, in my implementation, it gives a bunch of info regarding modes etc before ranging actually begins.

Oz