示例#1
0
int srslte_prach_gen(srslte_prach_t *p,
              uint32_t seq_index,
              uint32_t freq_offset,
              cf_t *signal)
{
  int ret = SRSLTE_ERROR;
  if(p          != NULL   &&
     seq_index  <  N_SEQS &&
     signal     != NULL)
  {
    // Calculate parameters
    uint32_t N_rb_ul = srslte_nof_prb(p->N_ifft_ul);
    uint32_t k_0 = freq_offset*N_RB_SC - N_rb_ul*N_RB_SC/2 + p->N_ifft_ul/2;
    uint32_t K = DELTA_F/DELTA_F_RA;
    uint32_t begin = PHI + (K*k_0) + (K/2);

    if (6 + freq_offset > N_rb_ul) {
      fprintf(stderr, "Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", freq_offset, N_rb_ul);
      return ret; 
    }
    
    DEBUG("N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d\n", 
          p->N_zc, p->N_cp, p->N_seq, p->N_ifft_prach, begin);
    
    // Map dft-precoded sequence to ifft bins
    memset(p->ifft_in, 0, begin*sizeof(cf_t));
    memcpy(&p->ifft_in[begin], p->dft_seqs[seq_index], p->N_zc * sizeof(cf_t));
    memset(&p->ifft_in[begin+p->N_zc], 0, (p->N_ifft_prach - begin - p->N_zc) * sizeof(cf_t));

    srslte_dft_run(p->ifft, p->ifft_in, p->ifft_out);

    // Copy CP into buffer
    memcpy(signal, &p->ifft_out[p->N_ifft_prach-p->N_cp], p->N_cp*sizeof(cf_t));

    // Copy preamble sequence into buffer
    for(int i=0;i<p->N_seq;i++){
      signal[p->N_cp+i] = p->ifft_out[i%p->N_ifft_prach];
    }
    
    ret = SRSLTE_SUCCESS;
  }

  return ret;
}
示例#2
0
int srslte_prach_detect(srslte_prach_t *p,
                 uint32_t freq_offset,
                 cf_t *signal,
                 uint32_t sig_len,
                 uint32_t *indices,
                 uint32_t *n_indices)
{
  int ret = SRSLTE_ERROR;
  if(p       != NULL &&
     signal  != NULL &&
     sig_len > 0     &&
     indices != NULL)
  {
    if(sig_len != p->N_ifft_prach){
      INFO("srslte_prach_detect: Signal is not of length %d", p->N_ifft_prach);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }

    // FFT incoming signal
    srslte_dft_run(p->fft, signal, signal);

    memset(p->prach_bins, 0, sizeof(cf_t)*p->N_zc);
    *n_indices = 0;

    // Extract bins of interest
    uint32_t N_rb_ul = prach_get_rb_ul(p->N_ifft_ul);
    uint32_t k_0 = freq_offset*N_RB_SC - N_rb_ul*N_RB_SC/2 + p->N_ifft_ul/2;
    uint32_t K = DELTA_F/DELTA_F_RA;
    uint32_t begin = PHI + (K*k_0) + (K/2);

    for(int i=0;i<p->N_zc;i++){
      p->prach_bins[i] = signal[begin+i];
    }

    for(int i=0;i<p->N_roots;i++){
      memset(p->corr_spec, 0, sizeof(cf_t)*p->N_zc);
      memset(p->corr, 0, sizeof(float)*p->N_zc);
      float corr_max = 0;
      float corr_ave = 0;

      cf_t *root_spec = p->dft_seqs[p->root_seqs_idx[i]];

      for(int j=0;j<p->N_zc;j++){
        p->corr_spec[j] = p->prach_bins[j]*conjf(root_spec[j]);
      }

      srslte_dft_run(p->zc_ifft, p->corr_spec, p->corr_spec);

      float norm = sqrtf(p->N_zc);
      for(int j=0;j<p->N_zc;j++){
        p->corr[j] = cabsf(p->corr_spec[j])/norm;
        corr_ave += p->corr[j];
      }
      corr_ave /= p->N_zc;

      uint32_t winsize = 0;
      if(p->N_cs != 0){
        winsize = p->N_cs;
      }else{
        winsize = p->N_zc;
      }
      uint32_t n_wins = p->N_zc/winsize;
      for(int j=0;j<n_wins;j++){
        uint32_t start = (p->N_zc-(j*p->N_cs))%p->N_zc;
        uint32_t end = start+winsize;
        corr_max = 0;
        for(int k=start;k<end;k++){
          if(p->corr[k] > corr_max){
            corr_max = p->corr[k];
          }
        }
        if(corr_max > PRACH_DETECT_FACTOR*corr_ave){
          indices[*n_indices] = (i*n_wins)+j;
          (*n_indices)++;
        }
      }
    }

    ret = SRSLTE_SUCCESS;
  }
  return ret;
}
示例#3
0
int srslte_prach_init(srslte_prach_t *p,
               uint32_t N_ifft_ul,
               uint32_t preamble_format,
               uint32_t root_seq_index,
               bool high_speed_flag,
               uint32_t zero_corr_zone_config)
{
  int ret = SRSLTE_ERROR;
  if(p                      != NULL      &&
     N_ifft_ul              <  2049      &&
     preamble_format        <  4         && // Currently supporting formats 0-3
     root_seq_index         <  MAX_ROOTS &&
     zero_corr_zone_config  < 16)
  {

    p->f = preamble_format;
    p->rsi = root_seq_index;
    p->hs = high_speed_flag;
    p->zczc = zero_corr_zone_config;
    
    // Determine N_zc and N_cs
    if(4 == preamble_format){
      p->N_zc = 139;
      p->N_cs = prach_Ncs_format4[p->zczc];
    }else{
      p->N_zc = 839;
      if(p->hs){
        p->N_cs = prach_Ncs_restricted[p->zczc];
      }else{
        p->N_cs = prach_Ncs_unrestricted[p->zczc];
      }
    }

    // Set up containers
    p->prach_bins = srslte_vec_malloc(sizeof(cf_t)*p->N_zc);
    p->corr_spec = srslte_vec_malloc(sizeof(cf_t)*p->N_zc);
    p->corr = srslte_vec_malloc(sizeof(float)*p->N_zc);

    // Set up ZC FFTS
    p->zc_fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->zc_fft, p->N_zc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){
      return SRSLTE_ERROR;
    }
    srslte_dft_plan_set_mirror(p->zc_fft, false);
    srslte_dft_plan_set_norm(p->zc_fft, true);

    p->zc_ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->zc_ifft, p->N_zc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)){
      return SRSLTE_ERROR;
    }
    srslte_dft_plan_set_mirror(p->zc_ifft, false);
    srslte_dft_plan_set_norm(p->zc_ifft, true);

    // Generate our 64 sequences
    p->N_roots = 0;
    srslte_prach_gen_seqs(p);

    // Generate sequence FFTs
    for(int i=0;i<N_SEQS;i++){
      srslte_dft_run(p->zc_fft, p->seqs[i], p->dft_seqs[i]);
    }

    // Create our FFT objects and buffers
    p->N_ifft_ul = N_ifft_ul;
    if(4 == preamble_format){
      p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA_4;
    }else{
      p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA;
    }

    p->ifft_in = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t));
    p->ifft_out = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t));
    p->ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) {
      fprintf(stderr, "Error creating DFT plan\n");
      return -1;
    }
    srslte_dft_plan_set_mirror(p->ifft, true);
    srslte_dft_plan_set_norm(p->ifft, true);

    p->fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->fft, p->N_ifft_prach, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){
      fprintf(stderr, "Error creating DFT plan\n");
      return -1;
    }
    srslte_dft_plan_set_mirror(p->fft, true);
    srslte_dft_plan_set_norm(p->fft, true);

    p->N_seq = prach_Tseq[p->f]*p->N_ifft_ul/2048;
    p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048;

    ret = SRSLTE_SUCCESS;
  } else {
    fprintf(stderr, "Invalid parameters\n");
  }

  return ret;
}
示例#4
0
int srslte_prach_detect_offset(srslte_prach_t *p,
                               uint32_t freq_offset,
                               cf_t *signal,
                               uint32_t sig_len,
                               uint32_t *indices,
                               float *t_offsets,
                               float    *peak_to_avg,
                               uint32_t *n_indices)
{
  int ret = SRSLTE_ERROR;
  if(p       != NULL &&
     signal  != NULL &&
     sig_len > 0     &&
     indices != NULL)
  {
    
    if(sig_len < p->N_ifft_prach){
      fprintf(stderr, "srslte_prach_detect: Signal length is %d and should be %d\n", sig_len, p->N_ifft_prach);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
    
    // FFT incoming signal
    srslte_dft_run(p->fft, signal, p->signal_fft);

    *n_indices = 0;

    // Extract bins of interest
    uint32_t N_rb_ul = srslte_nof_prb(p->N_ifft_ul);
    uint32_t k_0 = freq_offset*N_RB_SC - N_rb_ul*N_RB_SC/2 + p->N_ifft_ul/2;
    uint32_t K = DELTA_F/DELTA_F_RA;
    uint32_t begin = PHI + (K*k_0) + (K/2);

    memcpy(p->prach_bins, &p->signal_fft[begin], p->N_zc*sizeof(cf_t));
    
    for(int i=0;i<p->N_roots;i++){
      cf_t *root_spec = p->dft_seqs[p->root_seqs_idx[i]];
     
      srslte_vec_prod_conj_ccc(p->prach_bins, root_spec, p->corr_spec, p->N_zc);

      srslte_dft_run(p->zc_ifft, p->corr_spec, p->corr_spec);
      
      srslte_vec_abs_square_cf(p->corr_spec, p->corr, p->N_zc);

      float corr_ave = srslte_vec_acc_ff(p->corr, p->N_zc)/p->N_zc;
      
      uint32_t winsize = 0;
      if(p->N_cs != 0){
        winsize = p->N_cs;
      }else{
        winsize = p->N_zc;
      }
      uint32_t n_wins = p->N_zc/winsize;

      float max_peak = 0; 
      for(int j=0;j<n_wins;j++) {
        uint32_t start = (p->N_zc-(j*p->N_cs))%p->N_zc;
        uint32_t end = start+winsize;
        if (end>p->deadzone) {
          end-=p->deadzone;
        }
        start += p->deadzone;
        p->peak_values[j] = 0;
        for(int k=start;k<end;k++) {
          if(p->corr[k] > p->peak_values[j]) {
            p->peak_values[j]  = p->corr[k];
            p->peak_offsets[j] = k-start; 
            if (p->peak_values[j] > max_peak) {
              max_peak = p->peak_values[j];
            }
          }
        }
      }
      if (max_peak > p->detect_factor*corr_ave) {
        for (int j=0;j<n_wins;j++) {
          if(p->peak_values[j] > p->detect_factor*corr_ave)
          {
            printf("ncs=%d, nzc=%d, nwins=%d, Nroot=%d, i=%d, j=%d, start=%d, peak_value=%f, peak_offset=%d, tseq=%f\n", 
                   p->N_cs, p->N_zc, n_wins, p->N_roots, i, j, (p->N_zc-(j*p->N_cs))%p->N_zc, p->peak_values[j], 
                   p->peak_offsets[j], p->T_seq*1e6);
            memcpy(save_corr, p->corr, p->N_zc*sizeof(float));
            if (indices) {
              indices[*n_indices]     = (i*n_wins)+j;
            }
            if (peak_to_avg) {
              peak_to_avg[*n_indices] = p->peak_values[j]/corr_ave; 
            }
            if (t_offsets) {
              t_offsets[*n_indices] = (float) p->peak_offsets[j]*p->T_seq/p->N_zc; 
            }            
            (*n_indices)++;          
          }
        }
      }
    }

    ret = SRSLTE_SUCCESS;
  }
  return ret;
}
示例#5
0
int srslte_prach_init(srslte_prach_t *p,
               uint32_t N_ifft_ul,
               uint32_t config_idx,
               uint32_t root_seq_index,
               bool high_speed_flag,
               uint32_t zero_corr_zone_config)
{
  int ret = SRSLTE_ERROR;
  if(p                      != NULL      &&
     N_ifft_ul              <  2049      &&
     config_idx             <  16        && 
     root_seq_index         <  MAX_ROOTS)
  {
    uint32_t preamble_format = srslte_prach_get_preamble_format(config_idx);
    p->config_idx = config_idx; 
    p->f = preamble_format;
    p->rsi = root_seq_index;
    p->hs = high_speed_flag;
    p->zczc = zero_corr_zone_config;
    p->detect_factor = PRACH_DETECT_FACTOR; 
    
    
    // Determine N_zc and N_cs
    if(4 == preamble_format){
      if (p->zczc < 7) {
        p->N_zc = 139;
        p->N_cs = prach_Ncs_format4[p->zczc];
      } else {
        fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for format4\n", p->zczc);
        return SRSLTE_ERROR;
      }
    }else{
      p->N_zc = 839;
      if(p->hs){
        if (p->zczc < 15) {
          p->N_cs = prach_Ncs_restricted[p->zczc];
        } else {
          fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for restricted set\n", p->zczc);
          return SRSLTE_ERROR;
        }   
      }else{
        if (p->zczc < 16) {
          p->N_cs = prach_Ncs_unrestricted[p->zczc];
        } else {
          fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d\n", p->zczc);
          return SRSLTE_ERROR;
        }   
      }
    }
    
    // Set up containers
    p->prach_bins = srslte_vec_malloc(sizeof(cf_t)*p->N_zc);
    p->corr_spec = srslte_vec_malloc(sizeof(cf_t)*p->N_zc);
    p->corr = srslte_vec_malloc(sizeof(float)*p->N_zc);

    // Set up ZC FFTS
    p->zc_fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->zc_fft, p->N_zc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){
      return SRSLTE_ERROR;
    }
    srslte_dft_plan_set_mirror(p->zc_fft, false);
    srslte_dft_plan_set_norm(p->zc_fft, true);

    p->zc_ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->zc_ifft, p->N_zc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)){
      return SRSLTE_ERROR;
    }
    srslte_dft_plan_set_mirror(p->zc_ifft, false);
    srslte_dft_plan_set_norm(p->zc_ifft, false);

    // Generate our 64 sequences
    p->N_roots = 0;
    srslte_prach_gen_seqs(p);

    // Generate sequence FFTs
    for(int i=0;i<N_SEQS;i++){
      srslte_dft_run(p->zc_fft, p->seqs[i], p->dft_seqs[i]);
    }
    
    // Create our FFT objects and buffers
    p->N_ifft_ul = N_ifft_ul;
    if(4 == preamble_format){
      p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA_4;
    }else{
      p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA;
    }
    
    /* The deadzone specifies the number of samples at the end of the correlation window
     * that will be considered as belonging to the next preamble
     */
    p->deadzone = 0; 
    /*
    if(p->N_cs != 0) {
      float samp_rate=15000*p->N_ifft_ul;
      p->deadzone = (uint32_t) ceil((float) samp_rate/((float) p->N_zc*subcarrier_spacing));
    }*/

    p->ifft_in = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t));
    p->ifft_out = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t));
    p->ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) {
      fprintf(stderr, "Error creating DFT plan\n");
      return -1;
    }
    srslte_dft_plan_set_mirror(p->ifft, true);
    srslte_dft_plan_set_norm(p->ifft, true);

    p->fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
    if(srslte_dft_plan(p->fft, p->N_ifft_prach, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){
      fprintf(stderr, "Error creating DFT plan\n");
      return -1;
    }
    
    p->signal_fft = srslte_vec_malloc(sizeof(cf_t)*p->N_ifft_prach);
    if (!p->signal_fft) {
      fprintf(stderr, "Error allocating memory\n");
      return -1; 
    }
    
    srslte_dft_plan_set_mirror(p->fft, true);
    srslte_dft_plan_set_norm(p->fft, false);

    p->N_seq = prach_Tseq[p->f]*p->N_ifft_ul/2048;
    p->N_cp  = prach_Tcp[p->f]*p->N_ifft_ul/2048;
    p->T_seq = prach_Tseq[p->f]*SRSLTE_LTE_TS;
    
    ret = SRSLTE_SUCCESS;
  } else {
    fprintf(stderr, "Invalid parameters\n");
  }

  return ret;
}