mirror of https://github.com/PentHertz/srsLTE.git
Added SSB search measure/decode file test
This commit is contained in:
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)
|
||||
|
|
Binary file not shown.
|
@ -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…
Reference in New Issue