SIDEKIQ: fix tx time protection

This commit is contained in:
Xavier Arteaga 2020-10-26 15:45:21 +01:00 committed by Xavier Arteaga
parent ecf668ee9e
commit b3d9a94dd5
3 changed files with 43 additions and 10 deletions

View File

@ -898,6 +898,7 @@ int rf_skiq_send_timed_multi(void* h_,
if (is_start_of_burst) {
if (has_time_spec) {
h->next_tstamp = time_to_tstamp(h, secs, frac_secs);
SKIQ_RF_DEBUG("[Tx SOB] ts=%ld\n", h->next_tstamp);
} else {
h->next_tstamp = rf_skiq_card_read_rf_timestamp(&h->cards[0]);
h->next_tstamp += (uint64_t)round(h->current_srate_hz / 10); // increment a 10th of a second

View File

@ -100,4 +100,11 @@ extern uint32_t rf_skiq_logging_level;
} \
} while (false)
#endif // SRSRAN_RF_SKIQ_IMP_CFG_H
#define SKIQ_RF_ERROR(...) \
do { \
if (rf_skiq_logging_level >= SKIQ_LOG_ERROR) { \
fprintf(stdout, "[SKIQ RF ERROR] " __VA_ARGS__); \
} \
} while (false)
#endif // SRSLTE_RF_SKIQ_IMP_CFG_H

View File

@ -84,25 +84,44 @@ static void* writer_thread(void* arg)
break;
}
// If the ring buffer read resulted in timeout
if (n == SRSRAN_ERROR_TIMEOUT) {
continue;
}
// Ignore blocks with TS=0
if (q->p_tx_block->timestamp == 0) {
if (p_tx_block->timestamp == 0) {
continue;
}
// Check if the timestamp is the past (this can be caused by sample rate change)
if (last_tx_ts > q->p_tx_block->timestamp) {
skiq_read_curr_tx_timestamp(q->card, q->hdl, &last_tx_ts);
if (last_tx_ts > q->p_tx_block->timestamp) {
ERROR("Tx block (ts=%ld) is in the past (%ld), ignoring\n", q->p_tx_block->timestamp, last_tx_ts);
if (last_tx_ts > p_tx_block->timestamp) {
// Get current RF timestamp
uint64_t curr_tx_ts = 0UL;
skiq_read_curr_tx_timestamp(q->card, q->hdl, &curr_tx_ts);
// Avoids giving a block to the FPGA that has already passed, otherwise it could hang forever
if (curr_tx_ts > p_tx_block->timestamp) {
SKIQ_RF_ERROR("[Tx %d:%d block] Tx block (ts=%ld) is in the past (last_tx_ts=%ld, curr_tx_ts=%ld), ignoring\n",
q->card,
(int)q->hdl,
q->p_tx_block->timestamp,
last_tx_ts,
curr_tx_ts);
continue;
}
}
last_tx_ts = q->p_tx_block->timestamp + q->block_size;
last_tx_ts = p_tx_block->timestamp + q->block_size;
// If the ring-buffer did not return with error code...
if (n > SRSRAN_SUCCESS) {
SKIQ_RF_DEBUG(
"[Tx %d:%d block] ts=%ld; nsamples=%d;\n", q->card, (int)q->hdl, p_tx_block->timestamp, q->block_size);
SKIQ_RF_DEBUG("[Tx %d:%d block] ts=%ld; nsamples=%d; last_tx_ts=%ld;\n",
q->card,
(int)q->hdl,
p_tx_block->timestamp,
q->block_size,
last_tx_ts);
if (skiq_transmit(q->card, q->hdl, p_tx_block, NULL) < 0) {
ERROR("Error transmitting card %d\n", q->card);
@ -247,7 +266,7 @@ void rf_skiq_tx_port_end_of_burst(rf_skiq_tx_port_t* q)
// Write block into the ring-buffer
srsran_ringbuffer_write_block(&q->rb, q->p_tx_block, q->p_block_nbytes);
SKIQ_RF_DEBUG("[Tx %d:%d] Padding offset=%d; n=%d; ts=%ld\n",
SKIQ_RF_DEBUG("[Tx EOB %d:%d] Padding offset=%d; n=%d; ts=%ld\n",
q->card,
(int)q->hdl,
q->next_offset,
@ -268,6 +287,11 @@ int rf_skiq_tx_port_send(rf_skiq_tx_port_t* q, const cf_t* buffer, uint32_t nsam
return nsamples;
}
// If no data and no block has started, early return
if (buffer == NULL && q->next_offset == 0) {
return nsamples;
}
pthread_mutex_lock(&q->mutex);
// Calculate destination where IQ shall be stored
@ -390,6 +414,7 @@ int rf_skiq_rx_port_init(rf_skiq_rx_port_t* q, uint8_t card, skiq_rx_hdl_t hdl,
void rf_skiq_rx_port_free(rf_skiq_rx_port_t* q)
{
srsran_ringbuffer_free(&q->rb);
}