Merge branch 'next_novolk' of https://github.com/softwareradiosystems/srsLTE into next_novolk

master
Xavier Arteaga 7 years ago
commit a400999927

@ -249,7 +249,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
return -1; return -1;
} }
if (srslte_ue_dl_init(&ue_dl, cell.nof_prb, 1)) { if (srslte_ue_dl_init(&ue_dl, sf_buffer, cell.nof_prb, 1)) {
fprintf(stderr, "Error initiating UE downlink processing module\n"); fprintf(stderr, "Error initiating UE downlink processing module\n");
return -1; return -1;
} }
@ -257,7 +257,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error initiating UE downlink processing module\n"); fprintf(stderr, "Error initiating UE downlink processing module\n");
return -1; return -1;
} }
if (srslte_ue_mib_init(&ue_mib, cell.nof_prb)) { if (srslte_ue_mib_init(&ue_mib, sf_buffer, cell.nof_prb)) {
fprintf(stderr, "Error initaiting UE MIB decoder\n"); fprintf(stderr, "Error initaiting UE MIB decoder\n");
return -1; return -1;
} }
@ -272,7 +272,15 @@ int main(int argc, char **argv) {
/* Initialize subframe counter */ /* Initialize subframe counter */
sf_cnt = 0; sf_cnt = 0;
if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) { int sf_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);
cf_t *sf_symbols = srslte_vec_malloc(sf_re * sizeof(cf_t));
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
ce[i] = srslte_vec_malloc(sizeof(cf_t) * sf_re);
}
if (srslte_ofdm_rx_init(&fft, cell.cp, sf_buffer[0], sf_symbols, cell.nof_prb)) {
fprintf(stderr, "Error initiating FFT\n"); fprintf(stderr, "Error initiating FFT\n");
return -1; return -1;
} }
@ -285,14 +293,6 @@ int main(int argc, char **argv) {
return -1; return -1;
} }
int sf_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);
cf_t *sf_symbols = srslte_vec_malloc(sf_re * sizeof(cf_t));
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
ce[i] = srslte_vec_malloc(sizeof(cf_t) * sf_re);
}
srslte_rf_start_rx_stream(&rf); srslte_rf_start_rx_stream(&rf);
float rx_gain_offset = 0; float rx_gain_offset = 0;
@ -315,7 +315,7 @@ int main(int argc, char **argv) {
case DECODE_MIB: case DECODE_MIB:
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
srslte_pbch_decode_reset(&ue_mib.pbch); srslte_pbch_decode_reset(&ue_mib.pbch);
n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset); n = srslte_ue_mib_decode(&ue_mib, bch_payload, NULL, &sfn_offset);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE MIB\n"); fprintf(stderr, "Error decoding UE MIB\n");
return -1; return -1;
@ -351,7 +351,7 @@ int main(int argc, char **argv) {
if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) {
/* Run FFT for all subframe data */ /* Run FFT for all subframe data */
srslte_ofdm_rx_sf(&fft, sf_buffer[0], sf_symbols); srslte_ofdm_rx_sf(&fft);
srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync)); srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync));

