Commit 5b53f4ee authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/NR_UE_cell_search' into integration_2024_w22

parents 76f06a93 dac55975
......@@ -182,6 +182,123 @@ const nr_bandentry_t nr_bandtable[] = {
{261,27500040,28350000,27500040,28350000, 2,2070833, 120}
};
// synchronization raster per band tables (Rel.15)
// (38.101-1 Table 5.4.3.3-1 and 38.101-2 Table 5.4.3.3-1)
// band nb, sub-carrier spacing index, Range of gscn (First, Step size, Last)
// clang-format off
const sync_raster_t sync_raster[] = {
{1, 0, 5279, 1, 5419},
{2, 0, 4829, 1, 4969},
{3, 0, 4517, 1, 4693},
{5, 0, 2177, 1, 2230},
{5, 1, 2183, 1, 2224},
{7, 0, 6554, 1, 6718},
{8, 0, 2318, 1, 2395},
{12, 0, 1828, 1, 1858},
{13, 0, 1871, 1, 1885},
{14, 0, 1901, 1, 1915},
{18, 0, 2156, 1, 2182},
{20, 0, 1982, 1, 2047},
{24, 0, 3818, 1, 3892},
{24, 1, 3824, 1, 3886},
{25, 0, 4829, 1, 4981},
{26, 0, 2153, 1, 2230},
{28, 0, 1901, 1, 2002},
{29, 0, 1798, 1, 1813},
{30, 0, 5879, 1, 5893},
{34, 0, 5030, 1, 5056},
{34, 1, 5036, 1, 5050},
{38, 0, 6431, 1, 6544},
{38, 1, 6437, 1, 6538},
{39, 0, 4706, 1, 4795},
{39, 1, 4712, 1, 4789},
{40, 1, 5762, 1, 5989},
{41, 0, 6246, 3, 6717},
{41, 1, 6252, 3, 6714},
{48, 1, 7884, 1, 7982},
{50, 0, 3584, 1, 3787},
{51, 0, 3572, 1, 3574},
{53, 0, 6215, 1, 6232},
{53, 1, 6221, 1, 6226},
{65, 0, 5279, 1, 5494},
{66, 0, 5279, 1, 5494},
{66, 1, 5285, 1, 5488},
{67, 0, 1850, 1, 1888},
{70, 0, 4993, 1, 5044},
{71, 0, 1547, 1, 1624},
{74, 0, 3692, 1, 3790},
{75, 0, 3584, 1, 3787},
{76, 0, 3572, 1, 3574},
{77, 1, 7711, 1, 8329},
{78, 1, 7711, 1, 8051},
{79, 1, 8480, 16, 8880},
{85, 0, 1826, 1, 1858},
{90, 1, 6252, 1, 6714},
{91, 0, 3572, 1, 3574},
{92, 0, 3584, 1, 3787},
{93, 0, 3572, 1, 3574},
{94, 0, 3584, 1, 3587},
{257, 3, 22388, 1, 22558},
{257, 4, 22390, 2, 22556},
{258, 3, 22257, 1, 22443},
{258, 4, 22258, 2, 22442},
{260, 3, 22995, 1, 23166},
{260, 4, 22996, 2, 23164},
{261, 3, 22446, 1, 22492},
{261, 4, 22446, 2, 22490},
};
// clang-format on
// Section 5.4.3 of 38.101-1 and -2
void check_ssb_raster(uint64_t freq, int band, int scs)
{
int start_gscn = 0, step_gscn = 0, end_gscn = 0;
for (int i = 0; i < sizeof(sync_raster) / sizeof(sync_raster_t); i++) {
if (sync_raster[i].band == band && sync_raster[i].scs_index == scs) {
start_gscn = sync_raster[i].first_gscn;
step_gscn = sync_raster[i].step_gscn;
end_gscn = sync_raster[i].last_gscn;
break;
}
}
AssertFatal(start_gscn != 0, "Couldn't find band %d with SCS %d\n", band, scs);
int gscn;
if (freq < 3000000000) {
int N = 0;
int M = 0;
for (int k = 0; k < 3; k++) {
M = (k << 1) + 1;
if ((freq - M * 50000) % 1200000 == 0) {
N = (freq - M * 50000) / 1200000;
break;
}
}
AssertFatal(N != 0, "SSB frequency %lu Hz not on the synchronization raster (N * 1200kHz + M * 50 kHz)\n", freq);
gscn = (3 * N) + (M - 3) / 2;
} else if (freq < 24250000000) {
AssertFatal((freq - 3000000000) % 1440000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (3000 MHz + N * 1.44 MHz)\n",
freq);
gscn = ((freq - 3000000000) / 1440000) + 7499;
} else {
AssertFatal((freq - 24250080000) % 17280000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (24250.08 MHz + N * 17.28 MHz)\n",
freq);
gscn = ((freq - 24250080000) / 17280000) + 22256;
}
AssertFatal(gscn >= start_gscn && gscn <= end_gscn,
"GSCN %d corresponding to SSB frequency %lu does not belong to GSCN range for band %d\n",
gscn,
freq,
band);
int rel_gscn = gscn - start_gscn;
AssertFatal(rel_gscn % step_gscn == 0,
"GSCN %d corresponding to SSB frequency %lu not in accordance with GSCN step for band %d\n",
gscn,
freq,
band);
}
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb)
{
int bw_index = get_supported_band_index(scs, frequency_range, nb_rb);
......@@ -910,6 +1027,129 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
return ssb_offset_point_a;
}
static double get_start_freq(const double fc, const int nbRB, const int mu)
{
const int scs = MU_SCS(mu) * 1000;
return fc - (nbRB / 2 * NR_NB_SC_PER_RB * scs);
}
static double get_stop_freq(const double fc, const int nbRB, const int mu)
{
int scs = MU_SCS(mu) * 1000;
return fc + (nbRB / 2 * NR_NB_SC_PER_RB * scs);
}
static void compute_M_and_N(const int gscn, int *rM, int *rN)
{
if (gscn > 1 && gscn < 7499) {
for (int M = 1; M < 6; M += 2) {
/* GSCN = 3N + (M-3) / 2
N(int) = 2 * GSCN + 3 - M
*/
if (((2 * gscn + 3 - M) % 6) == 0) {
*rM = M;
*rN = (2 * gscn + 3 - M) / 6;
break;
}
}
} else if (gscn > 7498 && gscn < 22256) {
*rN = gscn - 7499;
} else if (gscn > 22255 && gscn < 26638) {
*rN = gscn - 22256;
} else {
LOG_E(NR_PHY, "Invalid GSCN\n");
abort();
}
}
// Section 5.4.3 of 38.101-1 and -2
static double get_ssref_from_gscn(const int gscn)
{
int M, N = -1;
compute_M_and_N(gscn, &M, &N);
if (gscn > 1 && gscn < 7499) { // Sub 3GHz
AssertFatal(N > 0 && N < 2500, "Invalid N\n");
AssertFatal(M > 0 && M < 6 && (M & 0x1), "Invalid M\n");
return (N * 1200e3 + M * 50e3);
} else if (gscn > 7498 && gscn < 22256) {
AssertFatal(N > -1 && N < 14757, "Invalid N\n");
return (3000e6 + N * 1.44e6);
} else if (gscn > 22255 && gscn < 26638) {
AssertFatal(N > -1 && N < 4382, "Invalid N\n");
return (24250.08e6 + N * 17.28e6);
} else {
LOG_E(NR_PHY, "Invalid GSCN\n");
abort();
}
}
static void find_gscn_to_scan(const double startFreq,
const double stopFreq,
const sync_raster_t gscn,
int *scanGscnStart,
int *scanGscnStop)
{
const double scs = MU_SCS(gscn.scs_index) * 1e3;
const double ssbBW = 20 * NR_NB_SC_PER_RB * scs;
for (int g = gscn.first_gscn; g < gscn.last_gscn; g += gscn.step_gscn) {
const double centerSSBFreq = get_ssref_from_gscn(g);
const double startSSBFreq = centerSSBFreq - ssbBW / 2;
if (startSSBFreq < startFreq)
continue;
*scanGscnStart = g;
break;
}
for (int g = gscn.last_gscn; g > gscn.first_gscn; g -= gscn.step_gscn) {
const double centerSSBFreq = get_ssref_from_gscn(g);
const double stopSSBFreq = centerSSBFreq + ssbBW / 2 - 1;
if (stopSSBFreq > stopFreq)
continue;
*scanGscnStop = g;
break;
}
}
static int get_ssb_first_sc(const double pointA, const double ssbCenter, const int mu)
{
const double scs = MU_SCS(mu) * 1e3;
const int ssbRBs = 20;
return (int)((ssbCenter - pointA) / scs - (ssbRBs / 2 * NR_NB_SC_PER_RB));
}
/* Returns array of first SCS offset in the scanning window */
int get_scan_ssb_first_sc(const double fc, const int nbRB, const int nrBand, const int mu, nr_gscn_info_t ssbInfo[MAX_GSCN_BAND])
{
const double startFreq = get_start_freq(fc, nbRB, mu);
const double stopFreq = get_stop_freq(fc, nbRB, mu);
int scanGscnStart = -1;
int scanGscnStop = -1;
sync_raster_t tmpRaster = {0};
for (const sync_raster_t *r = sync_raster; r < r + (sizeof(sync_raster) / sizeof(sync_raster_t)); r++) {
if (r->band == nrBand && r->scs_index == mu) {
tmpRaster = *r;
break;
}
}
find_gscn_to_scan(startFreq, stopFreq, tmpRaster, &scanGscnStart, &scanGscnStop);
const double scs = MU_SCS(mu) * 1e3;
const double pointA = fc - (nbRB / 2 * scs * NR_NB_SC_PER_RB);
int numGscn = 0;
for (int g = scanGscnStart; (g <= scanGscnStop) && (numGscn < MAX_GSCN_BAND); g += tmpRaster.step_gscn) {
ssbInfo[numGscn].ssRef = get_ssref_from_gscn(g);
ssbInfo[numGscn].ssbFirstSC = get_ssb_first_sc(pointA, ssbInfo[numGscn].ssRef, mu);
ssbInfo[numGscn].gscn = g;
numGscn++;
}
return numGscn;
}
int get_delay_idx(int delay, int max_delay_comp)
{
int delay_idx = max_delay_comp + delay;
......
......@@ -77,6 +77,9 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
}
#undef R
#define MU_SCS(m) (15 << m)
#define MAX_GSCN_BAND 620 // n78 has the highest GSCN range of 619
#define NR_MAX_NB_LAYERS 4 // 8
// Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when
......@@ -104,6 +107,12 @@ typedef struct {
int last_gscn;
} sync_raster_t;
typedef struct {
int gscn;
double ssRef;
int ssbFirstSC;
} nr_gscn_info_t;
typedef enum frequency_range_e {
FR1 = 0,
FR2
......@@ -238,6 +247,14 @@ void freq2time(uint16_t ofdm_symbol_size,
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay);
int get_scan_ssb_first_sc(const double fc,
const int nbRB,
const int nrBand,
const int mu,
nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]);
void check_ssb_raster(uint64_t freq, int band, int scs);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
......
......@@ -102,6 +102,9 @@ Command line parameters for UE in `--sa` mode:
- `--band` : NR band number (default value 78)
- `--ssb` : SSB start subcarrier (default value 516)
**Optional parameters**:
- `--ue-scan-carrier` : scan for cells in current bandwidth. This option can be used if the SSB position of the gNB is unknown. If multiple cells are detected, the UE will try to connect to the first cell. By default, this option is disabled and the UE attempts to only decode SSB given by `--ssb`.
To simplify the configuration for the user testing OAI UE with OAI gNB, the latter prints the following LOG that guides the user to correctly set some of the UE command line parameters.
```
......
......@@ -46,7 +46,7 @@
#define CONFIG_HLP_UETXG "set UE TX gain\n"
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
#define CONFIG_HLP_UESCAN "set UE to scan all possible GSCN in current bandwidth\n"
#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
......
......@@ -49,7 +49,6 @@
#include "PHY_INTERFACE/phy_interface_vars.h"
#include "gnb_config.h"
#include "SIMULATION/TOOLS/sim.h"
#include "executables/lte-softmodem.h"
#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
......@@ -604,6 +603,7 @@ static void initialize_agent(ngran_node_t node_type, e2_agent_args_t oai_args)
}
#endif
void init_eNB_afterRU(void);
configmodule_interface_t *uniqCfg = NULL;
int main( int argc, char **argv ) {
int ru_id, CC_id = 0;
......
......@@ -94,12 +94,6 @@
*
*/
typedef enum {
pss = 0,
pbch = 1,
si = 2
} sync_mode_t;
static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len)
......@@ -348,134 +342,51 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
* \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
*/
typedef nr_rxtx_thread_data_t syncData_t;
typedef struct {
PHY_VARS_NR_UE *UE;
UE_nr_rxtx_proc_t proc;
nr_gscn_info_t gscnInfo[MAX_GSCN_BAND];
int numGscn;
int rx_offset;
} syncData_t;
static void UE_synch(void *arg) {
syncData_t *syncD=(syncData_t *) arg;
int i, hw_slot_offset;
syncData_t *syncD = (syncData_t *)arg;
PHY_VARS_NR_UE *UE = syncD->UE;
sync_mode_t sync_mode = pbch;
//int CC_id = UE->CC_id;
static int freq_offset = 0;
UE->is_synchronized = 0;
if (UE->UE_scan == 0) {
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %f, UL %f (RF card %d, oai_exit %d, channel %d, rx_num_channels %d)\n",
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i],
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i],
UE->rf_map.card,
oai_exit,
i,
openair0_cfg[0].rx_num_channels);
}
sync_mode = pbch;
} else {
LOG_E(PHY,"Fixme!\n");
/*
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
}
*/
}
if (UE->target_Nid_cell != -1) {
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
} else {
LOG_W(NR_PHY, "Starting sync detection\n");
}
switch (sync_mode) {
/*
case pss:
LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
//lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
current_offset += 20000000; // increase by 20 MHz
if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
current_band++;
current_offset=0;
}
if (current_band==bands_to_scan.nbands) {
current_band=0;
oai_exit=1;
}
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
if (UE->UE_scan_carrier) {
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
}
break;
*/
case pbch:
LOG_I(PHY, "[UE thread Synch] Running Initial Synch \n");
uint64_t dl_carrier, ul_carrier;
nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier);
nr_initial_sync_t ret = nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa);
if (ret.cell_detected) {
syncD->rx_offset = ret.rx_offset;
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
hw_slot_offset =
((ret.rx_offset << 1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe)
+ round((float)((ret.rx_offset << 1) % UE->frame_parms.samples_per_subframe) / UE->frame_parms.samples_per_slot0);
// rerun with new cell parameters and frequency-offset
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
hw_slot_offset,
freq_offset,
openair0_cfg[UE->rf_map.card].rx_gain[0],
openair0_cfg[UE->rf_map.card].rx_freq[0],
openair0_cfg[UE->rf_map.card].tx_freq[0]);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0]);
if (UE->UE_scan_carrier == 1)
UE->UE_scan_carrier = 0;
else
UE->is_synchronized = 1;
} else {
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0]);
}
}
break;
case si:
default:
break;
LOG_I(PHY, "[UE thread Synch] Running Initial Synch \n");
uint64_t dl_carrier, ul_carrier;
nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier);
nr_initial_sync_t ret = nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa, syncD->gscnInfo, syncD->numGscn);
if (ret.cell_detected) {
syncD->rx_offset = ret.rx_offset;
const int freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
const int hw_slot_offset =
((ret.rx_offset << 1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe)
+ round((float)((ret.rx_offset << 1) % UE->frame_parms.samples_per_subframe) / UE->frame_parms.samples_per_slot0);
// rerun with new cell parameters and frequency-offset
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
LOG_I(PHY,
"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
hw_slot_offset,
freq_offset,
openair0_cfg[UE->rf_map.card].rx_gain[0],
openair0_cfg[UE->rf_map.card].rx_freq[0],
openair0_cfg[UE->rf_map.card].tx_freq[0]);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]);
UE->is_synchronized = 1;
}
}
......@@ -609,6 +520,7 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc
// Start synchronization with a target gNB
if (UE->synch_request.received_synch_request == 1) {
UE->is_synchronized = 0;
UE->UE_scan_carrier = UE->synch_request.synch_req.ssb_bw_scan;
UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell;
clean_UE_harq(UE);
UE->synch_request.received_synch_request = 0;
......@@ -803,16 +715,16 @@ void *UE_thread(void *arg)
delNotifiedFIFO_elt(res);
stream_status = STREAM_STATUS_UNSYNC;
} else {
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// For IQ recorder-player we force synchronization to happen in 280 ms
while (trashed_frames != 28) {
readFrame(UE, &sync_timestamp, true);
trashed_frames += 2;
}
} else {
readFrame(UE, &sync_timestamp, true);
trashed_frames += 2;
}
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// For IQ recorder-player we force synchronization to happen in 280 ms
while (trashed_frames != 28) {
readFrame(UE, &sync_timestamp, true);
trashed_frames += 2;
}
} else {
readFrame(UE, &sync_timestamp, true);
trashed_frames += 2;
}
continue;
}
}
......@@ -823,6 +735,20 @@ void *UE_thread(void *arg)
readFrame(UE, &sync_timestamp, false);
notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
if (UE->UE_scan_carrier) {
// Get list of GSCN in this band for UE's bandwidth and center frequency.
LOG_W(PHY, "UE set to scan all GSCN in current bandwidth\n");
syncMsg->numGscn =
get_scan_ssb_first_sc(fp->dl_CarrierFreq, fp->N_RB_DL, fp->nr_band, fp->numerology_index, syncMsg->gscnInfo);
} else {
LOG_W(PHY, "SSB position provided\n");
nr_gscn_info_t *g = syncMsg->gscnInfo;
g->ssbFirstSC = fp->ssb_start_subcarrier;
g->gscn = 0;
g->ssRef = 0;
syncMsg->numGscn = 1;
}
syncMsg->UE = UE;
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
pushTpool(&(get_nrUE_params()->Tpool), Msg);
......
......@@ -687,6 +687,7 @@ typedef struct
typedef struct {
int16_t target_Nid_cell;
bool ssb_bw_scan;
} fapi_nr_synch_request_t;
typedef struct {
......
......@@ -706,7 +706,6 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
void phy_term_nr_top(void)
{
free_ul_reference_signal_sequences();
free_context_synchro_nr();
}
static void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id)
......
......@@ -109,9 +109,8 @@ void set_Lmax(NR_DL_FRAME_PARMS *fp) {
}
}
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) {
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb)
{
int mu = fp->numerology_index;
int symbol = 0;
uint8_t n, n_temp;
......
......@@ -25,7 +25,7 @@
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_UE.h"
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb);
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
......
......@@ -61,12 +61,11 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
uint32_t sample_offset,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]);
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int nr_slot_fep_init_sync(const NR_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
int sample_offset,
bool pbch_decoded,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
const c16_t **rxdata,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
int link_type);
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
......
......@@ -203,31 +203,19 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
return 0;
}
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int nr_slot_fep_init_sync(const NR_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
int sample_offset,
bool pbch_decoded,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
const c16_t **rxdata,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
int link_type)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
int Ns = proc->nr_slot_rx;
int Ns = 0;
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
if (pbch_decoded) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
}
else {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
}
unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
unsigned int frame_length_samples = frame_parms->samples_per_frame;
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
......@@ -236,10 +224,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int rx_offset = sample_offset + slot_offset;
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
rx_offset += (frame_parms->ofdm_symbol_size + nb_prefix_samples) * symbol + nb_prefix_samples;
#ifdef DEBUG_FEP
// if (ue->frame <100)
......@@ -256,38 +241,29 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
// rxdata is 2 frames len
// we have to wrap on the end
memcpy((void *)&tmp_dft_in[0],
(void *)&common_vars->rxdata[aa][rx_offset],
(frame_length_samples*2 - rx_offset) * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[frame_length_samples*2 - rx_offset],
(void *)&common_vars->rxdata[aa][0],
(frame_parms->ofdm_symbol_size - (frame_length_samples*2 - rx_offset)) * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], (frame_length_samples * 2 - rx_offset) * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[frame_length_samples * 2 - rx_offset],
(void *)&rxdata[aa][0],
(frame_parms->ofdm_symbol_size - (frame_length_samples * 2 - rx_offset)) * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in;
} else if ((rx_offset & 7) != 0) {
// if input to dft is not 256-bit aligned
memcpy((void *)&tmp_dft_in[0],
(void *)&common_vars->rxdata[aa][rx_offset],
frame_parms->ofdm_symbol_size * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in;
} else {
// use dft input from RX buffer directly
rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
rxdata_ptr = (int16_t *)&rxdata[aa][rx_offset];
}
start_meas(&ue->rx_dft_stats);
dft(dftsize,
rxdata_ptr,
(int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1);
stop_meas(&ue->rx_dft_stats);
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset];
rot2.i=-rot2.i;
......
......@@ -202,7 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
return(0);
}
void nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink)
void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink)
{
int m,m0,m1;
uint8_t idx=0;
......
......@@ -21,15 +21,13 @@
#include "refsig_defs_ue.h"
void nr_gold_pbch(PHY_VARS_NR_UE* ue)
void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax)
{
unsigned int n = 0, x1 = 0, x2 = 0;
unsigned int Nid, i_ssb, i_ssb2;
unsigned char Lmax, l, n_hf, N_hf;
unsigned int i_ssb, i_ssb2;
unsigned char l, n_hf, N_hf;
uint8_t reset;
Nid = ue->frame_parms.Nid_cell;
Lmax = ue->frame_parms.Lmax;
N_hf = (Lmax == 4)? 2:1;
for (n_hf = 0; n_hf < N_hf; n_hf++) {
......@@ -42,7 +40,7 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
for (n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) {
ue->nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
......
......@@ -76,8 +76,17 @@
#define SYNCF_TMP_SIZE (SYNCHRO_FFT_SIZE_MAX*IQ_SIZE)
void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
void free_context_synchro_nr(void);
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change);
int pss_synchro_nr(const c16_t **rxdata,
const NR_DL_FRAME_PARMS *frame_parms,
const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size],
int is,
bool fo_flag,
int target_Nid_cell,
int *nid2,
int *f_off,
int *pssPeak,
int *pssAvg);
void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssbFirstSCS, c16_t pssTime[fp->ofdm_symbol_size]);
int16_t *get_primary_synchro_nr2(const int nid2);
#endif /* PSS_NR_H */
......
......@@ -30,7 +30,7 @@
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/
void nr_pbch_dmrs_rx(int dmrss, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink);
void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink);
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
......@@ -51,7 +51,7 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned short nb_pdsch_rb,
uint8_t config_type);
void nr_gold_pbch(PHY_VARS_NR_UE* ue);
void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax);
void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
unsigned short n_idDMRS);
......
......@@ -95,11 +95,15 @@ void free_context_sss_nr(void);
void insert_sss_nr(int16_t *sss_time,
NR_DL_FRAME_PARMS *frame_parms);
bool rx_sss_nr(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
int nid2,
int target_Nid_cell,
int freq_offset_pss,
int ssb_start_subcarrier,
int *Nid_cell,
int32_t *tot_metric,
uint8_t *phase_max,
int *freq_offset_sss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
c16_t rxdataF[][frame_parms->samples_per_slot_wCP]);
#endif /* SSS_NR_H */
......@@ -555,21 +555,24 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
return(0);
}
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc,
const int symbol,
const int dmrss,
const int Nid_cell,
const int ssb_start_subcarrier,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
const c16_t rxdataF[][fp->samples_per_slot_wCP])
{
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
if (ssb_offset >= fp->ofdm_symbol_size)
ssb_offset -= fp->ofdm_symbol_size;
int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
int symbol_offset = fp->ofdm_symbol_size * symbol;
unsigned int k = ue->frame_parms.Nid_cell % 4;
unsigned int k = Nid_cell % 4;
DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%u symbol %d\n",
proc->gNB_id,
......@@ -583,8 +586,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
c16_t pilot[200] __attribute__((aligned(16)));
nr_pbch_dmrs_rx(dmrss, (uint32_t *)nr_gold_pbch, pilot, false);
c32_t computed_val = {0};
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
c16_t *pil = pilot;
const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
......@@ -599,49 +601,50 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) {
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset + 144) % fp->ofdm_symbol_size;
}
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
}
}
return computed_val;
}
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *fp,
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
const sl_nr_ue_phy_params_t *sl_phy_params,
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
......@@ -650,7 +653,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf,
c16_t rxdataF[][fp->samples_per_slot_wCP],
int ssb_start_subcarrier,
const c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink,
uint16_t Nid)
{
......@@ -659,13 +663,11 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
//int slot_pbch;
uint8_t nushift = 0, lastsymbol = 0, num_rbs = 0;
uint32_t *gold_seq = NULL;
const uint32_t *gold_seq = NULL;
if (sidelink) {
AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), "symbol %d is illegal for PSBCH DM-RS \n", dmrss);
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
LOG_D(PHY, "PSBCH Channel Estimation SLSSID:%d\n", Nid);
gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid];
......@@ -673,16 +675,16 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL;
} else {
nushift = fp->Nid_cell % 4;
nushift = Nid % 4;
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
gold_seq = ue->nr_gold_pbch[n_hf][ssb_index];
gold_seq = nr_gold_pbch[n_hf][ssb_index];
lastsymbol = 2;
num_rbs = 20;
}
unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier;
unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
if (ssb_offset >= fp->ofdm_symbol_size)
ssb_offset -= fp->ofdm_symbol_size;
......@@ -739,7 +741,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
c16_t *pil = pilot;
c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset];
memset(dl_ch, 0, sizeof(c16_t) * fp->ofdm_symbol_size);
......@@ -824,15 +826,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
{
// do ifft of channel estimate
LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
freq2time(ue->frame_parms.ofdm_symbol_size,
(int16_t *)&dl_ch_estimates[aarx][ch_offset],
(int16_t *)&dl_ch_estimates_time[aarx]);
freq2time(fp->ofdm_symbol_size, (int16_t *)&dl_ch_estimates[aarx][ch_offset], (int16_t *)&dl_ch_estimates_time[aarx]);
}
}
if (!sidelink && dmrss == lastsymbol)
UEscopeCopy(ue, pbchDlChEstimateTime, (void *)dl_ch_estimates_time, sizeof(c16_t), fp->nb_antennas_rx, fp->ofdm_symbol_size, 0);
return(0);
}
......
......@@ -57,15 +57,18 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc,
const int symbol,
const int dmrss,
const int Nid_cell,
const int ssb_start_subcarrier,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
const c16_t rxdataF[][fp->samples_per_slot_wCP]);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *fp,
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
const sl_nr_ue_phy_params_t *sl_phy_params,
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
......@@ -74,7 +77,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf,
c16_t rxdataF[][fp->samples_per_slot_wCP],
int ssb_start_subcarrier,
const c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink,
uint16_t Nid);
......
......@@ -462,8 +462,9 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
uint8_t decoded_output[4];
for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) {
nr_pbch_channel_estimation(UE,
frame_parms,
nr_pbch_channel_estimation(frame_parms,
&UE->SL_UE_PHY_PARAMS,
UE->nr_gold_pbch,
rxdataF_sz,
dl_ch_estimates,
dl_ch_estimates_time,
......@@ -472,6 +473,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
symbol,
0,
0,
frame_parms->ssb_start_subcarrier,
rxdataF,
1,
rx_slss_id);
......
This diff is collapsed.
......@@ -291,12 +291,19 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
int nr_rx_pbch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const int estimateSz,
bool is_synchronized,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
NR_DL_FRAME_PARMS *frame_parms,
const NR_DL_FRAME_PARMS *frame_parms,
uint8_t i_ssb,
int ssb_start_subcarrier,
int Nid_cell,
fapiPbch_t *result,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int *half_frame_bit,
int *ssb_index,
int *ret_symbol_offset,
int rxdataFSize,
const struct complex16 rxdataF[][rxdataFSize]);
#ifndef modOrder
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
......@@ -319,11 +326,12 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue,
@param n_frames
@param sa current running mode
*/
typedef struct {
bool cell_detected;
int rx_offset;
} nr_initial_sync_t;
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa);
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *phy_vars_ue,
int n_frames,
int sa,
nr_gscn_info_t gscnInfo[MAX_GSCN_BAND],
int numGscn);
/*!
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the
......@@ -435,13 +443,13 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
// Reuse already existing PBCH functions
int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms,
const NR_DL_FRAME_PARMS *frame_parms,
int nb_re);
void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
int nb_re,
struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms,
const NR_DL_FRAME_PARMS *frame_parms,
uint8_t output_shift);
void nr_pbch_unscrambling(int16_t *demod_pbch_e,
uint16_t Nid,
......
This diff is collapsed.
......@@ -187,13 +187,14 @@ void insert_sss_nr(int16_t *sss_time,
*
*********************************************************************/
static int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms,
int nid2,
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
{
int16_t *pss = get_primary_synchro_nr2(ue->common_vars.nid2);
int16_t *pss = get_primary_synchro_nr2(nid2);
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
c16_t *sss_ext2 = sss_ext[aarx];
c16_t *pss_ext2 = pss_ext[aarx];
for (int i = 0; i < LENGTH_PSS_NR; i++) {
......@@ -250,16 +251,15 @@ static int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
*********************************************************************/
static int do_pss_sss_extract_nr(
PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const NR_DL_FRAME_PARMS *frame_parms,
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t doPss,
uint8_t doSss,
uint8_t subframe,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
int ssb_start_subcarrier,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n");
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
......@@ -275,11 +275,8 @@ static int do_pss_sss_extract_nr(
c16_t *pss_rxF_ext = pss_ext[aarx];
c16_t *sss_rxF_ext = sss_ext[aarx];
unsigned int k = frame_parms->first_carrier_offset +
frame_parms->ssb_start_subcarrier +
((get_softmodem_params()->sl_mode == 0) ?
PSS_SSS_SUB_CARRIER_START :
PSS_SSS_SUB_CARRIER_START_SL);
unsigned int k = frame_parms->first_carrier_offset + ssb_start_subcarrier
+ ((get_softmodem_params()->sl_mode == 0) ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL);
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
......@@ -333,14 +330,21 @@ static int do_pss_sss_extract_nr(
*
*********************************************************************/
static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
const UE_nr_rxtx_proc_t *proc,
static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms,
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t subframe,
c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP])
int ssb_start_subcarrier,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
{
return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe, rxdataF);
return do_pss_sss_extract_nr(frame_parms,
pss_ext,
sss_ext,
1 /* doPss */,
1 /* doSss */,
subframe,
ssb_start_subcarrier,
rxdataF);
}
/*******************************************************************
......@@ -355,31 +359,29 @@ static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
* so Nid_cell in ue context is set according to Nid1 & Nid2
*
*********************************************************************/
bool rx_sss_nr(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
int nid2,
int target_Nid_cell,
int freq_offset_pss,
int ssb_start_subcarrier,
int *Nid_cell,
int32_t *tot_metric,
uint8_t *phase_max,
int *freq_offset_sss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
{
uint8_t i;
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0};
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0};
uint8_t Nid2 = GET_NID2(ue->common_vars.nid2);
uint8_t Nid2 = GET_NID2(nid2);
uint16_t Nid1;
uint8_t phase;
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int32_t metric, metric_re;
int16_t *d;
// pss sss extraction
pss_sss_extract_nr(ue,
proc,
pss_ext,
sss_ext,
0,
rxdataF); /* subframe */
pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, 0, ssb_start_subcarrier, rxdataF); /* subframe */
#ifdef DEBUG_PLOT_SSS
......@@ -406,9 +408,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
// get conjugated channel estimate from PSS, H* = R* \cdot PSS
// and do channel estimation and compensation based on PSS
pss_ch_est_nr(ue,
pss_ext,
sss_ext);
pss_ch_est_nr(frame_parms, nid2, pss_ext, sss_ext);
// now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h
*tot_metric = INT_MIN;
......@@ -453,8 +453,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
uint16_t Nid1_start = 0;
uint16_t Nid1_end = N_ID_1_NUMBER;
if (ue->target_Nid_cell != -1) {
Nid1_start = GET_NID1(ue->target_Nid_cell);
if (target_Nid_cell != -1) {
Nid1_start = GET_NID1(target_Nid_cell);
Nid1_end = Nid1_start + 1;
}
......@@ -476,7 +476,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
// if the current metric is better than the last save it
if (metric > *tot_metric) {
*tot_metric = metric;
ue->frame_parms.Nid_cell = Nid2+(3*Nid1);
*Nid_cell = Nid2 + (3 * Nid1);
*phase_max = phase;
#ifdef DEBUG_SSS_NR
......@@ -490,9 +490,9 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
//#ifdef DEBUG_SSS_NR
#define SSS_METRIC_FLOOR_NR (30000)
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
Nid2 = GET_NID2(frame_parms->Nid_cell);
Nid1 = GET_NID1(frame_parms->Nid_cell);
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
Nid2 = GET_NID2(*Nid_cell);
Nid1 = GET_NID1(*Nid_cell);
LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
}
// #endif
......@@ -500,11 +500,11 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
int re = 0;
int im = 0;
if (Nid1 == N_ID_1_NUMBER) {
LOG_W(PHY,
LOG_D(PHY,
"Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n",
*tot_metric,
SSS_METRIC_FLOOR_NR,
frame_parms->Nid_cell);
*Nid_cell);
return false;
}
d = (int16_t *)&d_sss[Nid2][Nid1];
......@@ -515,10 +515,10 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
double ffo_sss = atan2(im,re)/M_PI/4.3;
*freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing);
double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing;
LOG_W(NR_PHY,
double ffo_pss = ((double)freq_offset_pss) / frame_parms->subcarrier_spacing;
LOG_D(NR_PHY,
"SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n",
frame_parms->Nid_cell,
*Nid_cell,
ffo_pss,
(int)(ffo_pss * frame_parms->subcarrier_spacing),
ffo_sss,
......
......@@ -49,6 +49,7 @@
#include "common_lib.h"
#include "fapi_nr_ue_interface.h"
#include "assertions.h"
//#include "openair1/SCHED_NR_UE/defs.h"
#ifdef MEX
#define msg mexPrintf
......@@ -60,9 +61,9 @@
#endif
#define msg(aRGS...) LOG_D(PHY, ##aRGS)
#endif
//use msg in the real-time thread context
// use msg in the real-time thread context
#define msg_nrt printf
//use msg_nrt in the non real-time context (for initialization, ...)
// use msg_nrt in the non real-time context (for initialization, ...)
#ifndef malloc16
#define malloc16(x) memalign(32,x)
#endif
......@@ -123,6 +124,11 @@ typedef enum {
#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg
typedef struct {
uint8_t decoded_output[3]; // PBCH paylod not larger than 3B
uint8_t xtra_byte;
} fapiPbch_t;
typedef struct {
// RRC measurements
......@@ -614,6 +620,32 @@ typedef struct {
int frame_rx;
} UE_nr_rxtx_proc_t;
typedef struct {
bool cell_detected;
int rx_offset;
int frame_id;
} nr_initial_sync_t;
typedef struct {
nr_gscn_info_t gscnInfo;
int foFlag;
int targetNidCell;
c16_t **rxdata;
NR_DL_FRAME_PARMS *fp;
UE_nr_rxtx_proc_t *proc;
int nFrames;
int halfFrameBit;
int symbolOffset;
int ssbIndex;
int ssbOffset;
int nidCell;
int freqOffset;
nr_initial_sync_t syncRes;
fapiPbch_t pbchResult;
int pssCorrPeakPower;
int pssCorrAvgPower;
} nr_ue_ssb_scan_t;
typedef struct nr_phy_data_tx_s {
NR_UE_ULSCH_t ulsch;
NR_UE_PUCCH pucch_vars;
......
......@@ -81,12 +81,6 @@
#define DAQ_AGC_ON 1
#define DAQ_AGC_OFF 0
typedef struct {
uint8_t decoded_output[3]; // PBCH paylod not larger than 3B
uint8_t xtra_byte;
} fapiPbch_t;
/** @addtogroup _PHY_PROCEDURES_
* @{
*/
......
......@@ -371,13 +371,21 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id);
fapiPbch_t result;
int hf_frame_bit, ssb_index, symb_offset;
ret = nr_rx_pbch(ue,
proc,
ue->is_synchronized,
estimateSz,
dl_ch_estimates,
&ue->frame_parms,
(ue->frame_parms.ssb_index)&7,
(ue->frame_parms.ssb_index) & 7,
ue->frame_parms.ssb_start_subcarrier,
ue->frame_parms.Nid_cell,
&result,
&hf_frame_bit,
&ssb_index,
&symb_offset,
ue->frame_parms.samples_per_frame_wCP,
rxdataF);
if (ret==0) {
......@@ -868,8 +876,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
nr_slot_fep(ue, fp, proc, (ssb_start_symbol + i) % (fp->symbols_per_slot), rxdataF, link_type_dl);
start_meas(&ue->dlsch_channel_estimation_stats);
nr_pbch_channel_estimation(ue,
&ue->frame_parms,
nr_pbch_channel_estimation(&ue->frame_parms,
NULL,
ue->nr_gold_pbch,
estimateSz,
dl_ch_estimates,
dl_ch_estimates_time,
......@@ -878,10 +887,20 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
i - 1,
ssb_index & 7,
ssb_slot_2 == nr_slot_rx,
fp->ssb_start_subcarrier,
rxdataF,
false,
fp->Nid_cell);
stop_meas(&ue->dlsch_channel_estimation_stats);
if (i - 1 == 2)
UEscopeCopy(ue,
pbchDlChEstimateTime,
(void *)dl_ch_estimates_time,
sizeof(c16_t),
fp->nb_antennas_rx,
fp->ofdm_symbol_size,
0);
}
nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, rxdataF);
......
......@@ -193,8 +193,9 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
nr_slot_fep(ue, fp, proc, sym, rxdataF, link_type_ul);
start_meas(&sl_phy_params->channel_estimation_stats);
nr_pbch_channel_estimation(ue,
fp,
nr_pbch_channel_estimation(fp,
&ue->SL_UE_PHY_PARAMS,
ue->nr_gold_pbch,
estimateSz,
dl_ch_estimates,
dl_ch_estimates_time,
......@@ -203,10 +204,19 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
sym,
0,
0,
fp->ssb_start_subcarrier,
rxdataF,
true,
sl_phy_params->sl_config.sl_sync_source.rx_slss_id);
stop_meas(&sl_phy_params->channel_estimation_stats);
if (sym == 12)
UEscopeCopy(ue,
pbchDlChEstimateTime,
(void *)dl_ch_estimates_time,
sizeof(c16_t),
fp->nb_antennas_rx,
fp->ofdm_symbol_size,
0);
// PSBCH present in symbols 0, 5-12 for normal cp
sym = (sym == 0) ? 5 : sym + 1;
......
......@@ -830,7 +830,7 @@ int main(int argc, char **argv)
init_nr_ue_transport(UE);
nr_gold_pbch(UE);
nr_gold_pbch(UE->nr_gold_pbch, frame_parms->Nid_cell, frame_parms->Lmax);
// compute the scramblingID_pdcch and the gold pdcch
UE->scramblingID_pdcch = frame_parms->Nid_cell;
......
......@@ -199,6 +199,7 @@ int main(int argc, char **argv)
uint16_t Nid_cell=0;
uint64_t SSB_positions=0x01;
int ssb_subcarrier_offset = 0;
int ssb_scan_threads = 0;
channel_desc_t *gNB2UE;
get_softmodem_params()->sa = 1;
......@@ -500,8 +501,9 @@ int main(int argc, char **argv)
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
phy_init_nr_gNB(gNB);
frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset;
initFloatingCoresTpool(ssb_scan_threads, &nrUE_params.Tpool, false, "UE-tpool");
uint8_t n_hf = 0;
int n_hf = 0;
int cyclic_prefix_type = NFAPI_CP_NORMAL;
double fs=0, eps;
......@@ -615,7 +617,7 @@ int main(int argc, char **argv)
exit(-1);
}
nr_gold_pbch(UE);
nr_gold_pbch(UE->nr_gold_pbch, Nid_cell, frame_parms->Lmax);
processingData_L1tx_t msgDataTx;
// generate signal
......@@ -766,13 +768,16 @@ int main(int argc, char **argv)
}
if (n_trials==1) {
LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_parms->samples_per_frame,1,1);
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_frame,1,1);
LOG_M("rxsig0.m", "rxs0", UE->common_vars.rxdata[0], frame_parms->samples_per_frame, 1, 1);
if (gNB->frame_parms.nb_antennas_tx > 1)
LOG_M("rxsig1.m", "rxs1", UE->common_vars.rxdata[1], frame_parms->samples_per_frame, 1, 1);
}
if (UE->is_synchronized == 0) {
UE_nr_rxtx_proc_t proc={0};
nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0);
UE_nr_rxtx_proc_t proc = {0};
nr_gscn_info_t gscnInfo[MAX_GSCN_BAND] = {0};
const int numGscn = 1;
gscnInfo[0].ssbFirstSC = frame_parms->ssb_start_subcarrier;
nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0, gscnInfo, numGscn);
printf("nr_initial_sync1 returns %s\n", ret.cell_detected ? "cell detected" : "cell not detected");
if (!ret.cell_detected)
n_errors++;
......@@ -795,8 +800,9 @@ int main(int argc, char **argv)
for (int i = UE->symbol_offset + 1; i < UE->symbol_offset + 4; i++) {
nr_slot_fep(UE, frame_parms, &proc, i % frame_parms->symbols_per_slot, rxdataF, link_type_dl);
nr_pbch_channel_estimation(UE,
&UE->frame_parms,
nr_pbch_channel_estimation(&UE->frame_parms,
&UE->SL_UE_PHY_PARAMS,
UE->nr_gold_pbch,
estimateSz,
dl_ch_estimates,
dl_ch_estimates_time,
......@@ -805,12 +811,29 @@ int main(int argc, char **argv)
i - (UE->symbol_offset + 1),
ssb_index % 8,
n_hf,
frame_parms->ssb_start_subcarrier,
rxdataF,
false,
frame_parms->Nid_cell);
}
fapiPbch_t result;
ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF);
int ret_ssb_idx;
int ret_symbol_offset;
ret = nr_rx_pbch(UE,
&proc,
true,
estimateSz,
dl_ch_estimates,
frame_parms,
ssb_index % 8,
frame_parms->ssb_start_subcarrier,
Nid_cell,
&result,
&n_hf,
&ret_ssb_idx,
&ret_symbol_offset,
frame_parms->samples_per_frame_wCP,
rxdataF);
if (ret == 0) {
// UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically
......
......@@ -96,71 +96,6 @@
extern uint16_t sf_ahead;
// synchronization raster per band tables (Rel.15)
// (38.101-1 Table 5.4.3.3-1 and 38.101-2 Table 5.4.3.3-1)
// band nb, sub-carrier spacing index, Range of gscn (First, Step size, Last)
const sync_raster_t sync_raster[] = {
{1, 0, 5279, 1, 5419},
{2, 0, 4829, 1, 4969},
{3, 0, 4517, 1, 4693},
{5, 0, 2177, 1, 2230},
{5, 1, 2183, 1, 2224},
{7, 0, 6554, 1, 6718},
{8, 0, 2318, 1, 2395},
{12, 0, 1828, 1, 1858},
{13, 0, 1871, 1, 1885},
{14, 0, 1901, 1, 1915},
{18, 0, 2156, 1, 2182},
{20, 0, 1982, 1, 2047},
{24, 0, 3818, 1, 3892},
{24, 1, 3824, 1, 3886},
{25, 0, 4829, 1, 4981},
{26, 0, 2153, 1, 2230},
{28, 0, 1901, 1, 2002},
{29, 0, 1798, 1, 1813},
{30, 0, 5879, 1, 5893},
{34, 0, 5030, 1, 5056},
{34, 1, 5036, 1, 5050},
{38, 0, 6431, 1, 6544},
{38, 1, 6437, 1, 6538},
{39, 0, 4706, 1, 4795},
{39, 1, 4712, 1, 4789},
{40, 1, 5762, 1, 5989},
{41, 0, 6246, 3, 6717},
{41, 1, 6252, 3, 6714},
{48, 1, 7884, 1, 7982},
{50, 0, 3584, 1, 3787},
{51, 0, 3572, 1, 3574},
{53, 0, 6215, 1, 6232},
{53, 1, 6221, 1, 6226},
{65, 0, 5279, 1, 5494},
{66, 0, 5279, 1, 5494},
{66, 1, 5285, 1, 5488},
{67, 0, 1850, 1, 1888},
{70, 0, 4993, 1, 5044},
{71, 0, 1547, 1, 1624},
{74, 0, 3692, 1, 3790},
{75, 0, 3584, 1, 3787},
{76, 0, 3572, 1, 3574},
{77, 1, 7711, 1, 8329},
{78, 1, 7711, 1, 8051},
{79, 1, 8480, 16, 8880},
{85, 0, 1826, 1, 1858},
{90, 1, 6252, 1, 6714},
{91, 0, 3572, 1, 3574},
{92, 0, 3584, 1, 3787},
{93, 0, 3572, 1, 3574},
{94, 0, 3584, 1, 3587},
{257, 3, 22388, 1, 22558},
{257, 4, 22390, 2, 22556},
{258, 3, 22257, 1, 22443},
{258, 4, 22258, 2, 22442},
{260, 3, 22995, 1, 23166},
{260, 4, 22996, 2, 23164},
{261, 3, 22446, 1, 22492},
{261, 4, 22446, 2, 22490},
};
extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency,
int32_t uplink_frequency_offset, uint32_t frame_type);
......@@ -960,8 +895,6 @@ void RCconfig_NR_L1(void)
}
}
static void check_ssb_raster(uint64_t freq, int band, int scs);
static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME)
{
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(*scc));
......@@ -1543,56 +1476,6 @@ void config_security(gNB_RRC_INST *rrc)
}
}
// Section 5.4.3 of 38.101-1 and -2
static void check_ssb_raster(uint64_t freq, int band, int scs)
{
int start_gscn = 0, step_gscn = 0, end_gscn = 0;
for (int i = 0; i < sizeof(sync_raster) / sizeof(sync_raster_t); i++) {
if (sync_raster[i].band == band &&
sync_raster[i].scs_index == scs) {
start_gscn = sync_raster[i].first_gscn;
step_gscn = sync_raster[i].step_gscn;
end_gscn = sync_raster[i].last_gscn;
break;
}
}
AssertFatal(start_gscn != 0, "Couldn't find band %d with SCS %d\n", band, scs);
int gscn;
if (freq < 3000000000) {
int N = 0;
int M = 0;
for (int k = 0; k < 3; k++) {
M = (k << 1) + 1;
if ((freq - M * 50000) % 1200000 == 0) {
N = (freq - M * 50000) / 1200000;
break;
}
}
AssertFatal(N != 0, "SSB frequency %lu Hz not on the synchronization raster (N * 1200kHz + M * 50 kHz)\n",
freq);
gscn = (3 * N) + (M - 3) / 2;
}
else if (freq < 24250000000) {
AssertFatal((freq - 3000000000) % 1440000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (3000 MHz + N * 1.44 MHz)\n",
freq);
gscn = ((freq - 3000000000) / 1440000) + 7499;
}
else {
AssertFatal((freq - 24250080000) % 17280000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (24250.08 MHz + N * 17.28 MHz)\n",
freq);
gscn = ((freq - 24250080000) / 17280000) + 22256;
}
AssertFatal(gscn >= start_gscn && gscn <= end_gscn,
"GSCN %d corresponding to SSB frequency %lu does not belong to GSCN range for band %d\n",
gscn, freq, band);
int rel_gscn = gscn - start_gscn;
AssertFatal(rel_gscn % step_gscn == 0,
"GSCN %d corresponding to SSB frequency %lu not in accordance with GSCN step for band %d\n",
gscn, freq, band);
}
void RCconfig_NRRRC(gNB_RRC_INST *rrc)
{
......
......@@ -1420,6 +1420,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
NR_UE_MAC_reset_cause_t cause)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
fapi_nr_synch_request_t sync_req = {.target_Nid_cell = -1, .ssb_bw_scan = true};
switch (cause) {
case GO_TO_IDLE:
reset_ra(mac, true);
......@@ -1427,7 +1428,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
nr_ue_init_mac(mac);
nr_ue_mac_default_configs(mac);
// new sync but no target cell id -> -1
nr_ue_send_synch_request(mac, module_id, 0, -1);
nr_ue_send_synch_request(mac, module_id, 0, &sync_req);
break;
case DETACH:
LOG_A(NR_MAC, "Received detach indication\n");
......@@ -1448,7 +1449,9 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
nr_ue_reset_sync_state(mac);
release_mac_configuration(mac, cause);
// new sync with old cell ID (re-establishment on the same cell)
nr_ue_send_synch_request(mac, module_id, 0, mac->physCellId);
sync_req.target_Nid_cell = mac->physCellId;
sync_req.ssb_bw_scan = false;
nr_ue_send_synch_request(mac, module_id, 0, &sync_req);
break;
default:
AssertFatal(false, "Invalid MAC reset cause %d\n", cause);
......
......@@ -295,7 +295,7 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind);
void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac);
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac);
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id);
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, const fapi_nr_synch_request_t *sync_req);
/**
* @brief Get UE sync state
......
......@@ -98,12 +98,12 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
mac->scheduling_info.prohibitPHR_Timer = NR_PHR_Config__phr_ProhibitTimer_sf10;
}
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id)
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, const fapi_nr_synch_request_t *sync_req)
{
// Sending to PHY a request to resync
mac->synch_request.Mod_id = module_id;
mac->synch_request.CC_id = cc_id;
mac->synch_request.synch_req.target_Nid_cell = cell_id;
mac->synch_request.synch_req = *sync_req;
mac->if_module->synch_request(&mac->synch_request);
}
......
......@@ -1038,6 +1038,7 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac,
mac->mib_ssb = ssb_index;
mac->physCellId = cell_id;
mac->mib_additional_bits = additional_bits;
mac->ssb_start_subcarrier = ssb_start_subcarrier;
if(ssb_length == 64)
mac->frequency_range = FR2;
else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment