From eec089bf15b4dff8e5be9b61a80d9be6ca0152d7 Mon Sep 17 00:00:00 2001 From: ismagom Date: Thu, 14 Jan 2016 12:08:33 +0100 Subject: [PATCH] Added RF calibration functions --- srslte/include/srslte/rf/rf.h | 13 +++++++++++++ srslte/lib/rf/src/rf_blade_imp.c | 33 +++++++++++++++++++++----------- srslte/lib/rf/src/rf_blade_imp.h | 4 ++++ srslte/lib/rf/src/rf_dev.h | 12 ++++++++++-- srslte/lib/rf/src/rf_imp.c | 12 ++++++++++++ srslte/lib/rf/src/rf_uhd_imp.c | 13 ++++++++++++- srslte/lib/rf/src/rf_uhd_imp.h | 4 ++++ 7 files changed, 77 insertions(+), 14 deletions(-) diff --git a/srslte/include/srslte/rf/rf.h b/srslte/include/srslte/rf/rf.h index 3125a13df..fd49f7d8d 100644 --- a/srslte/include/srslte/rf/rf.h +++ b/srslte/include/srslte/rf/rf.h @@ -48,6 +48,13 @@ typedef struct { float tx_rx_gain_offset; } srslte_rf_t; +typedef struct { + float dc_gain; + float dc_phase; + float iq_i; + float iq_q; +} srslte_rf_cal_t; + typedef struct { enum { SRSLTE_RF_ERROR_LATE, @@ -68,11 +75,17 @@ SRSLTE_API int srslte_rf_open_devname(srslte_rf_t *h, char *devname, char *args); +SRSLTE_API const char *srslte_rf_name(srslte_rf_t *h); + SRSLTE_API int srslte_rf_start_gain_thread(srslte_rf_t *rf, bool tx_gain_same_rx); SRSLTE_API int srslte_rf_close(srslte_rf_t *h); +SRSLTE_API void srslte_rf_set_tx_cal(srslte_rf_t *h, srslte_rf_cal_t *cal); + +SRSLTE_API void srslte_rf_set_rx_cal(srslte_rf_t *h, srslte_rf_cal_t *cal); + SRSLTE_API int srslte_rf_start_rx_stream(srslte_rf_t *h); SRSLTE_API int srslte_rf_stop_rx_stream(srslte_rf_t *h); diff --git a/srslte/lib/rf/src/rf_blade_imp.c b/srslte/lib/rf/src/rf_blade_imp.c index 37a38c40a..4949ce035 100644 --- a/srslte/lib/rf/src/rf_blade_imp.c +++ b/srslte/lib/rf/src/rf_blade_imp.c @@ -104,7 +104,7 @@ int rf_blade_start_rx_stream(void *h) /* Configure the device's RX module for use with the sync interface. * SC16 Q11 samples *with* metadata are used. */ uint32_t buffer_size_rx = ms_buffer_size_rx*(handler->rx_rate/1000/1024); - printf("Setting buffer size %d for rate %d\n", buffer_size_rx, handler->rx_rate); + status = bladerf_sync_config(handler->dev, BLADERF_MODULE_RX, BLADERF_FORMAT_SC16_Q11_META, @@ -342,17 +342,28 @@ double rf_blade_set_tx_freq(void *h, double freq) return -1; } - /* Apply manual IQ correction for 2.5-2.6G */ - if (freq > 2.5e9 && freq < 2.6e9) { - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_PHASE, 184); - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_GAIN, 20); - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_I, 19); - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_Q, 97); - } - return freq; } +void rf_blade_set_tx_cal(void *h, srslte_rf_cal_t *cal) { + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_PHASE, cal->dc_gain); + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_GAIN, cal->dc_phase); + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i); + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q); + + printf("Set CAL values %f, %f, %f, %f\n", cal->dc_gain, cal->dc_phase, cal->iq_i, cal->iq_q); +} + +void rf_blade_set_rx_cal(void *h, srslte_rf_cal_t *cal) { + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_PHASE, cal->dc_gain); + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_GAIN, cal->dc_phase); + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i); + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q); +} + + static void timestamp_to_secs(uint32_t rate, uint64_t timestamp, time_t *secs, double *frac_secs) { double totalsecs = (double) timestamp/rate; time_t secs_i = (time_t) totalsecs; @@ -402,7 +413,7 @@ int rf_blade_recv_with_time(void *h, fprintf(stderr, "RX failed: nsamples exceeds buffer size (%d>%d)\n", nsamples, CONVERT_BUFFER_SIZE); return -1; } - status = bladerf_sync_rx(handler->dev, handler->rx_buffer, nsamples, &meta, 0); + status = bladerf_sync_rx(handler->dev, handler->rx_buffer, nsamples, &meta, 2000); if (status) { fprintf(stderr, "RX failed: %s\n\n", bladerf_strerror(status)); return -1; @@ -461,7 +472,7 @@ int rf_blade_send_timed(void *h, if (is_end_of_burst) { meta.flags |= BLADERF_META_FLAG_TX_BURST_END; } - status = bladerf_sync_tx(handler->dev, handler->tx_buffer, nsamples, &meta, 0); + status = bladerf_sync_tx(handler->dev, handler->tx_buffer, nsamples, &meta, 2000); if (status == BLADERF_ERR_TIME_PAST) { if (blade_error_handler) { srslte_rf_error_t error; diff --git a/srslte/lib/rf/src/rf_blade_imp.h b/srslte/lib/rf/src/rf_blade_imp.h index ef0a18d00..e6d05804d 100644 --- a/srslte/lib/rf/src/rf_blade_imp.h +++ b/srslte/lib/rf/src/rf_blade_imp.h @@ -33,6 +33,10 @@ SRSLTE_API int rf_blade_open(char *args, SRSLTE_API int rf_blade_close(void *h); +SRSLTE_API void rf_blade_set_tx_cal(void *h, srslte_rf_cal_t *cal); + +SRSLTE_API void rf_blade_set_rx_cal(void *h, srslte_rf_cal_t *cal); + SRSLTE_API int rf_blade_start_rx_stream(void *h); SRSLTE_API int rf_blade_start_rx_stream_nsamples(void *h, diff --git a/srslte/lib/rf/src/rf_dev.h b/srslte/lib/rf/src/rf_dev.h index 13c66d416..01d858fa7 100644 --- a/srslte/lib/rf/src/rf_dev.h +++ b/srslte/lib/rf/src/rf_dev.h @@ -54,6 +54,10 @@ typedef struct { int (*srslte_rf_send_timed)(void *h, void *data, int nsamples, time_t secs, double frac_secs, bool has_time_spec, bool blocking, bool is_start_of_burst, bool is_end_of_burst); + void (*srslte_rf_set_tx_cal)(void *h, srslte_rf_cal_t *cal); + + void (*srslte_rf_set_rx_cal)(void *h, srslte_rf_cal_t *cal); + } rf_dev_t; /* Define implementation for UHD */ @@ -85,7 +89,9 @@ static rf_dev_t dev_uhd = { rf_uhd_set_tx_freq, rf_uhd_get_time, rf_uhd_recv_with_time, - rf_uhd_send_timed + rf_uhd_send_timed, + rf_uhd_set_tx_cal, + rf_uhd_set_rx_cal }; #endif @@ -118,7 +124,9 @@ static rf_dev_t dev_blade = { rf_blade_set_tx_freq, rf_blade_get_time, rf_blade_recv_with_time, - rf_blade_send_timed + rf_blade_send_timed, + rf_blade_set_tx_cal, + rf_blade_set_rx_cal }; #endif diff --git a/srslte/lib/rf/src/rf_imp.c b/srslte/lib/rf/src/rf_imp.c index 51f1071c5..03c1cdaed 100644 --- a/srslte/lib/rf/src/rf_imp.c +++ b/srslte/lib/rf/src/rf_imp.c @@ -127,6 +127,18 @@ int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args) { return -1; } +void srslte_rf_set_tx_cal(srslte_rf_t *rf, srslte_rf_cal_t *cal) { + return ((rf_dev_t*) rf->dev)->srslte_rf_set_tx_cal(rf->handler, cal); +} + +void srslte_rf_set_rx_cal(srslte_rf_t *rf, srslte_rf_cal_t *cal) { + return ((rf_dev_t*) rf->dev)->srslte_rf_set_rx_cal(rf->handler, cal); +} + + +const char* srslte_rf_name(srslte_rf_t *rf) { + return ((rf_dev_t*) rf->dev)->name; +} bool srslte_rf_rx_wait_lo_locked(srslte_rf_t *rf) { diff --git a/srslte/lib/rf/src/rf_uhd_imp.c b/srslte/lib/rf/src/rf_uhd_imp.c index 9224733e1..639190211 100644 --- a/srslte/lib/rf/src/rf_uhd_imp.c +++ b/srslte/lib/rf/src/rf_uhd_imp.c @@ -150,6 +150,17 @@ bool rf_uhd_rx_wait_lo_locked(void *h) return val; } +void rf_uhd_set_tx_cal(void *h, srslte_rf_cal_t *cal) +{ + +} + +void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal) +{ + +} + + int rf_uhd_start_rx_stream(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; @@ -231,7 +242,7 @@ int rf_uhd_open(char *args, void **h) if (args[0]=='\0') { // If B200 is available, use it if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { - args = "type=b200,recv_frame_size=9232,num_recv_frames=64,send_frame_size=9232,num_send_frames=64"; + args = "type=b200,recv_frame_size=9232,send_frame_size=9232"; } } diff --git a/srslte/lib/rf/src/rf_uhd_imp.h b/srslte/lib/rf/src/rf_uhd_imp.h index d33e802c5..240cfc8f0 100644 --- a/srslte/lib/rf/src/rf_uhd_imp.h +++ b/srslte/lib/rf/src/rf_uhd_imp.h @@ -35,6 +35,10 @@ SRSLTE_API int rf_uhd_open(char *args, SRSLTE_API int rf_uhd_close(void *h); +SRSLTE_API void rf_uhd_set_tx_cal(void *h, srslte_rf_cal_t *cal); + +SRSLTE_API void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal); + SRSLTE_API int rf_uhd_start_rx_stream(void *h); SRSLTE_API int rf_uhd_start_rx_stream_nsamples(void *h,