@ -86,7 +86,7 @@ float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 2400000000;
bool null_file_sink=false; bool null_file_sink=false;
srslte_filesink_t fsink; srslte_filesink_t fsink;
srslte_ofdm_t ifft; srslte_ofdm_t ifft[SRSLTE_MAX_PORTS];
srslte_ofdm_t ifft_mbsfn; srslte_ofdm_t ifft_mbsfn;
srslte_pbch_t pbch; srslte_pbch_t pbch;
srslte_pcfich_t pcfich; srslte_pcfich_t pcfich;
@ -311,18 +311,21 @@ void base_init() {
} }
/* create ifft object */ /* create ifft object */
if (srslte_ofdm_tx_init(&ifft, SRSLTE_CP_NORM, cell.nof_prb)) { for (i = 0; i < cell.nof_ports; i++) {
if (srslte_ofdm_tx_init(&ifft[i], SRSLTE_CP_NORM, sf_buffer[i], output_buffer[i], cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n"); fprintf(stderr, "Error creating iFFT object\n");
exit(-1); exit(-1);
} }
if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn, SRSLTE_CP_EXT, cell.nof_prb)) {
srslte_ofdm_set_normalize(&ifft[i], true);
}
if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn, SRSLTE_CP_EXT, sf_buffer[0], output_buffer[0], cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n"); fprintf(stderr, "Error creating iFFT object\n");
exit(-1); exit(-1);
} }
srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn, 2); srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn, 2);
srslte_ofdm_set_normalize(&ifft_mbsfn, true); srslte_ofdm_set_normalize(&ifft_mbsfn, true);
srslte_ofdm_set_normalize(&ifft, true);
if (srslte_pbch_init(&pbch)) { if (srslte_pbch_init(&pbch)) {
fprintf(stderr, "Error creating PBCH object\n"); fprintf(stderr, "Error creating PBCH object\n");
@ -413,8 +416,9 @@ void base_free() {
srslte_pmch_free(&pmch); srslte_pmch_free(&pmch);
} }
srslte_ofdm_tx_free(&ifft_mbsfn); srslte_ofdm_tx_free(&ifft_mbsfn);
srslte_ofdm_tx_free(&ifft); for (i = 0; i < cell.nof_ports; i++) {
srslte_ofdm_tx_free(&ifft[i]);
}
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (data[i]) { if (data[i]) {
@ -977,10 +981,10 @@ int main(int argc, char **argv) {
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
if(sf_idx != 1 || mbsfn_area_id < 0){ if(sf_idx != 1 || mbsfn_area_id < 0){
for (i = 0; i < cell.nof_ports; i++) { for (i = 0; i < cell.nof_ports; i++) {
srslte_ofdm_tx_sf(&ifft, sf_buffer[i], output_buffer[i]); srslte_ofdm_tx_sf(&ifft[i]);
} }
}else{ }else{
srslte_ofdm_tx_sf(&ifft_mbsfn, sf_buffer[0], output_buffer[0]); srslte_ofdm_tx_sf(&ifft_mbsfn);
} }
/* send to file or usrp */ /* send to file or usrp */

@ -510,7 +510,10 @@ int main(int argc, char **argv) {
#endif #endif
} }
if (srslte_ue_mib_init(&ue_mib, cell.nof_prb)) { for (int i=0;i<prog_args.rf_nof_rx_ant;i++) {
sf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
if (srslte_ue_mib_init(&ue_mib, sf_buffer, cell.nof_prb)) {
fprintf(stderr, "Error initaiting UE MIB decoder\n"); fprintf(stderr, "Error initaiting UE MIB decoder\n");
exit(-1); exit(-1);
} }
@ -519,7 +522,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_ue_dl_init(&ue_dl, cell.nof_prb, prog_args.rf_nof_rx_ant)) { if (srslte_ue_dl_init(&ue_dl, sf_buffer, cell.nof_prb, prog_args.rf_nof_rx_ant)) {
fprintf(stderr, "Error initiating UE downlink processing module\n"); fprintf(stderr, "Error initiating UE downlink processing module\n");
exit(-1); exit(-1);
} }
@ -528,10 +531,6 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
for (int i=0;i<prog_args.rf_nof_rx_ant;i++) {
sf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
/* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */ /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */
srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti); srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti);
@ -632,7 +631,7 @@ int main(int argc, char **argv) {
switch (state) { switch (state) {
case DECODE_MIB: case DECODE_MIB:
if (sfidx == 0) { if (sfidx == 0) {
n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset); n = srslte_ue_mib_decode(&ue_mib, bch_payload, NULL, &sfn_offset);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE MIB\n"); fprintf(stderr, "Error decoding UE MIB\n");
exit(-1); exit(-1);

@ -101,8 +101,8 @@ typedef enum {SRSLTE_SF_NORM, SRSLTE_SF_MBSFN} srslte_sf_t;
#define SRSLTE_CP_ISEXT(cp) (cp==SRSLTE_CP_EXT) #define SRSLTE_CP_ISEXT(cp) (cp==SRSLTE_CP_EXT)
#define SRSLTE_CP_NSYMB(cp) (SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_NORM_NSYMB:SRSLTE_CP_EXT_NSYMB) #define SRSLTE_CP_NSYMB(cp) (SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_NORM_NSYMB:SRSLTE_CP_EXT_NSYMB)
#define SRSLTE_CP_LEN(symbol_sz, c) ((int) ceil((((float) (c)*(symbol_sz))/2048))) #define SRSLTE_CP_LEN(symbol_sz, c) ((int) ceilf((((float) (c)*(symbol_sz))/2048.0f)))
#define SRSLTE_CP_LEN_NORM(symbol, symbol_sz) ((symbol==0)?SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_NORM_0_LEN):SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_NORM_LEN)) #define SRSLTE_CP_LEN_NORM(symbol, symbol_sz) (((symbol)==0)?SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_NORM_0_LEN):SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_NORM_LEN))
#define SRSLTE_CP_LEN_EXT(symbol_sz) (SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_EXT_LEN)) #define SRSLTE_CP_LEN_EXT(symbol_sz) (SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_EXT_LEN))
#define SRSLTE_SLOT_LEN(symbol_sz) (symbol_sz*15/2) #define SRSLTE_SLOT_LEN(symbol_sz) (symbol_sz*15/2)

@ -63,6 +63,7 @@ typedef struct SRSLTE_API {
void *in; // Input buffer void *in; // Input buffer
void *out; // Output buffer void *out; // Output buffer
void *p; // DFT plan void *p; // DFT plan
bool is_guru;
bool forward; // Forward transform? bool forward; // Forward transform?
bool mirror; // Shift negative and positive frequencies? bool mirror; // Shift negative and positive frequencies?
bool db; // Provide output in dB? bool db; // Provide output in dB?
@ -85,6 +86,17 @@ SRSLTE_API int srslte_dft_plan_c(srslte_dft_plan_t *plan,
int dft_points, int dft_points,
srslte_dft_dir_t dir); srslte_dft_dir_t dir);
SRSLTE_API int srslte_dft_plan_guru_c(srslte_dft_plan_t *plan,
int dft_points,
srslte_dft_dir_t dir,
cf_t *in_buffer,
cf_t *out_buffer,
int istride,
int ostride,
int how_many,
int idist,
int odist);
SRSLTE_API int srslte_dft_plan_r(srslte_dft_plan_t *plan, SRSLTE_API int srslte_dft_plan_r(srslte_dft_plan_t *plan,
int dft_points, int dft_points,
srslte_dft_dir_t dir); srslte_dft_dir_t dir);
@ -92,6 +104,16 @@ SRSLTE_API int srslte_dft_plan_r(srslte_dft_plan_t *plan,
SRSLTE_API int srslte_dft_replan(srslte_dft_plan_t *plan, SRSLTE_API int srslte_dft_replan(srslte_dft_plan_t *plan,
const int new_dft_points); const int new_dft_points);
SRSLTE_API int srslte_dft_replan_guru_c(srslte_dft_plan_t *plan,
const int new_dft_points,
cf_t *in_buffer,
cf_t *out_buffer,
int istride,
int ostride,
int how_many,
int idist,
int odist);
SRSLTE_API int srslte_dft_replan_c(srslte_dft_plan_t *plan, SRSLTE_API int srslte_dft_replan_c(srslte_dft_plan_t *plan,
int new_dft_points); int new_dft_points);
@ -129,6 +151,8 @@ SRSLTE_API void srslte_dft_run_c(srslte_dft_plan_t *plan,
cf_t *in, cf_t *in,
cf_t *out); cf_t *out);
SRSLTE_API void srslte_dft_run_guru_c(srslte_dft_plan_t *plan);
SRSLTE_API void srslte_dft_run_r(srslte_dft_plan_t *plan, SRSLTE_API void srslte_dft_run_r(srslte_dft_plan_t *plan,
float *in, float *in,
float *out); float *out);

@ -47,14 +47,18 @@
/* This is common for both directions */ /* This is common for both directions */
typedef struct SRSLTE_API{ typedef struct SRSLTE_API{
srslte_dft_plan_t fft_plan; srslte_dft_plan_t fft_plan;
srslte_dft_plan_t fft_plan_sf[2];
uint32_t max_prb; uint32_t max_prb;
uint32_t nof_symbols; uint32_t nof_symbols;
uint32_t symbol_sz; uint32_t symbol_sz;
uint32_t nof_guards; uint32_t nof_guards;
uint32_t nof_re; uint32_t nof_re;
uint32_t slot_sz; uint32_t slot_sz;
uint32_t sf_sz;
srslte_cp_t cp; srslte_cp_t cp;
cf_t *tmp; // for removing zero padding cf_t *tmp; // for removing zero padding
cf_t *in_buffer;
cf_t *out_buffer;
bool mbsfn_subframe; bool mbsfn_subframe;
uint32_t mbsfn_guard_len; uint32_t mbsfn_guard_len;
@ -69,12 +73,16 @@ typedef struct SRSLTE_API{
SRSLTE_API int srslte_ofdm_init_(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_init_(srslte_ofdm_t *q,
srslte_cp_t cp, srslte_cp_t cp,
cf_t *in_buffer,
cf_t *out_buffer,
int symbol_sz, int symbol_sz,
int nof_prb, int nof_prb,
srslte_dft_dir_t dir); srslte_dft_dir_t dir);
SRSLTE_API int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q,
srslte_cp_t cp, srslte_cp_t cp,
cf_t *in_buffer,
cf_t *out_buffer,
int symbol_sz, int symbol_sz,
int nof_prb, int nof_prb,
srslte_dft_dir_t dir, srslte_dft_dir_t dir,
@ -82,12 +90,14 @@ SRSLTE_API int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q,
SRSLTE_API int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q,
srslte_cp_t cp_type, srslte_cp_t cp_type,
cf_t *in_buffer,
cf_t *out_buffer,
uint32_t nof_prb); uint32_t nof_prb);
SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q,
srslte_cp_t cp_type, srslte_cp_t cp_type,
cf_t *in_buffer,
cf_t *out_buffer,
uint32_t max_prb); uint32_t max_prb);
SRSLTE_API int srslte_ofdm_tx_set_prb(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_tx_set_prb(srslte_ofdm_t *q,
@ -101,38 +111,34 @@ SRSLTE_API int srslte_ofdm_rx_set_prb(srslte_ofdm_t *q,
SRSLTE_API void srslte_ofdm_rx_free(srslte_ofdm_t *q); SRSLTE_API void srslte_ofdm_rx_free(srslte_ofdm_t *q);
SRSLTE_API void srslte_ofdm_rx_slot(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_rx_slot(srslte_ofdm_t *q,
cf_t *input, int slot_in_sf);
cf_t *output);
SRSLTE_API void srslte_ofdm_rx_sf(srslte_ofdm_t *q,
cf_t *input,
cf_t *output);
SRSLTE_API void srslte_ofdm_rx_sf(srslte_ofdm_t *q);
SRSLTE_API int srslte_ofdm_tx_init(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_tx_init(srslte_ofdm_t *q,
srslte_cp_t cp_type, srslte_cp_t cp_type,
cf_t *in_buffer,
cf_t *out_buffer,
uint32_t nof_prb); uint32_t nof_prb);
SRSLTE_API int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q,
srslte_cp_t cp, srslte_cp_t cp,
cf_t *in_buffer,
cf_t *out_buffer,
uint32_t nof_prb); uint32_t nof_prb);
SRSLTE_API void srslte_ofdm_tx_free(srslte_ofdm_t *q); SRSLTE_API void srslte_ofdm_tx_free(srslte_ofdm_t *q);
SRSLTE_API void srslte_ofdm_tx_slot(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_tx_slot(srslte_ofdm_t *q,
cf_t *input, int slot_in_sf);
cf_t *output);
SRSLTE_API void srslte_ofdm_tx_slot_mbsfn(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_tx_slot_mbsfn(srslte_ofdm_t *q,
cf_t *input, cf_t *input,
cf_t *output); cf_t *output);
SRSLTE_API void srslte_ofdm_tx_sf(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_tx_sf(srslte_ofdm_t *q);
cf_t *input,
cf_t *output);
SRSLTE_API int srslte_ofdm_set_freq_shift(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_set_freq_shift(srslte_ofdm_t *q,
float freq_shift); float freq_shift);

@ -68,7 +68,7 @@ typedef struct SRSLTE_API {
cf_t *sf_symbols[SRSLTE_MAX_PORTS]; cf_t *sf_symbols[SRSLTE_MAX_PORTS];
cf_t *slot1_symbols[SRSLTE_MAX_PORTS]; cf_t *slot1_symbols[SRSLTE_MAX_PORTS];
srslte_ofdm_t ifft; srslte_ofdm_t ifft[SRSLTE_MAX_PORTS];
srslte_pbch_t pbch; srslte_pbch_t pbch;
srslte_pcfich_t pcfich; srslte_pcfich_t pcfich;
srslte_regs_t regs; srslte_regs_t regs;
@ -110,6 +110,7 @@ typedef struct {
/* This function shall be called just after the initial synchronization */ /* This function shall be called just after the initial synchronization */
SRSLTE_API int srslte_enb_dl_init(srslte_enb_dl_t *q, SRSLTE_API int srslte_enb_dl_init(srslte_enb_dl_t *q,
cf_t *out_buffer[SRSLTE_MAX_PORTS],
uint32_t max_prb); uint32_t max_prb);
SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q); SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q);
@ -146,8 +147,7 @@ SRSLTE_API void srslte_enb_dl_put_phich(srslte_enb_dl_t *q,
SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t *q, SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t *q,
uint32_t tti); uint32_t tti);
SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q, SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q);
cf_t *signal_buffer);
SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q,
uint16_t rnti); uint16_t rnti);

@ -101,6 +101,7 @@ typedef struct {
/* This function shall be called just after the initial synchronization */ /* This function shall be called just after the initial synchronization */
SRSLTE_API int srslte_enb_ul_init(srslte_enb_ul_t *q, SRSLTE_API int srslte_enb_ul_init(srslte_enb_ul_t *q,
cf_t *in_buffer,
uint32_t max_prb); uint32_t max_prb);
SRSLTE_API void srslte_enb_ul_free(srslte_enb_ul_t *q); SRSLTE_API void srslte_enb_ul_free(srslte_enb_ul_t *q);

@ -80,7 +80,7 @@ typedef struct SRSLTE_API {
srslte_pmch_t pmch; srslte_pmch_t pmch;
srslte_phich_t phich; srslte_phich_t phich;
srslte_regs_t regs; srslte_regs_t regs;
srslte_ofdm_t fft; srslte_ofdm_t fft[SRSLTE_MAX_PORTS];
srslte_ofdm_t fft_mbsfn; srslte_ofdm_t fft_mbsfn;
srslte_chest_dl_t chest; srslte_chest_dl_t chest;
@ -128,6 +128,7 @@ typedef struct SRSLTE_API {
/* This function shall be called just after the initial synchronization */ /* This function shall be called just after the initial synchronization */
SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q, SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q,
cf_t *in_buffer[SRSLTE_MAX_PORTS],
uint32_t max_prb, uint32_t max_prb,
uint32_t nof_rx_antennas); uint32_t nof_rx_antennas);

@ -79,6 +79,7 @@ typedef struct SRSLTE_API {
} srslte_ue_mib_t; } srslte_ue_mib_t;
SRSLTE_API int srslte_ue_mib_init(srslte_ue_mib_t *q, SRSLTE_API int srslte_ue_mib_init(srslte_ue_mib_t *q,
cf_t *in_buffer[SRSLTE_MAX_PORTS],
uint32_t max_prb); uint32_t max_prb);
SRSLTE_API void srslte_ue_mib_free(srslte_ue_mib_t *q); SRSLTE_API void srslte_ue_mib_free(srslte_ue_mib_t *q);
@ -89,7 +90,6 @@ SRSLTE_API int srslte_ue_mib_set_cell(srslte_ue_mib_t * q,
SRSLTE_API void srslte_ue_mib_reset(srslte_ue_mib_t * q); SRSLTE_API void srslte_ue_mib_reset(srslte_ue_mib_t * q);
SRSLTE_API int srslte_ue_mib_decode(srslte_ue_mib_t * q, SRSLTE_API int srslte_ue_mib_decode(srslte_ue_mib_t * q,
cf_t *input,
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN], uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN],
uint32_t *nof_tx_ports, uint32_t *nof_tx_ports,
int *sfn_offset); int *sfn_offset);

