This commit is contained in:
Laurent
2026-02-12 10:01:11 +01:00
committed by Laurent THOMAS
parent 8fb2a7aaa3
commit 8499ea9165
7 changed files with 113 additions and 80 deletions

View File

@@ -377,15 +377,8 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
if (fp->nb_antennas_rx > 1) {
nr_pdcch_detection_mrc(fp->nb_antennas_rx, rx_comp_sz, rxdataF_comp);
}
int avg_util = 0;
for (int i = 0; i < llr_size_symbol; i++)
avg_util += squaredMod(rxdataF_comp[0][i]);
// LOG_E(PHY,"avg: %d\n", avg_util);
nr_pdcch_llr(llr_size_symbol, rxdataF_comp[0], llr);
if (avg_util > 100000) {
UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), 1, llr_size_symbol, 0);
UEscopeCopy(ue, pdcchLlr, llr, sizeof(c16_t), 1, llr_size_symbol, 0);
}
nr_pdcch_llr(llr_size_symbol, rxdataF_comp[0], llr);
}
static bool is_start_symbol_in_ss(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, const int symbol, const int nb_symb_slot)

View File

@@ -277,7 +277,7 @@ void nr_scan_ssb(void *arg)
nr_ue_ssb_scan_t *ssbInfo = (nr_ue_ssb_scan_t *)arg;
c16_t **rxdata = ssbInfo->rxdata;
const NR_DL_FRAME_PARMS *fp = ssbInfo->fp;
LOG_I(PHY, "sync for power %d\n", signal_energy((int32_t *)(rxdata[0]), fp->samples_per_frame));
// Generate PSS time signal for this GSCN.
__attribute__((aligned(32))) c16_t pssTime[NUMBER_PSS_SEQUENCE][fp->ofdm_symbol_size];
const int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
@@ -295,64 +295,43 @@ void nr_scan_ssb(void *arg)
int detected_nid_cell = -1;
int ssb_offset = 0;
int freq_offset_pss = 0;
const int sync_pos = pss_synchro_nr((const c16_t **)rxdata,
fp,
pssTime,
frame_id,
ssbInfo->foFlag,
ssbInfo->targetNidCell,
&nid2,
&freq_offset_pss,
&ssbInfo->pssCorrPeakPower,
&ssbInfo->pssCorrAvgPower);
if (sync_pos < fp->nb_prefix_samples)
continue;
ssbInfo->ssbOffset = sync_pos - fp->nb_prefix_samples;
#if 1
LOG_I(PHY, "Initial sync : Estimated PSS position %d, Nid2 %d, ssb offset %d\n", sync_pos, nid2, ssbInfo->ssbOffset);
#endif
/* check that SSS/PBCH block is continuous inside the received buffer */
if (ssbInfo->ssbOffset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) >= fp->samples_per_frame) {
LOG_D(PHY, "Can't try to decode SSS from PSS position, will retry (PSS circular buffer wrapping): sync_pos %d\n", sync_pos);
continue;
}
// digital compensation of FFO for SSB symbols
if (ssbInfo->foFlag) {
compensate_freq_offset(rxdata, fp, freq_offset_pss, frame_id);
}
/* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
/* symbol number are from beginning of SS/PBCH blocks as below: */
/* Signal PSS PBCH SSS PBCH */
/* symbol number 0 1 2 3 */
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
const uint32_t rxdataF_sz = fp->samples_per_slot_wCP;
__attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz];
for (int i = 0; i < NR_N_SYMBOLS_SSB; i++)
nr_slot_fep(NULL, fp, 0, i, rxdataF, link_type_dl, frame_id * fp->samples_per_frame + ssbInfo->ssbOffset, (c16_t **)rxdata);
int freq_offset_sss = 0;
int32_t sss_metric = 0;
uint8_t sss_phase = 0;
int32_t metric_tdd_ncp = 0;
uint8_t phase_tdd_ncp;
ssbInfo->syncRes.cell_detected = rx_sss_nr(fp,
nid2,
ssbInfo->targetNidCell,
freq_offset_pss,
ssbInfo->gscnInfo.ssbFirstSC,
&ssbInfo->nidCell,
&metric_tdd_ncp,
&phase_tdd_ncp,
&freq_offset_sss,
rxdataF);
#if 1
nr_ssb_search_params_t search_params = {
.frame_parms = fp,
.rxdata = rxdata,
.rxdata_size = fp->samples_per_frame,
.ssb_start_subcarrier = ssbInfo->gscnInfo.ssbFirstSC,
.target_nid_cell = ssbInfo->targetNidCell,
.exclude_nid_cell = -1, // No exclusion for initial sync
.apply_freq_offset = ssbInfo->foFlag,
.search_frame_id = frame_id,
.fo_flag = ssbInfo->foFlag,
.rxdataF = rxdataF,
.pssTime = pssTime,
.detected_nid_cell = &detected_nid_cell,
.ssb_offset = &ssb_offset,
.sss_metric = &sss_metric,
.freq_offset_pss = &freq_offset_pss,
.freq_offset_sss = &freq_offset_sss,
.sss_phase = &sss_phase,
.pss_peak = &ssbInfo->pssCorrPeakPower,
.pss_avg = &ssbInfo->pssCorrAvgPower,
};
ssbInfo->syncRes.frame_id = frame_id;
ssbInfo->syncRes.cell_detected = nr_search_ssb_common(&search_params);
if (!ssbInfo->syncRes.cell_detected) {
continue;
}
ssbInfo->ssbOffset = ssb_offset;
ssbInfo->nidCell = detected_nid_cell;
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,
"TDD Normal prefix: sss detection result; %d, CellId %d metric %d, phase %d, measured offset %d\n",
ssbInfo->syncRes.cell_detected,

