Testing with amarisoft

master
ismagom 10 years ago
parent a96bb209b1
commit 5dc755f301

@ -220,6 +220,7 @@ void base_init() {
fprintf(stderr, "Error creating iFFT object\n");
exit(-1);
}
lte_fft_set_normalize(&ifft, true);
if (pbch_init(&pbch, cell)) {
fprintf(stderr, "Error creating PBCH object\n");
exit(-1);

@ -69,7 +69,8 @@ typedef struct {
float uhd_rx_freq;
float uhd_tx_freq;
float uhd_tx_freq_offset;
float uhd_gain;
float uhd_tx_gain;
float uhd_rx_gain;
}prog_args_t;
void args_default(prog_args_t *args) {
@ -81,13 +82,15 @@ void args_default(prog_args_t *args) {
args->uhd_rx_freq = 2112500000.0;
args->uhd_tx_freq = 1922500000.0;
args->uhd_tx_freq_offset = 8000000.0;
args->uhd_gain = 60.0;
args->uhd_tx_gain = 60.0;
args->uhd_rx_gain = 60.0;
}
void usage(prog_args_t *args, char *prog) {
printf("Usage: %s [agfFrlnv]\n", prog);
printf("\t-a UHD args [Default %s]\n", args->uhd_args);
printf("\t-g UHD TX/RX gain [Default %.2f dB]\n", args->uhd_gain);
printf("\t-g UHD TX/RX gain [Default %.2f dB]\n", args->uhd_rx_gain);
printf("\t-G UHD TX/RX gain [Default %.2f dB]\n", args->uhd_tx_gain);
printf("\t-f UHD RX freq [Default %.1f MHz]\n", args->uhd_rx_freq/1000000);
printf("\t-F UHD TX freq [Default %.1f MHz]\n", args->uhd_tx_freq/1000000);
printf("\t-r RNTI [Default 0x%x]\n",args->rnti);
@ -99,13 +102,16 @@ void usage(prog_args_t *args, char *prog) {
void parse_args(prog_args_t *args, int argc, char **argv) {
int opt;
args_default(args);
while ((opt = getopt(argc, argv, "agfFrlnv")) != -1) {
while ((opt = getopt(argc, argv, "agGfFrlnv")) != -1) {
switch (opt) {
case 'a':
args->uhd_args = argv[optind];
break;
case 'g':
args->uhd_gain = atof(argv[optind]);
args->uhd_rx_gain = atof(argv[optind]);
break;
case 'G':
args->uhd_tx_gain = atof(argv[optind]);
break;
case 'f':
args->uhd_rx_freq = atof(argv[optind]);
@ -175,7 +181,7 @@ cf_t *sf_buffer = NULL;
int generate_prach_sequences(){
for(int i=0;i<NOF_PRACH_SEQUENCES;i++){
if(prach_gen(&prach, i, 2, prach_buffers[i])){
if(prach_gen(&prach, i, 0, prach_buffers[i])){
fprintf(stderr, "Error generating prach sequence\n");
return -1;
}
@ -272,6 +278,8 @@ int rar_unpack(uint8_t *buffer, rar_msg_t *msg)
return(ret);
}
#define kk
#define use_usrp
int main(int argc, char **argv) {
int ret;
@ -288,10 +296,11 @@ int main(int argc, char **argv) {
timestamp_t uhd_time;
timestamp_t next_tx_time;
const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6, 0x00, 0x00, 0x00};
uint8_t data[100];
uint8_t data[500];
parse_args(&prog_args, argc, argv);
#ifdef use_usrp
printf("Opening UHD device...\n");
if (cuhd_open(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
@ -299,10 +308,10 @@ int main(int argc, char **argv) {
}
/* Set receiver gain */
cuhd_set_rx_gain(uhd, prog_args.uhd_gain);
cuhd_set_tx_gain(uhd, prog_args.uhd_gain);
//cuhd_set_tx_antenna(uhd, "TX/RX");
float x = cuhd_set_rx_gain(uhd, prog_args.uhd_rx_gain);
printf("Set RX gain to %.1f dB\n", x);
x = cuhd_set_tx_gain(uhd, prog_args.uhd_tx_gain);
printf("Set TX gain to %.1f dB\n", x);
/* set receiver frequency */
cuhd_set_rx_freq(uhd, (double) prog_args.uhd_rx_freq);
@ -312,6 +321,9 @@ int main(int argc, char **argv) {
cuhd_set_tx_freq_offset(uhd, prog_args.uhd_tx_freq, prog_args.uhd_tx_freq_offset);
printf("Tunning TX receiver to %.3f MHz\n", (double ) prog_args.uhd_tx_freq/1000000);
#endif
#ifdef kk
ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell);
if (ret < 0) {
fprintf(stderr, "Error searching for cell\n");
@ -320,7 +332,17 @@ int main(int argc, char **argv) {
printf("Cell not found\n");
exit(0);
}
#else
cell.id = 1;
cell.nof_ports = 1;
cell.nof_prb = 25;
cell.cp = CPNORM;
cell.phich_length = PHICH_NORM;
cell.phich_resources = R_1;
#endif
#ifdef use_usrp
/* set sampling frequency */
int srate = lte_sampling_freq_hz(cell.nof_prb);
if (srate != -1) {
@ -334,6 +356,8 @@ int main(int argc, char **argv) {
INFO("Stopping UHD and flushing buffer...\r",0);
cuhd_stop_rx_stream(uhd);
cuhd_flush_buffer(uhd);
#endif
if (ue_mib_init(&ue_mib, cell)) {
fprintf(stderr, "Error initaiting UE MIB decoder\n");
@ -364,6 +388,12 @@ int main(int argc, char **argv) {
refsignal_drms_pusch_cfg_t drms_cfg;
bzero(&drms_cfg, sizeof(refsignal_drms_pusch_cfg_t));
drms_cfg.beta_pusch = 1.0;
drms_cfg.group_hopping_en = false;
drms_cfg.sequence_hopping_en = false;
drms_cfg.common.delta_ss = 0;
drms_cfg.common.cyclic_shift = 0;
drms_cfg.common.cyclic_shift_for_drms = 0;
drms_cfg.common.en_drms_2 = false;
ue_ul_set_pusch_cfg(&ue_ul, &drms_cfg, &hop_cfg);
cf_t *ul_signal = vec_malloc(sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
@ -373,159 +403,228 @@ int main(int argc, char **argv) {
}
bzero(ul_signal, sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
state = DECODE_MIB;
if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper_timed, uhd)) {
fprintf(stderr, "Error initiating ue_sync\n");
exit(-1);
}
if (ue_dl_init(&ue_dl, cell)) {
fprintf(stderr, "Error initiating UE downlink processing module\n");
exit(-1);
}
/* Initialize subframe counter */
sf_cnt = 0;
// Register Ctrl+C handler
signal(SIGINT, sig_int_handler);
#ifdef use_usrp
if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper_timed, uhd)) {
fprintf(stderr, "Error initiating ue_sync\n");
exit(-1);
}
cuhd_start_rx_stream(uhd);
#endif
struct timeval tdata[3];
uint16_t ra_rnti;
#ifdef kk
// Register Ctrl+C handler
signal(SIGINT, sig_int_handler);
state = DECODE_MIB;
#else
state = RECV_RAR;
#endif
/* Main loop */
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
#ifdef kk
ret = ue_sync_get_buffer(&ue_sync, &sf_buffer);
if (ret < 0) {
fprintf(stderr, "Error calling ue_sync_work()\n");
}
#else
ret = 1;
timestamp_t rx_time, tx_time;
cf_t dummy[4];
#endif
/* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
if (ret == 1) {
switch (state) {
case DECODE_MIB:
if (ue_sync_get_sfidx(&ue_sync) == 0) {
pbch_decode_reset(&ue_mib.pbch);
n = ue_mib_decode(&ue_mib, sf_buffer, bch_payload_unpacked, NULL, &sfn_offset);
if (n < 0) {
fprintf(stderr, "Error decoding UE MIB\n");
exit(-1);
} else if (n == MIB_FOUND) {
bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN);
bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn);
printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
sfn = (sfn + sfn_offset)%1024;
state = SEND_PRACH;
}
}
break;
case SEND_PRACH:
if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) {
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
cfo_correct(&ue_sync.sfind.cfocorr,
prach_buffers[7], prach_buffers[7],
-ue_sync_get_cfo(&ue_sync) / lte_symbol_sz(cell.nof_prb));
timestamp_copy(&next_tx_time, &uhd_time);
timestamp_add(&next_tx_time, 0, 0.01); // send next frame (10 ms)
printf("Send prach sfn: %d. Last frame time = %.6f, send prach time = %.6f\n",
sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time));
cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len,
next_tx_time.full_secs, next_tx_time.frac_secs);
ra_rnti = 2;
rar_window_start = sfn+1;
rar_window_stop = sfn+3;
state = RECV_RAR;
}
break;
case RECV_RAR:
if ((sfn == rar_window_start && ue_sync_get_sfidx(&ue_sync) > 3) || sfn > rar_window_start) {
gettimeofday(&tdata[1], NULL);
printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync));
n = ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync), ra_rnti);
if (n < 0) {
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
} else if (n > 0) {
gettimeofday(&tdata[2], NULL);
get_time_interval(tdata);
printf("time exec DL: %d\n",tdata[0].tv_usec);
gettimeofday(&tdata[1], NULL);
rar_unpack(data_rx, &rar_msg);
rar_msg_fprint(stdout, &rar_msg);
dci_rar_to_ra_ul(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, cell.nof_prb, &ra_pusch);
ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb);
if (state != RECV_RAR) {
/* Run FFT for all subframe data */
lte_fft_run_sf(&ue_dl.fft, sf_buffer, ue_dl.sf_symbols);
ra_ul_alloc(&ra_pusch.prb_alloc, &ra_pusch, 0, cell.nof_prb);
uint32_t ul_sf_idx = (ue_sync_get_sfidx(&ue_sync)+6)%10;
//ue_ul_set_cfo(&ue_ul, sync_get_cfo(&ue_sync.strack));
bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs);
n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, rar_msg.temp_c_rnti, ul_signal);
/* Get channel estimates for each port */
chest_dl_estimate(&ue_dl.chest, ue_dl.sf_symbols, ue_dl.ce, ue_sync_get_sfidx(&ue_sync));
}
if (sf_cnt > 1000) {
switch (state) {
case DECODE_MIB:
if (ue_sync_get_sfidx(&ue_sync) == 0) {
pbch_decode_reset(&ue_mib.pbch);
n = ue_mib_decode(&ue_mib, sf_buffer, bch_payload_unpacked, NULL, &sfn_offset);
if (n < 0) {
fprintf(stderr, "Error encoding PUSCH\n");
fprintf(stderr, "Error decoding UE MIB\n");
exit(-1);
} else if (n == MIB_FOUND) {
bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN);
bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn);
printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
sfn = (sfn + sfn_offset)%1024;
state = SEND_PRACH;
}
gettimeofday(&tdata[2], NULL);
get_time_interval(tdata);
printf("time exec UL: %d\n",tdata[0].tv_usec);
gettimeofday(&tdata[1], NULL);
cuhd_stop_rx_stream(uhd);
cuhd_flush_buffer(uhd);
gettimeofday(&tdata[2], NULL);
get_time_interval(tdata);
printf("time to stop RX: %d\n",tdata[0].tv_usec);
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
}
break;
case SEND_PRACH:
uint32_t n_ta = lte_N_ta_new_rar(rar_msg.timing_adv_cmd);
printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta);
float time_adv_sec = ((float) n_ta)*LTE_TS;
vec_sc_prod_cfc(ul_signal, 2, ul_signal, SF_LEN_PRB(cell.nof_prb));
#ifdef kk
if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) {
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
timestamp_copy(&next_tx_time, &uhd_time);
timestamp_add(&next_tx_time, 0, 0.01); // send next frame (10 ms)
printf("Send prach sfn: %d. Last frame time = %.6f, send prach time = %.6f\n",
sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time));
cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len,
next_tx_time.full_secs, next_tx_time.frac_secs);
timestamp_copy(&next_tx_time, &uhd_time);
timestamp_add(&next_tx_time, 0, 0.006 - time_adv_sec); // send after 6 sub-frames (6 ms)
printf("Send %d samples PUSCH sfn: %d. Last frame time = %.6f"
"send PUSCH time = %.6f TA: %.1f us\n",
SF_LEN_PRB(cell.nof_prb), sfn, timestamp_real(&uhd_time),
timestamp_real(&next_tx_time), time_adv_sec*1000000);
cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb),
next_tx_time.full_secs, next_tx_time.frac_secs);
vec_save_file("prach_example_signal", ul_signal, sizeof(cf_t)*7680);
go_exit = 1;
ra_rnti = 2;
rar_window_start = sfn+1;
rar_window_stop = sfn+3;
state = RECV_RAR;
}
if (sfn >= rar_window_stop) {
state = SEND_PRACH;
rar_trials++;
if (rar_trials >= 4) {
#else
cuhd_recv_with_time(uhd, dummy, 4, 1, &rx_time.full_secs, &rx_time.frac_secs);
timestamp_copy(&tx_time, &rx_time);
printf("Transmitting PRACH...\n");
vec_save_file("prach_tx", prach_buffers[7], prach_buffer_len*sizeof(cf_t));
while(1) {
timestamp_add(&tx_time, 0, 0.001); // send every (10 ms)
cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len,
tx_time.full_secs, tx_time.frac_secs);
}
#endif
break;
case RECV_RAR:
#ifdef kk
if ((sfn == rar_window_start && ue_sync_get_sfidx(&ue_sync) > 3) || sfn > rar_window_start) {
printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync));
n = ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync), ra_rnti);
if (n < 0) {
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
} else if (n > 0) {
cuhd_stop_rx_stream(uhd);
cuhd_flush_buffer(uhd);
rar_unpack(data_rx, &rar_msg);
rar_msg_fprint(stdout, &rar_msg);
dci_rar_to_ra_ul(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, cell.nof_prb, &ra_pusch);
ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb);
ra_ul_alloc(&ra_pusch.prb_alloc, &ra_pusch, 0, cell.nof_prb);
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs);
uint32_t n_ta = lte_N_ta_new_rar(rar_msg.timing_adv_cmd);
printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta);
float time_adv_sec = ((float) n_ta+15)/(15000.0*lte_symbol_sz(cell.nof_prb));
#define N_TX 5
const uint32_t rv[N_TX]={0,2,3,1,0};
for (int i=0; i<N_TX;i++) {
ra_pusch.rv_idx = rv[i];
uint32_t ul_sf_idx = (ue_sync_get_sfidx(&ue_sync)+6+i*8)%10;
n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, rar_msg.temp_c_rnti, ul_signal);
if (n < 0) {
fprintf(stderr, "Error encoding PUSCH\n");
exit(-1);
}
vec_sc_prod_cfc(ul_signal, 1.5, ul_signal, SF_LEN_PRB(cell.nof_prb));
/*
for (int i=0;i<7680;i++) {
if (i < 100) {
ul_signal[i] = 0;
} else {
ul_signal[i] = 0.5*cexpf(-I*2*M_PI*0.1*(float) i);
}
}
*/
vec_save_file("pusch_tx", ul_signal, sizeof(cf_t)*SF_LEN_PRB(cell.nof_prb));
timestamp_copy(&next_tx_time, &uhd_time);
timestamp_add(&next_tx_time, 0, 0.006 + i*0.008 - time_adv_sec); // send after 6 sub-frames (6 ms)
printf("Send %d samples PUSCH sfn: %d. RV_idx=%d, Last frame time = %.6f "
"send PUSCH time = %.6f TA: %.1f us\n",
SF_LEN_PRB(cell.nof_prb), sfn, ra_pusch.rv_idx,
timestamp_real(&uhd_time),
timestamp_real(&next_tx_time), time_adv_sec*1000000);
cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb),
next_tx_time.full_secs, next_tx_time.frac_secs);
}
go_exit = 1;
}
}
}
break;
}
if (ue_sync_get_sfidx(&ue_sync) == 9) {
sfn++;
if (sfn == 1024) {
sfn = 0;
}
}
if (sfn >= rar_window_stop) {
state = SEND_PRACH;
rar_trials++;
if (rar_trials >= 1) {
go_exit = 1;
}
}
}
#else
ra_pusch.mcs.mod = LTE_QPSK;
ra_pusch.mcs.tbs = 94;
ra_pusch.rv_idx = 0;
ra_pusch.prb_alloc.freq_hopping = 0;
ra_pusch.prb_alloc.L_prb = 4;
ra_pusch.prb_alloc.n_prb[0] = 19;
ra_pusch.prb_alloc.n_prb[1] = 19;
uint32_t ul_sf_idx = 4;
printf("L: %d\n", ra_pusch.prb_alloc.L_prb);
// ue_ul_set_cfo(&ue_ul, sync_get_cfo(&ue_sync.strack));
bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs);
n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, 111, ul_signal);
if (n < 0) {
fprintf(stderr, "Error encoding PUSCH\n");
exit(-1);
}
vec_save_file("pusch_tx", ul_signal, SF_LEN_PRB(cell.nof_prb)*sizeof(cf_t));
#ifdef use_usrp
cuhd_recv_with_time(uhd, dummy, 4, 1, &uhd_time.full_secs, &uhd_time.frac_secs);
timestamp_copy(&next_tx_time, &uhd_time);
while(1) {
timestamp_add(&next_tx_time, 0, 0.002); // send every 2 ms
cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb),
next_tx_time.full_secs, next_tx_time.frac_secs);
}
#else
exit(-1);
#endif
#endif
break;
}
if (ue_sync_get_sfidx(&ue_sync) == 9) {
sfn++;
if (sfn == 1024) {
sfn = 0;
}
}
}
} else if (ret == 0) {
printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r",
sync_get_peak_value(&ue_sync.sfind),

@ -37,8 +37,6 @@
#include "liblte/phy/common/phy_common.h"
#include "liblte/phy/utils/dft.h"
#define LTE_FFT_NORMALIZE
typedef _Complex float cf_t; /* this is only a shortcut */
/* This is common for both directions */
@ -87,4 +85,7 @@ LIBLTE_API void lte_ifft_run_sf(lte_fft_t *q,
LIBLTE_API int lte_fft_set_freq_shift(lte_fft_t *q,
float freq_shift);
LIBLTE_API void lte_fft_set_normalize(lte_fft_t *q,
bool normalize_enable);
#endif

@ -54,6 +54,8 @@ typedef struct LIBLTE_API {
cfo_t cfo;
lte_cell_t cell;
bool normalize_en;
float current_cfo;
refsignal_drms_pusch_cfg_t pusch_drms_cfg;
@ -77,6 +79,9 @@ LIBLTE_API void ue_ul_free(ue_ul_t *q);
LIBLTE_API void ue_ul_set_cfo(ue_ul_t *q,
float cur_cfo);
LIBLTE_API void ue_ul_set_normalization(ue_ul_t *q,
bool enabled);
LIBLTE_API void ue_ul_set_pusch_cfg(ue_ul_t *q,
refsignal_drms_pusch_cfg_t *pusch_drms_cfg,
pusch_hopping_cfg_t *pusch_hopping_cfg);

@ -129,7 +129,7 @@ int chest_dl_init(chest_dl_t *q, lte_cell_t cell)
float f[5]={0.05, 0.2, 0.5, 0.2, 0.05};
chest_dl_set_filter_freq(q, f, 5);
float t[2]={0.2, 0.8};
float t[2]={0.1, 0.9};
chest_dl_set_filter_time(q, t, 0);
q->cell = cell;

@ -287,8 +287,8 @@ int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg,
if (verbose == VERBOSE_DEBUG) {
uint32_t N_sz = largest_prime_lower_than(nof_prb*RE_X_RB);
DEBUG("Generating PUSCH DRMS sequence with parameters:\n",0);
DEBUG("\tnof_prb: %d, u: %d, v: %d, alpha: %f, N_sc: %d, root q: %d\n",
nof_prb, u, v, alpha, N_sz, get_q(u,v,N_sz));
DEBUG("\tbeta: %.1f, nof_prb: %d, u: %d, v: %d, alpha: %f, N_sc: %d, root q: %d, nprs: %d\n",
cfg->beta_pusch, nof_prb, u, v, alpha, N_sz, get_q(u,v,N_sz),q->n_prs_pusch[cfg->common.delta_ss][ns]);
}
// Do complex exponential and adjust amplitude

@ -182,6 +182,10 @@ void lte_ifft_run_slot(lte_fft_t *q, cf_t *input, cf_t *output) {
}
}
void lte_fft_set_normalize(lte_fft_t *q, bool normalize_enable) {
dft_plan_set_norm(&q->fft_plan, normalize_enable);
}
void lte_ifft_run_sf(lte_fft_t *q, cf_t *input, cf_t *output) {
uint32_t n;
for (n=0;n<2;n++) {
@ -190,7 +194,4 @@ void lte_ifft_run_sf(lte_fft_t *q, cf_t *input, cf_t *output) {
if (q->freq_shift) {
vec_prod_ccc(output, q->shift_buffer, output, 2*q->slot_sz);
}
#ifdef LTE_FFT_NORMALIZE
vec_sc_prod_cfc(output, (float) 1.0/sqrtf(q->symbol_sz),output,2*q->slot_sz);
#endif
}

@ -130,7 +130,7 @@ float pcfich_cfi_decode(pcfich_t *q, uint32_t *cfi) {
float max_corr = 0;
for (i = 0; i < 3; i++) {
float corr = vec_dot_prod_fff(q->cfi_table_float[i], q->data_f, PCFICH_CFI_LEN);
float corr = fabsf(vec_dot_prod_fff(q->cfi_table_float[i], q->data_f, PCFICH_CFI_LEN));
if (corr > max_corr) {
max_corr = corr;
index = i;

@ -399,9 +399,9 @@ int prach_gen(prach_t *p,
for(int i=0;i<p->N_seq;i++){
signal[p->N_cp+i] = p->ifft_out[i%p->N_ifft_prach];
}
// Normalize
vec_sc_prod_cfc(signal, 1.0/sqrtf(p->N_ifft_ul), signal, (p->N_cp + p->N_seq));
vec_sc_prod_cfc(signal, 1.0/sqrtf(p->N_ifft_prach*2), signal, (p->N_cp + p->N_seq));
ret = LIBLTE_SUCCESS;
}

@ -122,7 +122,8 @@ int pusch_cp(pusch_t *q, harq_t *harq, cf_t *input, cf_t *output, bool advance_i
n_prb_tilde = (n_vrb_tilde+f_hop(q, hopping, i)*n_rb_sb+
(n_rb_sb-1)-2*(n_vrb_tilde%n_rb_sb)*f_m(q, hopping, i))%(n_rb_sb*hopping->n_sb);
INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d\n", n_prb_tilde, n_vrb_tilde, n_rb_sb, hopping->n_sb);
INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d\n",
n_prb_tilde, n_vrb_tilde, n_rb_sb, hopping->n_sb);
if (hopping->n_sb > 1) {
n_prb_tilde += (hopping->hopping_offset-1)/2+1;
}

@ -198,8 +198,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
bzero(scfdma, sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
lte_fft_t fft;
lte_ifft_init(&fft, CPNORM, cell.nof_prb);
lte_fft_set_normalize(&fft, true);
lte_fft_set_freq_shift(&fft, 0.5);
lte_ifft_run_sf(&fft, sf_symbols, scfdma);
// Matlab toolbox expects further normalization
vec_sc_prod_cfc(scfdma, 1.0/sqrtf(512), scfdma, SF_LEN_PRB(cell.nof_prb));
if (nlhs >= 1) {
mexutils_write_cf(scfdma, &plhs[0], SF_LEN_PRB(cell.nof_prb), 1);

@ -188,7 +188,7 @@ int ue_dl_decode_fft_estimate(ue_dl_t *q, cf_t *input, uint32_t sf_idx, uint32_t
return LIBLTE_ERROR;
}
INFO("Decoded CFI=%d with correlation %.2f\n", cfi, cfi_corr);
INFO("Decoded CFI=%d with correlation %.2f\n", *cfi, cfi_corr);
if (regs_set_cfi(&q->regs, *cfi)) {
fprintf(stderr, "Error setting CFI\n");
@ -285,11 +285,12 @@ int ue_dl_decode_rnti_rv(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx
formats = ue_formats;
nof_formats = nof_ue_formats;
}
/* For all possible locations, try to decode a DCI message */
crc_rem = 0;
uint32_t found_dci = 0;
for (int f=0;f<nof_formats && !found_dci;f++) {
INFO("Trying format %s\n", dci_format_string(formats[f]));
for (i=0;i<nof_locations && !found_dci;i++) {
if (pdcch_decode_msg(&q->pdcch, &dci_msg, &locations[i], formats[f], &crc_rem)) {
fprintf(stderr, "Error decoding DCI msg\n");

@ -57,6 +57,9 @@ int ue_ul_init(ue_ul_t *q,
goto clean_exit;
}
lte_fft_set_freq_shift(&q->fft, 0.5);
lte_fft_set_normalize(&q->fft, true);
q->normalize_en = true;
if (cfo_init(&q->cfo, CURRENT_SFLEN)) {
fprintf(stderr, "Error creating CFO object\n");
@ -125,6 +128,11 @@ void ue_ul_set_cfo(ue_ul_t *q, float cur_cfo) {
q->current_cfo = cur_cfo;
}
void ue_ul_set_normalization(ue_ul_t *q, bool enabled)
{
q->normalize_en = enabled;
}
/* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while
* to execute, so shall be called once the final C-RNTI has been allocated for the session.
* For the connection procedure, use pusch_encode_rnti() or pusch_decode_rnti() functions
@ -194,17 +202,26 @@ int ue_ul_pusch_uci_encode_rnti(ue_ul_t *q, ra_pusch_t *ra_ul, uint8_t *data, uc
for (uint32_t i=0;i<2;i++) {
// FIXME: Pregenerate for all possible number of prb
if (refsignal_dmrs_pusch_gen(&q->drms, &q->pusch_drms_cfg, ra_ul->prb_alloc.L_prb, 2*sf_idx+i, q->refsignal)) {
if (refsignal_dmrs_pusch_gen(&q->drms, &q->pusch_drms_cfg,
q->harq_process[0].ul_alloc.L_prb, 2*sf_idx+i, q->refsignal))
{
fprintf(stderr, "Error generating PUSCH DRMS signals\n");
return ret;
}
refsignal_drms_pusch_put(&q->drms, &q->pusch_drms_cfg, q->refsignal, i,
ra_ul->prb_alloc.L_prb, ra_ul->prb_alloc.n_prb_tilde[i], q->sf_symbols);
q->harq_process[0].ul_alloc.L_prb,
q->harq_process[0].ul_alloc.n_prb_tilde[i],
q->sf_symbols);
}
lte_ifft_run_sf(&q->fft, q->sf_symbols, output_signal);
cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / lte_symbol_sz(q->cell.nof_prb));
//cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / lte_symbol_sz(q->cell.nof_prb));
if (q->normalize_en) {
float norm_factor = (float) q->cell.nof_prb/10/sqrtf(q->harq_process[0].ul_alloc.L_prb);
vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SF_LEN_PRB(q->cell.nof_prb));
}
ret = LIBLTE_SUCCESS;
}

@ -6,9 +6,9 @@ addpath('../../debug/lte/phy/lib/ch_estimation/test')
Hopping={'Off','Sequence','Group'};
k=1;
for prb=3
for ncell=0
for ns=8:9
for prb=4
for ncell=1
for ns=4
for h=1
for sg=0
for cs=0
@ -20,7 +20,7 @@ for prb=3
ueConfig.SeqGroup=sg;
ueConfig.CyclicShift=cs;
puschConfig.PRBSet=(0:(prb-1))';
puschConfig.PRBSet=(19:22)';
puschConfig.DynCyclicShift=ds;
[mat, info]=ltePUSCHDRS(ueConfig,puschConfig);

@ -0,0 +1,11 @@
ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',122,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',(19:22)','Modulation','QPSK','RV',0,'Shortened',0);
subframe_rx=lteSCFDMADemodulate(ueConfig,x.*transpose(exp(-1i*2*pi*0.04*(1:length(x))/512)));
idx=ltePUSCHIndices(ueConfig,puschConfig);
pusch_rx=subframe_rx(idx);
[hest, noiseest] = lteULChannelEstimate(ueConfig,puschConfig,subframe_rx);
ce=hest(idx);
[cws,symbols] = ltePUSCHDecode(ueConfig,puschConfig,pusch_rx,ce,noiseest);
[trblkout,blkcrc,stateout] = lteULSCHDecode(ueConfig,puschConfig,88,cws);
disp(blkcrc)

@ -1,6 +1,6 @@
clear
ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[0:2]','Modulation','QPSK','RV',0,'Shortened',0);
ueConfig=struct('NCellID',0,'NULRB',6,'NSubframe',5,'RNTI',79,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[1:4]','Modulation','QPSK','RV',0,'Shortened',0);
addpath('../../debug/lte/phy/lib/phch/test')
@ -10,7 +10,7 @@ addpath('../../debug/lte/phy/lib/phch/test')
% rvs=0;
% betas=0:3:11;
TBs=56;
TBs=88;
cqilen=0;
mods={'QPSK'};
rvs=0;

@ -0,0 +1,32 @@
clear
ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Modulation','QPSK','RV',0,'Shortened',0);
addpath('../../debug/lte/phy/lib/phch/test')
NULRB=[6 15 25 50 100];
Peak=[];
k=1;
for r=1:length(NULRB)
fprintf('NULRB: %d\n',NULRB(r));
for l=1:NULRB(r)
trblkin=randi(2,l*5,1)-1;
ueConfig.NULRB=NULRB(r);
puschConfig.PRBSet=(0:(l-1))';
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin);
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
idx=ltePUSCHIndices(ueConfig,puschConfig);
subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(idx)=cw_mat;
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0);
waveform = waveform*sqrt(512)/sqrt(l)*NULRB(r)/10;
Peak(k)=max(max(abs(real(waveform))),max(abs(imag(waveform))));
k=k+1;
end
end
plot(Peak(:)')
Loading…
Cancel
Save