コード例 #1
0
ファイル: phich.c プロジェクト: Intellifora/srsLTE
/** Initializes the phich channel receiver */
int srslte_phich_init(srslte_phich_t *q, srslte_regs_t *regs, srslte_cell_t cell) {
  int ret = SRSLTE_ERROR_INVALID_INPUTS;
  
  if (q         != NULL &&
      regs      != NULL &&
      srslte_cell_isvalid(&cell)) 
  {

    bzero(q, sizeof(srslte_phich_t));
    ret = SRSLTE_ERROR;
    
    q->cell = cell;
    q->regs = regs;
    
    if (srslte_precoding_init(&q->precoding, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp))) {
      fprintf(stderr, "Error initializing precoding\n");
    }

    if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_BPSK)) {
      goto clean;
    }

    for (int nsf = 0; nsf < SRSLTE_NSUBFRAMES_X_FRAME; nsf++) {
      if (srslte_sequence_phich(&q->seq[nsf], 2 * nsf, q->cell.id)) {
        goto clean;
      }
    }
    ret = SRSLTE_SUCCESS;
  }
  clean: 
  if (ret == SRSLTE_ERROR) {
    srslte_phich_free(q);
  }
  return ret;
}
コード例 #2
0
ファイル: pcfich.c プロジェクト: sshei/srsLTE
/** Initializes the pcfich channel receiver. 
 * On error, returns -1 and frees the structrure 
 */
