|
|
@ -158,7 +158,6 @@ uint32_t prach_zc_roots_format4[138] = {
|
|
|
|
61, 78, 62, 77, 63, 76, 64, 75, 65, 74, 66, 73,
|
|
|
|
61, 78, 62, 77, 63, 76, 64, 75, 65, 74, 66, 73,
|
|
|
|
67, 72, 68, 71, 69, 70};
|
|
|
|
67, 72, 68, 71, 69, 70};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
srslte_prach_sf_config_t prach_sf_config[16] = {
|
|
|
|
srslte_prach_sf_config_t prach_sf_config[16] = {
|
|
|
|
{1, {1, 0, 0, 0, 0}},
|
|
|
|
{1, {1, 0, 0, 0, 0}},
|
|
|
|
{1, {4, 0, 0, 0, 0}},
|
|
|
|
{1, {4, 0, 0, 0, 0}},
|
|
|
@ -192,8 +191,7 @@ srslte_prach_sfn_t srslte_prach_get_sfn(uint32_t config_idx) {
|
|
|
|
/* Returns true if current_tti is a valid opportunity for PRACH transmission and the is an allowed subframe,
|
|
|
|
/* Returns true if current_tti is a valid opportunity for PRACH transmission and the is an allowed subframe,
|
|
|
|
* or allowed_subframe == -1
|
|
|
|
* or allowed_subframe == -1
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
bool srslte_prach_tti_opportunity(srslte_prach_t *p, uint32_t current_tti, int allowed_subframe)
|
|
|
|
bool srslte_prach_tti_opportunity(srslte_prach_t *p, uint32_t current_tti, int allowed_subframe) {
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t config_idx = p->config_idx;
|
|
|
|
uint32_t config_idx = p->config_idx;
|
|
|
|
// Get SFN and sf_idx from the PRACH configuration index
|
|
|
|
// Get SFN and sf_idx from the PRACH configuration index
|
|
|
|
srslte_prach_sfn_t prach_sfn = srslte_prach_get_sfn(config_idx);
|
|
|
|
srslte_prach_sfn_t prach_sfn = srslte_prach_get_sfn(config_idx);
|
|
|
@ -204,14 +202,12 @@ bool srslte_prach_tti_opportunity(srslte_prach_t *p, uint32_t current_tti, int a
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((prach_sfn == SRSLTE_PRACH_SFN_EVEN && ((current_tti / 10) % 2) == 0) ||
|
|
|
|
if ((prach_sfn == SRSLTE_PRACH_SFN_EVEN && ((current_tti / 10) % 2) == 0) ||
|
|
|
|
prach_sfn == SRSLTE_PRACH_SFN_ANY)
|
|
|
|
prach_sfn == SRSLTE_PRACH_SFN_ANY) {
|
|
|
|
{
|
|
|
|
|
|
|
|
srslte_prach_sf_config_t sf_config;
|
|
|
|
srslte_prach_sf_config_t sf_config;
|
|
|
|
srslte_prach_sf_config(config_idx, &sf_config);
|
|
|
|
srslte_prach_sf_config(config_idx, &sf_config);
|
|
|
|
for (int i = 0; i < sf_config.nof_sf; i++) {
|
|
|
|
for (int i = 0; i < sf_config.nof_sf; i++) {
|
|
|
|
if (((current_tti % 10) == sf_config.sf[i] && allowed_subframe == -1) ||
|
|
|
|
if (((current_tti % 10) == sf_config.sf[i] && allowed_subframe == -1) ||
|
|
|
|
((current_tti%10) == sf_config.sf[i] && (current_tti%10) == allowed_subframe))
|
|
|
|
((current_tti % 10) == sf_config.sf[i] && (current_tti % 10) == allowed_subframe)) {
|
|
|
|
{
|
|
|
|
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -219,23 +215,19 @@ bool srslte_prach_tti_opportunity(srslte_prach_t *p, uint32_t current_tti, int a
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void srslte_prach_sf_config(uint32_t config_idx, srslte_prach_sf_config_t *sf_config) {
|
|
|
|
void srslte_prach_sf_config(uint32_t config_idx, srslte_prach_sf_config_t *sf_config) {
|
|
|
|
memcpy(sf_config, &prach_sf_config[config_idx % 16], sizeof(srslte_prach_sf_config_t));
|
|
|
|
memcpy(sf_config, &prach_sf_config[config_idx % 16], sizeof(srslte_prach_sf_config_t));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// For debug use only
|
|
|
|
// For debug use only
|
|
|
|
void print(void *d, uint32_t size, uint32_t len, char* file_str)
|
|
|
|
void print(void *d, uint32_t size, uint32_t len, char *file_str) {
|
|
|
|
{
|
|
|
|
|
|
|
|
FILE *f;
|
|
|
|
FILE *f;
|
|
|
|
f = fopen(file_str, "wb");
|
|
|
|
f = fopen(file_str, "wb");
|
|
|
|
fwrite(d, size, len, f);
|
|
|
|
fwrite(d, size, len, f);
|
|
|
|
fclose(f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int srslte_prach_gen_seqs(srslte_prach_t *p)
|
|
|
|
int srslte_prach_gen_seqs(srslte_prach_t *p) {
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t u = 0;
|
|
|
|
uint32_t u = 0;
|
|
|
|
uint32_t v = 1;
|
|
|
|
uint32_t v = 1;
|
|
|
|
int v_max = 0;
|
|
|
|
int v_max = 0;
|
|
|
@ -281,10 +273,12 @@ int srslte_prach_gen_seqs(srslte_prach_t *p)
|
|
|
|
N_shift = d_u / p->N_cs;
|
|
|
|
N_shift = d_u / p->N_cs;
|
|
|
|
d_start = 2 * d_u + N_shift * p->N_cs;
|
|
|
|
d_start = 2 * d_u + N_shift * p->N_cs;
|
|
|
|
N_group = p->N_zc / d_start;
|
|
|
|
N_group = p->N_zc / d_start;
|
|
|
|
|
|
|
|
if (p->N_zc > 2 * d_u + N_group * d_start) {
|
|
|
|
N_neg_shift = (p->N_zc - 2 * d_u - N_group * d_start) / p->N_cs;
|
|
|
|
N_neg_shift = (p->N_zc - 2 * d_u - N_group * d_start) / p->N_cs;
|
|
|
|
if(N_neg_shift < 0)
|
|
|
|
|
|
|
|
N_neg_shift = 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
N_neg_shift = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (p->N_zc / 3 <= d_u && d_u <= (p->N_zc - p->N_cs) / 2) {
|
|
|
|
N_shift = (p->N_zc - 2 * d_u) / p->N_cs;
|
|
|
|
N_shift = (p->N_zc - 2 * d_u) / p->N_cs;
|
|
|
|
d_start = p->N_zc - 2 * d_u + N_shift * p->N_cs;
|
|
|
|
d_start = p->N_zc - 2 * d_u + N_shift * p->N_cs;
|
|
|
|
N_group = d_u / d_start;
|
|
|
|
N_group = d_u / d_start;
|
|
|
@ -293,6 +287,8 @@ int srslte_prach_gen_seqs(srslte_prach_t *p)
|
|
|
|
N_neg_shift = 0;
|
|
|
|
N_neg_shift = 0;
|
|
|
|
if (N_neg_shift > N_shift)
|
|
|
|
if (N_neg_shift > N_shift)
|
|
|
|
N_neg_shift = N_shift;
|
|
|
|
N_neg_shift = N_shift;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
N_shift = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v_max = N_shift * N_group + N_neg_shift - 1;
|
|
|
|
v_max = N_shift * N_group + N_neg_shift - 1;
|
|
|
|
if (v_max < 0) {
|
|
|
|
if (v_max < 0) {
|
|
|
@ -320,6 +316,9 @@ int srslte_prach_gen_seqs(srslte_prach_t *p)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
C_v = v * p->N_cs;
|
|
|
|
C_v = v * p->N_cs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 46) {
|
|
|
|
|
|
|
|
printf("i=%d, C_v=%d\n", i, C_v);
|
|
|
|
|
|
|
|
}
|
|
|
|
for (int j = 0; j < p->N_zc; j++) {
|
|
|
|
for (int j = 0; j < p->N_zc; j++) {
|
|
|
|
p->seqs[i][j] = root[(j + C_v) % p->N_zc];
|
|
|
|
p->seqs[i][j] = root[(j + C_v) % p->N_zc];
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -329,8 +328,7 @@ int srslte_prach_gen_seqs(srslte_prach_t *p)
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int srslte_prach_init_cfg(srslte_prach_t *p, srslte_prach_cfg_t *cfg, uint32_t nof_prb)
|
|
|
|
int srslte_prach_init_cfg(srslte_prach_t *p, srslte_prach_cfg_t *cfg, uint32_t nof_prb) {
|
|
|
|
{
|
|
|
|
|
|
|
|
if (srslte_prach_init(p, srslte_symbol_sz(nof_prb))) {
|
|
|
|
if (srslte_prach_init(p, srslte_symbol_sz(nof_prb))) {
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -342,12 +340,10 @@ int srslte_prach_init_cfg(srslte_prach_t *p, srslte_prach_cfg_t *cfg, uint32_t n
|
|
|
|
cfg->zero_corr_zone);
|
|
|
|
cfg->zero_corr_zone);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int srslte_prach_init(srslte_prach_t *p, uint32_t max_N_ifft_ul)
|
|
|
|
int srslte_prach_init(srslte_prach_t *p, uint32_t max_N_ifft_ul) {
|
|
|
|
{
|
|
|
|
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
if (p != NULL &&
|
|
|
|
if (p != NULL &&
|
|
|
|
max_N_ifft_ul < 2049)
|
|
|
|
max_N_ifft_ul < 2049) {
|
|
|
|
{
|
|
|
|
|
|
|
|
bzero(p, sizeof(srslte_prach_t));
|
|
|
|
bzero(p, sizeof(srslte_prach_t));
|
|
|
|
|
|
|
|
|
|
|
|
p->max_N_ifft_ul = max_N_ifft_ul;
|
|
|
|
p->max_N_ifft_ul = max_N_ifft_ul;
|
|
|
@ -403,20 +399,17 @@ int srslte_prach_init(srslte_prach_t *p, uint32_t max_N_ifft_ul)
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int srslte_prach_set_cell(srslte_prach_t *p,
|
|
|
|
int srslte_prach_set_cell(srslte_prach_t *p,
|
|
|
|
uint32_t N_ifft_ul,
|
|
|
|
uint32_t N_ifft_ul,
|
|
|
|
uint32_t config_idx,
|
|
|
|
uint32_t config_idx,
|
|
|
|
uint32_t root_seq_index,
|
|
|
|
uint32_t root_seq_index,
|
|
|
|
bool high_speed_flag,
|
|
|
|
bool high_speed_flag,
|
|
|
|
uint32_t zero_corr_zone_config)
|
|
|
|
uint32_t zero_corr_zone_config) {
|
|
|
|
{
|
|
|
|
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
if (p != NULL &&
|
|
|
|
if (p != NULL &&
|
|
|
|
N_ifft_ul < 2049 &&
|
|
|
|
N_ifft_ul < 2049 &&
|
|
|
|
config_idx < 64 &&
|
|
|
|
config_idx < 64 &&
|
|
|
|
root_seq_index < MAX_ROOTS)
|
|
|
|
root_seq_index < MAX_ROOTS) {
|
|
|
|
{
|
|
|
|
|
|
|
|
if (N_ifft_ul > p->max_N_ifft_ul) {
|
|
|
|
if (N_ifft_ul > p->max_N_ifft_ul) {
|
|
|
|
fprintf(stderr, "PRACH: Error in set_cell(): N_ifft_ul must be lower or equal max_N_ifft_ul in init()\n");
|
|
|
|
fprintf(stderr, "PRACH: Error in set_cell(): N_ifft_ul must be lower or equal max_N_ifft_ul in init()\n");
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
@ -521,13 +514,11 @@ int srslte_prach_set_cell(srslte_prach_t *p,
|
|
|
|
int srslte_prach_gen(srslte_prach_t *p,
|
|
|
|
int srslte_prach_gen(srslte_prach_t *p,
|
|
|
|
uint32_t seq_index,
|
|
|
|
uint32_t seq_index,
|
|
|
|
uint32_t freq_offset,
|
|
|
|
uint32_t freq_offset,
|
|
|
|
cf_t *signal)
|
|
|
|
cf_t *signal) {
|
|
|
|
{
|
|
|
|
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
if (p != NULL &&
|
|
|
|
if (p != NULL &&
|
|
|
|
seq_index < N_SEQS &&
|
|
|
|
seq_index < N_SEQS &&
|
|
|
|
signal != NULL)
|
|
|
|
signal != NULL) {
|
|
|
|
{
|
|
|
|
|
|
|
|
// Calculate parameters
|
|
|
|
// Calculate parameters
|
|
|
|
uint32_t N_rb_ul = srslte_nof_prb(p->N_ifft_ul);
|
|
|
|
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_0 = freq_offset * N_RB_SC - N_rb_ul * N_RB_SC / 2 + p->N_ifft_ul / 2;
|
|
|
@ -572,8 +563,7 @@ int srslte_prach_detect(srslte_prach_t *p,
|
|
|
|
cf_t *signal,
|
|
|
|
cf_t *signal,
|
|
|
|
uint32_t sig_len,
|
|
|
|
uint32_t sig_len,
|
|
|
|
uint32_t *indices,
|
|
|
|
uint32_t *indices,
|
|
|
|
uint32_t *n_indices)
|
|
|
|
uint32_t *n_indices) {
|
|
|
|
{
|
|
|
|
|
|
|
|
return srslte_prach_detect_offset(p, freq_offset, signal, sig_len, indices, NULL, NULL, n_indices);
|
|
|
|
return srslte_prach_detect_offset(p, freq_offset, signal, sig_len, indices, NULL, NULL, n_indices);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -584,14 +574,12 @@ int srslte_prach_detect_offset(srslte_prach_t *p,
|
|
|
|
uint32_t *indices,
|
|
|
|
uint32_t *indices,
|
|
|
|
float *t_offsets,
|
|
|
|
float *t_offsets,
|
|
|
|
float *peak_to_avg,
|
|
|
|
float *peak_to_avg,
|
|
|
|
uint32_t *n_indices)
|
|
|
|
uint32_t *n_indices) {
|
|
|
|
{
|
|
|
|
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
int ret = SRSLTE_ERROR;
|
|
|
|
if (p != NULL &&
|
|
|
|
if (p != NULL &&
|
|
|
|
signal != NULL &&
|
|
|
|
signal != NULL &&
|
|
|
|
sig_len > 0 &&
|
|
|
|
sig_len > 0 &&
|
|
|
|
indices != NULL)
|
|
|
|
indices != NULL) {
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sig_len < p->N_ifft_prach) {
|
|
|
|
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);
|
|
|
|
fprintf(stderr, "srslte_prach_detect: Signal length is %d and should be %d\n", sig_len, p->N_ifft_prach);
|
|
|
@ -651,8 +639,7 @@ int srslte_prach_detect_offset(srslte_prach_t *p,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (max_peak > p->detect_factor * corr_ave) {
|
|
|
|
if (max_peak > p->detect_factor * corr_ave) {
|
|
|
|
for (int j = 0; j < n_wins; j++) {
|
|
|
|
for (int j = 0; j < n_wins; j++) {
|
|
|
|
if(p->peak_values[j] > p->detect_factor*corr_ave)
|
|
|
|
if (p->peak_values[j] > p->detect_factor * corr_ave) {
|
|
|
|
{
|
|
|
|
|
|
|
|
//printf("saving prach correlation\n");
|
|
|
|
//printf("saving prach correlation\n");
|
|
|
|
//memcpy(save_corr, p->corr, p->N_zc*sizeof(float));
|
|
|
|
//memcpy(save_corr, p->corr, p->N_zc*sizeof(float));
|
|
|
|
if (indices) {
|
|
|
|
if (indices) {
|
|
|
@ -695,10 +682,8 @@ int srslte_prach_free(srslte_prach_t *p) {
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int srslte_prach_print_seqs(srslte_prach_t *p)
|
|
|
|
int srslte_prach_print_seqs(srslte_prach_t *p) {
|
|
|
|
{
|
|
|
|
for (int i = 0; i < N_SEQS; i++) {
|
|
|
|
for(int i=0; i<N_SEQS;i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
FILE *f;
|
|
|
|
FILE *f;
|
|
|
|
char str[32];
|
|
|
|
char str[32];
|
|
|
|
sprintf(str, "prach_seq_%d.bin", i);
|
|
|
|
sprintf(str, "prach_seq_%d.bin", i);
|
|
|
@ -706,8 +691,7 @@ int srslte_prach_print_seqs(srslte_prach_t *p)
|
|
|
|
fwrite(p->seqs[i], sizeof(cf_t), p->N_zc, f);
|
|
|
|
fwrite(p->seqs[i], sizeof(cf_t), p->N_zc, f);
|
|
|
|
fclose(f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(int i=0; i<N_SEQS;i++)
|
|
|
|
for (int i = 0; i < N_SEQS; i++) {
|
|
|
|
{
|
|
|
|
|
|
|
|
FILE *f;
|
|
|
|
FILE *f;
|
|
|
|
char str[32];
|
|
|
|
char str[32];
|
|
|
|
sprintf(str, "prach_dft_seq_%d.bin", i);
|
|
|
|
sprintf(str, "prach_dft_seq_%d.bin", i);
|
|
|
@ -715,8 +699,7 @@ int srslte_prach_print_seqs(srslte_prach_t *p)
|
|
|
|
fwrite(p->dft_seqs[i], sizeof(cf_t), p->N_zc, f);
|
|
|
|
fwrite(p->dft_seqs[i], sizeof(cf_t), p->N_zc, f);
|
|
|
|
fclose(f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(int i=0;i<p->N_roots;i++)
|
|
|
|
for (int i = 0; i < p->N_roots; i++) {
|
|
|
|
{
|
|
|
|
|
|
|
|
FILE *f;
|
|
|
|
FILE *f;
|
|
|
|
char str[32];
|
|
|
|
char str[32];
|
|
|
|
sprintf(str, "prach_root_seq_%d.bin", i);
|
|
|
|
sprintf(str, "prach_root_seq_%d.bin", i);
|
|
|
|