Tested new UHD interface with srsLTE examples

This commit is contained in:
ismagom 2015-12-10 17:27:03 +01:00
parent 96f7639ea0
commit b86007249b
6 changed files with 108 additions and 79 deletions

View File

@ -187,6 +187,8 @@ int main(int argc, char **argv) {
rf_rx_wait_lo_locked(&rf);
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_freq/1000000);
cell_detect_config.init_agc = (prog_args.rf_gain<0);
uint32_t ntrial=0;
do {
ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell);

View File

@ -50,7 +50,7 @@ cell_search_cfg_t cell_detect_config = {
10.0 // threshold
};
#else
#warning Compiling pdsch_ue with no UHD support
#warning Compiling pdsch_ue with no RF support
#endif
//#define STDOUT_COMPACT
@ -300,14 +300,14 @@ int main(int argc, char **argv) {
/* Set receiver gain */
if (prog_args.rf_gain > 0) {
printf("Opening UHD device...\n");
printf("Opening RF device...\n");
if (rf_open(&rf, prog_args.rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_rx_gain(&rf, prog_args.rf_gain);
} else {
printf("Opening UHD device with threaded RX Gain control ...\n");
printf("Opening RF device with threaded RX Gain control ...\n");
if (rf_open_th(&rf, prog_args.rf_args, false)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
@ -325,9 +325,9 @@ int main(int argc, char **argv) {
rf_set_master_clock_rate(&rf, 30.72e6);
/* set receiver frequency */
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_freq/1000000);
rf_set_rx_freq(&rf, (double) prog_args.rf_freq);
rf_rx_wait_lo_locked(&rf);
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_freq/1000000);
uint32_t ntrial=0;
do {
@ -362,7 +362,7 @@ int main(int argc, char **argv) {
exit(-1);
}
INFO("Stopping UHD and flushing buffer...\r",0);
INFO("Stopping RF and flushing buffer...\r",0);
rf_stop_rx_stream(&rf);
rf_flush_buffer(&rf);
}

View File

@ -26,6 +26,7 @@
#include "srslte/srslte.h"
#include "srslte/rf/rf.h"
typedef struct SRSLTE_API {
uint32_t max_frames_pbch; // maximum number of 5ms frames to capture for MIB decoding
@ -34,23 +35,23 @@ typedef struct SRSLTE_API {
float init_agc; // 0 or negative to disable AGC
} cell_search_cfg_t;
SRSLTE_API int rf_rssi_scan(void *uhd,
SRSLTE_API int rf_rssi_scan(rf_t *rf,
float *freqs,
float *rssi,
int nof_bands,
double fs,
int nsamp);
SRSLTE_API int rf_mib_decoder(void *uhd,
SRSLTE_API int rf_mib_decoder(rf_t *rf,
cell_search_cfg_t *config,
srslte_cell_t *cell);
SRSLTE_API int rf_cell_search(void *uhd,
SRSLTE_API int rf_cell_search(rf_t *rf,
cell_search_cfg_t *config,
int force_N_id_2,
srslte_cell_t *cell);
SRSLTE_API int rf_search_and_decode_mib(void *uhd,
SRSLTE_API int rf_search_and_decode_mib(rf_t *rf,
cell_search_cfg_t *config,
int force_N_id_2,
srslte_cell_t *cell);

View File

@ -30,6 +30,44 @@
#include "srslte/srslte.h"
#include "rf_dev.h"
int rf_get_available_devices(char **devnames, int max_strlen) {
int i=0;
while(available_devices[i]->name) {
strncpy(devnames[i], available_devices[i]->name, max_strlen);
i++;
}
return i;
}
int rf_open_devname(rf_t *rf, char *devname, char *args, bool agc_thread, bool tx_gain_same_rx) {
/* Try to open the device if name is provided */
if (devname) {
int i=0;
while(available_devices[i] != NULL) {
if (!strcmp(available_devices[i]->name, devname)) {
rf->dev = available_devices[i];
return available_devices[i]->rf_open(args, &rf->handler, agc_thread, tx_gain_same_rx);
}
i++;
}
printf("Device %s not found. Switching to auto mode\n", devname);
}
/* If in auto mode or provided device not found, try to open in order of apperance in available_devices[] array */
int i=0;
while(available_devices[i] != NULL) {
if (!available_devices[i]->rf_open(args, &rf->handler, agc_thread, tx_gain_same_rx)) {
rf->dev = available_devices[i];
return 0;
}
i++;
}
fprintf(stderr, "No compatible RF frontend found\n");
return -1;
}
bool rf_rx_wait_lo_locked(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_rx_wait_lo_locked(rf->handler);
@ -80,30 +118,6 @@ void rf_register_msg_handler(rf_t *rf, rf_msg_handler_t msg_handler)
((rf_dev_t*) rf->dev)->rf_register_msg_handler(rf->handler, msg_handler);
}
int rf_open_devname(rf_t *rf, char *devname, char *args, bool agc_thread, bool tx_gain_same_rx) {
/* Try to open the device if name is provided */
if (devname) {
int i=0;
while(available_devices[i] != NULL) {
if (!strcmp(available_devices[i]->name, devname)) {
rf->dev = &available_devices[i];
return available_devices[i]->rf_open(args, &rf->handler, agc_thread, tx_gain_same_rx);
}
}
}
/* If in auto mode, try to open in order of apperance in available_devices[] array */
int i=0;
while(available_devices[i] != NULL) {
if (!available_devices[i]->rf_open(args, &rf->handler, agc_thread, tx_gain_same_rx)) {
rf->dev = &available_devices[i];
return 0;
}
}
fprintf(stderr, "No compatible RF frontend found\n");
return -1;
}
int rf_open(rf_t *h, char *args)
{
return rf_open_devname(h, NULL, args, false, false);
@ -111,7 +125,7 @@ int rf_open(rf_t *h, char *args)
int rf_open_th(rf_t *h, char *args, bool tx_gain_same_rx)
{
return rf_open_devname(h, NULL, args, false, tx_gain_same_rx);
return rf_open_devname(h, NULL, args, true, tx_gain_same_rx);
}
int rf_close(rf_t *rf)

View File

@ -79,7 +79,7 @@ static bool find_string(uhd_string_vector_handle h, char *str)
uhd_string_vector_size(h, &n);
for (int i=0;i<n;i++) {
uhd_string_vector_at(h, i, buff, 128);
if (!strcmp(buff, str)) {
if (strstr(buff, str)) {
return true;
}
}
@ -109,10 +109,9 @@ bool rf_uhd_rx_wait_lo_locked(void *h)
uhd_string_vector_handle rx_sensors;
char *sensor_name;
uhd_sensor_value_handle value_h;
uhd_string_vector_make(&mb_sensors);
uhd_string_vector_make(&rx_sensors);
uhd_sensor_value_make_from_bool(&value_h, "", true, "True", "False");
uhd_usrp_get_mboard_sensor_names(handler->usrp, 0, &mb_sensors);
uhd_usrp_get_rx_sensor_names(handler->usrp, 0, &rx_sensors);
@ -125,7 +124,7 @@ bool rf_uhd_rx_wait_lo_locked(void *h)
}
double report = 0.0;
while (isLocked(handler, sensor_name, &value_h) && report < 30.0) {
while (!isLocked(handler, sensor_name, &value_h) && report < 30.0) {
report += 0.1;
usleep(1000);
}
@ -173,6 +172,7 @@ void rf_uhd_flush_buffer(void *h)
bool rf_uhd_has_rssi(void *h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_string_vector_handle rx_sensors;
uhd_string_vector_make(&rx_sensors);
uhd_usrp_get_rx_sensor_names(handler->usrp, 0, &rx_sensors);
bool ret = find_string(rx_sensors, "rssi");
uhd_string_vector_free(&rx_sensors);
@ -182,6 +182,7 @@ bool rf_uhd_has_rssi(void *h) {
float rf_uhd_get_rssi(void *h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_sensor_value_handle value;
uhd_sensor_value_make_from_realnum(&value, "rssi", 0, "dBm", "%f");
uhd_usrp_get_rx_sensor(handler->usrp, "rssi", 0, &value);
double val_out;
uhd_sensor_value_to_realnum(value, &val_out);
@ -229,6 +230,8 @@ static void* thread_gain_fcn(void *h) {
return NULL;
}
static char uhd_args[1024];
int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same_rx)
{
char err_msg[256];
@ -244,24 +247,31 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same
/* Set priority to UHD threads */
uhd_set_thread_priority(uhd_default_thread_priority, true);
/* Find available USRP devices in case args is empty */
if (args[0] == '\0') {
uhd_string_vector_handle devices_str;
uhd_string_vector_make(&devices_str);
uhd_usrp_find("", &devices_str);
if (find_string(devices_str, "b200")) {
// build args here
/* Set correct options for the USRP device */
uhd_string_vector_handle devices_str;
uhd_string_vector_make(&devices_str);
uhd_usrp_find("", &devices_str);
/* If device type or name not given in args, choose a B200 */
if (!strstr(args, "type") && !strstr(args, "name")) {
// If B200 is available, use it
if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) {
snprintf(uhd_args, 1024, "type=b200,recv_frame_size=9232,num_recv_frames=64,send_frame_size=9232,num_send_frames=64,%s", args);
}
// If we explicitly define a B200 but do not give frame arguments, define them
} else if (strstr(args, "type=b200") && !strstr(args, "recv_frame_size")) {
snprintf(uhd_args, 1024, "recv_frame_size=9232,num_recv_frames=64,send_frame_size=9232,num_send_frames=64,%s", args);
}
/* Create UHD handler */
uhd_error error = uhd_usrp_make(&handler->usrp, args);
printf("Opening USRP with args: %s\n", uhd_args);
uhd_error error = uhd_usrp_make(&handler->usrp, uhd_args);
if (error) {
uhd_usrp_last_error(handler->usrp, err_msg, 256);
fprintf(stderr, "Error opening UHD: %s\n", err_msg);
return -1;
}
size_t channel = 0;
uhd_stream_args_t stream_args = {
.cpu_format = "fc32",
@ -277,17 +287,19 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same
if (error) {
uhd_rx_streamer_last_error(handler->rx_stream, err_msg, 256);
fprintf(stderr, "Error opening RX stream: %s\n", err_msg);
return -1;
}
uhd_tx_streamer_make(&handler->tx_stream);
error = uhd_usrp_get_tx_stream(handler->usrp, &stream_args, handler->tx_stream);
if (error) {
uhd_tx_streamer_last_error(handler->tx_stream, err_msg, 256);
fprintf(stderr, "Error opening TX stream: %s\n", err_msg);
return -1;
}
uhd_rx_streamer_num_channels(handler->rx_stream, &handler->rx_nof_samples);
uhd_tx_streamer_num_channels(handler->tx_stream, &handler->tx_nof_samples);
uhd_rx_streamer_max_num_samps(handler->rx_stream, &handler->rx_nof_samples);
uhd_tx_streamer_max_num_samps(handler->tx_stream, &handler->tx_nof_samples);
handler->tx_gain_same_rx = tx_gain_same_rx;
handler->tx_rx_gain_offset = 0.0;
uhd_meta_range_make(&handler->rx_gain_range);
@ -306,13 +318,12 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same
if (pthread_cond_init(&handler->cond, NULL)) {
return -1;
}
if (pthread_create(&handler->thread_gain, NULL, thread_gain_fcn, handler)) {
perror("pthread_create");
return -1;
}
}
/* Find out if the master clock rate is configurable */
double cur_clock, new_clock;
uhd_usrp_get_master_clock_rate(handler->usrp, 0, &cur_clock);
@ -334,7 +345,7 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same
printf("Master clock is configurable. Using reduced symbol sizes and sampling rates.\n");
handler->dynamic_rate = true;
}
return 0;
}
@ -459,7 +470,7 @@ int rf_uhd_recv_with_time(void *h,
cf_t *data_c = (cf_t*) data;
do {
size_t rx_samples = handler->rx_nof_samples;
if (rx_samples > nsamples - n) {
rx_samples = nsamples - n;
}
@ -467,6 +478,7 @@ int rf_uhd_recv_with_time(void *h,
void **buffs_ptr = (void**) &buff;
uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, buffs_ptr,
rx_samples, md, 3.0, false, &rxd_samples);
if (error) {
uhd_rx_streamer_last_error(handler->rx_stream, err_msg, 256);
fprintf(stderr, "Error receiving from UHD: %s\n", err_msg);

View File

@ -39,32 +39,32 @@
#include "srslte/rf/rf.h"
#include "srslte/rf/rf_utils.h"
int rf_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) {
int rf_rssi_scan(rf_t *rf, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) {
int i, j;
int ret = -1;
_Complex float *buffer;
cf_t *buffer;
double f;
buffer = calloc(nsamp, sizeof(_Complex float));
buffer = calloc(nsamp, sizeof(cf_t));
if (!buffer) {
goto free_and_exit;
}
rf_set_rx_gain(uhd, 20.0);
rf_set_rx_srate(uhd, fs);
rf_set_rx_gain(rf, 20.0);
rf_set_rx_srate(rf, fs);
for (i=0;i<nof_bands;i++) {
rf_stop_rx_stream(uhd);
rf_stop_rx_stream(rf);
f = (double) freqs[i];
rf_set_rx_freq(uhd, f);
rf_rx_wait_lo_locked(uhd);
rf_set_rx_freq(rf, f);
rf_rx_wait_lo_locked(rf);
usleep(10000);
rf_start_rx_stream(uhd);
rf_start_rx_stream(rf);
/* discard first samples */
for (j=0;j<2;j++) {
if (rf_recv(uhd, buffer, nsamp, 1) != nsamp) {
if (rf_recv(rf, buffer, nsamp, 1) != nsamp) {
goto free_and_exit;
}
}
@ -74,7 +74,7 @@ int rf_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs,
printf("\n");
}
}
rf_stop_rx_stream(uhd);
rf_stop_rx_stream(rf);
ret = 0;
free_and_exit:
@ -95,12 +95,12 @@ double rf_set_rx_gain_th_wrapper(void *h, double f) {
/** This function is simply a wrapper to the ue_cell_search module for rf devices
* Return 1 if the MIB is decoded, 0 if not or -1 on error.
*/
int rf_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) {
int rf_mib_decoder(rf_t *rf, cell_search_cfg_t *config, srslte_cell_t *cell) {
int ret = SRSLTE_ERROR;
srslte_ue_mib_sync_t ue_mib;
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, rf_recv_wrapper_cs, uhd)) {
if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, rf_recv_wrapper_cs, (void*) rf)) {
fprintf(stderr, "Error initiating srslte_ue_mib_sync\n");
goto clean_exit;
}
@ -111,10 +111,10 @@ int rf_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) {
int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB);
INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000);
rf_set_rx_srate(uhd, (float) srate);
rf_set_rx_srate(rf, (float) srate);
INFO("Starting receiver...\n", 0);
rf_start_rx_stream(uhd);
rf_start_rx_stream(rf);
/* Find and decody MIB */
ret = srslte_ue_mib_sync_decode(&ue_mib, config->max_frames_pss, bch_payload, &cell->nof_ports, NULL);
@ -133,7 +133,7 @@ int rf_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) {
clean_exit:
rf_stop_rx_stream(uhd);
rf_stop_rx_stream(rf);
srslte_ue_mib_sync_free(&ue_mib);
return ret;
@ -141,7 +141,7 @@ clean_exit:
/** This function is simply a wrapper to the ue_cell_search module for rf devices
*/
int rf_cell_search(void *uhd, cell_search_cfg_t *config,
int rf_cell_search(rf_t *rf, cell_search_cfg_t *config,
int force_N_id_2, srslte_cell_t *cell)
{
int ret = SRSLTE_ERROR;
@ -150,7 +150,7 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config,
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
if (srslte_ue_cellsearch_init(&cs, rf_recv_wrapper_cs, uhd)) {
if (srslte_ue_cellsearch_init(&cs, rf_recv_wrapper_cs, (void*) rf)) {
fprintf(stderr, "Error initiating UE cell detect\n");
return SRSLTE_ERROR;
}
@ -167,10 +167,10 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config,
}
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000);
rf_set_rx_srate(uhd, SRSLTE_CS_SAMP_FREQ);
rf_set_rx_srate(rf, SRSLTE_CS_SAMP_FREQ);
INFO("Starting receiver...\n", 0);
rf_start_rx_stream(uhd);
rf_start_rx_stream(rf);
/* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */
uint32_t max_peak_cell = 0;
@ -211,7 +211,7 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config,
config->init_agc = srslte_agc_get_gain(&cs.ue_sync.agc);
}
rf_stop_rx_stream(uhd);
rf_stop_rx_stream(rf);
srslte_ue_cellsearch_free(&cs);
return ret;
@ -223,15 +223,15 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config,
* 0 if no cell was found or MIB could not be decoded,
* -1 on error
*/
int rf_search_and_decode_mib(void *uhd, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell)
int rf_search_and_decode_mib(rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell)
{
int ret = SRSLTE_ERROR;
printf("Searching for cell...\n");
ret = rf_cell_search(uhd, config, force_N_id_2, cell);
ret = rf_cell_search(rf, config, force_N_id_2, cell);
if (ret > 0) {
printf("Decoding PBCH for cell %d (N_id_2=%d)\n", cell->id, cell->id%3);
ret = rf_mib_decoder(uhd, config, cell);
ret = rf_mib_decoder(rf, config, cell);
if (ret < 0) {
fprintf(stderr, "Could not decode PBCH from CELL ID %d\n", cell->id);
return SRSLTE_ERROR;