@ -108,6 +108,7 @@ typedef struct SRSLTE_API {
/* This function shall be called just after the initial synchronization */ /* This function shall be called just after the initial synchronization */
SRSLTE_API int srslte_ue_ul_init(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_init(srslte_ue_ul_t *q,
cf_t *out_buffer,
uint32_t max_prb); uint32_t max_prb);
SRSLTE_API void srslte_ue_ul_free(srslte_ue_ul_t *q); SRSLTE_API void srslte_ue_ul_free(srslte_ue_ul_t *q);

@ -56,9 +56,7 @@ void srslte_dft_load() {
void srslte_dft_exit() { void srslte_dft_exit() {
#ifdef FFTW_WISDOM_FILE #ifdef FFTW_WISDOM_FILE
if (!fftwf_export_wisdom_to_filename(FFTW_WISDOM_FILE)) { fftwf_export_wisdom_to_filename(FFTW_WISDOM_FILE);
fprintf(stderr, "Error saving FFTW wisdom to file %s\n", FFTW_WISDOM_FILE);
}
#endif #endif
} }
@ -93,6 +91,27 @@ static void allocate(srslte_dft_plan_t *plan, int size_in, int size_out, int len
plan->out = fftwf_malloc(size_out*len); plan->out = fftwf_malloc(size_out*len);
} }
int srslte_dft_replan_guru_c(srslte_dft_plan_t *plan, const int new_dft_points, cf_t *in_buffer,
cf_t *out_buffer, int istride, int ostride, int how_many,
int idist, int odist) {
int sign = (plan->forward) ? FFTW_FORWARD : FFTW_BACKWARD;
const fftwf_iodim iodim = {new_dft_points, istride, ostride};
const fftwf_iodim howmany_dims = {how_many, idist, odist};
/* Destroy current plan */
fftwf_destroy_plan(plan->p);
plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE);
if (!plan->p) {
return -1;
}
plan->size = new_dft_points;
plan->init_size = plan->size;
return 0;
}
int srslte_dft_replan_c(srslte_dft_plan_t *plan, const int new_dft_points) { int srslte_dft_replan_c(srslte_dft_plan_t *plan, const int new_dft_points) {
int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD;
if (plan->p) { if (plan->p) {
@ -107,6 +126,32 @@ int srslte_dft_replan_c(srslte_dft_plan_t *plan, const int new_dft_points) {
return 0; return 0;
} }
int srslte_dft_plan_guru_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir, cf_t *in_buffer,
cf_t *out_buffer, int istride, int ostride, int how_many,
int idist, int odist) {
int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD;
const fftwf_iodim iodim = {dft_points, istride, ostride};
const fftwf_iodim howmany_dims = {how_many, idist, odist};
plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE);
if (!plan->p) {
return -1;
}
plan->size = dft_points;
plan->init_size = plan->size;
plan->mode = SRSLTE_DFT_COMPLEX;
plan->dir = dir;
plan->forward = (dir==SRSLTE_DFT_FORWARD)?true:false;
plan->mirror = false;
plan->db = false;
plan->norm = false;
plan->dc = false;
plan->is_guru = true;
return 0;
}
int srslte_dft_plan_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir) { int srslte_dft_plan_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir) {
allocate(plan,sizeof(fftwf_complex),sizeof(fftwf_complex), dft_points); allocate(plan,sizeof(fftwf_complex),sizeof(fftwf_complex), dft_points);
int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD;
@ -123,6 +168,7 @@ int srslte_dft_plan_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_
plan->db = false; plan->db = false;
plan->norm = false; plan->norm = false;
plan->dc = false; plan->dc = false;
plan->is_guru = false;
return 0; return 0;
} }
@ -232,6 +278,14 @@ void srslte_dft_run_c(srslte_dft_plan_t *plan, cf_t *in, cf_t *out) {
plan->forward, plan->mirror, plan->dc); plan->forward, plan->mirror, plan->dc);
} }
void srslte_dft_run_guru_c(srslte_dft_plan_t *plan) {
if (plan->is_guru == true) {
fftwf_execute(plan->p);
} else {
fprintf(stderr, "srslte_dft_run_guru_c: the selected plan is not guru!\n");
}
}
void srslte_dft_run_r(srslte_dft_plan_t *plan, float *in, float *out) { void srslte_dft_run_r(srslte_dft_plan_t *plan, float *in, float *out) {
float norm; float norm;
int i; int i;
@ -255,8 +309,10 @@ void srslte_dft_run_r(srslte_dft_plan_t *plan, float *in, float *out) {
void srslte_dft_plan_free(srslte_dft_plan_t *plan) { void srslte_dft_plan_free(srslte_dft_plan_t *plan) {
if (!plan) return; if (!plan) return;
if (!plan->size) return; if (!plan->size) return;
if (!plan->is_guru) {
if (plan->in) fftwf_free(plan->in); if (plan->in) fftwf_free(plan->in);
if (plan->out) fftwf_free(plan->out); if (plan->out) fftwf_free(plan->out);
}
if (plan->p) fftwf_destroy_plan(plan->p); if (plan->p) fftwf_destroy_plan(plan->p);
bzero(plan, sizeof(srslte_dft_plan_t)); bzero(plan, sizeof(srslte_dft_plan_t));
} }

@ -37,23 +37,79 @@
#include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/vector.h" #include "srslte/phy/utils/vector.h"
/* Uncomment next line for avoiding Guru DFT call */
//#define AVOID_GURU
int srslte_ofdm_init_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof_prb, srslte_dft_dir_t dir) { int srslte_ofdm_init_(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, int symbol_sz, int nof_prb, srslte_dft_dir_t dir) {
return srslte_ofdm_init_mbsfn_(q, cp, symbol_sz, nof_prb, dir, SRSLTE_SF_NORM); return srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, dir, SRSLTE_SF_NORM);
} }
int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, int symbol_sz, int nof_prb, srslte_dft_dir_t dir, srslte_sf_t sf_type) {
int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof_prb, srslte_dft_dir_t dir, srslte_sf_t sf_type) { /* Set OFDM object attributes */
q->symbol_sz = (uint32_t) symbol_sz;
q->nof_symbols = SRSLTE_CP_NSYMB(cp);
q->nof_symbols_mbsfn = SRSLTE_CP_NSYMB(SRSLTE_CP_EXT);
q->cp = cp;
q->freq_shift = false;
q->nof_re = (uint32_t) nof_prb * SRSLTE_NRE;
q->nof_guards = ((symbol_sz - q->nof_re) / 2);
q->slot_sz = (uint32_t) SRSLTE_SLOT_LEN(symbol_sz);
q->sf_sz = (uint32_t) SRSLTE_SF_LEN(symbol_sz);
q->in_buffer = in_buffer;
q->out_buffer= out_buffer;
if (srslte_dft_plan_c(&q->fft_plan, symbol_sz, dir)) { if (srslte_dft_plan_c(&q->fft_plan, symbol_sz, dir)) {
fprintf(stderr, "Error: Creating DFT plan\n"); fprintf(stderr, "Error: Creating DFT plan\n");
return -1; return -1;
} }
#ifdef AVOID_GURU
q->tmp = srslte_vec_malloc((uint32_t) symbol_sz * sizeof(cf_t)); q->tmp = srslte_vec_malloc((uint32_t) symbol_sz * sizeof(cf_t));
if (!q->tmp) { if (!q->tmp) {
perror("malloc"); perror("malloc");
return -1; return -1;
} }
bzero(q->tmp, sizeof(cf_t) * symbol_sz);
#else
int cp1 = SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN_NORM(0, symbol_sz):SRSLTE_CP_LEN_EXT(symbol_sz);
int cp2 = SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN_NORM(1, symbol_sz):SRSLTE_CP_LEN_EXT(symbol_sz);
q->tmp = srslte_vec_malloc(sizeof(cf_t) * q->sf_sz);
if (!q->tmp) {
perror("malloc");
return -1;
}
bzero(q->tmp, sizeof(cf_t) * q->sf_sz);
if (dir == SRSLTE_DFT_BACKWARD) {
bzero(in_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_RE(nof_prb, cp));
}else {
bzero(in_buffer, sizeof(cf_t) * q->sf_sz);
}
for (int slot = 0; slot < 2; slot++) {
//bzero(&q->fft_plan_sf[slot], sizeof(srslte_dft_plan_t));
//bzero(q->tmp + SRSLTE_CP_NSYMB(cp)*symbol_sz*slot, sizeof(cf_t) * (cp1 + (SRSLTE_CP_NSYMB(cp) - 1)*cp2 + SRSLTE_CP_NSYMB(cp)*symbol_sz));
if (dir == SRSLTE_DFT_FORWARD) {
if (srslte_dft_plan_guru_c(&q->fft_plan_sf[slot], symbol_sz, dir,
in_buffer + cp1 + q->slot_sz * slot,
q->tmp + q->nof_symbols * q->symbol_sz * slot,
1, 1, SRSLTE_CP_NSYMB(cp), symbol_sz + cp2, symbol_sz)) {
fprintf(stderr, "Error: Creating DFT plan (1)\n");
return -1;
}
} else {
if (srslte_dft_plan_guru_c(&q->fft_plan_sf[slot], symbol_sz, dir,
q->tmp + q->nof_symbols * q->symbol_sz * slot,
out_buffer + cp1 + q->slot_sz * slot,
1, 1, SRSLTE_CP_NSYMB(cp), symbol_sz, symbol_sz + cp2)) {
fprintf(stderr, "Error: Creating DFT plan (1)\n");
return -1;
}
}
}
#endif
q->shift_buffer = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN(symbol_sz)); q->shift_buffer = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN(symbol_sz));
if (!q->shift_buffer) { if (!q->shift_buffer) {
@ -64,15 +120,6 @@ int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int
srslte_dft_plan_set_mirror(&q->fft_plan, true); srslte_dft_plan_set_mirror(&q->fft_plan, true);
srslte_dft_plan_set_dc(&q->fft_plan, true); srslte_dft_plan_set_dc(&q->fft_plan, true);
q->symbol_sz = (uint32_t) symbol_sz;
q->nof_symbols = SRSLTE_CP_NSYMB(cp);
q->nof_symbols_mbsfn = SRSLTE_CP_NSYMB(SRSLTE_CP_EXT);
q->cp = cp;
q->freq_shift = false;
q->nof_re = nof_prb * SRSLTE_NRE;
q->nof_guards = ((symbol_sz - q->nof_re) / 2);
q->slot_sz = SRSLTE_SLOT_LEN(symbol_sz);
DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp=%s, nof_re=%d, nof_guards=%d\n", DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp=%s, nof_re=%d, nof_guards=%d\n",
dir==SRSLTE_DFT_FORWARD?"FFT":"iFFT", q->symbol_sz, q->nof_symbols, dir==SRSLTE_DFT_FORWARD?"FFT":"iFFT", q->symbol_sz, q->nof_symbols,
q->cp==SRSLTE_CP_NORM?"Normal":"Extended", q->nof_re, q->nof_guards); q->cp==SRSLTE_CP_NORM?"Normal":"Extended", q->nof_re, q->nof_guards);
@ -101,9 +148,60 @@ int srslte_ofdm_replan_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof
q->symbol_sz = (uint32_t) symbol_sz; q->symbol_sz = (uint32_t) symbol_sz;
q->nof_symbols = SRSLTE_CP_NSYMB(cp); q->nof_symbols = SRSLTE_CP_NSYMB(cp);
q->cp = cp; q->cp = cp;
q->nof_re = nof_prb * SRSLTE_NRE; q->nof_re = (uint32_t) nof_prb * SRSLTE_NRE;
q->nof_guards = ((symbol_sz - q->nof_re) / 2); q->nof_guards = ((symbol_sz - q->nof_re) / 2);
q->slot_sz = SRSLTE_SLOT_LEN(symbol_sz); q->slot_sz = (uint32_t) SRSLTE_SLOT_LEN(symbol_sz);
q->sf_sz = (uint32_t) SRSLTE_SF_LEN(symbol_sz);
#ifndef AVOID_GURU
cf_t *in_buffer = q->in_buffer;
cf_t *out_buffer = q->out_buffer;
int cp1 = SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN_NORM(0, symbol_sz):SRSLTE_CP_LEN_EXT(symbol_sz);
int cp2 = SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN_NORM(1, symbol_sz):SRSLTE_CP_LEN_EXT(symbol_sz);
srslte_dft_dir_t dir = q->fft_plan_sf[0].dir;
if (q->tmp) {
free(q->tmp);
}
q->tmp = srslte_vec_malloc(sizeof(cf_t) * q->sf_sz);
if (!q->tmp) {
perror("malloc");
return -1;
}
bzero(q->tmp, sizeof(cf_t) * q->sf_sz);
if (dir == SRSLTE_DFT_BACKWARD) {
bzero(in_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_RE(nof_prb, cp));
}else {
bzero(in_buffer, sizeof(cf_t) * q->sf_sz);
}
for (int slot = 0; slot < 2; slot++) {
srslte_dft_plan_free(&q->fft_plan_sf[slot]);
if (dir == SRSLTE_DFT_FORWARD) {
if (srslte_dft_plan_guru_c(&q->fft_plan_sf[slot], symbol_sz, dir,
in_buffer + cp1 + q->slot_sz * slot,
q->tmp + q->nof_symbols * q->symbol_sz * slot,
1, 1, SRSLTE_CP_NSYMB(cp), symbol_sz + cp2, symbol_sz)) {
fprintf(stderr, "Error: Creating DFT plan (1)\n");
return -1;
}
} else {
if (srslte_dft_plan_guru_c(&q->fft_plan_sf[slot], symbol_sz, dir,
q->tmp + q->nof_symbols * q->symbol_sz * slot,
out_buffer + cp1 + q->slot_sz * slot,
1, 1, SRSLTE_CP_NSYMB(cp), symbol_sz, symbol_sz + cp2)) {
fprintf(stderr, "Error: Creating DFT plan (1)\n");
return -1;
}
}
}
#endif /* AVOID_GURU */
if (q->freq_shift) { if (q->freq_shift) {
srslte_ofdm_set_freq_shift(q, q->freq_shift_f); srslte_ofdm_set_freq_shift(q, q->freq_shift_f);
@ -118,6 +216,15 @@ int srslte_ofdm_replan_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof
void srslte_ofdm_free_(srslte_ofdm_t *q) { void srslte_ofdm_free_(srslte_ofdm_t *q) {
srslte_dft_plan_free(&q->fft_plan); srslte_dft_plan_free(&q->fft_plan);
#ifndef AVOID_GURU
for (int slot = 0; slot < 2; slot++) {
if (q->fft_plan_sf[slot].init_size) {
srslte_dft_plan_free(&q->fft_plan_sf[slot]);
}
}
#endif
if (q->tmp) { if (q->tmp) {
free(q->tmp); free(q->tmp);
} }
@ -127,28 +234,28 @@ void srslte_ofdm_free_(srslte_ofdm_t *q) {
bzero(q, sizeof(srslte_ofdm_t)); bzero(q, sizeof(srslte_ofdm_t));
} }
int srslte_ofdm_rx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t max_prb) { int srslte_ofdm_rx_init(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t max_prb) {
int symbol_sz = srslte_symbol_sz(max_prb); int symbol_sz = srslte_symbol_sz(max_prb);
if (symbol_sz < 0) { if (symbol_sz < 0) {
fprintf(stderr, "Error: Invalid nof_prb=%d\n", max_prb); fprintf(stderr, "Error: Invalid nof_prb=%d\n", max_prb);
return -1; return -1;
} }
q->max_prb = max_prb; q->max_prb = max_prb;
return srslte_ofdm_init_(q, cp, symbol_sz, max_prb, SRSLTE_DFT_FORWARD); return srslte_ofdm_init_(q, cp, in_buffer, out_buffer, symbol_sz, max_prb, SRSLTE_DFT_FORWARD);
} }
int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t nof_prb)
{ {
int symbol_sz = srslte_symbol_sz(nof_prb); int symbol_sz = srslte_symbol_sz(nof_prb);
if (symbol_sz < 0) { if (symbol_sz < 0) {
fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb); fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb);
return -1; return -1;
} }
return srslte_ofdm_init_mbsfn_(q, cp, symbol_sz, nof_prb, SRSLTE_DFT_FORWARD, SRSLTE_SF_MBSFN); return srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, SRSLTE_DFT_FORWARD, SRSLTE_SF_MBSFN);
} }
int srslte_ofdm_tx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t max_prb) { int srslte_ofdm_tx_init(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t max_prb) {
uint32_t i; uint32_t i;
int ret; int ret;
@ -158,7 +265,7 @@ int srslte_ofdm_tx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t max_prb) {
return -1; return -1;
} }
q->max_prb = max_prb; q->max_prb = max_prb;
ret = srslte_ofdm_init_(q, cp, symbol_sz, max_prb, SRSLTE_DFT_BACKWARD); ret = srslte_ofdm_init_(q, cp, in_buffer, out_buffer, symbol_sz, max_prb, SRSLTE_DFT_BACKWARD);
if (ret == SRSLTE_SUCCESS) { if (ret == SRSLTE_SUCCESS) {
@ -173,7 +280,7 @@ int srslte_ofdm_tx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t max_prb) {
return ret; return ret;
} }
int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t nof_prb)
{ {
uint32_t i; uint32_t i;
int ret; int ret;
@ -184,7 +291,7 @@ int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb
return -1; return -1;
} }
ret = srslte_ofdm_init_mbsfn_(q, cp, symbol_sz, nof_prb, SRSLTE_DFT_BACKWARD, SRSLTE_SF_MBSFN); ret = srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, SRSLTE_DFT_BACKWARD, SRSLTE_SF_MBSFN);
if (ret == SRSLTE_SUCCESS) { if (ret == SRSLTE_SUCCESS) {
srslte_dft_plan_set_norm(&q->fft_plan, false); srslte_dft_plan_set_norm(&q->fft_plan, false);
@ -207,7 +314,8 @@ int srslte_ofdm_rx_set_prb(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) {
} }
return srslte_ofdm_replan_(q, cp, symbol_sz, nof_prb); return srslte_ofdm_replan_(q, cp, symbol_sz, nof_prb);
} else { } else {
fprintf(stderr, "OFDM: Error calling set_prb: nof_prb must be equal or lower initialized max_prb\n"); fprintf(stderr, "OFDM (Rx): Error calling set_prb: nof_prb (%d) must be equal or lower initialized max_prb (%d)\n",
nof_prb, q->max_prb);
return -1; return -1;
} }
} }
@ -234,7 +342,8 @@ int srslte_ofdm_tx_set_prb(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) {
} }
return ret; return ret;
} else { } else {
fprintf(stderr, "OFDM: Error calling set_prb: nof_prb must be equal or lower initialized max_prb\n"); fprintf(stderr, "OFDM (Tx): Error calling set_prb: nof_prb (%d) must be equal or lower initialized max_prb (%d)\n",
nof_prb, q->max_prb);
return -1; return -1;
} }
} }
@ -274,8 +383,12 @@ void srslte_ofdm_tx_free(srslte_ofdm_t *q) {
/* Transforms input samples into output OFDM symbols. /* Transforms input samples into output OFDM symbols.
* Performs FFT on a each symbol and removes CP. * Performs FFT on a each symbol and removes CP.
*/ */
void srslte_ofdm_rx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) { void srslte_ofdm_rx_slot(srslte_ofdm_t *q, int slot_in_sf) {
cf_t *output = q->out_buffer + slot_in_sf * q->nof_re * q->nof_symbols;
#ifdef AVOID_GURU
uint32_t i; uint32_t i;
cf_t *input = q->in_buffer + slot_in_sf * q->slot_sz;
for (i=0;i<q->nof_symbols;i++) { for (i=0;i<q->nof_symbols;i++) {
input += SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz); input += SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz);
srslte_dft_run_c(&q->fft_plan, input, q->tmp); srslte_dft_run_c(&q->fft_plan, input, q->tmp);
@ -283,6 +396,25 @@ void srslte_ofdm_rx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
input += q->symbol_sz; input += q->symbol_sz;
output += q->nof_re; output += q->nof_re;
} }
#else
float norm = 1.0f/sqrtf(q->fft_plan.size);
cf_t *tmp = q->tmp + slot_in_sf * q->symbol_sz * q->nof_symbols;
uint32_t dc = (q->fft_plan.dc) ? 1:0;
srslte_dft_run_guru_c(&q->fft_plan_sf[slot_in_sf]);
for (int i = 0; i < q->nof_symbols; i++) {
memcpy(output, tmp + q->symbol_sz - q->nof_re / 2, sizeof(cf_t) * q->nof_re / 2);
memcpy(output + q->nof_re / 2, &tmp[dc], sizeof(cf_t) * q->nof_re / 2);
if (q->fft_plan.norm) {
srslte_vec_sc_prod_cfc(output, norm, output, q->nof_re);
}
tmp += q->symbol_sz;
output += q->nof_re;
}
#endif
} }
void srslte_ofdm_rx_slot_mbsfn(srslte_ofdm_t *q, cf_t *input, cf_t *output) void srslte_ofdm_rx_slot_mbsfn(srslte_ofdm_t *q, cf_t *input, cf_t *output)
@ -314,29 +446,32 @@ void srslte_ofdm_rx_slot_zerocopy(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
} }
} }
void srslte_ofdm_rx_sf(srslte_ofdm_t *q, cf_t *input, cf_t *output) { void srslte_ofdm_rx_sf(srslte_ofdm_t *q) {
uint32_t n; uint32_t n;
if (q->freq_shift) { if (q->freq_shift) {
srslte_vec_prod_ccc(input, q->shift_buffer, input, 2*q->slot_sz); srslte_vec_prod_ccc(q->in_buffer, q->shift_buffer, q->in_buffer, 2*q->slot_sz);
} }
if(!q->mbsfn_subframe){ if(!q->mbsfn_subframe){
for (n=0;n<2;n++) { for (n=0;n<2;n++) {
srslte_ofdm_rx_slot(q, &input[n*q->slot_sz], &output[n*q->nof_re*q->nof_symbols]); srslte_ofdm_rx_slot(q, n);
} }
} }
else{ else{
srslte_ofdm_rx_slot_mbsfn(q, &input[0*q->slot_sz], &output[0*q->nof_re*q->nof_symbols]); srslte_ofdm_rx_slot_mbsfn(q, &q->in_buffer[0*q->slot_sz], &q->out_buffer[0*q->nof_re*q->nof_symbols]);
srslte_ofdm_rx_slot(q, &input[1*q->slot_sz], &output[1*q->nof_re*q->nof_symbols]); srslte_ofdm_rx_slot(q, 1);
} }
} }
/* Transforms input OFDM symbols into output samples. /* Transforms input OFDM symbols into output samples.
* Performs FFT on a each symbol and adds CP. * Performs FFT on a each symbol and adds CP.
*/ */
void srslte_ofdm_tx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) { void srslte_ofdm_tx_slot(srslte_ofdm_t *q, int slot_in_sf) {
uint32_t i, cp_len; cf_t *input = q->in_buffer + slot_in_sf * q->nof_re * q->nof_symbols;
for (i=0;i<q->nof_symbols;i++) { cf_t *output = q->out_buffer + slot_in_sf * q->slot_sz;
cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz);
#ifdef AVOID_GURU
for (int i=0;i<q->nof_symbols;i++) {
int cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz);
memcpy(&q->tmp[q->nof_guards], input, q->nof_re * sizeof(cf_t)); memcpy(&q->tmp[q->nof_guards], input, q->nof_re * sizeof(cf_t));
srslte_dft_run_c(&q->fft_plan, q->tmp, &output[cp_len]); srslte_dft_run_c(&q->fft_plan, q->tmp, &output[cp_len]);
input += q->nof_re; input += q->nof_re;
@ -344,6 +479,60 @@ void srslte_ofdm_tx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
memcpy(output, &output[q->symbol_sz], cp_len * sizeof(cf_t)); memcpy(output, &output[q->symbol_sz], cp_len * sizeof(cf_t));
output += q->symbol_sz + cp_len; output += q->symbol_sz + cp_len;
} }
#else
float norm = 1.0f/sqrtf(q->symbol_sz);
cf_t *tmp = q->tmp + slot_in_sf * q->symbol_sz * q->nof_symbols;
bzero(tmp, q->slot_sz);
uint32_t dc = (q->fft_plan.dc) ? 1:0;
for (int i = 0; i < q->nof_symbols; i++) {
memcpy(&tmp[dc], &input[q->nof_re / 2], q->nof_re / 2 * sizeof(cf_t));
memcpy(&tmp[q->symbol_sz - q->nof_re / 2], &input[0], q->nof_re / 2 * sizeof(cf_t));
input += q->nof_re;
tmp += q->symbol_sz;
}
srslte_dft_run_guru_c(&q->fft_plan_sf[slot_in_sf]);
for (int i=0;i<q->nof_symbols;i++) {
int cp_len = SRSLTE_CP_ISNORM(q->cp) ? SRSLTE_CP_LEN_NORM(i, q->symbol_sz) : SRSLTE_CP_LEN_EXT(q->symbol_sz);
if (q->fft_plan.norm) {
srslte_vec_sc_prod_cfc(&output[cp_len], norm, &output[cp_len], q->symbol_sz);
}
/* add CP */
memcpy(output, &output[q->symbol_sz], cp_len * sizeof(cf_t));
output += q->symbol_sz + cp_len;
}
#endif
/*input = q->in_buffer + slot_in_sf * q->nof_re * q->nof_symbols;
cf_t *output2 = srslte_vec_malloc(sizeof(cf_t) * q->slot_sz);
cf_t *o2 = output2;
bzero(q->tmp, sizeof(cf_t)*q->symbol_sz);
//bzero(output2, sizeof(cf_t)*q->slot_sz);
for (int i=0;i<q->nof_symbols;i++) {
int cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz);
memcpy(&q->tmp[q->nof_guards], input, q->nof_re * sizeof(cf_t));
srslte_dft_run_c(&q->fft_plan, q->tmp, &o2[cp_len]);
input += q->nof_re;
memcpy(o2, &o2[q->symbol_sz], cp_len * sizeof(cf_t));
o2 += q->symbol_sz + cp_len;
}
cf_t *output1 = q->out_buffer + slot_in_sf * q->slot_sz;//srslte_vec_malloc(sizeof(cf_t) * q->slot_sz);
for (int i = 0; i < q->slot_sz; i++) {
float error = cabsf(output1[i] - output2[i])/cabsf(output2[i]);
cf_t k = output1[i]/output2[i];
if (error > 0.1) printf("%d/%05d error=%f output=%+f%+fi gold=%+f%+fi k=%+f%+fi\n", slot_in_sf, i, error,
__real__ output1[i], __imag__ output1[i],
__real__ output2[i], __imag__ output2[i],
__real__ k, __imag__ k);
}
free(output2);/**/
} }
void srslte_ofdm_tx_slot_mbsfn(srslte_ofdm_t *q, cf_t *input, cf_t *output) void srslte_ofdm_tx_slot_mbsfn(srslte_ofdm_t *q, cf_t *input, cf_t *output)
@ -369,20 +558,20 @@ void srslte_ofdm_set_normalize(srslte_ofdm_t *q, bool normalize_enable) {
srslte_dft_plan_set_norm(&q->fft_plan, normalize_enable); srslte_dft_plan_set_norm(&q->fft_plan, normalize_enable);
} }
void srslte_ofdm_tx_sf(srslte_ofdm_t *q, cf_t *input, cf_t *output) void srslte_ofdm_tx_sf(srslte_ofdm_t *q)
{ {
uint32_t n; uint32_t n;
if(!q->mbsfn_subframe){ if(!q->mbsfn_subframe){
for (n=0;n<2;n++) { for (n=0;n<2;n++) {
srslte_ofdm_tx_slot(q, &input[n*q->nof_re*q->nof_symbols], &output[n*q->slot_sz]); srslte_ofdm_tx_slot(q, n);
} }
} }
else{ else{
srslte_ofdm_tx_slot_mbsfn(q, &input[0*q->nof_re*q->nof_symbols], &output[0*q->slot_sz]); srslte_ofdm_tx_slot_mbsfn(q, &q->in_buffer[0*q->nof_re*q->nof_symbols], &q->out_buffer[0*q->slot_sz]);
srslte_ofdm_tx_slot(q, &input[1*q->nof_re*q->nof_symbols], &output[1*q->slot_sz]); srslte_ofdm_tx_slot(q, 1);
} }
if (q->freq_shift) { if (q->freq_shift) {
srslte_vec_prod_ccc(output, q->shift_buffer, output, 2*q->slot_sz); srslte_vec_prod_ccc(q->out_buffer, q->shift_buffer, q->out_buffer, 2*q->slot_sz);
} }
} }

