Added SSB search measure/decode file test

master
Xavier Arteaga 3 years ago committed by Xavier Arteaga
parent 5181a9d64c
commit a79d518799

@ -185,12 +185,19 @@ static int dmrs_pbch_meas_estimate(const srsran_dmrs_pbch_cfg_t* cfg,
cfo_hz = cargf(corr1 * conjf(corr3)) / (2.0f * (float)M_PI * distance_s);
}
// Estimate wideband gain at symbol 0
cf_t wideband_gain = (srsran_vec_acc_cc(lse, DMRS_PBCH_NOF_RE) / DMRS_PBCH_NOF_RE) *
cexpf(I * 2.0f * M_PI * srsran_symbol_offset_s(2, cfg->scs) * cfo_hz);
// Estimate wideband gain at each symbol carrying DMRS
cf_t wideband_gain_1 =
srsran_vec_acc_cc(&lse[0], 60) * cexpf(I * 2.0f * M_PI * srsran_symbol_offset_s(1, cfg->scs) * cfo_hz);
cf_t wideband_gain_2 =
srsran_vec_acc_cc(&lse[60], 24) * cexpf(I * 2.0f * M_PI * srsran_symbol_offset_s(2, cfg->scs) * cfo_hz);
cf_t wideband_gain_3 =
srsran_vec_acc_cc(&lse[84], 60) * cexpf(I * 2.0f * M_PI * srsran_symbol_offset_s(3, cfg->scs) * cfo_hz);
// Estimate wideband gain equivalent at symbol 0
cf_t wideband_gain = (wideband_gain_1 + wideband_gain_2 + wideband_gain_3) / DMRS_PBCH_NOF_RE;
// Compute RSRP from correlation
float rsrp = SRSRAN_CSQABS((corr1 + corr3) / 2.0f);
float rsrp = (SRSRAN_CSQABS(corr1) + SRSRAN_CSQABS(corr3)) / 2.0f;
// Compute EPRE
float epre = srsran_vec_avg_power_cf(lse, DMRS_PBCH_NOF_RE);