View File

@@ -40,10 +40,10 @@ void nfapi_setmode(nfapi_mode_t nfapi_mode) {}
void set_taus_seed(unsigned int seed_init){};
// configmodule_interface_t *uniqCfg = NULL;
const int tx_ahead = DFT * 7;
const int tx_ahead = DFT * 20;
openair0_timestamp_t rx_timestamp = 0;
openair0_timestamp_t tx_timestamp = 0;
openair0_timestamp last_hole = 0;
openair0_timestamp_t last_hole = 0;
pthread_cond_t tx_trig;
#define GEN_CHIRP
@@ -97,7 +97,6 @@ void *write_thread(void *arg)
openair0_timestamp_t last_tx_timestamp = 0, new_tx = 0;
char *flag = getenv("HOLE");
while (!oai_exit) {
do {
AssertFatal(!pthread_mutex_lock(&params->txMutex), "");

View File

@@ -919,6 +919,7 @@ void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
nr_pdcch_generate_llr(ue, proc, symbol, phy_data, llr_size_symbol, num_monitoring_occ, max_nb_symb_pdcch, rxdataF_symb, pdcch_llr);
if (symbol == last_symb_pdcch) {
nr_pdcch_dci_indication(proc, llr_size_symbol * max_nb_symb_pdcch, num_monitoring_occ, ue, phy_data, pdcch_llr);
UEscopeCopy(ue, pdcchLlr, pdcch_llr, sizeof(c16_t), 1, sizeof(pdcch_llr) / sizeof(c16_t), 0);
}
}
stop_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);

View File

