Sending and recv works fine in debug mode but not release

Hello fellas,

I have an annoying issue where my program works fine in debug mode but not when I try to run it regular. My setup is that I have three DWM1001-dev boards and two of them is working as anchors and one as a tag.

As I said in the subject, I have a problem when it’s in running mode but not in an debug mode.

My code works like this in the tag. First it sends a message to an anchor and that is working just fine, and then it should start listening for a message that is meant for the tag that the anchor is going to send.

[code] dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
dwt_writetxdata(sizeof(init_tx_range_msg), init_tx_range_msg, 0); /* Zero offset in TX buffer. /
dwt_writetxfctrl(sizeof(init_tx_range_msg), 0, 0); /
Zero offset in TX buffer, ranging. */

            int ret;

            ret = dwt_starttx(DWT_START_TX_IMMEDIATE);
            if(ret == DWT_SUCCESS) {
                    printf("range init sent\r\n");
                    init_rx_range_msg[5] = id[0];
                    init_rx_range_msg[6] = id[1];
                    init_rx_range_msg[7] = id[2];
                    init_rx_range_msg[8] = id[3];

                    /* Poll DW1000 until TX frame sent event set. See NOTE 6 below. */
                    while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
                    { };
                    /* Clear TXFRS event. */
                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
                    bool resp = true;
                    int frame_len;
                    int frames = 0;
                    dwt_setrxtimeout(0);


                    while(frames < 10) {
                            dwt_rxenable(DWT_START_RX_IMMEDIATE);
                            while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))
                            { };
                            if (status_reg & SYS_STATUS_RXFCG)
                            {
                                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);

                                    frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
                                    if (frame_len <= RX_BUF_LEN)
                                    {
                                            dwt_readrxdata(rx_buffer, frame_len, 0);
                                    }
                                    //if(memcmp(rx_buffer, init_tx_range_msg, ALL_MSG_COMMON_LEN) == 0){
                                    rx_buffer[ALL_MSG_SN_IDX] = 0;
                                    int loopIndex;
                                    for(loopIndex = 0; loopIndex < sizeof(rx_buffer); loopIndex = loopIndex + 1) {
                                            printf("%x ", rx_buffer[loopIndex]);
                                    }
                                    printf("\r\n");
                                    //}

                            }else{
                                    
                                    /* Clear RX error/timeout events in the DW1000 status register. */
                                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR);

                                    /* Reset RX to properly reinitialise LDE operation. */
                                    dwt_rxreset();
                            }

                            frames++;
                    }[/code]

The anchor of the other hand, receives the message and start to send its own message to the other anchor, how ever I can’t see those messages being transfer in the tag (using UART) when in running mode, but I can see that when I run debug mode on the anchor that receives the message from the tag.
Here is the code for the anchor.

[code]for(t = 0; t < 2; t++) {
/* Retrieve poll reception timestamp. */
poll_rx_ts = get_rx_timestamp_u64();

                            /* Compute final message transmission time. See NOTE 7 below. */
                            uint32 resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;
                            dwt_setdelayedtrxtime(resp_tx_time);
                            dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
                            dwt_writetxdata(sizeof(rx_poll_msg), rx_poll_msg, 0); /* Zero offset in TX buffer. */
                            dwt_writetxfctrl(sizeof(rx_poll_msg), 0, 1); /* Zero offset in TX buffer, ranging. */

                            /* Start transmission, indicating that a response is expected so that reception is enabled automatically after the frame is sent and the delay
                             * set by dwt_setrxaftertxdelay() has elapsed. */

                            dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED);


                            /* Poll for reception of a frame or error/timeout. See NOTE 6 below. */
                            while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))
                            { };

     #if 0  // include if required to help debug timeouts.
                            int temp = 0;
                            if(status_reg & SYS_STATUS_RXFCG )
                                    temp =1;
                            else if(status_reg & SYS_STATUS_ALL_RX_TO )
                                    temp =2;
                            if(status_reg & SYS_STATUS_ALL_RX_ERR )
                                    temp =3;
     #endif

                            /* Increment frame sequence number after transmission of the poll message (modulo 256). */
                            frame_seq_nb++;
                            if (status_reg & SYS_STATUS_RXFCG)
                            {
                                    uint32 frame_len;

                                    /* Clear good RX frame event in the DW1000 status register. */
                                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);

                                    /* A frame has been received, read it into the local buffer. */
                                    frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
                                    if (frame_len <= RX_BUF_LEN)
                                    {
                                            dwt_readrxdata(rx_buffer, frame_len, 0);
                                    }

                                    /* Check that the frame is the expected response from the companion "SS TWR responder" example.
                                     * As the sequence number field of the frame is not relevant, it is cleared to simplify the validation of the frame. */
                                    rx_buffer[ALL_MSG_SN_IDX] = 0;
                                    if (memcmp(rx_buffer, tx_resp_msg, ALL_MSG_COMMON_LEN) == 0)
                                    {
                                            uint32 poll_tx_ts, resp_rx_ts, poll_rx_ts, resp_tx_ts;
                                            int32 rtd_init, rtd_resp;
                                            float clockOffsetRatio;
                                            double tof;
                                            double distance;
                                            /* Retrieve poll transmission and response reception timestamps. See NOTE 9 below. */
                                            poll_tx_ts = dwt_readtxtimestamplo32();
                                            resp_rx_ts = dwt_readrxtimestamplo32();

                                            /* Read carrier integrator value and calculate clock offset ratio. See NOTE 11 below. */
                                            clockOffsetRatio = dwt_readcarrierintegrator() * (FREQ_OFFSET_MULTIPLIER * HERTZ_TO_PPM_MULTIPLIER_CHAN_5 / 1.0e6);

                                            /* Get timestamps embedded in response message. */
                                            resp_msg_get_ts(&rx_buffer[RESP_MSG_POLL_RX_TS_IDX], &poll_rx_ts);
                                            resp_msg_get_ts(&rx_buffer[RESP_MSG_RESP_TX_TS_IDX], &resp_tx_ts);

                                            /* Compute time of flight and distance, using clock offset ratio to correct for differing local and remote clock rates */
                                            rtd_init = resp_rx_ts - poll_tx_ts;
                                            rtd_resp = resp_tx_ts - poll_rx_ts;

                                            tof = ((rtd_init - rtd_resp * (1.0f - clockOffsetRatio)) / 2.0f) * DWT_TIME_UNITS; // Specifying 1.0f and 2.0f are floats to clear warning
                                            distance = tof * SPEED_OF_LIGHT;
                                            //fflush();
                                            //deca_sleep(1000);
                                            vTaskDelay(xDelay);


                                    }
                            }
                            else
                            {
                                    /* Clear RX error/timeout events in the DW1000 status register. */
                                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR);

                                    /* Reset RX to properly reinitialise LDE operation. */
                                    dwt_rxreset();
                            }
                    }[/code]

