SIDEKIQ: fix tx time protection

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent ecf668ee9e
commit b3d9a94dd5

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

@ -100,4 +100,11 @@ extern uint32_t rf_skiq_logging_level;
} \ } \
} while (false) } 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

@ -84,25 +84,44 @@ static void* writer_thread(void* arg)
break; break;
} }
// If the ring buffer read resulted in timeout
if (n == SRSRAN_ERROR_TIMEOUT) {
continue;
}
// Ignore blocks with TS=0 // Ignore blocks with TS=0
if (q->p_tx_block->timestamp == 0) { if (p_tx_block->timestamp == 0) {
continue; continue;
} }
// Check if the timestamp is the past (this can be caused by sample rate change) // Check if the timestamp is the past (this can be caused by sample rate change)
if (last_tx_ts > q->p_tx_block->timestamp) { if (last_tx_ts > 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) { // Get current RF timestamp
ERROR("Tx block (ts=%ld) is in the past (%ld), ignoring\n", q->p_tx_block->timestamp, last_tx_ts); 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; 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 the ring-buffer did not return with error code...
if (n > SRSRAN_SUCCESS) { if (n > SRSRAN_SUCCESS) {
SKIQ_RF_DEBUG( SKIQ_RF_DEBUG("[Tx %d:%d block] ts=%ld; nsamples=%d; last_tx_ts=%ld;\n",
"[Tx %d:%d block] ts=%ld; nsamples=%d;\n", q->card, (int)q->hdl, p_tx_block->timestamp, q->block_size); 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) { if (skiq_transmit(q->card, q->hdl, p_tx_block, NULL) < 0) {
ERROR("Error transmitting card %d\n", q->card); 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 // Write block into the ring-buffer
srsran_ringbuffer_write_block(&q->rb, q->p_tx_block, q->p_block_nbytes); 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, q->card,
(int)q->hdl, (int)q->hdl,
q->next_offset, 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; 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); pthread_mutex_lock(&q->mutex);
// Calculate destination where IQ shall be stored // 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) void rf_skiq_rx_port_free(rf_skiq_rx_port_t* q)
{ {
srsran_ringbuffer_free(&q->rb); srsran_ringbuffer_free(&q->rb);
} }

Loading…
Cancel
Save