@@ -397,7 +397,6 @@ static void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info,
NR_SchedulingInfo_t *schedulingInfo = si_SchedulingInfo->schedulingInfoList.list.array[i];
for (int j = 0; j < schedulingInfo->sib_MappingInfo.list.count; j++) {
NR_SIB_TypeInfo_t *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j];
LOG_W(PHY,"SIB1 tells us we have SIB%ld\n", sib_Type->type+2);
SI_info->default_otherSI_map[i] |= 1 << sib_Type->type;
}
}
@@ -1884,11 +1883,15 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
LOG_E(NR_RRC, "NR_BCCH_BCH decode error\n");
return;
}
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
static time_t t = 0;
time_t t2 = time(0);
if (LOG_DEBUGFLAG(DEBUG_ASN1) && t != t2)
if (t != t2) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message);
t = t2;
}
}
// Actions following cell selection while T311 is running
NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants;
if (nr_timer_is_active(&timers->T311)) {

View File

@@ -150,7 +150,7 @@ int openair0_transport_load(openair0_device_t *device, openair0_config_t *openai
static void writerEnqueue(re_order_t *ctx, openair0_timestamp_t timestamp, void **txp, int nsamps, int nbAnt, int flags)
{
pthread_mutex_lock(&ctx->mutex_store);
// LOG_W(HW, "Enqueue write for TS: %lu to %lu\n", timestamp, timestamp + nsamps);
LOG_D(HW, "Enqueue write for TS: %lu\n", timestamp);
int i;
for (i = 0; i < WRITE_QUEUE_SZ; i++)
if (!ctx->queue[i].active) {

View File

@@ -88,7 +88,7 @@ static const uint64_t magic_tx = 0xA5A50be3A5A5A5A5LL;
static const uint64_t magic_rx = 0xA5A50be3A5A5A5A5LL;
static const uint32_t magic_footer1 = 0xce11;
static const uint32_t magic_footer2 = 0x5A;
static const uint64_t tx_ahead = WRITE_BLOCK_NB_SAMPLES * NB_BLOCKS_PER_WRITE * 3;
static const uint64_t tx_ahead = WRITE_BLOCK_NB_SAMPLES * 24;
typedef struct {
uint64_t control;
@@ -187,6 +187,7 @@ typedef struct {
openair0_timestamp_t rx_timestamp;
openair0_timestamp_t rx_ts_interface;
openair0_timestamp_t tx_ts;
uint txSeq;
uint64_t gap;
tx_packet_t *tx_block;
size_t tx_block_pos;
@@ -257,7 +258,29 @@ void *write_thread(void *arg)
return NULL;
}
static int32_t signalEnergy(int32_t *input, uint32_t length)
struct energy_s {
float mean;
float papr_dB;
float peak;
};
struct energy_s compute_papr_db(const c16_t *x, size_t N)
{
float p_max = 0.0f;
float p_sum = 0.0f;
for (size_t n = 0; n < N; n++) {
float p = (float)x[n].r * x[n].r + (float)x[n].i * x[n].i;
p_sum += p;
if (p > p_max)
p_max = p;
}
float p_avg = p_sum / N;
float papr = p_max / p_avg;
return (struct energy_s){p_avg, 10.0f * log10f(papr), sqrt(p_max)};
}
static int32_t signalEnergy(c16_t *input, uint32_t length)
{
// init
simde__m128 mm0 = simde_mm_setzero_ps();
@@ -271,8 +294,8 @@ static int32_t signalEnergy(int32_t *input, uint32_t length)
// leftover
float leftover_sum = 0;
c16_t *leftover_input = (c16_t *)input;
uint16_t lefover_count = length - ((length >> 2) << 2);
c16_t *leftover_input = input + (length & ~3);
uint16_t lefover_count = length & 3;
for (int32_t i = 0; i < lefover_count; i++) {
leftover_sum += leftover_input[i].r * leftover_input[i].r + leftover_input[i].i * leftover_input[i].i;
}
@@ -350,6 +373,16 @@ static int oc_write(openair0_device_t *device, openair0_timestamp_t timestamp, v
if (s->tx_ts != timestamp + nsamps)
LOG_E(HW,"tx samples count error\n");
s->tx_ts = timestamp + nsamps;
#if 0
static uint nsamps0 = 0;
struct energy_s e = compute_papr_db((c16_t *)*buff, nsamps);
if (e.mean > 1) {
LOG_I(HW, "sent power: %f, papr %f, max %f after %d samples with no energy\n", e.mean, e.papr_dB, e.peak, nsamps0);
nsamps0 = 0;
} else {
nsamps0 += nsamps;
}
#endif
return nsamps;
}
@@ -494,6 +527,31 @@ static bool get_blocks(oc_state_t *s, rx_packet_t *p)
return true;
}
void *read_thread(void *arg)
{
oc_state_t *s = (oc_state_t *)arg;
while (true) {
if (s->rx_count == -1)
initial_block_align(s);
if (s->rx_count == -1) {
usleep(10);
continue;
}
if (s->read_queue->m_queue.size() > 100) {
LOG_W(HW, "rx consumer is too slow, trashing rx queue\n");
while (s->read_queue->m_queue.size())
free(s->read_queue->pop());
}
rx_packet_t *tmp = (rx_packet_t *)malloc(sizeof(*s->rx_live) * s->nb_blocks_per_read);
if (!get_blocks(s, tmp)) {
printf("getblocks returned bad\n");
free(tmp);
} else
s->read_queue->push(tmp);
}
return NULL;
}
static int oc_read(openair0_device_t *device, openair0_timestamp_t *ptimestamp, void **buff, int nsamps, int cc)
{
oc_state_t *s = (oc_state_t *)device->priv;