As you see, I try to send the message to the other anchor twice, but I don’t know if it does or not, I’ve no idea how I can print that or something (sense the anchor doesn’t have UART).

Appreciate the help!

Thanks.

After some further investigation, I can see that my recv is doing something it shouldn’t. I goes brilliant to receive one message but I can’t see anymore than that, even though I know it’s three messages being sent from one anchor to another anchor.

This is my code right now for the receiving part.

[code]while(frames < 1000) {
dwt_rxenable(0);
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR))){};
if (status_reg & SYS_STATUS_RXFCG)
{
//dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
//dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_GOOD);
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
if (frame_len <= RX_BUF_LEN)
{
dwt_readrxdata(rx_buffer, frame_len, 0);
}
//if(frames != 0){
//if(memcmp(rx_buffer, init_tx_range_msg, ALL_MSG_COMMON_LEN) == 0){
rx_buffer[ALL_MSG_SN_IDX] = 0;
int loopIndex;
for(loopIndex = 0; loopIndex < sizeof(rx_buffer); loopIndex = loopIndex + 1) {
printf("%x “, rx_buffer[loopIndex]);
}
printf(”\r\n");

                                    //}

                            }else{
                                    /* Clear RX error/timeout events in the DW1000 status register. */
                                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR);

                                    /* Reset RX to properly reinitialise LDE operation. */
                                    dwt_rxreset();
                            }
                            deca_sleep(10);
                            frames++;
                    }[/code]

And as I said, I can only see the first message and then it seems like it won’t go into receiving mode anymore.

After further debugging I got it to work sometimes… Sometimes my listener gets the messages and print them out really nicely, but sometimes it does not work at all.

This is my solution right now.

[code] bool resp = true;
int frame_len;
int frames = 0;

                    while(resp) {
                            while (!(
                            (status_reg = dwt_read32bitreg(SYS_STATUS_ID))
                             & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
                             {};
                            if (status_reg & SYS_STATUS_RXFCG)
                            {
                                    //dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
                                    //dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_GOOD);
                                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
                                    //dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR);
                                    frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
                                    if (frame_len <= RX_BUF_LEN)
                                    {
                                            dwt_readrxdata(rx_buffer, frame_len, 0);
                                    }
                                    
                                    //if(frames != 0){
                                    
                                    
                                    printf("%d\r\n", frames);
                                    if(memcmp(rx_buffer, init_tx_range_msg, ALL_MSG_COMMON_LEN) == 0){
                                      resp = false;
                                      rx_buffer[ALL_MSG_SN_IDX] = 0;
                                      int loopIndex;
                                      for(loopIndex = 0; loopIndex < sizeof(rx_buffer); loopIndex = loopIndex + 1) {
                                            printf("%x ", rx_buffer[loopIndex]);
                                      }
                                      printf("\r\n");
                                    }else{
                                      dwt_rxenable(0);
                                    }
                            }else{
                              printf("NO!");
                                    /* Clear RX error/timeout events in the DW1000 status register. */
                                    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR);

                                    /* Reset RX to properly reinitialise LDE operation. */
                                    dwt_rxreset();
                            }
                            frames++;
                    }[/code]

And to your knowledge, it should be 20 frames sense the anchor is sending 10 messages to the other anchor and that anchor sends 10 messages, and I’ve no deca_sleep or vTaskDelay in does functions.

Hi Deggo,

Do you have the same optimization level in both debug and release mode ? Or any other preprocessor difference ?

A slight variation of the running time of the program can actually disturb the system, in particular with delayed transmission.

Thanks
Yves