From 0a5a6245f167e8fbcb9a02fa1f55ffe64fa07be5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 13 Feb 2017 13:29:20 +0100 Subject: [PATCH] pdsch ue working with 1 and 2 antennas --- srslte/examples/cell_measurement.c | 23 ++--- srslte/examples/cell_search.c | 12 ++- srslte/examples/pdsch_ue.c | 27 +++--- srslte/examples/usrp_capture_sync.c | 14 +-- srslte/include/srslte/rf/rf_utils.h | 3 + srslte/include/srslte/ue/ue_cell_search.h | 6 +- srslte/include/srslte/ue/ue_dl.h | 15 ++-- srslte/include/srslte/ue/ue_mib.h | 5 +- srslte/include/srslte/ue/ue_sync.h | 14 ++- srslte/lib/ch_estimation/chest_dl.c | 1 - srslte/lib/phch/test/pdsch_pdcch_file_test.c | 4 +- srslte/lib/rf/rf_utils.c | 27 +++--- srslte/lib/ue/ue_cell_search.c | 19 +++- srslte/lib/ue/ue_dl.c | 92 ++++++++++++-------- srslte/lib/ue/ue_mib.c | 26 ++++-- srslte/lib/ue/ue_sync.c | 77 +++++++--------- 16 files changed, 211 insertions(+), 154 deletions(-) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index de9962513..9794f04c7 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -129,9 +129,10 @@ void sig_int_handler(int signo) } } -int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *q) { +int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *q) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return srslte_rf_recv(h, data, nsamples, 1); + + return srslte_rf_recv(h, data[0], nsamples, 1); } enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; @@ -141,7 +142,7 @@ enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; int main(int argc, char **argv) { int ret; - cf_t *sf_buffer; + cf_t *sf_buffer[SRSLTE_MAX_RXANT] = {NULL, NULL}; prog_args_t prog_args; srslte_cell_t cell; int64_t sf_cnt; @@ -180,6 +181,8 @@ int main(int argc, char **argv) { } srslte_rf_set_rx_gain(&rf, 50); } + + sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100)); sigset_t sigset; sigemptyset(&sigset); @@ -198,7 +201,7 @@ int main(int argc, char **argv) { uint32_t ntrial=0; do { - ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); + ret = rf_search_and_decode_mib(&rf, 1, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); if (ret < 0) { fprintf(stderr, "Error searching for cell\n"); exit(-1); @@ -234,11 +237,11 @@ int main(int argc, char **argv) { srslte_rf_stop_rx_stream(&rf); srslte_rf_flush_buffer(&rf); - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { + if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); return -1; } - if (srslte_ue_dl_init(&ue_dl, cell)) { + if (srslte_ue_dl_init(&ue_dl, cell, 1)) { fprintf(stderr, "Error initiating UE downlink processing module\n"); return -1; } @@ -280,7 +283,7 @@ int main(int argc, char **argv) { /* Main loop */ while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { - ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); + ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); } @@ -292,7 +295,7 @@ int main(int argc, char **argv) { case DECODE_MIB: if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { srslte_pbch_decode_reset(&ue_mib.pbch); - n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); + n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset); if (n < 0) { fprintf(stderr, "Error decoding UE MIB\n"); return -1; @@ -329,11 +332,11 @@ int main(int argc, char **argv) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { /* Run FFT for all subframe data */ - srslte_ofdm_rx_sf(&fft, sf_buffer, sf_symbols); + srslte_ofdm_rx_sf(&fft, sf_buffer[0], sf_symbols); srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync)); - rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer,SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05); + rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer[0],SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05); rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05); rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05); rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05); diff --git a/srslte/examples/cell_search.c b/srslte/examples/cell_search.c index 02c3d8ada..a15d5be8e 100644 --- a/srslte/examples/cell_search.c +++ b/srslte/examples/cell_search.c @@ -120,9 +120,13 @@ void parse_args(int argc, char **argv) { } } -int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { +int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return srslte_rf_recv((srslte_rf_t*) h, data, nsamples, 1); + void *ptr[SRSLTE_MAX_RXANT]; + for (int i=0;icell.nof_ports;port_id++) { - printf("rxant=%d, port=%d, input=0x%x, ce=0x%x\n", rxant, port_id, input[rxant], ce[port_id][rxant]); if (srslte_chest_dl_estimate_port(q, input[rxant], ce[port_id][rxant], sf_idx, port_id)) { return SRSLTE_ERROR; } diff --git a/srslte/lib/phch/test/pdsch_pdcch_file_test.c b/srslte/lib/phch/test/pdsch_pdcch_file_test.c index 33ad2c58d..f31cc38da 100644 --- a/srslte/lib/phch/test/pdsch_pdcch_file_test.c +++ b/srslte/lib/phch/test/pdsch_pdcch_file_test.c @@ -137,7 +137,7 @@ int base_init() { exit(-1); } - if (srslte_ue_dl_init(&ue_dl, cell)) { + if (srslte_ue_dl_init(&ue_dl, cell, 1)) { fprintf(stderr, "Error initializing UE DL\n"); return -1; } @@ -177,7 +177,7 @@ int main(int argc, char **argv) { srslte_filesource_read(&fsrc, input_buffer, flen); INFO("Reading %d samples sub-frame %d\n", flen, sf_idx); - ret = srslte_ue_dl_decode(&ue_dl, input_buffer, data, sf_idx); + ret = srslte_ue_dl_decode(&ue_dl, &input_buffer, data, sf_idx); if(ret > 0) { printf("PDSCH Decoded OK!\n"); } else if (ret == 0) { diff --git a/srslte/lib/rf/rf_utils.c b/srslte/lib/rf/rf_utils.c index 0d5c8a529..935425b16 100644 --- a/srslte/lib/rf/rf_utils.c +++ b/srslte/lib/rf/rf_utils.c @@ -82,11 +82,13 @@ free_and_exit: return ret; } -cf_t data2[1920*160]; -int srslte_rf_recv_wrapper_cs(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { +int srslte_rf_recv_wrapper_cs(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - void *d[2] = {data, data2}; - return srslte_rf_recv_with_time_multi(h, d, nsamples, 1, NULL, NULL); + void *ptr[SRSLTE_MAX_RXANT]; + for (int i=0;iid, cell->cp, srslte_rf_recv_wrapper_cs, (void*) rf)) { + if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } @@ -152,8 +154,9 @@ clean_exit: /** This function is simply a wrapper to the ue_cell_search module for rf devices */ -int rf_cell_search(srslte_rf_t *rf, cell_search_cfg_t *config, - int force_N_id_2, srslte_cell_t *cell, float *cfo) +int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas, + cell_search_cfg_t *config, + int force_N_id_2, srslte_cell_t *cell, float *cfo) { int ret = SRSLTE_ERROR; srslte_ue_cellsearch_t cs; @@ -161,7 +164,7 @@ int rf_cell_search(srslte_rf_t *rf, cell_search_cfg_t *config, bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); - if (srslte_ue_cellsearch_init(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, (void*) rf)) { + if (srslte_ue_cellsearch_init(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); return SRSLTE_ERROR; } @@ -235,15 +238,15 @@ int rf_cell_search(srslte_rf_t *rf, 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(srslte_rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell, float *cfo) +int rf_search_and_decode_mib(srslte_rf_t *rf, uint32_t nof_rx_antennas, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell, float *cfo) { int ret = SRSLTE_ERROR; printf("Searching for cell...\n"); - ret = rf_cell_search(rf, config, force_N_id_2, cell, cfo); + ret = rf_cell_search(rf, nof_rx_antennas, config, force_N_id_2, cell, cfo); if (ret > 0) { printf("Decoding PBCH for cell %d (N_id_2=%d)\n", cell->id, cell->id%3); - ret = rf_mib_decoder(rf, config, cell, cfo); + ret = rf_mib_decoder(rf, nof_rx_antennas, config, cell, cfo); if (ret < 0) { fprintf(stderr, "Could not decode PBCH from CELL ID %d\n", cell->id); return SRSLTE_ERROR; diff --git a/srslte/lib/ue/ue_cell_search.c b/srslte/lib/ue/ue_cell_search.c index 018f20a8a..a535b7c64 100644 --- a/srslte/lib/ue/ue_cell_search.c +++ b/srslte/lib/ue/ue_cell_search.c @@ -36,7 +36,9 @@ #include "srslte/utils/vector.h" int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, - int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler) + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -50,11 +52,16 @@ int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, cell.id = SRSLTE_CELL_ID_UNKNOWN; cell.nof_prb = SRSLTE_CS_NOF_PRB; - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); goto clean_exit; } + for (int i=0;isf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100)); + } + q->nof_rx_antennas = nof_rx_antennas; + q->candidates = calloc(sizeof(srslte_ue_cellsearch_result_t), max_frames); if (!q->candidates) { perror("malloc"); @@ -86,6 +93,11 @@ clean_exit: void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t * q) { + for (int i=0;inof_rx_antennas;i++) { + if (q->sf_buffer[i]) { + free(q->sf_buffer[i]); + } + } if (q->candidates) { free(q->candidates); } @@ -203,7 +215,6 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, srslte_ue_cellsearch_result_t *found_cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - cf_t *sf_buffer = NULL; uint32_t nof_detected_frames = 0; uint32_t nof_scanned_frames = 0; @@ -215,7 +226,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, srslte_ue_sync_reset(&q->ue_sync); do { - ret = srslte_ue_sync_get_buffer(&q->ue_sync, &sf_buffer); + ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index d1a19620a..6f326b114 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -46,11 +46,13 @@ const uint32_t nof_common_formats = 2; int srslte_ue_dl_init(srslte_ue_dl_t *q, - srslte_cell_t cell) + srslte_cell_t cell, + uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - if (q != NULL && + if (q != NULL && + nof_rx_antennas <= SRSLTE_MAX_RXANT && srslte_cell_isvalid(&cell)) { ret = SRSLTE_ERROR; @@ -62,6 +64,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, q->pkts_total = 0; q->pending_ul_dci_rnti = 0; q->sample_offset = 0; + q->nof_rx_antennas = nof_rx_antennas; if (srslte_ofdm_rx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); @@ -89,7 +92,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, goto clean_exit; } - if (srslte_pdsch_init(&q->pdsch, q->cell)) { + if (srslte_pdsch_init_multi(&q->pdsch, q->cell, nof_rx_antennas)) { fprintf(stderr, "Error creating PDSCH object\n"); goto clean_exit; } @@ -103,17 +106,19 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, } srslte_cfo_set_tol(&q->sfo_correct, 1e-5/q->fft.symbol_sz); - q->sf_symbols = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->sf_symbols) { - perror("malloc"); - goto clean_exit; - } - for (uint32_t i=0;icell.nof_ports;i++) { - q->ce[i] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->ce[i]) { + for (int j=0;jsf_symbols[j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->sf_symbols[j]) { perror("malloc"); goto clean_exit; } + for (uint32_t i=0;icell.nof_ports;i++) { + q->ce[i][j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->ce[i][j]) { + perror("malloc"); + goto clean_exit; + } + } } ret = SRSLTE_SUCCESS; @@ -140,12 +145,14 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { srslte_pdsch_free(&q->pdsch); srslte_cfo_free(&q->sfo_correct); srslte_softbuffer_rx_free(&q->softbuffer); - if (q->sf_symbols) { - free(q->sf_symbols); - } - for (uint32_t i=0;icell.nof_ports;i++) { - if (q->ce[i]) { - free(q->ce[i]); + for (int j=0;jnof_rx_antennas;j++) { + if (q->sf_symbols[j]) { + free(q->sf_symbols[j]); + } + for (uint32_t i=0;icell.nof_ports;i++) { + if (q->ce[i][j]) { + free(q->ce[i][j]); + } } } bzero(q, sizeof(srslte_ue_dl_t)); @@ -186,23 +193,25 @@ void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { * - PDCCH decoding: Find DCI for RNTI given by previous call to srslte_ue_dl_set_rnti() * - PDSCH decoding: Decode TB scrambling with RNTI given by srslte_ue_dl_set_rnti() */ -int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti) { +int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint8_t *data, uint32_t tti) { return srslte_ue_dl_decode_rnti(q, input, data, tti, q->current_rnti); } -int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf_idx, uint32_t *cfi) { +int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint32_t sf_idx, uint32_t *cfi) { if (input && q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Run FFT for all subframe data */ - srslte_ofdm_rx_sf(&q->fft, input, q->sf_symbols); - - /* Correct SFO multiplying by complex exponential in the time domain */ - if (q->sample_offset) { - for (int i=0;i<2*SRSLTE_CP_NSYMB(q->cell.cp);i++) { - srslte_cfo_correct(&q->sfo_correct, - &q->sf_symbols[i*q->cell.nof_prb*SRSLTE_NRE], - &q->sf_symbols[i*q->cell.nof_prb*SRSLTE_NRE], - q->sample_offset / q->fft.symbol_sz); + for (int j=0;jnof_rx_antennas;j++) { + srslte_ofdm_rx_sf(&q->fft, input[j], q->sf_symbols[j]); + + /* Correct SFO multiplying by complex exponential in the time domain */ + if (q->sample_offset) { + for (int i=0;i<2*SRSLTE_CP_NSYMB(q->cell.cp);i++) { + srslte_cfo_correct(&q->sfo_correct, + &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], + &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], + q->sample_offset / q->fft.symbol_sz); + } } } return srslte_ue_dl_decode_estimate(q, sf_idx, cfi); @@ -216,10 +225,14 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c if (q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Get channel estimates for each port */ - srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx); + srslte_chest_dl_estimate_multi(&q->chest, q->sf_symbols, q->ce, sf_idx, q->nof_rx_antennas); /* First decode PCFICH and obtain CFI */ - if (srslte_pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, + cf_t *ce0[SRSLTE_MAX_PORTS]; + for (int i=0;ice[i][0]; + } + if (srslte_pcfich_decode(&q->pcfich, q->sf_symbols[0], ce0, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); @@ -245,7 +258,7 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx); } -int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti) +int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint8_t *data, uint32_t tti, uint16_t rnti) { srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; @@ -259,7 +272,11 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint return ret; } - if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { + cf_t *ce0[SRSLTE_MAX_PORTS]; + for (int i=0;ice[i][0]; + } + if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols[0], ce0, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } @@ -299,7 +316,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { - ret = srslte_pdsch_decode(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, + ret = srslte_pdsch_decode_multi(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, q->sf_symbols, q->ce, noise_estimate, rnti, data); @@ -502,7 +519,14 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr INFO("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d, Ngroups=%d, Nsf=%d\n", sf_idx, n_prb_lowest, n_dmrs, ngroup, nseq, srslte_phich_ngroups(&q->phich), srslte_phich_nsf(&q->phich)); - if (!srslte_phich_decode(&q->phich, q->sf_symbols, q->ce, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { + + cf_t *ce0[SRSLTE_MAX_PORTS]; + for (int i=0;ice[i][0]; + } + + + if (!srslte_phich_decode(&q->phich, q->sf_symbols[0], ce0, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance); } else { fprintf(stderr, "Error decoding PHICH\n"); diff --git a/srslte/lib/ue/ue_mib.c b/srslte/lib/ue/ue_mib.c index 5cfeaaadd..7e178161b 100644 --- a/srslte/lib/ue/ue_mib.c +++ b/srslte/lib/ue/ue_mib.c @@ -164,10 +164,11 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, - uint32_t cell_id, - srslte_cp_t cp, - int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), - void *stream_handler) + uint32_t cell_id, + srslte_cp_t cp, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t, srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) { srslte_cell_t cell; // If the ports are set to 0, ue_mib goes through 1, 2 and 4 ports to blindly detect nof_ports @@ -176,11 +177,16 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, cell.cp = cp; cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; + for (int i=0;isf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); + } + q->nof_rx_antennas = nof_rx_antennas; + if (srslte_ue_mib_init(&q->ue_mib, cell)) { fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; @@ -190,6 +196,11 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, } void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q) { + for (int i=0;inof_rx_antennas;i++) { + if (q->sf_buffer[i]) { + free(q->sf_buffer[i]); + } + } srslte_ue_mib_free(&q->ue_mib); srslte_ue_sync_free(&q->ue_sync); } @@ -207,7 +218,6 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q, { int ret = SRSLTE_ERROR_INVALID_INPUTS; - cf_t *sf_buffer = NULL; uint32_t nof_frames = 0; int mib_ret = SRSLTE_UE_MIB_NOTFOUND; @@ -216,13 +226,13 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q, ret = SRSLTE_SUCCESS; do { mib_ret = SRSLTE_UE_MIB_NOTFOUND; - ret = srslte_ue_sync_get_buffer(&q->ue_sync, &sf_buffer); + ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; } else if (srslte_ue_sync_get_sfidx(&q->ue_sync) == 0) { if (ret == 1) { - mib_ret = srslte_ue_mib_decode(&q->ue_mib, sf_buffer, bch_payload, nof_tx_ports, sfn_offset); + mib_ret = srslte_ue_mib_decode(&q->ue_mib, q->sf_buffer[0], bch_payload, nof_tx_ports, sfn_offset); } else { DEBUG("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt); srslte_ue_mib_reset(&q->ue_mib); diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index 6ef05daff..bc045eb57 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -39,7 +39,6 @@ #define MAX_TIME_OFFSET 128 -cf_t dummy[MAX_TIME_OFFSET]; #define TRACK_MAX_LOST 4 #define TRACK_FRAME_SIZE 32 @@ -47,7 +46,11 @@ cf_t dummy[MAX_TIME_OFFSET]; #define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0 #define DEFAULT_SFO_EMA_COEFF 0.1 -cf_t dummy_offset_buffer[1024*1024]; +cf_t dummy_buffer0[15*2048/2]; +cf_t dummy_buffer1[15*2048/2]; + +// FIXME: this will break for 4 antennas!! +cf_t *dummy_offset_buffer[SRSLTE_MAX_RXANT] = {dummy_buffer0, dummy_buffer1}; int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, int offset_time, float offset_freq) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -74,12 +77,6 @@ int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_n goto clean_exit; } - q->input_buffer = srslte_vec_malloc(2 * q->sf_len * sizeof(cf_t)); - if (!q->input_buffer) { - perror("malloc"); - goto clean_exit; - } - INFO("Offseting input file by %d samples and %.1f kHz\n", offset_time, offset_freq/1000); srslte_filesource_read(&q->file_source, dummy_offset_buffer, offset_time); @@ -111,14 +108,16 @@ int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(voi int srslte_ue_sync_init(srslte_ue_sync_t *q, srslte_cell_t cell, - int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, void *stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && stream_handler != NULL && - srslte_nofprb_isvalid(cell.nof_prb) && + srslte_nofprb_isvalid(cell.nof_prb) && + nof_rx_antennas <= SRSLTE_MAX_RXANT && recv_callback != NULL) { ret = SRSLTE_ERROR; @@ -127,6 +126,7 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q, q->stream = stream_handler; q->recv_callback = recv_callback; + q->nof_rx_antennas = nof_rx_antennas; q->cell = cell; q->fft_size = srslte_symbol_sz(q->cell.nof_prb); q->sf_len = SRSLTE_SF_LEN(q->fft_size); @@ -209,13 +209,6 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q, } - /* FIXME: Go for zerocopy only and eliminate this allocation */ - q->input_buffer = srslte_vec_malloc(2*q->frame_len * sizeof(cf_t)); - if (!q->input_buffer) { - perror("malloc"); - goto clean_exit; - } - srslte_ue_sync_reset(q); ret = SRSLTE_SUCCESS; @@ -233,9 +226,6 @@ uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q) { } void srslte_ue_sync_free(srslte_ue_sync_t *q) { - if (q->input_buffer) { - free(q->input_buffer); - } if (q->do_agc) { srslte_agc_free(&q->agc); } @@ -309,7 +299,7 @@ void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q, uint32_t period) { q->agc_period = period; } -static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer) { +static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { if (srslte_sync_sss_detected(&q->sfind)) { @@ -408,7 +398,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { discard the offseted samples to align next frame */ if (q->next_rf_sample_offset > 0 && q->next_rf_sample_offset < MAX_TIME_OFFSET) { DEBUG("Positive time offset %d samples.\n", q->next_rf_sample_offset); - if (q->recv_callback(q->stream, dummy, (uint32_t) q->next_rf_sample_offset, &q->last_timestamp) < 0) { + if (q->recv_callback(q->stream, dummy_offset_buffer, (uint32_t) q->next_rf_sample_offset, &q->last_timestamp) < 0) { fprintf(stderr, "Error receiving from USRP\n"); return SRSLTE_ERROR; } @@ -443,7 +433,7 @@ static int track_peak_no(srslte_ue_sync_t *q) { } -static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { +static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { /* A negative time offset means there are samples in our buffer for the next subframe, because we are sampling too fast. @@ -453,7 +443,11 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { } /* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */ - if (q->recv_callback(q->stream, &input_buffer[q->next_rf_sample_offset], q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) { + cf_t *ptr[SRSLTE_MAX_RXANT]; + for (int i=0;inext_rf_sample_offset]; + } + if (q->recv_callback(q->stream, ptr, q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) { return SRSLTE_ERROR; } @@ -465,17 +459,8 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { bool first_track = true; -int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { - int ret = srslte_ue_sync_zerocopy(q, q->input_buffer); - if (sf_symbols) { - *sf_symbols = q->input_buffer; - } - return ret; - -} - /* Returns 1 if the subframe is synchronized in time, 0 otherwise */ -int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { +int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t track_idx; @@ -484,7 +469,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { { if (q->file_mode) { - int n = srslte_filesource_read(&q->file_source, input_buffer, q->sf_len); + int n = srslte_filesource_read(&q->file_source, input_buffer[0], q->sf_len); if (n < 0) { fprintf(stderr, "Error reading input file\n"); return SRSLTE_ERROR; @@ -492,7 +477,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { if (n == 0) { srslte_filesource_seek(&q->file_source, 0); q->sf_idx = 9; - int n = srslte_filesource_read(&q->file_source, input_buffer, q->sf_len); + int n = srslte_filesource_read(&q->file_source, input_buffer[0], q->sf_len); if (n < 0) { fprintf(stderr, "Error reading input file\n"); return SRSLTE_ERROR; @@ -500,8 +485,8 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { } if (q->correct_cfo) { srslte_cfo_correct(&q->file_cfo_correct, - input_buffer, - input_buffer, + input_buffer[0], + input_buffer[0], q->file_cfo / 15000 / q->fft_size); } @@ -519,7 +504,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { switch (q->state) { case SF_FIND: - switch(srslte_sync_find(&q->sfind, input_buffer, 0, &q->peak_idx)) { + switch(srslte_sync_find(&q->sfind, input_buffer[0], 0, &q->peak_idx)) { case SRSLTE_SYNC_ERROR: ret = SRSLTE_ERROR; fprintf(stderr, "Error finding correlation peak (%d)\n", ret); @@ -539,7 +524,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { break; } if (q->do_agc) { - srslte_agc_process(&q->agc, input_buffer, q->sf_len); + srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } break; @@ -557,7 +542,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { if (q->do_agc && (q->agc_period == 0 || (q->agc_period && (q->frame_total_cnt%q->agc_period) == 0))) { - srslte_agc_process(&q->agc, input_buffer, q->sf_len); + srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } #ifdef MEASURE_EXEC_TIME @@ -570,7 +555,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { /* Track PSS/SSS around the expected PSS position * In tracking phase, the subframe carrying the PSS is always the last one of the frame */ - switch(srslte_sync_find(&q->strack, input_buffer, + switch(srslte_sync_find(&q->strack, input_buffer[0], q->frame_len - q->sf_len/2 - q->fft_size - q->strack.max_offset/2, &track_idx)) { @@ -607,10 +592,12 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { q->frame_total_cnt++; } if (q->correct_cfo) { - srslte_cfo_correct(&q->sfind.cfocorr, - input_buffer, - input_buffer, + for (int i=0;inof_rx_antennas;i++) { + srslte_cfo_correct(&q->sfind.cfocorr, + input_buffer[i], + input_buffer[i], -srslte_sync_get_cfo(&q->strack) / q->fft_size); + } } break; }