int srslte_pcfich_init(srslte_pcfich_t *q, srslte_regs_t *regs, srslte_cell_t cell) {
  int ret = SRSLTE_ERROR_INVALID_INPUTS;
  
  if (q                         != NULL &&
      regs                      != NULL &&
      srslte_cell_isvalid(&cell)) 
  {   
    ret = SRSLTE_ERROR;
    
    bzero(q, sizeof(srslte_pcfich_t));
    q->cell = cell;
    q->regs = regs;
    q->nof_symbols = PCFICH_RE;
    
    if (srslte_precoding_init(&q->precoding, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp))) {
      fprintf(stderr, "Error initializing precoding\n");
    }

    if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) {
      goto clean;
    }

    for (int nsf = 0; nsf < SRSLTE_NSUBFRAMES_X_FRAME; nsf++) {
      if (srslte_sequence_pcfich(&q->seq[nsf], 2 * nsf, q->cell.id)) {
        goto clean;
      }
    }
    
    /* convert cfi bit tables to floats for demodulation */
    for (int i=0;i<3;i++) {
      for (int j=0;j<PCFICH_CFI_LEN;j++) {
        q->cfi_table_float[i][j] = (float) 2.0*cfi_table[i][j]-1.0; 
      }
    }

    ret = SRSLTE_SUCCESS;
  }
  
  clean: 
  if (ret == SRSLTE_ERROR) {
    srslte_pcfich_free(q);
  }
  return ret;
}
コード例 #3
0
ファイル: pdsch.c プロジェクト: sdnnfv/srsLTE
/** Initializes the PDCCH transmitter and receiver */
int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) {
    int ret = SRSLTE_ERROR_INVALID_INPUTS;
    int i;

    if (q                         != NULL                  &&
            srslte_cell_isvalid(&cell))
    {

        bzero(q, sizeof(srslte_pdsch_t));
        ret = SRSLTE_ERROR;

        q->cell = cell;
        q->max_re = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp);

        INFO("Init PDSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports,
             q->cell.nof_prb, q->max_re);

        if (srslte_precoding_init(&q->precoding, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp))) {
            fprintf(stderr, "Error initializing precoding\n");
            goto clean;
        }

        for (i = 0; i < 4; i++) {
            if (srslte_modem_table_lte(&q->mod[i], modulations[i])) {
                goto clean;
            }
            srslte_modem_table_bytes(&q->mod[i]);
        }

        srslte_sch_init(&q->dl_sch);

        q->rnti_is_set = false;

        // Allocate int16_t for reception (LLRs)
        q->e = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM));
        if (!q->e) {
            goto clean;
        }

        q->d = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
        if (!q->d) {
            goto clean;
        }

        for (i = 0; i < q->cell.nof_ports; i++) {
            q->ce[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
            if (!q->ce[i]) {
                goto clean;
            }
            q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
            if (!q->x[i]) {
                goto clean;
            }
            q->symbols[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
            if (!q->symbols[i]) {
                goto clean;
            }
        }

        ret = SRSLTE_SUCCESS;
    }
clean:
    if (ret == SRSLTE_ERROR) {
        srslte_pdsch_free(q);
    }
    return ret;
}
コード例 #4
0
ファイル: precoding_test.c プロジェクト: Intellifora/srsLTE
int main(int argc, char **argv) {
  int i, j;
  float mse;
  cf_t *x[SRSLTE_MAX_LAYERS], *r[SRSLTE_MAX_PORTS], *y[SRSLTE_MAX_PORTS], *h[SRSLTE_MAX_PORTS],
      *xr[SRSLTE_MAX_LAYERS];
  srslte_mimo_type_t type;
  srslte_precoding_t precoding; 
  
  parse_args(argc, argv);

  if (nof_ports > SRSLTE_MAX_PORTS || nof_layers > SRSLTE_MAX_LAYERS) {
    fprintf(stderr, "Invalid number of layers or ports\n");
    exit(-1);
  }

  if (srslte_str2mimotype(mimo_type_name, &type)) {
    fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name);
    exit(-1);
  }

  for (i = 0; i < nof_layers; i++) {
    x[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols);
    if (!x[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
    xr[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols);
    if (!xr[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
  }
  for (i = 0; i < nof_ports; i++) {
    y[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers);
    // TODO: The number of symbols per port is different in spatial multiplexing.
    if (!y[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
    h[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers);
    if (!h[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
  }

  /* only 1 receiver antenna supported now */
  r[0] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers);
  if (!r[0]) {
    perror("srslte_vec_malloc");
    exit(-1);
  }

  /* generate random data */
  for (i = 0; i < nof_layers; i++) {
    for (j = 0; j < nof_symbols; j++) {
      x[i][j] = (2*(rand()%2)-1+(2*(rand()%2)-1)*_Complex_I)/sqrt(2);
    }
  }
  
  if (srslte_precoding_init(&precoding, nof_symbols * nof_layers)) {
    fprintf(stderr, "Error initializing precoding\n");
    exit(-1);
  }

  /* precoding */
  if (srslte_precoding_type(&precoding, x, y, nof_layers, nof_ports, nof_symbols, type) < 0) {
    fprintf(stderr, "Error layer mapper encoder\n");
    exit(-1);
  }

  /* generate channel */
  for (i = 0; i < nof_ports; i++) {
    for (j = 0; j < nof_symbols; j++) {
      h[i][nof_layers*j] = (float) rand()/RAND_MAX+((float) rand()/RAND_MAX)*_Complex_I;
      // assume the channel is time-invariant in nlayer consecutive symbols
      for (int k=0;k<nof_layers;k++) {
        h[i][nof_layers*j+k] = h[i][nof_layers*j];      
      }
    }
  }

  /* pass signal through channel
   (we are in the frequency domain so it's a multiplication) */
  /* there's only one receiver antenna, signals from different transmitter
   * ports are simply combined at the receiver
   */
  for (j = 0; j < nof_symbols * nof_layers; j++) {
    r[0][j] = 0;
    for (i = 0; i < nof_ports; i++) {
      r[0][j] += y[i][j] * h[i][j];
    }
  }
  
  /* predecoding / equalization */
  struct timeval t[3];
  gettimeofday(&t[1], NULL);
  if (srslte_predecoding_type(&precoding, r[0], h, xr, nof_ports, nof_layers,
      nof_symbols * nof_layers, type, 0) < 0) {
    fprintf(stderr, "Error layer mapper encoder\n");
    exit(-1);
  }
  gettimeofday(&t[2], NULL);
  get_time_interval(t);
  printf("Execution Time: %d us\n", t[0].tv_usec);
  
  /* check errors */
  mse = 0;
  for (i = 0; i < nof_layers; i++) {
    for (j = 0; j < nof_symbols; j++) {
      mse += cabsf(xr[i][j] - x[i][j]);
    }
  }
  printf("MSE: %f\n", mse/ nof_layers / nof_symbols );
  if (mse / nof_layers / nof_symbols > MSE_THRESHOLD) {
    exit(-1);
  } 

  for (i = 0; i < nof_layers; i++) {
    free(x[i]);
    free(xr[i]);
  }
  for (i = 0; i < nof_ports; i++) {
    free(y[i]);
    free(h[i]);
  }

  free(r[0]);
  
  srslte_precoding_free(&precoding);
  
  printf("Ok\n");
  exit(0); 
}
コード例 #5
0
/* the gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

  int i;
  srslte_cell_t cell; 
  srslte_chest_dl_t chest;
  srslte_precoding_t cheq; 
  cf_t *input_signal = NULL, *output_signal[SRSLTE_MAX_LAYERS]; 
  cf_t *output_signal2 = NULL;
  cf_t *ce[SRSLTE_MAX_PORTS]; 
  double *outr0=NULL, *outi0=NULL;
  double *outr1=NULL, *outi1=NULL;
  double *outr2=NULL, *outi2=NULL;
  
  if (!mxIsDouble(CELLID) && mxGetN(CELLID) != 1 && 
      !mxIsDouble(PORTS) && mxGetN(PORTS) != 1 && 
      mxGetM(CELLID) != 1) {
    help();
    return;
  }

  cell.id = (uint32_t) *((double*) mxGetPr(CELLID));
  cell.nof_prb = mxGetM(INPUT)/SRSLTE_NRE;
  cell.nof_ports = (uint32_t) *((double*) mxGetPr(PORTS)); 
  if ((mxGetN(INPUT)%14) == 0) {
    cell.cp = SRSLTE_CP_NORM;    
  } else if ((mxGetN(INPUT)%12)!=0) {
    cell.cp = SRSLTE_CP_EXT;
  } else {
    mexErrMsgTxt("Invalid number of symbols\n");
    help();
    return;
  }
  
  if (srslte_chest_dl_init(&chest, cell)) {
    mexErrMsgTxt("Error initiating channel estimator\n");
    return;
  }
  
  int nsubframes;
  if (cell.cp == SRSLTE_CP_NORM) {
    nsubframes = mxGetN(INPUT)/14;
  } else {
    nsubframes = mxGetN(INPUT)/12;
  }
  
  uint32_t sf_idx=0; 
  if (nsubframes == 1) {
    if (nrhs != NOF_INPUTS+1) {
      mexErrMsgTxt("Received 1 subframe. Need to provide subframe index.\n");
      help();
      return;
    }
    sf_idx = (uint32_t) *((double*) mxGetPr(SFIDX));
  } 
  
  if (nrhs > 5) {
    uint32_t filter_len = 0;
    float *filter; 
    double *f; 
    
    filter_len = mxGetNumberOfElements(FREQ_FILTER);
    filter = malloc(sizeof(float) * filter_len);
    f = (double*) mxGetPr(FREQ_FILTER);
    for (i=0;i<filter_len;i++) {
      filter[i] = (float) f[i];
    }

    srslte_chest_dl_set_filter_freq(&chest, filter, filter_len);

    filter_len = mxGetNumberOfElements(TIME_FILTER);
    filter = malloc(sizeof(float) * filter_len);
    f = (double*) mxGetPr(TIME_FILTER);
    for (i=0;i<filter_len;i++) {
      filter[i] = (float) f[i];
    }
    srslte_chest_dl_set_filter_time(&chest, filter, filter_len);
  }  


  double *inr=(double *)mxGetPr(INPUT);
  double *ini=(double *)mxGetPi(INPUT);
  
  /** Allocate input buffers */
  int nof_re = 2*SRSLTE_CP_NSYMB(cell.cp)*cell.nof_prb*SRSLTE_NRE;
  for (i=0;i<SRSLTE_MAX_PORTS;i++) {
    ce[i] = srslte_vec_malloc(nof_re * sizeof(cf_t));
  }
  input_signal = srslte_vec_malloc(nof_re * sizeof(cf_t));
  for (i=0;i<SRSLTE_MAX_PORTS;i++) {
    output_signal[i] = srslte_vec_malloc(nof_re * sizeof(cf_t));
  }
  output_signal2 = srslte_vec_malloc(nof_re * sizeof(cf_t));
  
  srslte_precoding_init(&cheq, nof_re);
  
  /* Create output values */
  if (nlhs >= 1) {
    plhs[0] = mxCreateDoubleMatrix(nof_re * nsubframes, cell.nof_ports, mxCOMPLEX);
    outr0 = mxGetPr(plhs[0]);
    outi0 = mxGetPi(plhs[0]);
  }  
  if (nlhs >= 2) {
    plhs[1] = mxCreateDoubleMatrix(SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb)*nsubframes, cell.nof_ports, mxCOMPLEX);
    outr1 = mxGetPr(plhs[1]);
    outi1 = mxGetPi(plhs[1]);
  }
  if (nlhs >= 3) {
    plhs[2] = mxCreateDoubleMatrix(nof_re * nsubframes, 1,  mxCOMPLEX);
    outr2 = mxGetPr(plhs[2]);
    outi2 = mxGetPi(plhs[2]);
  }
    
  for (int sf=0;sf<nsubframes;sf++) {
    /* Convert input to C complex type */
    for (i=0;i<nof_re;i++) {
      __real__ input_signal[i] = (float) *inr;
      if (ini) {
        __imag__ input_signal[i] = (float) *ini;
      }
      inr++;
      ini++;
    }
    
    if (nsubframes != 1) {
      sf_idx = sf%10;
    }
    
    if (srslte_chest_dl_estimate(&chest, input_signal, ce, sf_idx)) {
      mexErrMsgTxt("Error running channel estimator\n");
      return;
    }    
       
    if (cell.nof_ports == 1) {
      srslte_predecoding_single(input_signal, ce[0], output_signal2, nof_re, srslte_chest_dl_get_noise_estimate(&chest));            
    } else {
      srslte_predecoding_diversity(&cheq, input_signal, ce, output_signal, cell.nof_ports, nof_re, srslte_chest_dl_get_noise_estimate(&chest));
      srslte_layerdemap_diversity(output_signal, output_signal2, cell.nof_ports, nof_re/cell.nof_ports);
    }
    
    if (nlhs >= 1) { 
      for (int j=0;j<cell.nof_ports;j++) {
        for (i=0;i<nof_re;i++) {      
          *outr0 = (double) crealf(ce[j][i]);
          if (outi0) {
            *outi0 = (double) cimagf(ce[j][i]);
          }
          outr0++;
          outi0++;
        } 
      }
    }
    if (nlhs >= 2) {    
      for (int j=0;j<cell.nof_ports;j++) {
        for (i=0;i<SRSLTE_REFSIGNAL_NUM_SF(cell.nof_prb,j);i++) {
          *outr1 = (double) crealf(chest.pilot_estimates_average[j][i]);
          if (outi1) {
            *outi1 = (double) cimagf(chest.pilot_estimates_average[j][i]);
          }
          outr1++;
          outi1++;
        }
      }    
    }
    if (nlhs >= 3) {
      for (i=0;i<nof_re;i++) {      
        *outr2 = (double) crealf(output_signal2[i]);
        if (outi2) {
          *outi2 = (double) cimagf(output_signal2[i]);
        }
        outr2++;
        outi2++;
      }
    }
  }

  if (nlhs >= 4) {
    plhs[3] = mxCreateDoubleScalar(srslte_chest_dl_get_noise_estimate(&chest));
  }
  if (nlhs >= 5) {
    plhs[4] = mxCreateDoubleScalar(srslte_chest_dl_get_rsrp(&chest));
  }
  
  srslte_chest_dl_free(&chest);
  srslte_precoding_free(&cheq);

  return;
}