Added RF calibration functions

master
ismagom 9 years ago
parent bfd6fca7d0
commit eec089bf15

@ -48,6 +48,13 @@ typedef struct {
float tx_rx_gain_offset; float tx_rx_gain_offset;
} srslte_rf_t; } srslte_rf_t;
typedef struct {
float dc_gain;
float dc_phase;
float iq_i;
float iq_q;
} srslte_rf_cal_t;
typedef struct { typedef struct {
enum { enum {
SRSLTE_RF_ERROR_LATE, SRSLTE_RF_ERROR_LATE,
@ -68,11 +75,17 @@ SRSLTE_API int srslte_rf_open_devname(srslte_rf_t *h,
char *devname, char *devname,
char *args); 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, SRSLTE_API int srslte_rf_start_gain_thread(srslte_rf_t *rf,
bool tx_gain_same_rx); bool tx_gain_same_rx);
SRSLTE_API int srslte_rf_close(srslte_rf_t *h); 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_start_rx_stream(srslte_rf_t *h);
SRSLTE_API int srslte_rf_stop_rx_stream(srslte_rf_t *h); SRSLTE_API int srslte_rf_stop_rx_stream(srslte_rf_t *h);

@ -104,7 +104,7 @@ int rf_blade_start_rx_stream(void *h)
/* Configure the device's RX module for use with the sync interface. /* Configure the device's RX module for use with the sync interface.
* SC16 Q11 samples *with* metadata are used. */ * SC16 Q11 samples *with* metadata are used. */
uint32_t buffer_size_rx = ms_buffer_size_rx*(handler->rx_rate/1000/1024); 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, status = bladerf_sync_config(handler->dev,
BLADERF_MODULE_RX, BLADERF_MODULE_RX,
BLADERF_FORMAT_SC16_Q11_META, BLADERF_FORMAT_SC16_Q11_META,
@ -342,17 +342,28 @@ double rf_blade_set_tx_freq(void *h, double freq)
return -1; return -1;
} }
/* Apply manual IQ correction for 2.5-2.6G */ return freq;
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) { static void timestamp_to_secs(uint32_t rate, uint64_t timestamp, time_t *secs, double *frac_secs) {
double totalsecs = (double) timestamp/rate; double totalsecs = (double) timestamp/rate;
time_t secs_i = (time_t) totalsecs; 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); fprintf(stderr, "RX failed: nsamples exceeds buffer size (%d>%d)\n", nsamples, CONVERT_BUFFER_SIZE);
return -1; 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) { if (status) {
fprintf(stderr, "RX failed: %s\n\n", bladerf_strerror(status)); fprintf(stderr, "RX failed: %s\n\n", bladerf_strerror(status));
return -1; return -1;
@ -461,7 +472,7 @@ int rf_blade_send_timed(void *h,
if (is_end_of_burst) { if (is_end_of_burst) {
meta.flags |= BLADERF_META_FLAG_TX_BURST_END; 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 (status == BLADERF_ERR_TIME_PAST) {
if (blade_error_handler) { if (blade_error_handler) {
srslte_rf_error_t error; srslte_rf_error_t error;

@ -33,6 +33,10 @@ SRSLTE_API int rf_blade_open(char *args,
SRSLTE_API int rf_blade_close(void *h); 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(void *h);
SRSLTE_API int rf_blade_start_rx_stream_nsamples(void *h, SRSLTE_API int rf_blade_start_rx_stream_nsamples(void *h,

@ -54,6 +54,10 @@ typedef struct {
int (*srslte_rf_send_timed)(void *h, void *data, int nsamples, int (*srslte_rf_send_timed)(void *h, void *data, int nsamples,
time_t secs, double frac_secs, bool has_time_spec, time_t secs, double frac_secs, bool has_time_spec,
bool blocking, bool is_start_of_burst, bool is_end_of_burst); 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; } rf_dev_t;
/* Define implementation for UHD */ /* Define implementation for UHD */
@ -85,7 +89,9 @@ static rf_dev_t dev_uhd = {
rf_uhd_set_tx_freq, rf_uhd_set_tx_freq,
rf_uhd_get_time, rf_uhd_get_time,
rf_uhd_recv_with_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 #endif
@ -118,7 +124,9 @@ static rf_dev_t dev_blade = {
rf_blade_set_tx_freq, rf_blade_set_tx_freq,
rf_blade_get_time, rf_blade_get_time,
rf_blade_recv_with_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 #endif

@ -127,6 +127,18 @@ int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args) {
return -1; 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) bool srslte_rf_rx_wait_lo_locked(srslte_rf_t *rf)
{ {

@ -150,6 +150,17 @@ bool rf_uhd_rx_wait_lo_locked(void *h)
return val; 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) int rf_uhd_start_rx_stream(void *h)
{ {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) 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 (args[0]=='\0') {
// If B200 is available, use it // If B200 is available, use it
if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { 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";
} }
} }

@ -35,6 +35,10 @@ SRSLTE_API int rf_uhd_open(char *args,
SRSLTE_API int rf_uhd_close(void *h); 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(void *h);
SRSLTE_API int rf_uhd_start_rx_stream_nsamples(void *h, SRSLTE_API int rf_uhd_start_rx_stream_nsamples(void *h,

Loading…
Cancel
Save