Force RX to stop and start to TX, application get TX_DONE but frame loss in air

We made a board with DWM1001 module and write our code with deca driver to control DW1000. In our application DW1000 need to send a frame exactly every 100ms. During other time it should work in receiving mode, but probably there is nothing to receive.

So I start a timer every time the module enters RX mode. After timeout I issue TRXOFF and RX reset, then start a delayed transmit. It worked as expected on my first board. But when I tried to run it on other boards, I found on some boards many transmitted frames (30~70%, depending on board) cannot be heard by other receiving modules. The firmware seems good with API return code and TX_DONE interrupt bit. Just frames lost in air – at least nobody receive it.

Sometimes the frame loss did not start at beginning. It get worse after for example, 10+ minutes.

Anyone has similar experience or made such application successfully (Force RX to stop and switch to TX, as normal operation flow) or could you give me some advice? Many thanks.

Hello ccwan,

Could you send a snippet of your code ?

I think you’re approach is not correct.

One you program the DW1000 to perform a Delayed Tx. The device will remain in an IDLE state until the Tx is perform. It cannot go to Rx at the mean time.

My understanding is that you are using delayed Tx to 100ms, and then enable RX ? If this is what you are doing, the Rx will not be performed until the Tx is done, 100 ms later. Also, when the device is in Rx, it must quit this mode before beeing able to perform a Tx again. How do you do that in the situation where you do not receive a frame ? The max timeout for DW1000 is 65ms so there may be an issue there. And if you use no timeout, then I suspect the next Tx will never happen as you will remain in Rx state.

Hope it helps,

Hi Yves thanks for your answer.

I understand that DW1000 should not start RX after a delayed transmitting is scheduled. I enable RX in TX Done callback. And I know that the max TO is ~65ms. So I enable RX no timeout and instead start a timer to wait for 100ms.

static void tx_conf_cb(const dwt_cb_data_t *cb_data)
    err_code = app_timer_start(m_rx_timer, __about_96_millsec, NULL);
    m_rx_timer_start_tick = app_timer_cnt_get();

In the time callback I stop RX (call dwt_forcetrxoff and dwt_rxreset in timer callback).

static void rx_timeout_handler(void * p_context)
   // call  dwt_starttx(DWT_START_TX_DELAYED)) here

In RX OK callback just re-enable RX. To avoid the timing competition, I will not re-enable RX if there is less than 4 ms left before the timer timeout.

static void rx_ok_cb(const dwt_cb_data_t *cb_data)
    uint32_t curr = app_timer_cnt_get();
    uint32_t consumed = app_timer_cnt_diff_compute(curr, m_rx_timer_start_tick);
    if ((consumed > 0) && (consumed < _about_4_millsec )) 
         dwt_rxenable(DWT_START_RX_IMMEDIATE | DWT_NO_SYNC_PTRS);

Now we know the sync loss is related to some power supply issue in hardware. But I still wonder if my scheme has problem (stop RX by call dwt_forcetrxoff and dwt_rxreset). forcetrxoff sounds like an error handle function. It’s all right to call it so frequently as a step in normal process?

The second question is, if there is timing conflict between timer timeout and a RX OK interrupt? I called trxoff in timer callback so may I assume I will not see RX OK interrupt until next RX enable?