@ -35,16 +35,28 @@
int nof_prb = -1; int nof_prb = -1;
srslte_cp_t cp = SRSLTE_CP_NORM; srslte_cp_t cp = SRSLTE_CP_NORM;
int nof_repetitions = 128;
static double elapsed_us(struct timeval *ts_start, struct timeval *ts_end) {
if (ts_end->tv_usec > ts_start->tv_usec) {
return ((double) ts_end->tv_sec - (double) ts_start->tv_sec) * 1000000 +
(double) ts_end->tv_usec - (double) ts_start->tv_usec;
} else {
return ((double) ts_end->tv_sec - (double) ts_start->tv_sec - 1) * 1000000 +
((double) ts_end->tv_usec + 1000000) - (double) ts_start->tv_usec;
}
}
void usage(char *prog) { void usage(char *prog) {
printf("Usage: %s\n", prog); printf("Usage: %s\n", prog);
printf("\t-n nof_prb [Default All]\n"); printf("\t-n nof_prb [Default All]\n");
printf("\t-e extended cyclic prefix [Default Normal]\n"); printf("\t-e extended cyclic prefix [Default Normal]\n");
printf("\t-r nof_repetitions [Default %d]\n", nof_repetitions);
} }
void parse_args(int argc, char **argv) { void parse_args(int argc, char **argv) {
int opt; int opt;
while ((opt = getopt(argc, argv, "ne")) != -1) { while ((opt = getopt(argc, argv, "ner")) != -1) {
switch (opt) { switch (opt) {
case 'n': case 'n':
nof_prb = atoi(argv[optind]); nof_prb = atoi(argv[optind]);
@ -52,6 +64,9 @@ void parse_args(int argc, char **argv) {
case 'e': case 'e':
cp = SRSLTE_CP_EXT; cp = SRSLTE_CP_EXT;
break; break;
case 'r':
nof_repetitions = atoi(argv[optind]);
break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); exit(-1);
@ -61,6 +76,7 @@ void parse_args(int argc, char **argv) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
struct timeval start, end;
srslte_ofdm_t fft, ifft; srslte_ofdm_t fft, ifft;
cf_t *input, *outfft, *outifft; cf_t *input, *outfft, *outifft;
float mse; float mse;
@ -81,48 +97,65 @@ int main(int argc, char **argv) {
printf("Running test for %d PRB, %d RE... ", n_prb, n_re);fflush(stdout); printf("Running test for %d PRB, %d RE... ", n_prb, n_re);fflush(stdout);
input = malloc(sizeof(cf_t) * n_re); input = srslte_vec_malloc(sizeof(cf_t) * n_re * 2);
if (!input) { if (!input) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
outfft = malloc(sizeof(cf_t) * SRSLTE_SLOT_LEN(srslte_symbol_sz(n_prb))); outfft = srslte_vec_malloc(sizeof(cf_t) * n_re * 2);
if (!outfft) { if (!outfft) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
outifft = malloc(sizeof(cf_t) * n_re); outifft = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SLOT_LEN(srslte_symbol_sz(n_prb)) * 2);
if (!outifft) { if (!outifft) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
bzero(outifft, sizeof(cf_t) * SRSLTE_SLOT_LEN(srslte_symbol_sz(n_prb)) * 2);
if (srslte_ofdm_rx_init(&fft, cp, n_prb)) { if (srslte_ofdm_rx_init(&fft, cp, outifft, outfft, n_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
exit(-1); exit(-1);
} }
srslte_dft_plan_set_norm(&fft.fft_plan, true); srslte_ofdm_set_normalize(&fft, true);
if (srslte_ofdm_tx_init(&ifft, cp, n_prb)) { if (srslte_ofdm_tx_init(&ifft, cp, input, outifft, n_prb)) {
fprintf(stderr, "Error initializing iFFT\n"); fprintf(stderr, "Error initializing iFFT\n");
exit(-1); exit(-1);
} }
srslte_dft_plan_set_norm(&ifft.fft_plan, true); srslte_ofdm_set_normalize(&ifft, true);
for (i=0;i<n_re;i++) { for (i=0;i<n_re;i++) {
input[i] = 100 * ((float) rand()/RAND_MAX + (float) I*rand()/RAND_MAX); input[i] = 100 * ((float) rand() / (float) RAND_MAX + I * ((float) rand() / (float) RAND_MAX));
//input[i] = 100;
} }
srslte_ofdm_tx_slot(&ifft, input, outfft); gettimeofday(&start, NULL);
srslte_ofdm_rx_slot(&fft, outfft, outifft); for (int i = 0; i < nof_repetitions; i++) {
srslte_ofdm_tx_slot(&ifft, 0);
}
gettimeofday(&end, NULL);\
printf(" Tx@%.1fMsps", (float)(SRSLTE_SLOT_LEN(srslte_symbol_sz(n_prb))*nof_repetitions)/elapsed_us(&start, &end));
/* compute MSE */ gettimeofday(&start, NULL);
for (int i = 0; i < nof_repetitions; i++) {
srslte_ofdm_rx_slot(&fft, 0);
}
gettimeofday(&end, NULL);\
printf(" Rx@%.1fMsps", (float)(SRSLTE_SLOT_LEN(srslte_symbol_sz(n_prb))*nof_repetitions)/elapsed_us(&start, &end));
mse = 0; /* compute MSE */
mse = 0.0f;
for (i=0;i<n_re;i++) { for (i=0;i<n_re;i++) {
mse += cabsf(input[i] - outifft[i]); cf_t error = input[i] - outfft[i];
mse += (__real__ error * __real__ error + __imag__ error * __imag__ error)/cabsf(input[i]);
if (mse > 1.0f) printf("%04d. %+.1f%+.1fi Vs. %+.1f%+.1f %+.1f%+.1f (mse=%f)\n", i, __real__ input[i], __imag__ input[i], __real__ outifft[i], __imag__ outifft[i], __real__ outfft[i], __imag__ outfft[i], mse);
} }
printf("MSE=%f\n", mse); /*for (i=0;i<n_re;i++) {
mse += cabsf(input[i] - outfft[i]);
}*/
printf(" MSE=%.6f\n", mse);
if (mse >= 0.07) { if (mse >= 0.07) {
printf("MSE too large\n"); printf("MSE too large\n");

@ -41,7 +41,7 @@
#define SRSLTE_ENB_RF_AMP 0.1 #define SRSLTE_ENB_RF_AMP 0.1
int srslte_enb_dl_init(srslte_enb_dl_t *q, uint32_t max_prb) int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], uint32_t max_prb)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
@ -54,12 +54,25 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, uint32_t max_prb)
q->cfi = 3; q->cfi = 3;
q->tx_amp = SRSLTE_ENB_RF_AMP; q->tx_amp = SRSLTE_ENB_RF_AMP;
if (srslte_ofdm_tx_init(&q->ifft, SRSLTE_CP_NORM, max_prb)) { for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
fprintf(stderr, "Error initiating FFT\n"); q->sf_symbols[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t));
if (!q->sf_symbols[i]) {
perror("malloc");
goto clean_exit; goto clean_exit;
} }
q->slot1_symbols[i] = &q->sf_symbols[i][SRSLTE_SLOT_LEN_RE(max_prb, SRSLTE_CP_NORM)];
}
srslte_ofdm_set_normalize(&q->ifft, true); for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
if (srslte_ofdm_tx_init(&q->ifft[i], SRSLTE_CP_NORM, q->sf_symbols[i], out_buffer[i], max_prb)) {
fprintf(stderr, "Error initiating FFT (%d)\n", i);
goto clean_exit;
}
}
for (int i = 0; i < q->cell.nof_ports; i++) {
srslte_ofdm_set_normalize(&q->ifft[i], true);
}
if (srslte_pbch_init(&q->pbch)) { if (srslte_pbch_init(&q->pbch)) {
fprintf(stderr, "Error creating PBCH object\n"); fprintf(stderr, "Error creating PBCH object\n");
@ -89,15 +102,6 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, uint32_t max_prb)
goto clean_exit; goto clean_exit;
} }
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
q->sf_symbols[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t));
if (!q->sf_symbols[i]) {
perror("malloc");
goto clean_exit;
}
q->slot1_symbols[i] = &q->sf_symbols[i][SRSLTE_SLOT_LEN_RE(max_prb, SRSLTE_CP_NORM)];
}
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} else { } else {
@ -114,7 +118,9 @@ clean_exit:
void srslte_enb_dl_free(srslte_enb_dl_t *q) void srslte_enb_dl_free(srslte_enb_dl_t *q)
{ {
if (q) { if (q) {
srslte_ofdm_tx_free(&q->ifft); for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
srslte_ofdm_tx_free(&q->ifft[i]);
}
srslte_regs_free(&q->regs); srslte_regs_free(&q->regs);
srslte_pbch_free(&q->pbch); srslte_pbch_free(&q->pbch);
srslte_pcfich_free(&q->pcfich); srslte_pcfich_free(&q->pcfich);
@ -152,10 +158,12 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
fprintf(stderr, "Error resizing REGs\n"); fprintf(stderr, "Error resizing REGs\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (srslte_ofdm_rx_set_prb(&q->ifft, q->cell.cp, q->cell.nof_prb)) { for (int i = 0; i < q->cell.nof_ports; i++) {
fprintf(stderr, "Error initiating FFT\n"); if (srslte_ofdm_tx_set_prb(&q->ifft[i], q->cell.cp, q->cell.nof_prb)) {
fprintf(stderr, "Error re-planning iFFT (%d)\n", i);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
}
if (srslte_pbch_set_cell(&q->pbch, q->cell)) { if (srslte_pbch_set_cell(&q->pbch, q->cell)) {
fprintf(stderr, "Error creating PBCH object\n"); fprintf(stderr, "Error creating PBCH object\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -264,14 +272,15 @@ void srslte_enb_dl_put_base(srslte_enb_dl_t *q, uint32_t tti)
} }
void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q, cf_t *signal_buffer) void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q)
{ {
srslte_ofdm_tx_sf(&q->ifft, q->sf_symbols[0], signal_buffer);
// TODO: PAPR control // TODO: PAPR control
float norm_factor = (float) sqrt(q->cell.nof_prb)/15; float norm_factor = (float) sqrt(q->cell.nof_prb)/15;
srslte_vec_sc_prod_cfc(signal_buffer, q->tx_amp*norm_factor, signal_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
for (int i = 0; i < q->cell.nof_ports; i++) {
srslte_ofdm_tx_sf(&q->ifft[i]);
srslte_vec_sc_prod_cfc(q->ifft[i].out_buffer, q->tx_amp*norm_factor, q->ifft[i].out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
}
} }
int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, uint16_t rnti) int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, uint16_t rnti)

@ -40,6 +40,7 @@
#define MAX_CANDIDATES 16 #define MAX_CANDIDATES 16
int srslte_enb_ul_init(srslte_enb_ul_t *q, int srslte_enb_ul_init(srslte_enb_ul_t *q,
cf_t *in_buffer,
uint32_t max_prb) uint32_t max_prb)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
@ -56,7 +57,19 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q,
goto clean_exit; goto clean_exit;
} }
if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, max_prb)) { q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t));
if (!q->sf_symbols) {
perror("malloc");
goto clean_exit;
}
q->ce = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t));
if (!q->ce) {
perror("malloc");
goto clean_exit;
}
if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, in_buffer, q->sf_symbols, max_prb)) {
fprintf(stderr, "Error initiating FFT\n"); fprintf(stderr, "Error initiating FFT\n");
goto clean_exit; goto clean_exit;
} }
@ -80,18 +93,6 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q,
goto clean_exit; goto clean_exit;
} }
q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t));
if (!q->sf_symbols) {
perror("malloc");
goto clean_exit;
}
q->ce = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t));
if (!q->ce) {
perror("malloc");
goto clean_exit;
}
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} else { } else {
@ -254,7 +255,7 @@ int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint16_t rnti,
void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer) void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer)
{ {
srslte_ofdm_rx_sf(&q->fft, signal_buffer, q->sf_symbols); srslte_ofdm_rx_sf(&q->fft);
} }
int get_pucch(srslte_enb_ul_t *q, uint16_t rnti, int get_pucch(srslte_enb_ul_t *q, uint16_t rnti,

@ -140,7 +140,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_init_(&fft, cell.cp, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) { if (srslte_ofdm_init_(&fft, cell.cp, input_buffer, fft_buffer, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -203,7 +203,7 @@ int main(int argc, char **argv) {
if (nread > 0) { if (nread > 0) {
// process 1st subframe only // process 1st subframe only
srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft);
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0); srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0);

@ -120,15 +120,15 @@ int base_init() {
fmatlab = NULL; fmatlab = NULL;
} }
flen = SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb)); flen = SRSLTE_SF_LEN(srslte_symbol_sz_power2(cell.nof_prb));
input_buffer = malloc(flen * sizeof(cf_t)); input_buffer = srslte_vec_malloc(flen * sizeof(cf_t));
if (!input_buffer) { if (!input_buffer) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
fft_buffer = malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); fft_buffer = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
if (!fft_buffer) { if (!fft_buffer) {
perror("malloc"); perror("malloc");
return -1; return -1;
@ -151,7 +151,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_init_(&fft, cell.cp, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) { if (srslte_ofdm_init_(&fft, cell.cp, input_buffer, fft_buffer, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -215,7 +215,7 @@ int main(int argc, char **argv) {
n = srslte_filesource_read(&fsrc, input_buffer, flen); n = srslte_filesource_read(&fsrc, input_buffer, flen);
srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft);
if (fmatlab) { if (fmatlab) {
fprintf(fmatlab, "infft="); fprintf(fmatlab, "infft=");

@ -126,7 +126,7 @@ int base_init() {
exit(-1); exit(-1);
} }
flen = 2 * (SRSLTE_SLOT_LEN(srslte_symbol_sz(cell.nof_prb))); flen = 2 * (SRSLTE_SLOT_LEN(srslte_symbol_sz_power2(cell.nof_prb)));
input_buffer = malloc(flen * sizeof(cf_t)); input_buffer = malloc(flen * sizeof(cf_t));
if (!input_buffer) { if (!input_buffer) {
@ -157,7 +157,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_init_(&fft, cell.cp, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) { if (srslte_ofdm_init_(&fft, cell.cp, input_buffer, fft_buffer, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -231,7 +231,7 @@ int main(int argc, char **argv) {
INFO("Reading %d samples sub-frame %d\n", flen, frame_cnt); INFO("Reading %d samples sub-frame %d\n", flen, frame_cnt);
srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft);
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&chest, fft_buffer, ce, frame_cnt %10); srslte_chest_dl_estimate(&chest, fft_buffer, ce, frame_cnt %10);

@ -129,7 +129,7 @@ int base_init() {
exit(-1); exit(-1);
} }
flen = 2 * (SRSLTE_SLOT_LEN(srslte_symbol_sz(cell.nof_prb))); flen = SRSLTE_SF_LEN(srslte_symbol_sz_power2(cell.nof_prb));
input_buffer[0] = malloc(flen * sizeof(cf_t)); input_buffer[0] = malloc(flen * sizeof(cf_t));
if (!input_buffer[0]) { if (!input_buffer[0]) {
@ -137,7 +137,7 @@ int base_init() {
exit(-1); exit(-1);
} }
if (srslte_ue_dl_init(&ue_dl, cell.nof_prb, 1)) { if (srslte_ue_dl_init(&ue_dl, input_buffer, cell.nof_prb, 1)) {
fprintf(stderr, "Error initializing UE DL\n"); fprintf(stderr, "Error initializing UE DL\n");
return -1; return -1;
} }

@ -144,7 +144,7 @@ int base_init() {
fmatlab = NULL; fmatlab = NULL;
} }
flen = SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb)); flen = SRSLTE_SF_LEN(srslte_symbol_sz_power2(cell.nof_prb));
input_buffer = malloc(flen * sizeof(cf_t)); input_buffer = malloc(flen * sizeof(cf_t));
if (!input_buffer) { if (!input_buffer) {
@ -175,7 +175,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_init_(&fft, cell.cp, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) { if (srslte_ofdm_init_(&fft, cell.cp, input_buffer, fft_buffer, srslte_symbol_sz_power2(cell.nof_prb), cell.nof_prb, SRSLTE_DFT_FORWARD)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -242,7 +242,7 @@ int main(int argc, char **argv) {
n = srslte_filesource_read(&fsrc, input_buffer, flen); n = srslte_filesource_read(&fsrc, input_buffer, flen);
srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft);
if (fmatlab) { if (fmatlab) {
fprintf(fmatlab, "infft="); fprintf(fmatlab, "infft=");

@ -140,7 +140,7 @@ int base_init() {
exit(-1); exit(-1);
} }
if (srslte_ue_dl_init(&ue_dl, cell.nof_prb, 1)) { if (srslte_ue_dl_init(&ue_dl, input_buffer, cell.nof_prb, 1)) {
fprintf(stderr, "Error initializing UE DL\n"); fprintf(stderr, "Error initializing UE DL\n");
return -1; return -1;
} }

@ -139,7 +139,7 @@ cf_t *tx_slot_symbols[SRSLTE_MAX_PORTS];
cf_t *rx_slot_symbols[SRSLTE_MAX_PORTS]; cf_t *rx_slot_symbols[SRSLTE_MAX_PORTS];
srslte_pmch_t pmch_tx, pmch_rx; srslte_pmch_t pmch_tx, pmch_rx;
srslte_pdsch_cfg_t pmch_cfg; srslte_pdsch_cfg_t pmch_cfg;
srslte_ofdm_t ifft_mbsfn, fft_mbsfn; srslte_ofdm_t ifft_mbsfn[SRSLTE_MAX_PORTS], fft_mbsfn[SRSLTE_MAX_PORTS];
int main(int argc, char **argv) { int main(int argc, char **argv) {
uint32_t i, j, k; uint32_t i, j, k;
@ -181,41 +181,6 @@ int main(int argc, char **argv) {
} }
} }
#ifdef DO_OFDM
if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn, SRSLTE_CP_EXT, cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n");
exit(-1);
}
if (srslte_ofdm_rx_init_mbsfn(&fft_mbsfn, SRSLTE_CP_EXT, cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n");
exit(-1);
}
srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn, non_mbsfn_region);
srslte_ofdm_set_non_mbsfn_region(&fft_mbsfn, non_mbsfn_region);
srslte_ofdm_set_normalize(&ifft_mbsfn, true);
srslte_ofdm_set_normalize(&fft_mbsfn, true);
for (i = 0; i < cell.nof_ports; i++) {
tx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
for (i = 0; i < nof_rx_antennas; i++) {
rx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
#endif /* DO_OFDM */
/* Configure PDSCH */
if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) {
fprintf(stderr, "Error configuring PMCH\n");
exit(-1);
}
/* init memory */ /* init memory */
for (i=0;i<SRSLTE_MAX_PORTS;i++) { for (i=0;i<SRSLTE_MAX_PORTS;i++) {
for (j = 0; j < SRSLTE_MAX_PORTS; j++) { for (j = 0; j < SRSLTE_MAX_PORTS; j++) {
@ -235,6 +200,25 @@ int main(int argc, char **argv) {
} }
} }
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
softbuffers_tx[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1);
if (!softbuffers_tx[i]) {
fprintf(stderr, "Error allocating TX soft buffer\n");
}
if (srslte_softbuffer_tx_init(softbuffers_tx[i], cell.nof_prb)) {
fprintf(stderr, "Error initiating TX soft buffer\n");
goto quit;
}
}
for (i = 0; i < cell.nof_ports; i++) {
tx_slot_symbols[i] = calloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), sizeof(cf_t));
if (!tx_slot_symbols[i]) {
perror("srslte_vec_malloc");
goto quit;
}
}
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (grant.tb_en[i]) { if (grant.tb_en[i]) {
@ -270,6 +254,44 @@ int main(int argc, char **argv) {
} }
} }
#ifdef DO_OFDM
for (i = 0; i < cell.nof_ports; i++) {
tx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn[i], SRSLTE_CP_EXT, tx_slot_symbols[i], tx_sf_symbols[i], cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n");
exit(-1);
}
srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn[i], non_mbsfn_region);
srslte_ofdm_set_normalize(&ifft_mbsfn[i], true);
}
for (i = 0; i < nof_rx_antennas; i++) {
rx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
if (srslte_ofdm_rx_init_mbsfn(&fft_mbsfn[i], SRSLTE_CP_EXT, rx_sf_symbols[i], rx_slot_symbols[i], cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n");
exit(-1);
}
srslte_ofdm_set_non_mbsfn_region(&fft_mbsfn[i], non_mbsfn_region);
srslte_ofdm_set_normalize(&fft_mbsfn[i], true);
}
#endif /* DO_OFDM */
/* Configure PDSCH */
if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) {
fprintf(stderr, "Error configuring PMCH\n");
exit(-1);
}
if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) { if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) {
fprintf(stderr, "Error configuring PMCH\n"); fprintf(stderr, "Error configuring PMCH\n");
exit(-1); exit(-1);
@ -312,25 +334,7 @@ int main(int argc, char **argv) {
srslte_pmch_set_area_id(&pmch_rx, mbsfn_area_id); srslte_pmch_set_area_id(&pmch_rx, mbsfn_area_id);
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
softbuffers_tx[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1);
if (!softbuffers_tx[i]) {
fprintf(stderr, "Error allocating TX soft buffer\n");
}
if (srslte_softbuffer_tx_init(softbuffers_tx[i], cell.nof_prb)) {
fprintf(stderr, "Error initiating TX soft buffer\n");
goto quit;
}
}
for (i = 0; i < cell.nof_ports; i++) {
tx_slot_symbols[i] = calloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), sizeof(cf_t));
if (!tx_slot_symbols[i]) {
perror("srslte_vec_malloc");
goto quit;
}
}
for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
if (grant.tb_en[tb]) { if (grant.tb_en[tb]) {
@ -353,7 +357,7 @@ int main(int argc, char **argv) {
#ifdef DO_OFDM #ifdef DO_OFDM
for (i = 0; i < cell.nof_ports; i++) { for (i = 0; i < cell.nof_ports; i++) {
/* For each Tx antenna modulate OFDM */ /* For each Tx antenna modulate OFDM */
srslte_ofdm_tx_sf(&ifft_mbsfn, tx_slot_symbols[i], tx_sf_symbols[i]); srslte_ofdm_tx_sf(&ifft_mbsfn[i]);
} }
@ -387,7 +391,7 @@ int main(int argc, char **argv) {
#ifdef DO_OFDM #ifdef DO_OFDM
/* For each Rx antenna demodulate OFDM */ /* For each Rx antenna demodulate OFDM */
for (i = 0; i < nof_rx_antennas; i++) { for (i = 0; i < nof_rx_antennas; i++) {
srslte_ofdm_rx_sf(&fft_mbsfn, tx_sf_symbols[i], rx_slot_symbols[i]); srslte_ofdm_rx_sf(&fft_mbsfn[i]);
} }
#endif #endif
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {

@ -109,7 +109,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_ofdm_tx_init(&ifft, cp, nof_prb)) { if (srslte_ofdm_tx_init(&ifft, cp, buffer, fft_buffer, nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n"); fprintf(stderr, "Error creating iFFT object\n");
exit(-1); exit(-1);
} }
@ -150,7 +150,13 @@ int main(int argc, char **argv) {
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
memset(fft_buffer, 0, sizeof(cf_t) * FLEN); memset(fft_buffer, 0, sizeof(cf_t) * FLEN);
srslte_ofdm_tx_sf(&ifft, buffer, &fft_buffer[offset]); srslte_ofdm_tx_sf(&ifft);
/* Apply sample offset */
for (int i = 0; i < FLEN; i++) {
fft_buffer[FLEN - i - 1 + offset] = fft_buffer[FLEN - i - 1];
}
bzero(fft_buffer, sizeof(cf_t) * offset);
if (srslte_sync_find(&syncobj, fft_buffer, 0, &find_idx) < 0) { if (srslte_sync_find(&syncobj, fft_buffer, 0, &find_idx) < 0) {
fprintf(stderr, "Error running srslte_sync_find\n"); fprintf(stderr, "Error running srslte_sync_find\n");

@ -53,6 +53,7 @@ static srslte_dci_format_t common_formats[] = {SRSLTE_DCI_FORMAT1A,SRSLTE_DCI_FO
const uint32_t nof_common_formats = 2; const uint32_t nof_common_formats = 2;
int srslte_ue_dl_init(srslte_ue_dl_t *q, int srslte_ue_dl_init(srslte_ue_dl_t *q,
cf_t *in_buffer[SRSLTE_MAX_PORTS],
uint32_t max_prb, uint32_t max_prb,
uint32_t nof_rx_antennas) uint32_t nof_rx_antennas)
{ {
@ -73,12 +74,35 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q,
q->sample_offset = 0; q->sample_offset = 0;
q->nof_rx_antennas = nof_rx_antennas; q->nof_rx_antennas = nof_rx_antennas;
if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, max_prb)) { for (int j = 0; j < SRSLTE_MAX_PORTS; j++) {
q->sf_symbols_m[j] = srslte_vec_malloc(MAX_SFLEN_RE * sizeof(cf_t));
if (!q->sf_symbols_m[j]) {
perror("malloc");
goto clean_exit;
}
for (uint32_t i=0;i<SRSLTE_MAX_PORTS;i++) {
q->ce_m[i][j] = srslte_vec_malloc(MAX_SFLEN_RE * sizeof(cf_t));
if (!q->ce_m[i][j]) {
perror("malloc");
goto clean_exit;
}
bzero(q->ce_m[i][j], MAX_SFLEN_RE * sizeof(cf_t));
}
}
q->sf_symbols = q->sf_symbols_m[0];
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
q->ce[i] = q->ce_m[i][0];
}
for (int i = 0; i < nof_rx_antennas; i++) {
if (srslte_ofdm_rx_init(&q->fft[i], SRSLTE_CP_NORM, in_buffer[i], q->sf_symbols_m[i], max_prb)) {
fprintf(stderr, "Error initiating FFT\n"); fprintf(stderr, "Error initiating FFT\n");
goto clean_exit; goto clean_exit;
} }
}
if (srslte_ofdm_rx_init_mbsfn(&q->fft_mbsfn, SRSLTE_CP_EXT, max_prb)) { if (srslte_ofdm_rx_init_mbsfn(&q->fft_mbsfn, SRSLTE_CP_EXT, in_buffer[0], q->sf_symbols_m[0], max_prb)) {
fprintf(stderr, "Error initiating FFT for MBSFN subframes \n"); fprintf(stderr, "Error initiating FFT for MBSFN subframes \n");
goto clean_exit; goto clean_exit;
} }
@ -127,28 +151,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q,
fprintf(stderr, "Error initiating SFO correct\n"); fprintf(stderr, "Error initiating SFO correct\n");
goto clean_exit; goto clean_exit;
} }
srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft.symbol_sz); srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft[0].symbol_sz);
for (int j = 0; j < SRSLTE_MAX_PORTS; j++) {
q->sf_symbols_m[j] = srslte_vec_malloc(MAX_SFLEN_RE * sizeof(cf_t));
if (!q->sf_symbols_m[j]) {
perror("malloc");
goto clean_exit;
}
for (uint32_t i=0;i<SRSLTE_MAX_PORTS;i++) {
q->ce_m[i][j] = srslte_vec_malloc(MAX_SFLEN_RE * sizeof(cf_t));
if (!q->ce_m[i][j]) {
perror("malloc");
goto clean_exit;
}
bzero(q->ce_m[i][j], MAX_SFLEN_RE * sizeof(cf_t));
}
}
q->sf_symbols = q->sf_symbols_m[0];
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
q->ce[i] = q->ce_m[i][0];
}
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} else { } else {
@ -164,7 +167,9 @@ clean_exit:
void srslte_ue_dl_free(srslte_ue_dl_t *q) { void srslte_ue_dl_free(srslte_ue_dl_t *q) {
if (q) { if (q) {
srslte_ofdm_rx_free(&q->fft); for (int port = 0; port < SRSLTE_MAX_PORTS; port++) {
srslte_ofdm_rx_free(&q->fft[port]);
}
srslte_ofdm_rx_free(&q->fft_mbsfn); srslte_ofdm_rx_free(&q->fft_mbsfn);
srslte_chest_dl_free(&q->chest); srslte_chest_dl_free(&q->chest);
srslte_regs_free(&q->regs); srslte_regs_free(&q->regs);
@ -219,11 +224,13 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell)
fprintf(stderr, "Error resizing SFO correct\n"); fprintf(stderr, "Error resizing SFO correct\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
srslte_cfo_set_tol(&q->sfo_correct, 1e-5/q->fft.symbol_sz); srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft[0].symbol_sz);
if (srslte_ofdm_rx_set_prb(&q->fft, q->cell.cp, q->cell.nof_prb)) { for (int port = 0; port < q->nof_rx_antennas; port++) {
if (srslte_ofdm_rx_set_prb(&q->fft[port], q->cell.cp, q->cell.nof_prb)) {
fprintf(stderr, "Error resizing FFT\n"); fprintf(stderr, "Error resizing FFT\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
}
if (srslte_chest_dl_set_cell(&q->chest, q->cell)) { if (srslte_chest_dl_set_cell(&q->chest, q->cell)) {
fprintf(stderr, "Error resizing channel estimator\n"); fprintf(stderr, "Error resizing channel estimator\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -339,9 +346,9 @@ int srslte_ue_dl_decode_fft_estimate_mbsfn(srslte_ue_dl_t *q, cf_t *input[SRSLTE
/* Run FFT for all subframe data */ /* Run FFT for all subframe data */
for (int j=0;j<q->nof_rx_antennas;j++) { for (int j=0;j<q->nof_rx_antennas;j++) {
if(sf_type == SRSLTE_SF_MBSFN ) { if(sf_type == SRSLTE_SF_MBSFN ) {
srslte_ofdm_rx_sf(&q->fft_mbsfn, input[j], q->sf_symbols_m[j]); srslte_ofdm_rx_sf(&q->fft_mbsfn);
}else{ }else{
srslte_ofdm_rx_sf(&q->fft, input[j], q->sf_symbols_m[j]); srslte_ofdm_rx_sf(&q->fft[j]);
} }
/* Correct SFO multiplying by complex exponential in the time domain */ /* Correct SFO multiplying by complex exponential in the time domain */
@ -351,7 +358,7 @@ int srslte_ue_dl_decode_fft_estimate_mbsfn(srslte_ue_dl_t *q, cf_t *input[SRSLTE
srslte_cfo_correct(&q->sfo_correct, srslte_cfo_correct(&q->sfo_correct,
&q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE],
&q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE],
q->sample_offset / q->fft.symbol_sz); q->sample_offset / q->fft[j].symbol_sz);
} }
} }
} }

@ -36,6 +36,7 @@
#include "srslte/phy/utils/vector.h" #include "srslte/phy/utils/vector.h"
int srslte_ue_mib_init(srslte_ue_mib_t * q, int srslte_ue_mib_init(srslte_ue_mib_t * q,
cf_t *in_buffer[SRSLTE_MAX_PORTS],
uint32_t max_prb) uint32_t max_prb)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
@ -65,7 +66,7 @@ int srslte_ue_mib_init(srslte_ue_mib_t * q,
} }
} }
if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, max_prb)) { if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, in_buffer[0], q->sf_symbols, max_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
goto clean_exit; goto clean_exit;
} }
@ -143,14 +144,14 @@ void srslte_ue_mib_reset(srslte_ue_mib_t * q)
srslte_pbch_decode_reset(&q->pbch); srslte_pbch_decode_reset(&q->pbch);
} }
int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, int srslte_ue_mib_decode(srslte_ue_mib_t * q,
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN], uint32_t *nof_tx_ports, int *sfn_offset) uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN], uint32_t *nof_tx_ports, int *sfn_offset)
{ {
int ret = SRSLTE_SUCCESS; int ret = SRSLTE_SUCCESS;
cf_t *ce_slot1[SRSLTE_MAX_PORTS]; cf_t *ce_slot1[SRSLTE_MAX_PORTS];
/* Run FFT for the slot symbols */ /* Run FFT for the slot symbols */
srslte_ofdm_rx_sf(&q->fft, input, q->sf_symbols); srslte_ofdm_rx_sf(&q->fft);
/* Get channel estimates of sf idx #0 for each port */ /* Get channel estimates of sf idx #0 for each port */
ret = srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, 0); ret = srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, 0);
@ -198,7 +199,7 @@ int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q,
} }
q->nof_rx_antennas = nof_rx_antennas; q->nof_rx_antennas = nof_rx_antennas;
if (srslte_ue_mib_init(&q->ue_mib, SRSLTE_UE_MIB_NOF_PRB)) { if (srslte_ue_mib_init(&q->ue_mib, q->sf_buffer, SRSLTE_UE_MIB_NOF_PRB)) {
fprintf(stderr, "Error initiating ue_mib\n"); fprintf(stderr, "Error initiating ue_mib\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -274,7 +275,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q,
return -1; return -1;
} else if (srslte_ue_sync_get_sfidx(&q->ue_sync) == 0) { } else if (srslte_ue_sync_get_sfidx(&q->ue_sync) == 0) {
if (ret == 1) { if (ret == 1) {
mib_ret = srslte_ue_mib_decode(&q->ue_mib, q->sf_buffer[0], bch_payload, nof_tx_ports, sfn_offset); mib_ret = srslte_ue_mib_decode(&q->ue_mib, bch_payload, nof_tx_ports, sfn_offset);
} else { } else {
DEBUG("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt); DEBUG("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt);
srslte_ue_mib_reset(&q->ue_mib); srslte_ue_mib_reset(&q->ue_mib);

@ -41,6 +41,7 @@
#define DEFAULT_CFO_TOL 50.0 // Hz #define DEFAULT_CFO_TOL 50.0 // Hz
int srslte_ue_ul_init(srslte_ue_ul_t *q, int srslte_ue_ul_init(srslte_ue_ul_t *q,
cf_t *out_buffer,
uint32_t max_prb) uint32_t max_prb)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
@ -51,7 +52,13 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q,
bzero(q, sizeof(srslte_ue_ul_t)); bzero(q, sizeof(srslte_ue_ul_t));
if (srslte_ofdm_tx_init(&q->fft, SRSLTE_CP_NORM, max_prb)) { q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_PRB(max_prb) * sizeof(cf_t));
if (!q->sf_symbols) {
perror("malloc");
goto clean_exit;
}
if (srslte_ofdm_tx_init(&q->fft, SRSLTE_CP_NORM, q->sf_symbols, out_buffer, max_prb)) {
fprintf(stderr, "Error initiating FFT\n"); fprintf(stderr, "Error initiating FFT\n");
goto clean_exit; goto clean_exit;
} }
@ -83,11 +90,6 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q,
fprintf(stderr, "Error initiating srslte_refsignal_ul\n"); fprintf(stderr, "Error initiating srslte_refsignal_ul\n");
goto clean_exit; goto clean_exit;
} }
q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_PRB(max_prb) * sizeof(cf_t));
if (!q->sf_symbols) {
perror("malloc");
goto clean_exit;
}
q->refsignal = srslte_vec_malloc(2 * SRSLTE_NRE * max_prb * sizeof(cf_t)); q->refsignal = srslte_vec_malloc(2 * SRSLTE_NRE * max_prb * sizeof(cf_t));
if (!q->refsignal) { if (!q->refsignal) {
perror("malloc"); perror("malloc");
@ -347,7 +349,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
q->last_pucch_format = format; q->last_pucch_format = format;
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); srslte_ofdm_tx_sf(&q->fft);
if (q->cfo_en) { if (q->cfo_en) {
srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb)); srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb));
@ -417,7 +419,7 @@ int srslte_ue_ul_srs_encode(srslte_ue_ul_t *q, uint32_t tti, cf_t *output_signal
} }
} }
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); srslte_ofdm_tx_sf(&q->fft);
if (q->cfo_en) { if (q->cfo_en) {
srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb)); srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb));
@ -486,7 +488,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
} }
} }
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); srslte_ofdm_tx_sf(&q->fft);
if (q->cfo_en) { if (q->cfo_en) {
srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb)); srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb));

