Merge branch 'soapy_fixes' into next

master
Andre Puschmann 7 years ago
commit 2311e2a715

@ -232,6 +232,7 @@ int main(int argc, char **argv) {
srslte_vec_save_file(output_filename,buffer,11*flen*sizeof(cf_t)); srslte_vec_save_file(output_filename,buffer,11*flen*sizeof(cf_t));
srslte_rf_close(&rf);
srslte_prach_free(p); srslte_prach_free(p);
free(p); free(p);

@ -177,7 +177,7 @@ static rf_dev_t dev_soapy = {
rf_soapy_recv_with_time, rf_soapy_recv_with_time,
rf_soapy_recv_with_time_multi, rf_soapy_recv_with_time_multi,
rf_soapy_send_timed, rf_soapy_send_timed,
.srslte_rf_send_timed_multi = /* FIXME: Implement srslte_rf_send_timed_multi for Soapy SDR */ NULL, .srslte_rf_send_timed_multi = rf_soapy_send_timed_multi,
rf_soapy_set_tx_cal, rf_soapy_set_tx_cal,
rf_soapy_set_rx_cal rf_soapy_set_rx_cal
}; };

@ -88,12 +88,12 @@ void rf_soapy_register_error_handler(void *notused, srslte_rf_error_handler_t ne
} }
char* rf_soapy_devname(void* h) char* rf_soapy_devname(void* h)
{ {
return "soapy"; return "soapy";
} }
bool rf_soapy_rx_wait_lo_locked(void *h) bool rf_soapy_rx_wait_lo_locked(void *h)
{ {
printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n"); printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n");
@ -155,7 +155,6 @@ int rf_soapy_stop_tx_stream(void *h)
if(SoapySDRDevice_deactivateStream(handler->device, handler->txStream, 0, 0) != 0) if(SoapySDRDevice_deactivateStream(handler->device, handler->txStream, 0, 0) != 0)
return SRSLTE_ERROR; return SRSLTE_ERROR;
handler->tx_stream_active = false; handler->tx_stream_active = false;
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -175,7 +174,7 @@ void rf_soapy_flush_buffer(void *h)
bool rf_soapy_has_rssi(void *h) bool rf_soapy_has_rssi(void *h)
{ {
printf("TODO: implement rf_soapy_has_rssi()\n"); // TODO: implement rf_soapy_has_rssi()
return false; return false;
} }
@ -199,9 +198,8 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
} }
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++) {
printf("Soapy Has Found device #%d: ", (int)i); printf("Soapy has Found device #%d: ", (int)i);
for (size_t j = 0; j < soapy_args[i].size; j++) for (size_t j = 0; j < soapy_args[i].size; j++) {
{
printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]); printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]);
} }
printf("\n"); printf("\n");
@ -221,7 +219,6 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
handler->tx_stream_active = false; handler->tx_stream_active = false;
handler->rx_stream_active = false; handler->rx_stream_active = false;
if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_RX) > 0){ if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_RX) > 0){
printf("setting up RX stream\n"); printf("setting up RX stream\n");
if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) {
@ -251,12 +248,12 @@ int rf_soapy_open(char *args, void **h)
int rf_soapy_close(void *h) int rf_soapy_close(void *h)
{ {
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
if (handler->txStream) { if (handler->tx_stream_active) {
rf_soapy_stop_tx_stream(handler); rf_soapy_stop_tx_stream(handler);
SoapySDRDevice_closeStream(handler->device, handler->txStream); SoapySDRDevice_closeStream(handler->device, handler->txStream);
} }
if (handler->rxStream) { if (handler->rx_stream_active) {
rf_soapy_stop_rx_stream(handler); rf_soapy_stop_rx_stream(handler);
SoapySDRDevice_closeStream(handler->device, handler->rxStream); SoapySDRDevice_closeStream(handler->device, handler->rxStream);
} }
@ -285,9 +282,15 @@ double rf_soapy_set_rx_srate(void *h, double rate)
{ {
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_RX, 0, rate) != 0) { if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_RX, 0, rate) != 0) {
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); printf("setSampleRate Rx fail: %s\n", SoapySDRDevice_lastError());
return SRSLTE_ERROR;
}
if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_RX, 0, rate) != 0) {
printf("setBandwidth Rx failed: %s\n", SoapySDRDevice_lastError());
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0); return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0);
} }
@ -295,9 +298,15 @@ double rf_soapy_set_tx_srate(void *h, double rate)
{ {
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_TX, 0, rate) != 0) { if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_TX, 0, rate) != 0) {
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); printf("setSampleRate Tx fail: %s\n", SoapySDRDevice_lastError());
return SRSLTE_ERROR;
}
if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_TX, 0, rate) != 0) {
printf("setBandwidth Tx failed: %s\n", SoapySDRDevice_lastError());
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0); return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0);
} }
@ -349,6 +358,14 @@ double rf_soapy_set_rx_freq(void *h, double freq)
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
// Todo: expose antenna setting
if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_RX, 0, "LNAH") != 0) {
fprintf(stderr, "Failed to set Rx antenna.\n");
}
char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_RX, 0);
printf("Rx antenna set to %s\n", ant);
return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0); return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0);
} }
@ -360,14 +377,25 @@ double rf_soapy_set_tx_freq(void *h, double freq)
printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); printf("setFrequency fail: %s\n", SoapySDRDevice_lastError());
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0);
// Todo: expose antenna name in arguments
if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_TX, 0, "BAND1") != 0) {
fprintf(stderr, "Failed to set Tx antenna.\n");
} }
char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_TX, 0);
printf("Tx antenna set to %s\n", ant);
return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0);
}
void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs) {
void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs)
{
printf("Todo: implement rf_soapy_get_time()\n");
} }
//TODO: add multi-channel support //TODO: add multi-channel support
int rf_soapy_recv_with_time_multi(void *h, int rf_soapy_recv_with_time_multi(void *h,
void **data, void **data,
@ -395,7 +423,7 @@ int rf_soapy_recv_with_time_multi(void *h,
cf_t *data_c = (cf_t*) data[i]; cf_t *data_c = (cf_t*) data[i];
buffs_ptr[i] = &data_c[n]; buffs_ptr[i] = &data_c[n];
} }
ret = SoapySDRDevice_readStream(handler->device, handler->rxStream, buffs_ptr , rx_samples, &flags, &timeNs, 1000000); ret = SoapySDRDevice_readStream(handler->device, handler->rxStream, buffs_ptr, rx_samples, &flags, &timeNs, 10000);
if(ret < 0) { if(ret < 0) {
// continue when getting overflows // continue when getting overflows
if (ret == SOAPY_SDR_OVERFLOW) { if (ret == SOAPY_SDR_OVERFLOW) {
@ -407,17 +435,23 @@ int rf_soapy_recv_with_time_multi(void *h,
} }
} }
// update rx time
if (secs != NULL && frac_secs != NULL) {
*secs = timeNs / 1e9;
*frac_secs = (timeNs % 1000000000)/1e9;
//printf("rx_time: secs=%d, frac_secs=%lf timeNs=%lld\n", *secs, *frac_secs, timeNs);
}
n += ret; n += ret;
trials++; trials++;
} while (n < nsamples && trials < 100); } while (n < nsamples && trials < 100);
//*secs = timeNs / 1000000000;
//*frac_secs = (timeNs % 1000000000)/1000000000;
// printf("ret=%d, flags=%d, timeNs=%lld\n", ret, flags, timeNs);
return n; return n;
} }
int rf_soapy_recv_with_time(void *h, int rf_soapy_recv_with_time(void *h,
void *data, void *data,
uint32_t nsamples, uint32_t nsamples,
@ -439,40 +473,83 @@ int rf_soapy_send_timed(void *h,
bool is_start_of_burst, bool is_start_of_burst,
bool is_end_of_burst) bool is_end_of_burst)
{ {
void *_data[SRSLTE_MAX_PORTS]= {data, zero_mem, zero_mem, zero_mem};
return rf_soapy_send_timed_multi(h, _data, nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst);
}
int flags;
// Todo: Check correct handling of flags, use RF metrics API, fix timed transmissions
int rf_soapy_send_timed_multi(void *h,
void *data[SRSLTE_MAX_PORTS],
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst)
{
rf_soapy_handler_t *handler = (rf_soapy_handler_t *) h;
int flags = 0;
const long timeoutUs = 2000; // arbitrarily chosen
long long timeNs; long long timeNs;
int trials = 0; int trials = 0;
int ret = 0; int ret = 0;
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
timeNs = secs * 1000000000;
timeNs = timeNs + (frac_secs * 1000000000);
int n = 0; int n = 0;
if (!handler->tx_stream_active) { if (!handler->tx_stream_active) {
rf_soapy_start_tx_stream(h); rf_soapy_start_tx_stream(h);
} }
if (is_start_of_burst && is_end_of_burst) {
flags |= SOAPY_SDR_ONE_PACKET;
}
if (is_end_of_burst) {
flags |= SOAPY_SDR_END_BURST;
}
if (has_time_spec) {
flags |= SOAPY_SDR_HAS_TIME;
timeNs = secs * 1000000000;
timeNs = timeNs + (frac_secs * 1000000000);
//printf("time_spec: secs=%d, frac_secs=%lf timeNs=%lld\n", secs, frac_secs, timeNs);
}
cf_t *data_c = (cf_t*) data;
do { do {
size_t tx_samples = nsamples; size_t tx_samples = nsamples;
if (tx_samples > nsamples - n) { if (tx_samples > nsamples - n) {
tx_samples = nsamples - n; tx_samples = nsamples - n;
} }
void *buff = (void*) &data_c[n];
const void *buffs_ptr[1] = {buff}; ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, (const void *)data, tx_samples, &flags, timeNs, timeoutUs);
ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, buffs_ptr, tx_samples, &flags, timeNs, 10000); if (ret == SOAPY_SDR_TIMEOUT) {
if(ret < 0) printf("L");
continue;
}
if (ret == SOAPY_SDR_OVERFLOW) {
printf("O");
continue;
}
if (ret == SOAPY_SDR_UNDERFLOW) {
printf("U");
continue;
}
if (ret < 0) {
fprintf(stderr, "Error during writeStream\n");
exit(-1);
return SRSLTE_ERROR; return SRSLTE_ERROR;
}
n += ret; n += ret;
trials++; trials++;
} while (n < nsamples && trials < 100); } while (n < nsamples && trials < 100);
if(ret != nsamples) if (n != nsamples) {
fprintf(stderr, "Couldn't write all samples.\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
}
return ret; return ret;
} }

@ -116,3 +116,12 @@ SRSLTE_API int rf_soapy_send_timed(void *h,
bool is_start_of_burst, bool is_start_of_burst,
bool is_end_of_burst); bool is_end_of_burst);
int rf_soapy_send_timed_multi(void *h,
void *data[4],
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst);

@ -171,6 +171,7 @@ void phch_recv::radio_error() {
// Need to find a method to effectively reset radio, reloading the driver does not work // Need to find a method to effectively reset radio, reloading the driver does not work
//radio_h->reset(); //radio_h->reset();
radio_h->stop();
fprintf(stdout, "Error while receiving samples. Restart srsUE\n"); fprintf(stdout, "Error while receiving samples. Restart srsUE\n");
exit(-1); exit(-1);

Loading…
Cancel
Save