Beispiel #1
0
/* Returns 1 if the SSS is found, 0 if not and -1 if there is not enough space 
 * to correlate
 */
int sync_sss(sync_t *q, cf_t *input, uint32_t peak_pos, lte_cp_t cp) {
  int sss_idx, ret;

  sss_synch_set_N_id_2(&q->sss, q->N_id_2);

  /* Make sure we have enough room to find SSS sequence */
  sss_idx = (int) peak_pos-2*q->fft_size-CP(q->fft_size, (CP_ISNORM(q->cp)?CPNORM_LEN:CPEXT_LEN));
  if (sss_idx < 0) {
    INFO("Not enough room to decode CP SSS (sss_idx=%d, peak_pos=%d)\n", sss_idx, peak_pos);
    return LIBLTE_ERROR;
  }
  DEBUG("Searching SSS around sss_idx: %d, peak_pos: %d\n", sss_idx, peak_pos);
      
  switch(q->sss_alg) {
    case SSS_DIFF:
      sss_synch_m0m1_diff(&q->sss, &input[sss_idx], &q->m0, &q->m0_value, &q->m1, &q->m1_value);
      break;
    case SSS_PARTIAL_3:
      sss_synch_m0m1_partial(&q->sss, &input[sss_idx], 3, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value);
      break;
    case SSS_FULL:
      sss_synch_m0m1_partial(&q->sss, &input[sss_idx], 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value);
      break;
  }

  q->sf_idx = sss_synch_subframe(q->m0, q->m1);
  ret = sss_synch_N_id_1(&q->sss, q->m0, q->m1);
  if (ret >= 0) {
    q->N_id_1 = (uint32_t) ret;
    DEBUG("SSS detected N_id_1=%d, sf_idx=%d, %s CP\n",
      q->N_id_1, q->sf_idx, CP_ISNORM(q->cp)?"Normal":"Extended");
    return 1;
  } else {
    q->N_id_1 = 1000;
    return LIBLTE_SUCCESS;
  }
}
Beispiel #2
0
/* In this function, input points to the beginning of the subframe. Saves result in subframe_idx and N_id_1
 * Return 1 if the sequence was found, 0 if the peak is not found, -1 if the subframe_sz or symbol_sz are
 * invalid or not configured.
 * Before calling this function, the correlation threshold and symbol size duration need to be set
 * using sss_synch_set_threshold() and sss_synch_set_symbol_sz().
 */