@ -88,7 +88,7 @@ private:
bool running; bool running;
cf_t *signal_buffer_rx; cf_t *signal_buffer_rx;
cf_t *signal_buffer_tx; cf_t *signal_buffer_tx[SRSLTE_MAX_PORTS];
uint32_t tti_rx, tti_tx_dl, tti_tx_ul; uint32_t tti_rx, tti_tx_dl, tti_tx_ul;
uint32_t sf_rx, sf_tx, tx_mutex_cnt; uint32_t sf_rx, sf_tx, tx_mutex_cnt;
uint32_t t_rx, t_tx_dl, t_tx_ul; uint32_t t_rx, t_tx_dl, t_tx_ul;

@ -93,12 +93,13 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
fprintf(stderr, "Error allocating memory\n"); fprintf(stderr, "Error allocating memory\n");
return; return;
} }
signal_buffer_tx = (cf_t*) srslte_vec_malloc(2*SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t)); bzero(&signal_buffer_tx, sizeof(cf_t *) * SRSLTE_MAX_PORTS);
if (!signal_buffer_tx) { signal_buffer_tx[0] = (cf_t*) srslte_vec_malloc(2*SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t));
if (!signal_buffer_tx[0]) {
fprintf(stderr, "Error allocating memory\n"); fprintf(stderr, "Error allocating memory\n");
return; return;
} }
if (srslte_enb_dl_init(&enb_dl, phy->cell.nof_prb)) { if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, phy->cell.nof_prb)) {
fprintf(stderr, "Error initiating ENB DL\n"); fprintf(stderr, "Error initiating ENB DL\n");
return; return;
} }
@ -106,7 +107,7 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
fprintf(stderr, "Error initiating ENB DL\n"); fprintf(stderr, "Error initiating ENB DL\n");
return; return;
} }
if (srslte_enb_ul_init(&enb_ul, phy->cell.nof_prb)) { if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx, phy->cell.nof_prb)) {
fprintf(stderr, "Error initiating ENB UL\n"); fprintf(stderr, "Error initiating ENB UL\n");
return; return;
} }
@ -156,8 +157,10 @@ void phch_worker::stop()
if (signal_buffer_rx) { if (signal_buffer_rx) {
free(signal_buffer_rx); free(signal_buffer_rx);
} }
if (signal_buffer_tx) { for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
free(signal_buffer_tx); if (signal_buffer_tx[i]) {
free(signal_buffer_tx[i]);
}
} }
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
@ -338,9 +341,9 @@ void phch_worker::work_imp()
} }
// Generate signal and transmit // Generate signal and transmit
srslte_enb_dl_gen_signal(&enb_dl, signal_buffer_tx); srslte_enb_dl_gen_signal(&enb_dl);
Debug("Sending to radio\n"); Debug("Sending to radio\n");
phy->worker_end(tx_mutex_cnt, signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time); phy->worker_end(tx_mutex_cnt, signal_buffer_tx[0], SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time);
#ifdef DEBUG_WRITE_FILE #ifdef DEBUG_WRITE_FILE
fwrite(signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t), 1, f); fwrite(signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t), 1, f);

