mirror of https://github.com/PentHertz/srsLTE.git
fix multi channel tx support in soapy
This commit is contained in:
parent
81b143715b
commit
df2bbd4087
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -248,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,6 +285,12 @@ double rf_soapy_set_rx_srate(void *h, double rate)
|
||||||
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError());
|
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError());
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_RX, 0, rate) != 0) {
|
||||||
|
printf("setBandwidth failed: %s\n", SoapySDRDevice_lastError());
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0);
|
return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +301,12 @@ double rf_soapy_set_tx_srate(void *h, double rate)
|
||||||
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError());
|
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError());
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_TX, 0, rate) != 0) {
|
||||||
|
printf("setBandwidth failed: %s\n", SoapySDRDevice_lastError());
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0);
|
return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +357,15 @@ double rf_soapy_set_rx_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,6 +377,16 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,6 +396,7 @@ void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//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,
|
||||||
|
@ -405,17 +436,22 @@ int rf_soapy_recv_with_time_multi(void *h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
*secs = timeNs / 1000000000;
|
||||||
|
*frac_secs = (timeNs % 1000000000)/1000000000;
|
||||||
|
printf("ret=%d, flags=%d, timeNs=%lld\n", ret, flags, timeNs);
|
||||||
|
#endif
|
||||||
|
|
||||||
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,
|
||||||
|
@ -428,19 +464,37 @@ int rf_soapy_recv_with_time(void *h,
|
||||||
|
|
||||||
|
|
||||||
int rf_soapy_send_timed(void *h,
|
int rf_soapy_send_timed(void *h,
|
||||||
void *data,
|
void *data,
|
||||||
int nsamples,
|
int nsamples,
|
||||||
time_t secs,
|
time_t secs,
|
||||||
double frac_secs,
|
double frac_secs,
|
||||||
bool has_time_spec,
|
bool has_time_spec,
|
||||||
bool blocking,
|
bool blocking,
|
||||||
bool is_start_of_burst,
|
bool is_start_of_burst,
|
||||||
bool is_end_of_burst)
|
bool is_end_of_burst)
|
||||||
{
|
{
|
||||||
int flags;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
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;
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t *) h;
|
||||||
timeNs = secs * 1000000000;
|
timeNs = secs * 1000000000;
|
||||||
timeNs = timeNs + (frac_secs * 1000000000);
|
timeNs = timeNs + (frac_secs * 1000000000);
|
||||||
|
@ -449,25 +503,54 @@ int rf_soapy_send_timed(void *h,
|
||||||
if (!handler->tx_stream_active) {
|
if (!handler->tx_stream_active) {
|
||||||
rf_soapy_start_tx_stream(h);
|
rf_soapy_start_tx_stream(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
cf_t *data_c = (cf_t *) data;
|
//printf("send_timed_multi(): time_spec=%d blocking=%d, is_start_of_burst=%d is_end_of_burst=%d\n", has_time_spec, blocking, is_start_of_burst, is_end_of_burst);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ SRSLTE_API void rf_soapy_get_time(void *h,
|
||||||
time_t *secs,
|
time_t *secs,
|
||||||
double *frac_secs);
|
double *frac_secs);
|
||||||
|
|
||||||
SRSLTE_API int rf_soapy_send_timed(void *h,
|
SRSLTE_API int rf_soapy_send_timed(void *h,
|
||||||
void *data,
|
void *data,
|
||||||
int nsamples,
|
int nsamples,
|
||||||
time_t secs,
|
time_t secs,
|
||||||
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue