[DWM3001CDK]What should I do to start ranging between the two boards?

@kmatch98 Could you share the detail of fira_param?Tks so much.
controlee’s dest…addr is equal to controler’s short_addr,but it doesn’t work.

@kmatch98 Congrats, as Doney said, could you share some details of fira_param?
Tks so much.

@ kmatch98, Do we need to change SRC_ADDR and DST_ADDR each other?

Thanks for your patience, I was away from this for a couple of days. Here is my latest code for the function construct_fira_param_from_config from main_uwb.c. I modified the main_uwb function to pass the parameter ACCESSORY_RANGING_ROLE from main.c. This way I can keep the same set of code for the tag and anchor by just changing the ACCESSORY_RANGING_ROLE.

Note: I initially tried setting the Initiator/Responder based on AppSetFiraRole and AppGetFiraRole, but it acted strange, so I just fell back to passing a parameter to the main_uwb function.

Let me know if you have any success or if you encounter other difficulties.


construct_fira_param_from_config(fira_param_t *fira_param, fira_device_configure_t *config, int controller)

    char result[256];
    snprintf(result, sizeof(result), "construct_fira_param_from_config ->\n");            
    port_tx_msg(result, strlen(result));

    /*PHY config*/
    fira_param->dwt_config. txPreambLength = DWT_PLEN_64;
    fira_param->dwt_config. rxPAC     = DWT_PAC8;
    fira_param->dwt_config. dataRate  = DWT_BR_6M8;
    fira_param->dwt_config. phrMode   = DWT_PHRMODE_STD;
    fira_param->dwt_config. phrRate   = DWT_PHRRATE_STD;
    fira_param->dwt_config. sfdTO     = 65;             
    fira_param->dwt_config. stsMode   = DWT_STS_MODE_OFF;
    fira_param->dwt_config. stsLength = DWT_STS_LEN_64;
    fira_param->dwt_config. pdoaMode  = DWT_PDOA_M0;

    /* Configure specific fira app parameters */
    fira_param->dwt_config. sfdType   = (config->SP0_PHY_Set == BPRF_SET_2)?(DWT_SFD_IEEE_4Z):(DWT_SFD_IEEE_4A);
    fira_param->dwt_config. chan      = config->Channel_Number;
    fira_param->dwt_config. txCode    = config->Preamble_Code;
    fira_param->dwt_config. rxCode    = config->Preamble_Code;

    /* MAC configure */
    // fira_param->short_addr = AR2U16(config->SRC_ADDR); /* see below */
    fira_param->session_id = config->Session_ID;
    fira_param->session.initiation_time_ms = config->UWB_Init_Time_ms;

    snprintf(result, sizeof(result), "construct - 0\n");            
    port_tx_msg(result, strlen(result));

    snprintf(result, sizeof(result), "controller: %d\n", controller);            
    port_tx_msg(result, strlen(result));


    snprintf(result, sizeof(result), "AppGetFiRaRole: %d\n", AppGetFiRaRole());            
    port_tx_msg(result, strlen(result));

    if (controller == 1) { /* Initiator: 1 */
            fira_param->session.device_type = FIRA_DEVICE_TYPE_CONTROLLER;
            fira_param->session.device_role = FIRA_DEVICE_ROLE_INITIATOR;
            fira_param->short_addr = 98; /* override settings in <default_config.h> */
            fira_param->session.destination_short_address = 9;

    } else { /* Responder: 0 */
            fira_param->session.device_type = FIRA_DEVICE_TYPE_CONTROLEE;
            fira_param->session.device_role = FIRA_DEVICE_ROLE_RESPONDER;
            fira_param->short_addr = 9;
            fira_param->session.destination_short_address = 98;

    snprintf(result, sizeof(result), "construct - 1\n");            
    port_tx_msg(result, strlen(result));
    /* Only supporting Deferred DS-TWR */
    fira_param->session.ranging_round_usage = config->Ranging_Round_Usage;
    fira_param->session.rframe_config = config->Rframe_Config;
    fira_param->session.sfd_id = (config->SP0_PHY_Set == BPRF_SET_2)?(FIRA_SFD_ID_2):(FIRA_SFD_ID_0);
    fira_param->session.slot_duration_rstu = config->Slot_Duration_RSTU;
    fira_param->session.block_duration_ms = config->Block_Duration_ms;
    fira_param->session.round_duration_slots = config->Round_Duration_RSTU / config->Slot_Duration_RSTU;
    fira_param->session.multi_node_mode = config->Multi_Node_Mode;

    fira_param->session.round_hopping = config->Round_Hopping;
    fira_param->session.report_tof = config->ToF_Report;

    snprintf(result, sizeof(result), "----- short_addr: 0x%04x\n", fira_param->short_addr);            
    port_tx_msg(result, strlen(result));
    snprintf(result, sizeof(result), "----- session_id: %d\n", fira_param->session_id);            
    port_tx_msg(result, strlen(result));
    // fira_param->session.destination_short_address = AR2U16(config->DST_ADDR); /* see above */
    snprintf(result, sizeof(result), "----- destination_short_addr: 0x%04x\n", fira_param->session.destination_short_address);            
    port_tx_msg(result, strlen(result));

    fira_param->controlees_params.n_controlees = config->Number_of_Controlee;
    fira_param->controlees_params.controlees[0].address = fira_param->session.destination_short_address;

    fira_param->session.vupper64[7] = config->Vendor_ID[0];
    fira_param->session.vupper64[6] = config->Vendor_ID[1];
    fira_param->session.vupper64[5] = config->Static_STS_IV[0];
    fira_param->session.vupper64[4] = config->Static_STS_IV[1];
    fira_param->session.vupper64[3] = config->Static_STS_IV[2];
    fira_param->session.vupper64[2] = config->Static_STS_IV[3];
    fira_param->session.vupper64[1] = config->Static_STS_IV[4];
    fira_param->session.vupper64[0] = config->Static_STS_IV[5];

    /* Get parameters from global configuration. */
    fira_param->session.channel_number = config->Channel_Number;
    fira_param->session.preamble_code_index = config->Preamble_Code;

    /* Do not change below parameters */
    fira_param->session.rx_antenna_selection = 0;
    fira_param->session.rx_antenna_pair_azimuth = 0xFF;
    fira_param->session.rx_antenna_pair_elevation = 0xFF;
    fira_param->session.tx_antenna_selection = 1;
    fira_param->session.rx_antenna_switch = 0;
    fira_param->session.aoa_result_req = 0;
    fira_param->session.report_aoa_azimuth = 0;
    fira_param->session.report_aoa_fom = 0;

    snprintf(result, sizeof(result), "construct_fira_param_from_config <-\n");            
    port_tx_msg(result, strlen(result));

1 Like

@kmatch98 @carlos.silva Tks both very much, we finally got double-sided two way ranging working.

1 Like

@kmatch98 We face another problem when want to range with two responseres. We changed the ‘destination_short_address’ from 9 to 10, but the results are the same for 9. We do not know why it does not reset successfully.

    if(evt.status == osEventTimeout)
        snprintf(result, sizeof(result), "osEventTimeout ->\n");            
        port_tx_msg(result, strlen(result));

        construct_fira_param_from_config(fira_param, (void*)&AppConfigGet()->s.fira_config, 1,10);
        fira_helper_controller_1((void const *)fira_param);


    void fira_helper_controller_1(void const *arg)
        fira_param = (fira_param_t *)arg;


@kmatch98 Thank u so much.After changing addr, it works well. :+1: :+1: :+1:
@carlos.silva Thank u for your patient guidance.At now i finally understand your words.

1 Like

@Doney ,Congrats. Do you try to range with two responseres at the same time?

sorry,i didn’t try that because i just have only two boards.

Thanks for all the good feedback. Glad y’all are getting it working. Please send an update if you ever get the multiple tags working.


I’m trying to replicate your results, but I’m a little stuck.
For your final version, did you maintain your changes in the _defaultTask function or just used the original one and just changed the construct_fira_param_from_config one?
It would be great if you can upload the project to compare and check if I messed up, following the conversation…

I’ve been able to flash the DWM3001CDK boards and I get the message:

00> _defaultTask →

(or Responder for the other one) but it gets stuck in that print and doesn’t seem to be doing any ranging yet…


Hey @barratia I solved the problem by setting up before the while the receptor / initiator.
I’m able to get the data and it’s working.
Here the code updated :

static void _defaultTask(const void *arg)
    char str[256];
    osEvent evt;
    fira_param_t *fira_param = get_fira_config();
    param_block_t* app_config = AppConfigGet();

    char result[256];
    snprintf(result, sizeof(result), "_defaultTask ->\n");            
    port_tx_msg(result, strlen(result));


    if (ranging_role == 1) {
      construct_fira_param_from_config(fira_param, (void*)&AppConfigGet()->s.fira_config, 1);
      fira_helper_controller((void const *)fira_param);

    } else {
      construct_fira_param_from_config(fira_param, (void*)&AppConfigGet()->s.fira_config, 0);
      fira_helper_controlee((void const *)fira_param);

        evt = osSignalWait(Signal, 10000);
        osMutexWait(defaultTask.MutexId, 0);


        if(evt.status == osEventTimeout)




        snprintf(result, sizeof(result), "ResumeUWBTasks: evt.value_signals %d\n", evt.value.signals);            
        port_tx_msg(result, strlen(result));

        snprintf(result, sizeof(result), "_defaultTask - AppGetFiraRole: %d\n", AppGetFiRaRole());            
        port_tx_msg(result, strlen(result));

        if (ranging_role == 1) {
          construct_fira_param_from_config(fira_param, (void*)&AppConfigGet()->s.fira_config, 1);
          fira_helper_controller((void const *)fira_param);

        } else {
          construct_fira_param_from_config(fira_param, (void*)&AppConfigGet()->s.fira_config, 0);
          fira_helper_controlee((void const *)fira_param);

    snprintf(result, sizeof(result), "_defaultTask <-\n");            
    port_tx_msg(result, strlen(result));

1 Like

@kmatch98 @zyliu @Doney Any updates about multiple responseres at the same time? I will try to spend some times on it.

Which function should I change when I want to start ranging between two boards in the latest version of qorvo (Qorvo_Nearby_Interaction_3_1_0)?
I would be so appreciate if someone give some help.

Hello @Neuse !

For TWR between two boards, I recommend you use the Software Preview:

The DWM3001CDK Software Preview is available on the DWM3001CDK product page [Tab Documents]:

Is named “DWM3001CDK DK Software, Sources, Tools and Developer Guide”, here is the direct link if preferred:
DWM3001CDK DK Software, Sources, Tools and Developer Guide

There you will find applications for FiRa TWR implementing UCI (UWB Command Interface) and a CLI (Command Line Interface) app.
I recommend you try the CLI first, you can flash two boards and explore the configuration commands, then use “respf” to start one board as a responder and “initf” to start the other board as an initiator, then they will start TWR immediately.

Kind regards!

Hi @carlos.silva !

I successfully obtained “DWM3001CDK DK Software, Sources, Tools and Developer Guide”.
I would like to develop using Murata Type2AB (nRF52840 +QM33120W), is it compatible?

Thank you!

I found the QM33120W software at
QM33 DK Software, Sources, Tools and Developer Guide
I’ll try working on this.

1 Like

hi, did you got any success with multiples responders, could you share the code in that case?.
Thank you

Hi @carlos.silva
I tried implementing CLI app, I’m able to observe TWR between the boards. I then flashed UCI build and tried running the python script in each boards (one as controller and other as controlee) I’m able to see the variation in distance between the boards , but the AoaAzimuth and AoaDestinationAzimuth remains 0. Could you please assist?
Thank You

Hi @Bhargavi !

What boards are you using? The DWM3001CDK does not support AoA, so angles will always be zero.

Kind regards!