mirror of https://github.com/PentHertz/srsLTE.git
pdsch ue working with 1 and 2 antennas
This commit is contained in:
parent
e850caaf96
commit
0a5a6245f1
|
@ -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);
|
||||
|
|
|
@ -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;i<SRSLTE_MAX_RXANT;i++) {
|
||||
ptr[i] = data[i];
|
||||
}
|
||||
return srslte_rf_recv_with_time_multi((srslte_rf_t*) h, ptr, nsamples, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
bool go_exit = false;
|
||||
|
@ -200,7 +204,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
|
||||
|
||||
if (srslte_ue_cellsearch_init(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, (void*) &rf)) {
|
||||
if (srslte_ue_cellsearch_init(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
|
||||
fprintf(stderr, "Error initiating UE cell detect\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -228,7 +232,7 @@ int main(int argc, char **argv) {
|
|||
srslte_cell_t cell;
|
||||
cell.id = found_cells[i].cell_id;
|
||||
cell.cp = found_cells[i].cp;
|
||||
int ret = rf_mib_decoder(&rf, &cell_detect_config, &cell, NULL);
|
||||
int ret = rf_mib_decoder(&rf, 1, &cell_detect_config, &cell, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error decoding MIB\n");
|
||||
exit(-1);
|
||||
|
|
|
@ -260,10 +260,13 @@ void sig_int_handler(int signo)
|
|||
cf_t *sf_buffer[2] = {NULL, NULL};
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
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);
|
||||
void *d[2] = {data, sf_buffer[1]};
|
||||
return srslte_rf_recv_with_time_multi(h, d, nsamples, true, NULL, NULL);
|
||||
void *ptr[SRSLTE_MAX_RXANT];
|
||||
for (int i=0;i<SRSLTE_MAX_RXANT;i++) {
|
||||
ptr[i] = data[i];
|
||||
}
|
||||
return srslte_rf_recv_with_time_multi(h, ptr, nsamples, true, NULL, NULL);
|
||||
}
|
||||
|
||||
double srslte_rf_set_rx_gain_th_wrapper_(void *h, double f) {
|
||||
|
@ -351,7 +354,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, prog_args.rf_nof_rx_ant, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error searching for cell\n");
|
||||
exit(-1);
|
||||
|
@ -386,7 +389,7 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
printf("Stopping RF and flushing buffer...\r",0);
|
||||
INFO("Stopping RF and flushing buffer...\r",0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -408,7 +411,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
} else {
|
||||
#ifndef DISABLE_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, prog_args.rf_nof_rx_ant, (void*) &rf)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -420,7 +423,7 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_ue_dl_init(&ue_dl, cell)) { // This is the User RNTI
|
||||
if (srslte_ue_dl_init(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI
|
||||
fprintf(stderr, "Error initiating UE downlink processing module\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -471,11 +474,11 @@ int main(int argc, char **argv) {
|
|||
|
||||
srslte_pbch_decode_reset(&ue_mib.pbch);
|
||||
|
||||
printf("\nEntering main loop...\n\n", 0);
|
||||
INFO("\nEntering main loop...\n\n", 0);
|
||||
/* Main loop */
|
||||
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
|
||||
|
||||
ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer[0]);
|
||||
ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
|
||||
}
|
||||
|
@ -517,7 +520,7 @@ int main(int argc, char **argv) {
|
|||
if (decode_pdsch) {
|
||||
INFO("Attempting DL decode SFN=%d\n", sfn);
|
||||
n = srslte_ue_dl_decode(&ue_dl,
|
||||
sf_buffer[0],
|
||||
sf_buffer,
|
||||
data,
|
||||
sfn*10+srslte_ue_sync_get_sfidx(&ue_sync));
|
||||
|
||||
|
@ -698,7 +701,7 @@ void *plot_thread_run(void *arg) {
|
|||
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits.nof_re;
|
||||
if (!prog_args.disable_plots_except_constellation) {
|
||||
for (i = 0; i < nof_re; i++) {
|
||||
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));
|
||||
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[0][i]));
|
||||
if (isinf(tmp_plot[i])) {
|
||||
tmp_plot[i] = -80;
|
||||
}
|
||||
|
@ -707,7 +710,7 @@ void *plot_thread_run(void *arg) {
|
|||
bzero(tmp_plot2, sizeof(float)*sz);
|
||||
int g = (sz - 12*ue_dl.cell.nof_prb)/2;
|
||||
for (i = 0; i < 12*ue_dl.cell.nof_prb; i++) {
|
||||
tmp_plot2[g+i] = 20 * log10(cabs(ue_dl.ce[0][i]));
|
||||
tmp_plot2[g+i] = 20 * log10(cabs(ue_dl.ce[0][0][i]));
|
||||
if (isinf(tmp_plot2[g+i])) {
|
||||
tmp_plot2[g+i] = -80;
|
||||
}
|
||||
|
|
|
@ -98,13 +98,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(h, data, nsamples, 1);
|
||||
return srslte_rf_recv(h, data[2], nsamples, 1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
cf_t *buffer;
|
||||
cf_t *buffer[SRSLTE_MAX_RXANT] = {NULL, NULL};
|
||||
int n;
|
||||
srslte_rf_t rf;
|
||||
srslte_filesink_t sink;
|
||||
|
@ -124,6 +124,8 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
srslte_rf_set_master_clock_rate(&rf, 30.72e6);
|
||||
|
||||
buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100));
|
||||
|
||||
sigset_t sigset;
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGINT);
|
||||
|
@ -156,7 +158,7 @@ int main(int argc, char **argv) {
|
|||
cell.nof_prb = nof_prb;
|
||||
cell.nof_ports = 1;
|
||||
|
||||
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");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -167,7 +169,7 @@ int main(int argc, char **argv) {
|
|||
while((subframe_count < nof_subframes || nof_subframes == -1)
|
||||
&& !stop_capture)
|
||||
{
|
||||
n = srslte_ue_sync_get_buffer(&ue_sync, &buffer);
|
||||
n = srslte_ue_sync_zerocopy(&ue_sync, buffer);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error receiving samples\n");
|
||||
exit(-1);
|
||||
|
@ -179,7 +181,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
} else {
|
||||
printf("Writing to file %6d subframes...\r", subframe_count);
|
||||
srslte_filesink_write(&sink, buffer, SRSLTE_SF_LEN_PRB(nof_prb));
|
||||
srslte_filesink_write(&sink, buffer[0], SRSLTE_SF_LEN_PRB(nof_prb));
|
||||
subframe_count++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,17 +43,20 @@ SRSLTE_API int rf_rssi_scan(srslte_rf_t *rf,
|
|||
int nsamp);
|
||||
|
||||
SRSLTE_API int rf_mib_decoder(srslte_rf_t *rf,
|
||||
uint32_t nof_rx_antennas,
|
||||
cell_search_cfg_t *config,
|
||||
srslte_cell_t *cell,
|
||||
float *cfo);
|
||||
|
||||
SRSLTE_API 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);
|
||||
|
||||
SRSLTE_API 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,
|
||||
|
|
|
@ -69,6 +69,9 @@ typedef struct SRSLTE_API {
|
|||
typedef struct SRSLTE_API {
|
||||
srslte_ue_sync_t ue_sync;
|
||||
|
||||
cf_t *sf_buffer[SRSLTE_MAX_RXANT];
|
||||
uint32_t nof_rx_antennas;
|
||||
|
||||
uint32_t max_frames;
|
||||
uint32_t nof_valid_frames; // number of 5 ms frames to scan
|
||||
|
||||
|
@ -80,7 +83,8 @@ typedef struct SRSLTE_API {
|
|||
|
||||
SRSLTE_API int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t *q,
|
||||
uint32_t max_frames_total,
|
||||
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);
|
||||
|
||||
SRSLTE_API void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t *q);
|
||||
|
|
|
@ -88,8 +88,10 @@ typedef struct SRSLTE_API {
|
|||
srslte_ra_dl_dci_t dl_dci;
|
||||
srslte_cell_t cell;
|
||||
|
||||
cf_t *sf_symbols;
|
||||
cf_t *ce[SRSLTE_MAX_PORTS];
|
||||
uint32_t nof_rx_antennas;
|
||||
|
||||
cf_t *sf_symbols[SRSLTE_MAX_RXANT];
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT];
|
||||
|
||||
srslte_dci_format_t dci_format;
|
||||
uint64_t pkt_errors;
|
||||
|
@ -110,12 +112,13 @@ typedef struct SRSLTE_API {
|
|||
|
||||
/* This function shall be called just after the initial synchronization */
|
||||
SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
srslte_cell_t cell,
|
||||
uint32_t nof_rx_antennas);
|
||||
|
||||
SRSLTE_API void srslte_ue_dl_free(srslte_ue_dl_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q,
|
||||
cf_t *input,
|
||||
cf_t *input[SRSLTE_MAX_RXANT],
|
||||
uint32_t sf_idx,
|
||||
uint32_t *cfi);
|
||||
|
||||
|
@ -154,12 +157,12 @@ SRSLTE_API void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q,
|
|||
float sample_offset);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t * q,
|
||||
cf_t *input,
|
||||
cf_t *input[SRSLTE_MAX_RXANT],
|
||||
uint8_t *data,
|
||||
uint32_t tti);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t * q,
|
||||
cf_t *input,
|
||||
cf_t *input[SRSLTE_MAX_RXANT],
|
||||
uint8_t *data,
|
||||
uint32_t tti,
|
||||
uint16_t rnti);
|
||||
|
|
|
@ -100,12 +100,15 @@ SRSLTE_API int srslte_ue_mib_decode(srslte_ue_mib_t * q,
|
|||
typedef struct {
|
||||
srslte_ue_mib_t ue_mib;
|
||||
srslte_ue_sync_t ue_sync;
|
||||
cf_t *sf_buffer[SRSLTE_MAX_RXANT];
|
||||
uint32_t nof_rx_antennas;
|
||||
} srslte_ue_mib_sync_t;
|
||||
|
||||
SRSLTE_API 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 *),
|
||||
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t, srslte_timestamp_t *),
|
||||
uint32_t nof_rx_antennas,
|
||||
void *stream_handler);
|
||||
|
||||
SRSLTE_API void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q);
|
||||
|
|
|
@ -75,9 +75,11 @@ typedef struct SRSLTE_API {
|
|||
uint32_t agc_period;
|
||||
|
||||
void *stream;
|
||||
int (*recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*);
|
||||
int (*recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t, srslte_timestamp_t*);
|
||||
srslte_timestamp_t last_timestamp;
|
||||
|
||||
uint32_t nof_rx_antennas;
|
||||
|
||||
srslte_filesource_t file_source;
|
||||
bool file_mode;
|
||||
float file_cfo;
|
||||
|
@ -85,8 +87,6 @@ typedef struct SRSLTE_API {
|
|||
|
||||
srslte_ue_sync_state_t state;
|
||||
|
||||
cf_t *input_buffer;
|
||||
|
||||
uint32_t frame_len;
|
||||
uint32_t fft_size;
|
||||
uint32_t nof_recv_sf; // Number of subframes received each call to srslte_ue_sync_get_buffer
|
||||
|
@ -124,7 +124,8 @@ typedef struct SRSLTE_API {
|
|||
|
||||
SRSLTE_API 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);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q,
|
||||
|
@ -141,15 +142,12 @@ SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t *q,
|
|||
|
||||
SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q,
|
||||
cf_t **sf_symbols);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q,
|
||||
uint32_t period);
|
||||
|
||||
/* CAUTION: input_buffer MUST have space for 2 subframes */
|
||||
SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q,
|
||||
cf_t *input_buffer);
|
||||
cf_t *input_buffer[SRSLTE_MAX_RXANT]);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q,
|
||||
float cfo);
|
||||
|
|
|
@ -358,7 +358,6 @@ int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_
|
|||
{
|
||||
for (uint32_t rxant=0;rxant<nof_rx_antennas;rxant++) {
|
||||
for (uint32_t port_id=0;port_id<q->cell.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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;i<SRSLTE_MAX_RXANT;i++) {
|
||||
ptr[i] = data[i];
|
||||
}
|
||||
return srslte_rf_recv_with_time_multi(h, ptr, nsamples, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
double srslte_rf_set_rx_gain_th_wrapper(void *h, double f) {
|
||||
|
@ -96,12 +98,12 @@ double srslte_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(srslte_rf_t *rf, cell_search_cfg_t *config, srslte_cell_t *cell, float *cfo) {
|
||||
int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t *config, srslte_cell_t *cell, float *cfo) {
|
||||
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, 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;
|
||||
|
|
|
@ -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;i<nof_rx_antennas;i++) {
|
||||
q->sf_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;i<q->nof_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;
|
||||
|
|
|
@ -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;i<q->cell.nof_ports;i++) {
|
||||
q->ce[i] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t));
|
||||
if (!q->ce[i]) {
|
||||
for (int j=0;j<nof_rx_antennas;j++) {
|
||||
q->sf_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;i<q->cell.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;i<q->cell.nof_ports;i++) {
|
||||
if (q->ce[i]) {
|
||||
free(q->ce[i]);
|
||||
for (int j=0;j<q->nof_rx_antennas;j++) {
|
||||
if (q->sf_symbols[j]) {
|
||||
free(q->sf_symbols[j]);
|
||||
}
|
||||
for (uint32_t i=0;i<q->cell.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;j<q->nof_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;i<SRSLTE_MAX_PORTS;i++) {
|
||||
ce0[i] = q->ce[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;i<SRSLTE_MAX_PORTS;i++) {
|
||||
ce0[i] = q->ce[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;i<SRSLTE_MAX_PORTS;i++) {
|
||||
ce0[i] = q->ce[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");
|
||||
|
|
|
@ -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;i<nof_rx_antennas;i++) {
|
||||
q->sf_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;i<q->nof_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);
|
||||
|
|
|
@ -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;i<SRSLTE_MAX_RXANT;i++) {
|
||||
ptr[i] = &input_buffer[i][q->next_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;i<q->nof_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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue