예제 #1
0
파일: pcfich.c 프로젝트: guyt101z/srsLTE
/* Decodes the PCFICH channel and saves the CFI in the cfi pointer.
 *
 * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error
 */
int srslte_pcfich_decode(srslte_pcfich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
    uint32_t nsubframe, uint32_t *cfi, float *corr_result) 
{

  /* Set pointers for layermapping & precoding */
  int i;
  cf_t *x[SRSLTE_MAX_LAYERS];
  cf_t *ce_precoding[SRSLTE_MAX_PORTS];

  if (q                 != NULL                 && 
      slot_symbols      != NULL                 && 
      nsubframe         <  SRSLTE_NSUBFRAMES_X_FRAME) 
  {

    /* number of layers equals number of ports */
    for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
      x[i] = q->x[i];
    }
    for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
      ce_precoding[i] = q->ce[i];
    }

    /* extract symbols */
    if (q->nof_symbols
        != srslte_regs_pcfich_get(q->regs, slot_symbols, q->symbols[0])) {
      fprintf(stderr, "There was an error getting the PCFICH symbols\n");
      return SRSLTE_ERROR;
    }

    /* extract channel estimates */
    for (i = 0; i < q->cell.nof_ports; i++) {
      if (q->nof_symbols != srslte_regs_pcfich_get(q->regs, ce[i], q->ce[i])) {
        fprintf(stderr, "There was an error getting the PCFICH symbols\n");
        return SRSLTE_ERROR;
      }
    }

    /* in control channels, only diversity is supported */
    if (q->cell.nof_ports == 1) {
      /* no need for layer demapping */
      srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, q->nof_symbols, noise_estimate);
    } else {
      srslte_predecoding_diversity(q->symbols[0], ce_precoding, x,
          q->cell.nof_ports, q->nof_symbols);
      srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports,
          q->nof_symbols / q->cell.nof_ports);
    }

    /* demodulate symbols */
    srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, q->data_f, q->nof_symbols);

    /* Scramble with the sequence for slot nslot */
    srslte_scrambling_f(&q->seq[nsubframe], q->data_f);

    /* decode CFI */
    float corr = srslte_pcfich_cfi_decode(q, cfi);
    if (corr_result) {
      *corr_result = corr;
    }
    return 1;
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
  
}
예제 #2
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;
}
예제 #3
0
파일: pdsch.c 프로젝트: sdnnfv/srsLTE
/** Decodes the PDSCH from the received symbols
 */
int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
                             srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
                             cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
                             uint16_t rnti, uint8_t *data)
{

    /* Set pointers for layermapping & precoding */
    uint32_t i, n;
    cf_t *x[SRSLTE_MAX_LAYERS];

    if (q            != NULL &&
            sf_symbols   != NULL &&
            data         != NULL &&
            cfg          != NULL)
    {

        INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d, C_prb=%d\n",
             cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re,
             cfg->nbits.nof_bits, cfg->rv, cfg->grant.nof_prb);

        /* number of layers equals number of ports */
        for (i = 0; i < q->cell.nof_ports; i++) {
            x[i] = q->x[i];
        }
        memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));

        /* extract symbols */
        n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
        if (n != cfg->nbits.nof_re) {
            fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
            return SRSLTE_ERROR;
        }

        /* extract channel estimates */
        for (i = 0; i < q->cell.nof_ports; i++) {
            n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
            if (n != cfg->nbits.nof_re) {
                fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
                return SRSLTE_ERROR;
            }
        }

        /* TODO: only diversity is supported */
        if (q->cell.nof_ports == 1) {
            /* no need for layer demapping */
            srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, cfg->nbits.nof_re, noise_estimate);
        } else {
            srslte_predecoding_diversity(&q->precoding, q->symbols[0], q->ce, x, q->cell.nof_ports,
                                         cfg->nbits.nof_re, noise_estimate);
            srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports,
                                        cfg->nbits.nof_re / q->cell.nof_ports);
        }

        if (SRSLTE_VERBOSE_ISDEBUG()) {
            DEBUG("SAVED FILE pdsch_symbols.dat: symbols after equalization\n",0);
            srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits.nof_re*sizeof(cf_t));
        }

        /* demodulate symbols
        * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
        * thus we don't need tot set it in the LLRs normalization
        */
        srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re);

        /* descramble */
        if (rnti != q->rnti) {
            srslte_sequence_t seq;
            if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
                return SRSLTE_ERROR;
            }
            srslte_scrambling_s_offset(&seq, q->e, 0, cfg->nbits.nof_bits);
            srslte_sequence_free(&seq);
        } else {
            srslte_scrambling_s_offset(&q->seq[cfg->sf_idx], q->e, 0, cfg->nbits.nof_bits);
        }

        if (SRSLTE_VERBOSE_ISDEBUG()) {
            DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n",0);
            srslte_vec_save_file("llr.dat", q->e, cfg->nbits.nof_bits*sizeof(int16_t));
        }

        return srslte_dlsch_decode(&q->dl_sch, cfg, softbuffer, q->e, data);

    } else {
        return SRSLTE_ERROR_INVALID_INPUTS;
    }
}
예제 #4
0
파일: phich.c 프로젝트: Intellifora/srsLTE
/* Decodes the phich channel and saves the CFI in the cfi pointer.
 *
 * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error
 */