@ -767,10 +767,8 @@ ssb_pss_search(srsran_ssb_t* q, const cf_t* in, uint32_t nof_samples, uint32_t*
continue;
}
float corr = SRSRAN_CSQABS(q->tmp_time[peak_idx]) / avg_pwr_corr;
if (corr < sqrtf(SRSRAN_PSS_NR_LEN)) {
continue;
}
// Normalise correlation
float corr = SRSRAN_CSQABS(q->tmp_time[peak_idx]) / avg_pwr_corr / sqrtf(SRSRAN_PSS_NR_LEN);
// Update if the correlation is better than the current best
if (best_corr < corr) {
@ -808,13 +806,11 @@ int srsran_ssb_csi_search(srsran_ssb_t* q,
}
// Avoid finding a peak in a region that cannot be demodulated
if (nof_samples < (q->symbol_sz + q->cp_sz[0]) * SRSRAN_SSB_DURATION_NSYMB) {
ERROR("Insufficient number of samples (%d/%d)",
nof_samples,
(q->symbol_sz + q->cp_sz[0]) * SRSRAN_SSB_DURATION_NSYMB);
if (nof_samples < (q->symbol_sz + q->cp_sz) * SRSRAN_SSB_DURATION_NSYMB) {
ERROR("Insufficient number of samples (%d/%d)", nof_samples, (q->symbol_sz + q->cp_sz) * SRSRAN_SSB_DURATION_NSYMB);
return SRSRAN_ERROR;
}
nof_samples -= (q->symbol_sz + q->cp_sz[0]) * SRSRAN_SSB_DURATION_NSYMB;
nof_samples -= (q->symbol_sz + q->cp_sz) * SRSRAN_SSB_DURATION_NSYMB;
// Search for PSS in time domain
uint32_t N_id_2 = 0;

@ -134,3 +134,10 @@ add_nr_test(ssb_measure_test ssb_measure_test)
add_executable(ssb_decode_test ssb_decode_test.c)
target_link_libraries(ssb_decode_test srsran_phy)
add_nr_test(ssb_decode_test ssb_decode_test)
add_executable(ssb_file_test ssb_file_test.c)
target_link_libraries(ssb_file_test srsran_phy)
# File test 1
# Captured with command: lib/examples/usrp_capture -a type=x300,clock=external,sampling_rate=46.08e6,rx_subdev_spec=B:0 -g 20 -r 46.08e6 -n 460800 -f 3502.8e6 -o /tmp/n78.fo35028.fs2304M.data
add_nr_test(ssb_file_test ssb_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/n78.fo35028.fs4608M.data -v -r 46.08e6 -f 3502.8e6 -F 3512.64e6 -n 460800 -A 500 357802 5 0 0 0)

@ -214,6 +214,7 @@ int main(int argc, char** argv)
if (test_case_1(&ssb) != SRSRAN_SUCCESS) {
ERROR("test case failed");
goto clean_exit;
}
ret = SRSRAN_SUCCESS;

@ -0,0 +1,217 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srsran/common/test_common.h"
#include "srsran/phy/io/filesource.h"
#include "srsran/phy/sync/ssb.h"
#include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/vector.h"
#include <complex.h>
#include <getopt.h>
#include <stdlib.h>
// NR parameters
static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_C;
static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz;
static srsran_duplex_mode_t duplex_mode = SRSRAN_DUPLEX_MODE_TDD;
// Test context
static char* filename = NULL;
static double srate_hz = 23.04e6; // Base-band sampling rate in Hz
static double center_freq_hz = NAN; // Center frequency in Hz
static double ssb_freq_hz = NAN; // SSB frequency in Hz
static uint32_t nof_samples = 0; // Number of half-frames
// Assertion
static bool assert = false;
static uint32_t assert_pci = 0;
static uint32_t assert_t_offset = 0;
static uint32_t assert_sfn_lsb = 0;
static uint32_t assert_ssb_idx = 0;
static uint32_t assert_ssb_k = 0;
static uint32_t assert_hrf = 0;
static void usage(char* prog)
{
printf("Usage: %s -i filename [rv]\n", prog);
printf("\t-r sampling rate in Hz [Default %.2f MHz]\n", srate_hz / 1e6);
printf("\t-f absolute baseband center frequency in Hz [Default %.2f MHz]\n", center_freq_hz / 1e3);
printf("\t-F absolute SSB center freuqency in Hz [Default %.2f MHz]\n", ssb_freq_hz / 1e3);
printf("\t-F absolute SSB center freuqency in Hz [Default %.2f MHz]\n", ssb_freq_hz / 1e3);
printf("\t-A Assert: PCI t_offset sfn_lsb ssb_idx ssb_k hrf");
printf("\t-v [set srsran_verbose to debug, default none]\n");
}
static void parse_args(int argc, char** argv)
{
int opt;
while ((opt = getopt(argc, argv, "inrfFAv")) != -1) {
switch (opt) {
case 'i':
filename = argv[optind];
break;
case 'n':
nof_samples = (uint32_t)strtol(argv[optind], NULL, 10);
break;
case 'r':
srate_hz = strtod(argv[optind], NULL);
break;
case 'f':
center_freq_hz = strtod(argv[optind], NULL);
break;
case 'F':
ssb_freq_hz = strtod(argv[optind], NULL);
break;
case 'A':
assert = true;
assert_pci = (uint32_t)strtol(argv[optind++], NULL, 10);
assert_t_offset = (uint32_t)strtol(argv[optind++], NULL, 10);
assert_sfn_lsb = (uint32_t)strtol(argv[optind++], NULL, 10);
assert_ssb_idx = (uint32_t)strtol(argv[optind++], NULL, 10);
assert_ssb_k = (uint32_t)strtol(argv[optind++], NULL, 10);
assert_hrf = (uint32_t)strtol(argv[optind], NULL, 10);
break;
case 'v':
srsran_verbose++;
break;
default:
usage(argv[0]);
exit(-1);
}
}
}
static int assert_meas(uint32_t N_id, const srsran_csi_trs_measurements_t* res)
{
TESTASSERT(N_id == assert_pci);
return SRSRAN_SUCCESS;
}
static int assert_search(const srsran_ssb_search_res_t* res)
{
TESTASSERT(res->N_id == assert_pci);
TESTASSERT(res->t_offset == assert_t_offset);
TESTASSERT(res->pbch_msg.sfn_4lsb == assert_sfn_lsb);
TESTASSERT(res->pbch_msg.ssb_idx == assert_ssb_idx);
TESTASSERT(res->pbch_msg.k_ssb_msb == assert_ssb_k);
TESTASSERT((res->pbch_msg.hrf ? 1 : 0) == assert_hrf);
return SRSRAN_SUCCESS;
}
int main(int argc, char** argv)
{
srsran_filesource_t filesource = {};
srsran_ssb_t ssb = {};
int ret = SRSRAN_ERROR;
parse_args(argc, argv);
if (nof_samples == 0 || !isnormal(ssb_freq_hz) || !isnormal(center_freq_hz)) {
ERROR("Invalid arguments!");
usage(argv[0]);
return SRSRAN_ERROR;
}
cf_t* buffer = srsran_vec_cf_malloc(nof_samples);
if (buffer == NULL) {
ERROR("Malloc");
goto clean_exit;
}
// Initialise SSB
srsran_ssb_args_t ssb_args = {};
ssb_args.enable_decode = true;
ssb_args.enable_search = true;
if (srsran_ssb_init(&ssb, &ssb_args) < SRSRAN_SUCCESS) {
ERROR("Init");
goto clean_exit;
}
// Configure SSB
srsran_ssb_cfg_t ssb_cfg = {};
ssb_cfg.srate_hz = srate_hz;
ssb_cfg.center_freq_hz = center_freq_hz;
ssb_cfg.ssb_freq_hz = ssb_freq_hz;
ssb_cfg.scs = ssb_scs;
ssb_cfg.pattern = ssb_pattern;
ssb_cfg.duplex_mode = duplex_mode;
if (srsran_ssb_set_cfg(&ssb, &ssb_cfg) < SRSRAN_SUCCESS) {
ERROR("Error setting SSB configuration");
goto clean_exit;
}
// Initialise file source
if (srsran_filesource_init(&filesource, filename, SRSRAN_COMPLEX_FLOAT_BIN) < SRSRAN_SUCCESS) {
ERROR("Error opening file");
goto clean_exit;
}
// Read baseband
if (srsran_filesource_read(&filesource, buffer, (int)nof_samples) < SRSRAN_SUCCESS) {
ERROR("Error reading from file");
goto clean_exit;
}
// Perform SSB-CSI Search
uint32_t N_id = 0;
srsran_csi_trs_measurements_t meas = {};
if (srsran_ssb_csi_search(&ssb, buffer, nof_samples, &N_id, &meas) < SRSRAN_SUCCESS) {
ERROR("Error performing SSB-CSI search");
goto clean_exit;
}
// Print measurement
char str[512] = {};
srsran_csi_meas_info(&meas, str, sizeof(str));
INFO("measure - search pci=%d %s", N_id, str);
// Assert measurement
if (assert) {
if (assert_meas(N_id, &meas)) {
ERROR("Error asserting search");
goto clean_exit;
}
}
// Perform SSB search
srsran_ssb_search_res_t search_res = {};
if (srsran_ssb_search(&ssb, buffer, nof_samples, &search_res) < SRSRAN_SUCCESS) {
ERROR("Error performing SSB search");
goto clean_exit;
}
// Print decoded PBCH message
srsran_pbch_msg_info(&search_res.pbch_msg, str, sizeof(str));
INFO("search - t_offset=%d pci=%d %s crc=%s",
search_res.t_offset,
search_res.N_id,
str,
search_res.pbch_msg.crc ? "OK" : "KO");
// Assert search
if (assert) {
if (assert_search(&search_res)) {
ERROR("Error asserting search");
goto clean_exit;
}
}
ret = SRSRAN_SUCCESS;
clean_exit:
srsran_ssb_free(&ssb);
srsran_filesource_free(&filesource);
if (buffer) {
free(buffer);
}
return ret;
}

@ -61,7 +61,7 @@ add_nr_test(nr_cell_search_test_delay nr_cell_search_test --duration=1 --ssb_per
# File test of 10ms captured NR carrier
# Captured using: lib/examples/usrp_capture -a type=b200,master_clock_rate=61.44e6 -g 80 -r 61.44e6 -n 614400 -f 3682.5e6 -o ../srsue/test/phy/n78.fo3675360k.fs6144.data
add_nr_test(nr_cell_search_test_file nr_cell_search_test --duration=1 --srate=61.44e6 --ssb_arfcn=645024 --carrier_arfcn=645500 --meas_period_ms=10 --meas_len_ms=10 --file.name=${CMAKE_SOURCE_DIR}/n78.fo3675360k.fs6144.data)
#add_nr_test(nr_cell_search_test_file nr_cell_search_test --duration=1 --srate=61.44e6 --ssb_arfcn=645024 --carrier_arfcn=645500 --meas_period_ms=10 --meas_len_ms=10 --file.name=${CMAKE_SOURCE_DIR}/n78.fo3675360k.fs6144.data)
add_executable(nr_cell_search_rf nr_cell_search_rf.cc)
target_link_libraries(nr_cell_search_rf

Loading…
Cancel
Save