@ -347,7 +347,7 @@ private:
// Determine if it's a new transmission 5.3.2.2 // Determine if it's a new transmission 5.3.2.2
bool calc_is_new_transmission(Tgrant grant) { bool calc_is_new_transmission(Tgrant grant) {
if (grant.phy_grant.dl.mcs[tid].idx < 28 && // mcs 29,30,31 always retx regardless of rest if (grant.phy_grant.dl.mcs[tid].idx <= 28 && // mcs 29,30,31 always retx regardless of rest
((grant.ndi[tid] != cur_grant.ndi[tid]) || // 1st condition (NDI has changed) ((grant.ndi[tid] != cur_grant.ndi[tid]) || // 1st condition (NDI has changed)
(pid == HARQ_BCCH_PID && grant.rv[tid] == 0) || // 2nd condition (Broadcast and 1st transmission) (pid == HARQ_BCCH_PID && grant.rv[tid] == 0) || // 2nd condition (Broadcast and 1st transmission)
is_first_tb)) is_first_tb))

@ -104,12 +104,12 @@ void phch_recv:: init(srslte::radio_multi *_radio_handler, mac_interface_phy *_
srslte_ue_sync_start_agc(&cs.ue_sync, callback_set_rx_gain, last_gain); srslte_ue_sync_start_agc(&cs.ue_sync, callback_set_rx_gain, last_gain);
} }
if (srslte_ue_dl_init(&ue_dl_measure, SRSLTE_MAX_PRB, nof_rx_antennas)) { if (srslte_ue_dl_init(&ue_dl_measure, sf_buffer, SRSLTE_MAX_PRB, nof_rx_antennas)) {
Error("SYNC: Initiating ue_dl_measure\n"); Error("SYNC: Initiating ue_dl_measure\n");
return; return;
} }
if (srslte_ue_mib_init(&ue_mib, SRSLTE_MAX_PRB)) { if (srslte_ue_mib_init(&ue_mib, sf_buffer, SRSLTE_MAX_PRB)) {
Error("SYNC: Initiating UE MIB decoder\n"); Error("SYNC: Initiating UE MIB decoder\n");
return; return;
} }
@ -376,7 +376,7 @@ int phch_recv::cell_sync_sfn(void) {
int sfn_offset = 0; int sfn_offset = 0;
Info("SYNC: Trying to decode MIB... SNR=%.1f dB\n", Info("SYNC: Trying to decode MIB... SNR=%.1f dB\n",
10*log10(srslte_chest_dl_get_snr(&ue_mib.chest))); 10*log10(srslte_chest_dl_get_snr(&ue_mib.chest)));
int n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset); int n = srslte_ue_mib_decode(&ue_mib, bch_payload, NULL, &sfn_offset);
if (n < 0) { if (n < 0) {
Error("SYNC: Error decoding MIB while synchronising SFN"); Error("SYNC: Error decoding MIB while synchronising SFN");
return -1; return -1;

@ -117,12 +117,12 @@ bool phch_worker::init(uint32_t max_prb, srslte::log *log_h)
} }
} }
if (srslte_ue_dl_init(&ue_dl, max_prb, phy->args->nof_rx_ant)) { if (srslte_ue_dl_init(&ue_dl, signal_buffer, max_prb, phy->args->nof_rx_ant)) {
Error("Initiating UE DL\n"); Error("Initiating UE DL\n");
return false; return false;
} }
if (srslte_ue_ul_init(&ue_ul, max_prb)) { if (srslte_ue_ul_init(&ue_ul, signal_buffer[0], max_prb)) {
Error("Initiating UE UL\n"); Error("Initiating UE UL\n");
return false; return false;
} }

Loading…
Cancel
Save