int srslte_phich_decode(srslte_phich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
    uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) {

  /* Set pointers for layermapping & precoding */
  int i, j;
  cf_t *x[SRSLTE_MAX_LAYERS];
  cf_t *ce_precoding[SRSLTE_MAX_PORTS];
  
  if (q == NULL || slot_symbols == NULL) {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  if (subframe >= SRSLTE_NSUBFRAMES_X_FRAME) {
    fprintf(stderr, "Invalid nslot %d\n", subframe);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    if (nseq >= SRSLTE_PHICH_EXT_NSEQUENCES) {
      fprintf(stderr, "Invalid nseq %d\n", nseq);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
  } else {
    if (nseq >= SRSLTE_PHICH_NORM_NSEQUENCES) {
      fprintf(stderr, "Invalid nseq %d\n", nseq);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
  }
  if (ngroup >= srslte_regs_phich_ngroups(q->regs)) {
    fprintf(stderr, "Invalid ngroup %d\n", ngroup);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  DEBUG("Decoding PHICH Ngroup: %d, Nseq: %d\n", ngroup, nseq);

  /* number of layers equals number of ports */
  for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
    x[i] = q->x[i];
  }
  for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
    ce_precoding[i] = q->ce[i];
  }

  /* extract symbols */
  if (SRSLTE_PHICH_MAX_NSYMB
      != srslte_regs_phich_get(q->regs, slot_symbols, q->symbols[0], ngroup)) {
    fprintf(stderr, "There was an error getting the phich symbols\n");
    return SRSLTE_ERROR;
  }

  /* extract channel estimates */
  for (i = 0; i < q->cell.nof_ports; i++) {
    if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, ce[i], q->ce[i], ngroup)) {
      fprintf(stderr, "There was an error getting the phich symbols\n");
      return SRSLTE_ERROR;
    }
  }

  /* in control channels, only diversity is supported */
  if (q->cell.nof_ports == 1) {
    /* no need for layer demapping */
    srslte_predecoding_single(q->symbols[0], q->ce[0], q->d0, SRSLTE_PHICH_MAX_NSYMB, noise_estimate);
  } else {
    srslte_predecoding_diversity(&q->precoding, q->symbols[0], ce_precoding, x,
        q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, noise_estimate);
    srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports,
    SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports);
  }
  DEBUG("Recv!!: \n", 0);
  DEBUG("d0: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB);

  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    if (ngroup % 2) {
      for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) {
        q->d[2 * i + 0] = q->d0[4 * i + 2];
        q->d[2 * i + 1] = q->d0[4 * i + 3];
      }
    } else {
      for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) {
        q->d[2 * i + 0] = q->d0[4 * i];
        q->d[2 * i + 1] = q->d0[4 * i + 1];
      }
    }
  } else {
    memcpy(q->d, q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t));
  }

  DEBUG("d: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB);

  srslte_scrambling_c(&q->seq[subframe], q->d);

  /* De-spreading */
  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    for (i = 0; i < SRSLTE_PHICH_NBITS; i++) {
      q->z[i] = 0;
      for (j = 0; j < SRSLTE_PHICH_EXT_NSF; j++) {
        q->z[i] += conjf(w_ext[nseq][j])
            * q->d[i * SRSLTE_PHICH_EXT_NSF + j] / SRSLTE_PHICH_EXT_NSF;
      }
    }
  } else {
    for (i = 0; i < SRSLTE_PHICH_NBITS; i++) {
      q->z[i] = 0;
      for (j = 0; j < SRSLTE_PHICH_NORM_NSF; j++) {
        q->z[i] += conjf(w_normal[nseq][j])
            * q->d[i * SRSLTE_PHICH_NORM_NSF + j] / SRSLTE_PHICH_NORM_NSF;
      }
    }
  }

  DEBUG("z: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS);

  srslte_demod_soft_demodulate(SRSLTE_MOD_BPSK, q->z, q->data_rx, SRSLTE_PHICH_NBITS);

  if (ack) {
    *ack = srslte_phich_ack_decode(q->data_rx, distance);    
  }

  return SRSLTE_SUCCESS;
}