Ejemplo n.º 1
0
void srslte_enb_dl_prepare_power_allocation(srslte_enb_dl_t *q)
{
  uint32_t nof_symbols_slot = SRSLTE_CP_NSYMB(q->cell.cp);
  uint32_t nof_re_symbol = SRSLTE_NRE * q->cell.nof_prb;

  if (q->rho_b != 0.0f && q->rho_b != 1.0f) {
    float scaling = 1.0f / q->rho_b;
    for (uint32_t i = 0; i < q->cell.nof_ports; i++) {
      for (uint32_t j = 0; j < 2; j++) {
        cf_t *ptr;
        ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 0);
        srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
        if (q->cell.cp == SRSLTE_CP_NORM) {
          ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 4);
          srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
        } else {
          ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 3);
          srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
        }
        if (q->cell.nof_ports == 4) {
          ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 1);
          srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
        }
      }
    }
  }
}
Ejemplo n.º 2
0
void srslte_ue_dl_set_power_alloc(srslte_ue_dl_t *q, float rho_a, float rho_b) {
  if (q) {
    srslte_pdsch_set_power_allocation(&q->pdsch, rho_a);
    q->rho_b = rho_b;

    uint32_t nof_symbols_slot = SRSLTE_CP_NSYMB(q->cell.cp);
    uint32_t nof_re_symbol = SRSLTE_NRE * q->cell.nof_prb;

    /* Apply rho_b if required according to 3GPP 36.213 Table 5.2-2 */
    if (rho_b != 0.0f && rho_b != 1.0f) {
      float scaling = 1.0f / rho_b;
      for (uint32_t i = 0; i < q->nof_rx_antennas; i++) {
        for (uint32_t j = 0; j < 2; j++) {
          cf_t *ptr;
          ptr = q->sf_symbols_m[i] + nof_re_symbol * (j * nof_symbols_slot + 0);
          srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
          if (q->cell.cp == SRSLTE_CP_NORM) {
            ptr = q->sf_symbols_m[i] + nof_re_symbol * (j * nof_symbols_slot + 4);
            srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
          } else {
            ptr = q->sf_symbols_m[i] + nof_re_symbol * (j * nof_symbols_slot + 3);
            srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
          }
          if (q->cell.nof_ports == 4) {
            ptr = q->sf_symbols_m[i] + nof_re_symbol * (j * nof_symbols_slot + 1);
            srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
          }
        }
      }
    }
  }
}
Ejemplo n.º 3
0
int main(int argc, char **argv) {
  uint32_t cfi;
  float cfi_corr; 
  int n;

  if (argc < 3) {
    usage(argv[0]);
    exit(-1);
  }

  parse_args(argc,argv);

  if (base_init()) {
    fprintf(stderr, "Error initializing receiver\n");
    exit(-1);
  }

  n = srslte_filesource_read(&fsrc, input_buffer, flen);

  srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer);

  if (fmatlab) {
    fprintf(fmatlab, "infft=");
    srslte_vec_fprint_c(fmatlab, input_buffer, flen);
    fprintf(fmatlab, ";\n");

    fprintf(fmatlab, "outfft=");
    srslte_vec_sc_prod_cfc(fft_buffer, 1000.0, fft_buffer, SRSLTE_CP_NSYMB(cell.cp) * cell.nof_prb * SRSLTE_NRE);
    srslte_vec_fprint_c(fmatlab, fft_buffer, SRSLTE_CP_NSYMB(cell.cp) * cell.nof_prb * SRSLTE_NRE);
    fprintf(fmatlab, ";\n");
    srslte_vec_sc_prod_cfc(fft_buffer, 0.001, fft_buffer,   SRSLTE_CP_NSYMB(cell.cp) * cell.nof_prb * SRSLTE_NRE);
  }

  /* Get channel estimates for each port */
  srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0);

  INFO("Decoding PCFICH\n", 0);

  
  n = srslte_pcfich_decode(&pcfich, fft_buffer, ce, srslte_chest_dl_get_noise_estimate(&chest),  0, &cfi, &cfi_corr);
  printf("cfi: %d, distance: %f\n", cfi, cfi_corr);

  base_free();

  if (n < 0) {
    fprintf(stderr, "Error decoding PCFICH\n");
    exit(-1);
  } else if (n == 0) {
    printf("Could not decode PCFICH\n");
    exit(-1);
  } else {
    if (cfi_corr > 2.8 && cfi == 1) {
      exit(0);
    } else {
      exit(-1);
    }
  }
}
Ejemplo n.º 4
0
int srslte_pss_synch_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time, 
                                 uint32_t N_id_2, uint32_t fft_size, int cfo_i) {
  srslte_dft_plan_t plan;
  cf_t pss_signal_pad[2048];
  int ret = SRSLTE_ERROR_INVALID_INPUTS;
  
  if (srslte_N_id_2_isvalid(N_id_2)    && 
      fft_size                  <= 2048) 
  {
    
    srslte_pss_generate(pss_signal_freq, N_id_2);

    bzero(pss_signal_pad, fft_size * sizeof(cf_t));
    bzero(pss_signal_time, fft_size * sizeof(cf_t));
    memcpy(&pss_signal_pad[(fft_size-SRSLTE_PSS_LEN)/2+cfo_i], pss_signal_freq, SRSLTE_PSS_LEN * sizeof(cf_t));

    /* Convert signal into the time domain */    
    if (srslte_dft_plan(&plan, fft_size, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) {
      return SRSLTE_ERROR;
    }
    
    srslte_dft_plan_set_mirror(&plan, true);
    srslte_dft_plan_set_dc(&plan, true);
    srslte_dft_plan_set_norm(&plan, true);
    srslte_dft_run_c(&plan, pss_signal_pad, pss_signal_time);

    srslte_vec_conj_cc(pss_signal_time, pss_signal_time, fft_size);
    srslte_vec_sc_prod_cfc(pss_signal_time, 1.0/SRSLTE_PSS_LEN, pss_signal_time, fft_size);

    srslte_dft_plan_free(&plan);
        
    ret = SRSLTE_SUCCESS;
  }
  return ret;
}
Ejemplo n.º 5
0
void srslte_interp_linear_offset(srslte_interp_lin_t *q, cf_t *input, cf_t *output, 
                          uint32_t off_st, uint32_t off_end) 
{
  uint32_t i, j;
  cf_t diff; 
  
  i=0;
  for (j=0;j<off_st;j++) {
    output[j] = input[i] + (j+1) * (input[i+1]-input[i]) / q->M;
  }
  srslte_vec_sub_ccc(&input[1], input, q->diff_vec, (q->vector_len-1));
  srslte_vec_sc_prod_cfc(q->diff_vec, (float) 1/q->M, q->diff_vec, q->vector_len-1);
  for (i=0;i<q->vector_len-1;i++) {
    for (j=0;j<q->M;j++) {
      output[i*q->M+j+off_st] = input[i];  
      q->diff_vec2[i*q->M+j] = q->diff_vec[i];
    }
    srslte_vec_prod_cfc(&q->diff_vec2[i*q->M],q->ramp,&q->diff_vec2[i*q->M],q->M);
  }
  srslte_vec_sum_ccc(&output[off_st], q->diff_vec2, &output[off_st], q->M*(q->vector_len-1));
  
  if (q->vector_len > 1) {
    diff = input[q->vector_len-1]-input[q->vector_len-2];
    for (j=0;j<off_end;j++) {
      output[i*q->M+j+off_st] = input[i] + j * diff / q->M;  
    }
  }
}
Ejemplo n.º 6
0
void srslte_enb_dl_gen_signal(srslte_enb_dl_t* q)
{
  // TODO: PAPR control
  float norm_factor = 0.05f / sqrt(q->cell.nof_prb);

  if (q->dl_sf.sf_type == SRSLTE_SF_MBSFN) {
    srslte_ofdm_tx_sf(&q->ifft_mbsfn);
    srslte_vec_sc_prod_cfc(
        q->ifft_mbsfn.out_buffer, norm_factor, q->ifft_mbsfn.out_buffer, (uint32_t)SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
  } else {
    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, norm_factor, q->ifft[i].out_buffer, (uint32_t)SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
    }
  }
}
Ejemplo n.º 7
0
// TODO: Improve this implementation
void srslte_vec_norm_cfc(cf_t *x, float amplitude, cf_t *y, uint32_t len) {
  // We should use fabs() here but is statistically should be similar
  float *xp = (float*) x; 
  uint32_t idx = srslte_vec_max_fi(xp, 2*len);
  float max = xp[idx]; 

  // Normalize before TX 
  srslte_vec_sc_prod_cfc(x, amplitude/max, y, len);
}
Ejemplo n.º 8
0
void srslte_interp_linear_vector(srslte_interp_linsrslte_vec_t *q, cf_t *in0, cf_t *in1, cf_t *between, uint32_t M) 
{
  uint32_t i;
  
  srslte_vec_sub_ccc(in1, in0, q->diff_vec, q->vector_len);
  srslte_vec_sc_prod_cfc(q->diff_vec, (float) 1/M, q->diff_vec, q->vector_len);
  srslte_vec_sum_ccc(in0, q->diff_vec, between, q->vector_len);
  for (i=0;i<M-1;i++) {
    srslte_vec_sum_ccc(between, q->diff_vec, &between[q->vector_len], q->vector_len);
    between += q->vector_len;
  }
}
Ejemplo n.º 9
0
// TODO: Improve this implementation
void srslte_vec_norm_cfc(cf_t *x, float amplitude, cf_t *y, uint32_t len) {
  // Compute peak
  float max = 0; 
  float *t = (float*) x;
  for (int i=0;i<2*len;i++) {
    if (fabsf(t[i]) > max) {
      max = fabsf(t[i]);
    }
  }
    
  // Normalize before TX 
  srslte_vec_sc_prod_cfc(x, amplitude/max, y, len);
}
Ejemplo n.º 10
0
Archivo: pss.c Proyecto: srsLTE/srsLTE
/* input points to beginning of last OFDM symbol of slot 0 of subframe 0 or 5
 * It must be called after calling srslte_pss_cfo_compute() with filter enabled
 */
void srslte_pss_sic(srslte_pss_t *q, cf_t *input) {
  if (q->chest_on_filter) {

    bzero(q->tmp_fft, sizeof(cf_t)*q->fft_size);

    // Pass transmitted PSS sequence through the channel
    srslte_vec_prod_ccc(q->pss_signal_freq[q->N_id_2], q->tmp_ce, &q->tmp_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], SRSLTE_PSS_LEN);

    // Get time-domain version of the received PSS
    srslte_dft_run_c(&q->idftp_input, q->tmp_fft, q->tmp_fft2);

    // Substract received PSS from this N_id_2 from the input signal
    srslte_vec_sc_prod_cfc(q->tmp_fft2, 1.0/q->fft_size, q->tmp_fft2, q->fft_size);
    srslte_vec_sub_ccc(input, q->tmp_fft2, input, q->fft_size);

  } else {
    ERROR("Error calling srslte_pss_sic(): need to enable channel estimation on filtering\n");
  }
}
Ejemplo n.º 11
0
void srslte_dft_run_c(srslte_dft_plan_t *plan, cf_t *in, cf_t *out) {
  float norm;
  int i;
  fftwf_complex *f_out = plan->out;

  copy_pre((uint8_t*)plan->in, (uint8_t*)in, sizeof(cf_t), plan->size,
           plan->forward, plan->mirror, plan->dc);
  fftwf_execute(plan->p);
  if (plan->norm) {
    norm = 1.0/sqrtf(plan->size);
    srslte_vec_sc_prod_cfc(f_out, norm, f_out, plan->size);    
  }
  if (plan->db) {
    for (i=0;i<plan->size;i++) {
      f_out[i] = 10*log10(f_out[i]);
    }
  }
  copy_post((uint8_t*)out, (uint8_t*)plan->out, sizeof(cf_t), plan->size,
            plan->forward, plan->mirror, plan->dc);
}
Ejemplo n.º 12
0
int main(int argc, char **argv) {
  int sf_idx=0, N_id_2=0;
  cf_t pss_signal[SRSLTE_PSS_LEN];
  float sss_signal0[SRSLTE_SSS_LEN]; // for subframe 0
  float sss_signal5[SRSLTE_SSS_LEN]; // for subframe 5
  int i;
  
#ifdef DISABLE_UHD
  if (argc < 3) {
    usage(argv[0]);
    exit(-1);
  }
#endif

  parse_args(argc, argv);

  N_id_2 = cell.id % 3;
  sf_n_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE;
  sf_n_samples = 2 * SRSLTE_SLOT_LEN(srslte_symbol_sz(cell.nof_prb));

  cell.phich_length = SRSLTE_PHICH_NORM;
  cell.phich_resources = SRSLTE_PHICH_R_1;

  /* this *must* be called after setting slot_len_* */
  base_init();

  /* Generate PSS/SSS signals */
  srslte_pss_generate(pss_signal, N_id_2);
  srslte_sss_generate(sss_signal0, sss_signal5, cell.id);
  
  printf("Set TX rate: %.2f MHz\n",
      cuhd_set_tx_srate(uhd, srslte_sampling_freq_hz(cell.nof_prb)) / 1000000);
  printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain));
  printf("Set TX freq: %.2f MHz\n",
      cuhd_set_tx_freq(uhd, uhd_freq) / 1000000);

  uint32_t nbits; 
  
  srslte_modem_table_t modulator; 
  srslte_modem_table_init(&modulator);
  srslte_modem_table_lte(&modulator, modulation);

  srslte_tcod_t turbocoder; 
  srslte_tcod_init(&turbocoder, SRSLTE_TCOD_MAX_LEN_CB);

  srslte_dft_precoding_t dft_precod;
  srslte_dft_precoding_init(&dft_precod, 12);
  
  nbits = srslte_cbsegm_cbindex(sf_n_samples/8/srslte_mod_bits_x_symbol(modulation)/3 - 12);
  uint32_t ncoded_bits = sf_n_samples/8/srslte_mod_bits_x_symbol(modulation); 
  
  uint8_t *data     = malloc(sizeof(uint8_t)*nbits);
  uint8_t *data_enc = malloc(sizeof(uint8_t)*ncoded_bits);
  cf_t    *symbols  = malloc(sizeof(cf_t)*sf_n_samples);
  
  bzero(data_enc, sizeof(uint8_t)*ncoded_bits);
  while (1) {
    for (sf_idx = 0; sf_idx < SRSLTE_NSUBFRAMES_X_FRAME; sf_idx++) {
      bzero(sf_buffer, sizeof(cf_t) * sf_n_re);

#ifdef kk
      if (sf_idx == 0 || sf_idx == 5) {
        srslte_pss_put_slot(pss_signal, sf_buffer, cell.nof_prb, SRSLTE_CP_NORM);
        srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb,
            SRSLTE_CP_NORM);
        /* Transform to OFDM symbols */
        srslte_ofdm_tx_sf(&ifft, sf_buffer, output_buffer);
        
        float norm_factor = (float) sqrtf(cell.nof_prb)/15;
        srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
      
      } else {
#endif
        /* Generate random data */
        for (i=0;i<nbits;i++) {
          data[i] = rand()%2;
        }
        srslte_tcod_encode(&turbocoder, data, data_enc, nbits);
        srslte_mod_modulate(&modulator, data_enc, symbols, ncoded_bits);        
        srslte_interp_linear_offset_cabs(symbols, output_buffer, 8, sf_n_samples/8, 0, 0);
//    }
      
      /* send to usrp */
      srslte_vec_sc_prod_cfc(output_buffer, uhd_amp, output_buffer, sf_n_samples);
      cuhd_send(uhd, output_buffer, sf_n_samples, true);
    }
  }

  base_free();

  printf("Done\n");
  exit(0);
}
Ejemplo n.º 13
0
void srslte_vec_ema_filter(cf_t *new_data, cf_t *average, cf_t *output, float coeff, uint32_t len) {
  srslte_vec_sc_prod_cfc(new_data, coeff, new_data, len);
  srslte_vec_sc_prod_cfc(average, 1-coeff, output, len);
  srslte_vec_sum_ccc(output, new_data, output, len);
}
Ejemplo n.º 14
0
void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
  float gain_db = 10*log10(q->gain); 
  float gain_uhd_db = 1.0;
  //float gain_uhd = 1.0;  
  float y = 0; 
  // Apply current gain to input signal 
  if (!q->uhd_handler) {
    srslte_vec_sc_prod_cfc(signal, q->gain, signal, len);
  } else {
    if (q->gain < 1) {
      q->gain = 1.0; 
    }
    if (isinf(gain_db) || isnan(gain_db)) {
      q->gain = 10.0; 
    } else {
      gain_uhd_db = q->set_gain_callback(q->uhd_handler, gain_db);        
      q->gain = pow(10, gain_uhd_db/10);
    }
  }
  float *t; 
  switch(q->mode) {
    case SRSLTE_AGC_MODE_ENERGY:
      y = sqrtf(crealf(srslte_vec_dot_prod_conj_ccc(signal, signal, len))/len);
      break;
    case SRSLTE_AGC_MODE_PEAK_AMPLITUDE:
      t = (float*) signal; 
      y = t[srslte_vec_max_fi(t, 2*len)];// take only positive max to avoid abs() (should be similar) 
      break;
    default: 
      fprintf(stderr, "Unsupported AGC mode\n");
      return; 
  }
  
  if (q->nof_frames > 0) {
    q->y_tmp[q->frame_cnt++] = y; 
    if (q->frame_cnt == q->nof_frames) {
      q->frame_cnt = 0; 
      switch(q->mode) {
        case SRSLTE_AGC_MODE_ENERGY:
          y = srslte_vec_acc_ff(q->y_tmp, q->nof_frames)/q->nof_frames;
          break;
        case SRSLTE_AGC_MODE_PEAK_AMPLITUDE:
          y = q->y_tmp[srslte_vec_max_fi(q->y_tmp, q->nof_frames)];
          break;
        default: 
          fprintf(stderr, "Unsupported AGC mode\n");
          return; 
      }
    }
  }
  
  double gg = 1.0; 
  if (q->isfirst) {
    q->y_out = y; 
    q->isfirst = false; 
  } else {
    if (q->frame_cnt == 0) {
      q->y_out = (1-q->bandwidth) * q->y_out + q->bandwidth * y;
      if (!q->lock) {
        gg = expf(-0.5*q->bandwidth*logf(q->y_out/q->target));
        q->gain *= gg; 
      }          
      INFO("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg);      
    }
  }
}
Ejemplo n.º 15
0
/* the gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
 
  if (nrhs != NOF_INPUTS) {
    help();
    return;
  }
   
  uint32_t n_ul_rb = 0; 
  if (mexutils_read_uint32_struct(UECFG, "NULRB", &n_ul_rb)) {
    mexErrMsgTxt("Field NULRB not found in UE config\n");
    return;
  }  
  int r = srslte_symbol_sz(n_ul_rb);
  if (r < 0) {
    mexErrMsgTxt("Invalid NULRB\n");
    return;
  }
  uint32_t N_ifft_ul = (uint32_t) r; 
  
  uint32_t sf_idx = 0; 
  mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx);
  uint32_t nframe = 0; 
  mexutils_read_uint32_struct(UECFG, "NFrame", &nframe);

  uint32_t preamble_format = 0; 
  mexutils_read_uint32_struct(PRACHCFG, "Format", &preamble_format);
  uint32_t root_seq_idx = 0; 
  mexutils_read_uint32_struct(PRACHCFG, "SeqIdx", &root_seq_idx);
  uint32_t seq_idx = 0; 
  mexutils_read_uint32_struct(PRACHCFG, "PreambleIdx", &seq_idx);
  uint32_t zero_corr_zone = 0; 
  mexutils_read_uint32_struct(PRACHCFG, "CyclicShiftIdx", &zero_corr_zone);
  uint32_t high_speed_flag = 0; 
  mexutils_read_uint32_struct(PRACHCFG, "HighSpeed", &high_speed_flag);
  uint32_t timing_offset = 0; 
  mexutils_read_uint32_struct(PRACHCFG, "TimingOffset", &timing_offset);
  uint32_t frequency_offset = 0; 
  mexutils_read_uint32_struct(PRACHCFG, "FreqOffset", &frequency_offset);

  srslte_prach_t prach; 
  if (srslte_prach_init(&prach, N_ifft_ul, preamble_format, root_seq_idx, high_speed_flag, zero_corr_zone)) {
    mexErrMsgTxt("Error initiating PRACH\n");
    return;
  }

  uint32_t nof_samples = srslte_sampling_freq_hz(n_ul_rb) * 0.001;
  
  cf_t *signal = srslte_vec_malloc(sizeof(cf_t) * nof_samples);
  if (!signal) {
    mexErrMsgTxt("malloc");
    return;
  }
  bzero(signal, sizeof(cf_t) * nof_samples);
  if (srslte_prach_gen(&prach, seq_idx, frequency_offset, signal)) {
    mexErrMsgTxt("Error generating PRACH\n");
    return; 
  }

  srslte_vec_sc_prod_cfc(signal, 1.0/sqrtf(N_ifft_ul), signal, nof_samples);              
  
  if (nlhs >= 0) {
    mexutils_write_cf(signal, &plhs[0], nof_samples, 1);  
  }
  
  free(signal);
  
  srslte_prach_free(&prach);
  
  return;
}