int sss_synch_frame(sss_synch_t *q, cf_t *input, int *subframe_idx,
		int *N_id_1) {
	int m0,m1;
	float m0_value, m1_value;

	if (q->subframe_sz <= 0 || q->symbol_sz <= 0) {
		return -1;
	}

	sss_synch_m0m1(q, &input[SSS_SYMBOL_ST(q->subframe_sz, q->symbol_sz)],
			&m0, &m0_value, &m1, &m1_value);

	if (m0_value > q->corr_peak_threshold && m1_value > q->corr_peak_threshold) {
		if (subframe_idx) {
			*subframe_idx = sss_synch_subframe(m0, m1);
		}
		if (N_id_1) {
			*N_id_1 = sss_synch_N_id_1(q, m0, m1);
		}
		return 1;
	} else {
		return 0;
	}
}
Beispiel #3
0
int sync_run(sync_t *q, cf_t *input) {
  int N_id_2, peak_pos[3], sss_idx_n, sss_idx_e;
  int m0, m1;
  float m0_value_e, m1_value_e,m0_value_n, m1_value_n;
  int slot_id_e, N_id_1_e, slot_id_n, N_id_1_n;
  float peak_value[3];
  float mean_value[3];
  float max=-999;
  int i;
  int peak_detected;

  if (q->force_N_id_2 == -1) {
    for (N_id_2=0;N_id_2<3;N_id_2++) {
      peak_pos[N_id_2] = pss_synch_find_pss(&q->pss[N_id_2], input,
          &peak_value[N_id_2], &mean_value[N_id_2]);
    }
    for (i=0;i<3;i++) {
      if (peak_value[i] > max) {
        max = peak_value[i];
        N_id_2 = i;
      }
    }
  } else {
    N_id_2 = q->force_N_id_2;
    peak_pos[N_id_2] = pss_synch_find_pss(&q->pss[N_id_2], input,
        &peak_value[N_id_2], &mean_value[N_id_2]);
  }

  q->peak_to_avg = peak_value[N_id_2] / mean_value[N_id_2];

  DEBUG("PSS possible peak N_id_2=%d, pos=%d peak=%.2f par=%.2f threshold=%.2f\n",
      N_id_2, peak_pos[N_id_2], peak_value[N_id_2], q->peak_to_avg, q->threshold);

  /* If peak detected */
  peak_detected = 0;
  if (peak_pos[N_id_2] - 128 >= 0) {
    if (q->pss_mode == ABSOLUTE) {
      if (peak_value[N_id_2] > q->threshold) {
        peak_detected = 1;
      }
    } else {
      if (q->peak_to_avg  > q->threshold) {
        peak_detected = 1;
      }
    }
  }
  if (peak_detected) {

    q->cfo = pss_synch_cfo_compute(&q->pss[N_id_2], &input[peak_pos[N_id_2]-128]);

    INFO("PSS peak detected N_id_2=%d, pos=%d peak=%.2f par=%.2f th=%.2f cfo=%.4f\n", N_id_2,
        peak_pos[N_id_2], peak_value[N_id_2], q->peak_to_avg, q->threshold, q->cfo);

    if (q->sss_en) {

      /* Make sure we have enough room to find SSS sequence */
      sss_idx_n = peak_pos[N_id_2]-2*(128+CP(128,CPNORM_LEN));
      sss_idx_e = peak_pos[N_id_2]-2*(128+CP(128,CPEXT_LEN));

      if (q->detect_cp) {
        if (sss_idx_n < 0 || sss_idx_e < 0) {
          INFO("Not enough room to decode SSS (%d, %d)\n", sss_idx_n, sss_idx_e);
          return -1;
        }
      } else {
        if (CP_ISNORM(q->cp)) {
          if (sss_idx_n < 0) {
            INFO("Not enough room to decode SSS (%d)\n", sss_idx_n);
            return -1;
          }
        } else {
          if (sss_idx_e < 0) {
            INFO("Not enough room to decode SSS (%d)\n", sss_idx_e);
            return -1;
          }
        }
      }
      N_id_1_e = -1;
      N_id_1_n = -1;
      slot_id_e = -1;
      slot_id_n = -1;
      /* try Normal CP length */
      if (q->detect_cp || CP_ISNORM(q->cp)) {
        sss_synch_m0m1(&q->sss[N_id_2], &input[sss_idx_n],
            &m0, &m0_value_n, &m1, &m1_value_n);

        slot_id_n = 2 * sss_synch_subframe(m0, m1);
        N_id_1_n = sss_synch_N_id_1(&q->sss[N_id_2], m0, m1);
      }

      if (q->detect_cp || CP_ISEXT(q->cp)) {
        /* Now try Extended CP length */
        sss_synch_m0m1(&q->sss[N_id_2], &input[sss_idx_e],
            &m0, &m0_value_e, &m1, &m1_value_e);

        slot_id_e = 2 * sss_synch_subframe(m0, m1);
        N_id_1_e = sss_synch_N_id_1(&q->sss[N_id_2], m0, m1);
      }

      /* Correlation with extended CP hypoteshis is greater than with normal? */
      if ((q->detect_cp && m0_value_e * m1_value_e > m0_value_n * m1_value_n)
          || CP_ISEXT(q->cp)) {
        q->cp = CPEXT;
        q->slot_id = slot_id_e;
        q->N_id_1 = N_id_1_e;
      /* then is normal CP */
      } else {
        q->cp = CPNORM;
        q->slot_id = slot_id_n;
        q->N_id_1 = N_id_1_n;
      }
      q->N_id_2 = N_id_2;

      INFO("SSS detected N_id_1=%d, slot_idx=%d, %s CP\n",
          q->N_id_1, q->slot_id, CP_ISNORM(q->cp)?"Normal":"Extended");
    }

    return peak_pos[N_id_2];

  } else {
    return -1;
  }
}