I am trying a simple multi sided tag-anchor data exchange with distance. Problem is anchors dont know IDs of the tags. So tags need to broadcast their ID before responsing anchor’s polling for distance measurement. And anchors need to check if there is any coming message so they can save the tag’s ID and start polling to those IDs. I dont know why but anchors can get response to their polling but they can not get the other message.
void distance_uwb_run(target_device_info *target)
{
uint16_t counter = 0;
/* Activate reception immediately. */
dwt_rxenable(DWT_START_RX_IMMEDIATE);
do
{
counter++;
/* Wait for reception, timeout or error interrupt flag*/
while (!(to_int_flag|| er_int_flag));
if(counter == 10)
{
break;
}
}while (!rx_int_flag);
if(rx_int_flag)
{
uint32 frame_len;
/* 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_BUFFER_LEN)
{
dwt_readrxdata(rx_hsr_msg, frame_len, 0);
}
if (data_header_check(rx_hsr_msg, HAND_SHAKE_CODE) == true)
{
uint8_t temp_id[ID_LENGTH + 1] = {0};
/*Reseting receive interrupt flag*/
rx_int_flag = 0;
memcpy(temp_id, rx_hsr_msg, ID_LENGTH);
if(is_id_hand_shaked(temp_id) == false)
{
uint8_t hs_device_count = 0;
int ret;
/* Hand Shaked Device Count */
hs_device_count = get_config(HAND_SHAKED_DEVICE_CONF);
/* Hand Shaked Device ID */
memcpy(tag[hs_device_count].id, temp_id, ID_LENGTH);
printf("ID : %s, count: %d\r\n", temp_id, hs_device_count);
/* Enter Time */
//tag[hs_device_count].entry_time = get_time();
/* Hand Shaked Device Count + 1 */
hs_device_count++;
set_config(HAND_SHAKED_DEVICE_CONF, hs_device_count);
}
}
}
if (to_int_flag || er_int_flag)
{
dwt_rxreset();
/*Reseting interrupt flag*/
to_int_flag = 0 ;
er_int_flag = 0 ;
}
//static uint8_t temp_buf[12] = {0x41,0x88,0,0xca,0xde,'W','A','V','E',0xe0,0,0};
/* Making ready Tx Buffer for distance polling */
make_frame(DISTANCE_CODE, target->id, tx_dist_msg);
dwt_writetxdata(sizeof(tx_dist_msg), tx_dist_msg, 0); /* Zero offset in TX buffer. */
dwt_writetxfctrl(sizeof(tx_dist_msg), 0, 1); /* Zero offset in TX buffer, ranging. */
dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);
counter = 0;
do
{
counter++;
if(counter >= 1000)
{
break;
}
}while (!(tx_ds_int_flag));
if (tx_ds_int_flag)
{
/*Reseting tx interrupt flag*/
tx_ds_int_flag = 0 ;
}
/* Wait for reception, timeout or error interrupt flag*/
while (!(rx_int_flag || to_int_flag|| er_int_flag));
if (rx_int_flag)
{
uint32 frame_len;
uint8_t *device_id;
/* 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_BUFFER_LEN)
{
dwt_readrxdata(rx_dist_msg, frame_len, 0);
device_id = get_config_addr(ID_CONF);
/* 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_BUFFER_LEN)
{
dwt_readrxdata(rx_dist_msg, frame_len, 0);
}
/* As the sequence number field of the frame is not relevant, it is cleared to simplify the validation of the frame. */
if(data_header_check(rx_dist_msg, DISTANCE_CODE) == true)
{
uint32 poll_tx_ts, resp_rx_ts, poll_rx_ts, resp_tx_ts;
int32 rtd_init, rtd_resp;
float clockOffsetRatio;
uint8_t temp_id[ID_LENGTH + 1] = {0};
/* Retrieve poll transmission and response reception timestamps. See NOTE 4 below. */
poll_tx_ts = dwt_readtxtimestamplo32();
resp_rx_ts = dwt_readrxtimestamplo32();
/* Read carrier integrator value and calculate clock offset ratio. See NOTE 6 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_dist_msg[RESP_MSG_POLL_RX_TS_IDX], &poll_rx_ts);
resp_msg_get_ts(&rx_dist_msg[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;
memcpy(temp_id, rx_dist_msg + ID_LENGTH, ID_LENGTH);
printf("ID : %s, Distance : %f\r\n", temp_id, distance);
target->distance = distance;
/*Reseting receive interrupt flag*/
rx_int_flag = 0;
}
}
}
if (to_int_flag || er_int_flag)
{
dwt_rxreset();
/*Reseting interrupt flag*/
to_int_flag = 0 ;
er_int_flag = 0 ;
}
if((timeot_counter % 5) == 0)
{
/* Reset RX to properly reinitialise LDE operation. */
dwt_rxreset();
}
/* Execute a delay between ranging exchanges. */
// deca_sleep(RNG_DELAY_MS);
}`
tag
`void distance_uwb_response(target_device_info *target)
{
static uint8_t counter = 0;
counter++;
if((counter % 1) == 0)
{
/* Making ready Tx Buffer for hand shake polling */
make_frame(HAND_SHAKE_CODE, NULL, tx_hs_msg);
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
dwt_writetxdata(sizeof(tx_hs_msg), tx_hs_msg, 0); /* Zero offset in TX buffer. */
dwt_writetxfctrl(sizeof(tx_hs_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_IMMEDIATE);
if (tx_int_flag)
{
/*Reseting tx interrupt flag*/
tx_int_flag = 0 ;
}
}
/* Activate reception immediately. */
dwt_rxenable(DWT_START_RX_IMMEDIATE);
/* Wait for reception, timeout or error interrupt flag*/
while (!(rx_int_flag || to_int_flag|| er_int_flag));
if (rx_int_flag)
{
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_RXFL_MASK_1023;
if (frame_len <= RX_BUFFER_LEN)
{
dwt_readrxdata(rx_dist_msg, frame_len, 0);
}
if (data_header_check(rx_dist_msg, DISTANCE_CODE) == true)
{
uint32 resp_tx_time;
int ret;
/* Making ready Tx Buffer for command send */
make_frame(DISTANCE_CODE, target->id, tx_dist_msg);
/* Retrieve poll reception timestamp. */
poll_rx_ts = get_rx_timestamp_u64();
/* Compute final message transmission time. See NOTE 7 below. */
resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;
dwt_setdelayedtrxtime(resp_tx_time);
/* Response TX timestamp is the transmission time we programmed plus the antenna delay. */
resp_tx_ts = (((uint64)(resp_tx_time & 0xFFFFFFFEUL)) << 8) + TX_ANT_DLY;
/* Write all timestamps in the final message. See NOTE 8 below. */
resp_msg_set_ts(&tx_dist_msg[RESP_MSG_POLL_RX_TS_IDX], poll_rx_ts);
resp_msg_set_ts(&tx_dist_msg[RESP_MSG_RESP_TX_TS_IDX], resp_tx_ts);
/* Write and send the response message */
dwt_writetxdata(sizeof(tx_dist_msg), tx_dist_msg, 0); /* Zero offset in TX buffer. See Note 5 below.*/
dwt_writetxfctrl(sizeof(tx_dist_msg), 0, 1); /* Zero offset in TX buffer, ranging. */
ret = dwt_starttx(DWT_START_TX_DELAYED);
//ret = dwt_starttx(DWT_START_TX_IMMEDIATE);
/* If dwt_starttx() returns an error, abandon this ranging exchange and proceed to the next one. */
if (ret == DWT_SUCCESS)
{
/*Waiting for transmission success flag*/
while (!(tx_int_flag))
{};
if (tx_int_flag)
{
/*Reseting tx interrupt flag*/
tx_int_flag = 0 ;
}
}
else
{
dwt_rxreset();
}
/*Reseting receive interrupt flag*/
rx_int_flag = 0;
}
}
if (to_int_flag || er_int_flag)
{
/* Reset RX to properly reinitialise LDE operation. */
dwt_rxreset();
/*Reseting interrupt flag*/
to_int_flag = 0 ;
er_int_flag = 0 ;
}
}`
Hi,
I am trying a simple multi sided tag-anchor data exchange with distance. Problem is anchors dont know IDs of the tags. So tags need to broadcast their ID before responsing anchor’s polling for distance measurement. And anchors need to check if there is any coming message so they can save the tag’s ID and start polling to those IDs. I dont know why but anchors can get response to their polling but they can not get the other message.