Fixed PRS sequence generation

master
ismagom 11 years ago
parent c328a29e39
commit 893cab84f1

@ -28,9 +28,6 @@ target_link_libraries(equalizer_test ${LIBRARIES})
add_executable(viterbi_test viterbi_test.c)
target_link_libraries(viterbi_test ${LIBRARIES})
add_executable(bch_test bch_test.c)
target_link_libraries(bch_test ${LIBRARIES})
add_executable(cell_search cell_search.c)
target_link_libraries(cell_search ${LIBRARIES})

@ -1,130 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include "lte.h"
char *input_file_name;
int frame_length=1920, symbol_sz=128, nof_slots=1;
void usage(char *prog) {
printf("Usage: %s [ls] -i input_file\n", prog);
printf("\t-l frame_length [Default %d]\n", frame_length);
printf("\t-s symbol_sz [Default %d]\n", symbol_sz);
printf("\t-n nof_frames [Default %d]\n", nof_slots);
printf("\t-v [set verbose to debug, default none]\n");
}
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "ilsnv")) != -1) {
switch(opt) {
case 'i':
input_file_name = argv[optind];
break;
case 'l':
frame_length = atoi(argv[optind]);
break;
case 's':
symbol_sz = atoi(argv[optind]);
break;
case 'n':
nof_slots = atoi(argv[optind]);
break;
case 'v':
verbose++;
break;
default:
usage(argv[0]);
exit(-1);
}
}
if (!input_file_name) {
usage(argv[0]);
exit(-1);
}
}
void fft_run_slot(dft_plan_t *fft_plan, cf_t *input, cf_t *output) {
int i;
for (i=0;i<7;i++) {
input += CP_NORM(i, symbol_sz);
dft_run_c2c(fft_plan, input, output);
input += symbol_sz;
output += symbol_sz;
}
}
int main(int argc, char **argv) {
filesource_t fsrc;
pbch_mib_t pbch_data;
pbch_t pbch;
dft_plan_t fft_plan;
int frame_cnt;
cf_t *input, *outfft;
if (argc < 3) {
usage(argv[0]);
exit(-1);
}
parse_args(argc,argv);
if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT)) {
fprintf(stderr, "Error opening file %s\n", input_file_name);
exit(-1);
}
input = malloc(frame_length*sizeof(cf_t));
if (!input) {
perror("malloc");
exit(-1);
}
outfft = malloc(7*symbol_sz*sizeof(cf_t));
if (!outfft) {
perror("malloc");
exit(-1);
}
/* Init FFT plan */
if (dft_plan_c2c(symbol_sz, FORWARD, &fft_plan)) {
fprintf(stderr, "Error initiating FFT plan\n");
exit(-1);
}
fft_plan.options = DFT_DC_OFFSET | DFT_MIRROR_POS | DFT_NORMALIZE;
if (pbch_init(&pbch, 0, CPNORM)) {
fprintf(stderr, "Error initiating PBCH\n");
exit(-1);
}
int res = 0;
frame_cnt = 0;
while (frame_length == filesource_read(&fsrc, input, frame_length)
&& frame_cnt < nof_slots
&& res == 0) {
fft_run_slot(&fft_plan, &input[960], outfft);
res = pbch_decode(&pbch, outfft, &pbch_data, 6, 1);
if (res == -1) {
fprintf(stderr, "Error decoding PBCH\n");
break;
}
frame_cnt++;
}
if (res == 1) {
printf("MIB found\n");
} else {
printf("MIB not found after %d frames\n", frame_cnt);
}
pbch_free(&pbch);
free(input);
free(outfft);
printf("Done\n");
exit(0);
}

@ -8,16 +8,18 @@
char *input_file_name = NULL;
int nof_slots=100;
float corr_peak_threshold=2.5;
int ntime = 4;
int nfreq = 10;
float corr_peak_threshold=15;
int file_binary = 0;
int force_N_id_2=-1;
int nof_ports = 1;
#define FLEN 9600
filesource_t fsrc;
cf_t *input_buffer, *fft_buffer;
cf_t *input_buffer, *fft_buffer, *ce[MAX_PORTS];
pbch_t pbch;
dft_plan_t fft_plan;
lte_fft_t fft;
chest_t chest;
sync_t synch;
@ -64,29 +66,43 @@ void parse_args(int argc, char **argv) {
}
int base_init() {
int i;
file_data_type_t type = file_binary?COMPLEX_FLOAT_BIN:COMPLEX_FLOAT;
if (filesource_init(&fsrc, input_file_name, type)) {
fprintf(stderr, "Error opening file %s\n", input_file_name);
exit(-1);
}
input_buffer = malloc(4 * 960 * sizeof(cf_t));
input_buffer = malloc(4 * FLEN * sizeof(cf_t));
if (!input_buffer) {
perror("malloc");
exit(-1);
}
fft_buffer = malloc(CPNORM_NSYMB * 128 * sizeof(cf_t));
fft_buffer = malloc(CPNORM_NSYMB * 72 * sizeof(cf_t));
if (!fft_buffer) {
perror("malloc");
return -1;
}
/* Init FFT plan */
if (dft_plan_c2c(128, FORWARD, &fft_plan)) {
fprintf(stderr, "Error initiating FFT plan\n");
for (i=0;i<nof_ports;i++) {
ce[i] = malloc(CPNORM_NSYMB * 72 * sizeof(cf_t));
if (!ce[i]) {
perror("malloc");
return -1;
}
}
if (chest_init(&chest, CPNORM, 6, 1)) {
fprintf(stderr, "Error initializing equalizer\n");
return -1;
}
if (lte_fft_init(&fft, CPNORM, 6)) {
fprintf(stderr, "Error initializing FFT\n");
return -1;
}
fft_plan.options = DFT_DC_OFFSET | DFT_MIRROR_POS | DFT_NORMALIZE;
DEBUG("Memory init OK\n",0);
return 0;
@ -96,14 +112,10 @@ int base_init() {
int mib_decoder_init(int cell_id) {
/*
if (chest_LTEDL_init(&chest, ntime, nfreq, CPNORM_NSYMB, cell_id, 6)) {
fprintf(stderr, "Error initiating LTE equalizer\n");
if (chest_ref_LTEDL(&chest, cell_id)) {
fprintf(stderr, "Error initializing reference signal\n");
return -1;
}
*/
DEBUG("Channel estimation initiated ntime=%d nfreq=%d\n", ntime, nfreq);
if (pbch_init(&pbch, cell_id, CPNORM)) {
fprintf(stderr, "Error initiating PBCH\n");
@ -113,21 +125,17 @@ int mib_decoder_init(int cell_id) {
return 0;
}
void fft_run_slot(dft_plan_t *fft_plan, cf_t *input, cf_t *output) {
int mib_decoder_run(cf_t *input, pbch_mib_t *mib) {
int i;
for (i=0;i<CPNORM_NSYMB;i++) {
DEBUG("Running FFT %d\n", i);
input += CP_NORM(i, 128);
dft_run_c2c(fft_plan, input, output);
input += 128;
output += 128;
lte_fft_run(&fft, input, fft_buffer);
/* Get channel estimates for each port */
for (i=0;i<nof_ports;i++) {
chest_ce_slot_port(&chest, fft_buffer, ce[i], 1, 0);
}
}
int mib_decoder_run(cf_t *input, pbch_mib_t *mib) {
fft_run_slot(&fft_plan, input, fft_buffer);
DEBUG("Decoding PBCH\n", 0);
return pbch_decode(&pbch, fft_buffer, mib, 6, 1);
return pbch_decode(&pbch, fft_buffer, ce, nof_ports, 6, 1, mib);
}
int get_samples(int length, int offset) {
@ -155,7 +163,7 @@ enum radio_state { DONE, SYNC, MIB};
int main(int argc, char **argv) {
enum radio_state state;
int sf_size, slot_start;
int read_length, slot_idx;
int read_length, frame_idx;
int mib_attempts;
pbch_mib_t mib;
int cell_id;
@ -176,19 +184,20 @@ int main(int argc, char **argv) {
exit(-1);
}
if (sync_init(&synch, 960)) {
if (sync_init(&synch, FLEN)) {
fprintf(stderr, "Error initiating PSS/SSS\n");
exit(-1);
}
sync_force_N_id_2(&synch, force_N_id_2);
sync_set_threshold(&synch, corr_peak_threshold);
sync_pss_det_peakmean(&synch);
state = SYNC;
sf_size = 960;
sf_size = FLEN;
read_length = sf_size;
slot_start = 0;
slot_idx = 0;
frame_idx = 0;
mib_attempts = 0;
frame_cnt = -1;
read_offset = 0;
@ -203,39 +212,39 @@ int main(int argc, char **argv) {
}
if (read_length) {
frame_cnt++;
INFO("\n\tSlot idx=%d\n\n", slot_idx);
INFO("\nFrame idx=%d\n\n", frame_idx);
INFO("Correcting CFO=%.4f\n", cfo);
nco_cexp_f_direct(&input_buffer[read_offset], -cfo/128, read_length);
}
switch(state) {
case SYNC:
INFO("State Sync, Slot idx=%d\n", slot_idx);
INFO("State Sync, Slot idx=%d\n", frame_idx);
idx = sync_run(&synch, input_buffer, read_offset);
if (idx != -1) {
slot_start = read_offset + idx;
read_length = idx;
read_offset += 960;
read_offset += FLEN;
cell_id = sync_get_cell_id(&synch);
cfo = sync_get_cfo(&synch);
slot_idx = sync_get_slot_id(&synch);
frame_idx = sync_get_slot_id(&synch)?1:0;
state = MIB;
if (mib_decoder_init(cell_id)) {
fprintf(stderr, "Error initiating MIB decoder\n");
exit(-1);
}
INFO("SYNC done, cell_id=%d slot_start=%d\n", cell_id, slot_start);
INFO("SYNC done, cell_id=%d slot_start=%d frame_idx=%d\n", cell_id, slot_start, frame_idx);
} else {
read_offset = 960;
memcpy(input_buffer, &input_buffer[960], 960 * sizeof(cf_t));
read_offset = FLEN;
memcpy(input_buffer, &input_buffer[FLEN], FLEN * sizeof(cf_t));
}
break;
case MIB:
read_length = 960;
read_length = FLEN;
read_offset = slot_start;
INFO("State MIB, Slot idx=%d\n", slot_idx);
if (slot_idx == 1) {
INFO("State MIB, frame idx=%d\n", frame_idx);
if (frame_idx == 0) {
INFO("Trying to find MIB offset %d\n", slot_start);
if (mib_decoder_run(&input_buffer[slot_start], &mib)) {
if (mib_decoder_run(&input_buffer[slot_start+FLEN/10], &mib)) {
INFO("MIB detected attempt=%d\n", mib_attempts);
state = DONE;
} else {
@ -248,16 +257,16 @@ int main(int argc, char **argv) {
}
break;
case DONE:
INFO("State Done, Slot idx=%d\n", slot_idx);
INFO("State Done, Slot idx=%d\n", frame_idx);
pbch_mib_fprint(stdout, &mib);
printf("Done\n");
break;
}
if (read_length) {
slot_idx++;
if (slot_idx == 20) {
slot_idx = 0;
frame_idx++;
if (frame_idx == 2) {
frame_idx = 0;
}
}
}

@ -120,7 +120,7 @@ int main(int argc, char **argv) {
goto do_exit;
}
if (lte_fft_init(&fft, cp, lte_symbol_sz(nof_prb))) {
if (lte_fft_init(&fft, cp, nof_prb)) {
fprintf(stderr, "Error: initializing FFT\n");
goto do_exit;
}
@ -142,11 +142,19 @@ int main(int argc, char **argv) {
while (in_slot_length() == filesource_read(&fsrc, input, in_slot_length())
&& (slot_cnt < nof_slots || nof_slots == -1)) {
fprintf(f, "infft=");
vec_fprint_c(f, input, CP_NSYMB(cp) * 128);
fprintf(f, ";\n");
lte_fft_run(&fft, input, outfft);
chest_ce_slot_port(&eq, outfft, ce, slot_cnt%20, 0);
fprintf(f, "outfft=");
vec_fprint_c(f, outfft, CP_NSYMB(cp) * nof_prb * RE_X_RB);
fprintf(f, ";\n");
chest_ce_slot_port(&eq, outfft, ce, 0, 0);
//chest_fprint(&eq, f, slot_cnt%20, 0);
chest_fprint(&eq, f, slot_cnt%20, 0);
for (i=0;i<CP_NSYMB(cp);i++) {
fprintf(f, "ce(%d,:)=", slot_cnt * CP_NSYMB(cp) + i + 1);

@ -39,7 +39,6 @@ typedef struct {
int nof_ports;
int nof_symbols;
int nof_prb;
int symbol_sz;
lte_cp_t cp;
refsignal_t refsignal[MAX_PORTS][NSLOTS_X_FRAME];
}chest_t;

@ -65,7 +65,7 @@ typedef enum {CPNORM, CPEXT} lte_cp_t;
#define GUARD_RE(nof_prb) ((lte_symbol_sz(nof_prb)-nof_prb*RE_X_RB)/2)
#define SAMPLE_IDX(symbol_sz, symbol_idx, sample_idx) (symbol_idx*symbol_sz + sample_idx)
#define SAMPLE_IDX(nof_prb, symbol_idx, sample_idx) (symbol_idx*nof_prb*RE_X_RB + sample_idx)
const int lte_symbol_sz(int nof_prb);
int lte_re_x_prb(int ns, int symbol, int nof_ports, int nof_symbols);

@ -33,14 +33,17 @@ typedef struct {
dft_plan_t fft_plan;
int nof_symbols;
int symbol_sz;
int nof_guards;
int nof_re;
lte_cp_t cp_type;
cf_t *tmp; // for removing zero padding
}lte_fft_t;
int lte_fft_init(lte_fft_t *q, lte_cp_t cp_type, int symbol_sz);
int lte_fft_init(lte_fft_t *q, lte_cp_t cp_type, int nof_prb);
void lte_fft_free(lte_fft_t *q);
void lte_fft_run(lte_fft_t *q, cf_t *input, cf_t *output);
int lte_ifft_init(lte_fft_t *q, lte_cp_t cp_type, int symbol_sz);
int lte_ifft_init(lte_fft_t *q, lte_cp_t cp_type, int nof_prb);
void lte_ifft_free(lte_fft_t *q);
void lte_ifft_run(lte_fft_t *q, cf_t *input, cf_t *output);

@ -67,7 +67,7 @@ typedef struct {
int pbch_init(pbch_t *q, int cell_id, lte_cp_t cp);
void pbch_free(pbch_t *q);
int pbch_decode(pbch_t *q, cf_t *slot1_symbols, pbch_mib_t *data, int nof_prb, float ebno);
int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t **ce, int nof_ports, int nof_prb, float ebno, pbch_mib_t *data);
void pbch_mib_fprint(FILE *stream, pbch_mib_t *mib);

@ -77,8 +77,12 @@ void chest_ce_ref(chest_t *q, cf_t *input, int nslot, int port_id, int nref) {
fidx = q->refsignal[port_id][nslot].refs[nref].freq_idx; // reference frequency index
tidx = q->refsignal[port_id][nslot].refs[nref].time_idx; // reference time index
known_ref = q->refsignal[port_id][nslot].refs[nref].simbol;
channel_ref = input[SAMPLE_IDX(q->symbol_sz, tidx, fidx)];
channel_ref = input[SAMPLE_IDX(q->nof_prb, tidx, fidx)];
q->refsignal[port_id][nslot].refs[nref].recv_simbol = channel_ref;
DEBUG("Reference %d pos (%d,%d)=%d %.2f/%.2f=%.2f %.2f/%.2f=%.2f\n", nref, tidx, fidx, SAMPLE_IDX(q->nof_prb, tidx, fidx),
cabsf(channel_ref),cabsf(known_ref),cabsf(channel_ref/known_ref),
cargf(channel_ref)/M_PI,cargf(known_ref)/M_PI,cargf(channel_ref/known_ref)/M_PI);
/* FIXME: compare with treshold */
if (channel_ref != 0) {
q->refsignal[port_id][nslot].ch_est[nref] = channel_ref/known_ref;
@ -147,12 +151,11 @@ int chest_init(chest_t *q, lte_cp_t cp, int nof_prb, int nof_ports) {
q->nof_ports = nof_ports;
q->nof_symbols = CP_NSYMB(cp);
q->symbol_sz = lte_symbol_sz(nof_prb);
q->cp = cp;
q->nof_prb = nof_prb;
INFO("Initializing channel estimator size %dx%d nof_prb=%d, nof_ports=%d\n",
q->nof_symbols, q->symbol_sz, nof_prb, nof_ports);
INFO("Initializing channel estimator size %dx%d, nof_ports=%d\n",
q->nof_symbols, nof_prb, nof_ports);
return 0;
}
@ -165,8 +168,6 @@ int chest_ref_LTEDL_slot_port(chest_t *q, int port, int nslot, int cell_id) {
return -1;
}
INFO("Setting LTE DL reference signals port=%d, nslot=%d, cell_id=%d\n", port, nslot, cell_id);
if (refsignal_init_LTEDL(&q->refsignal[port][nslot], port, nslot, cell_id, q->cp, q->nof_prb)) {
fprintf(stderr, "Error initiating CRS port=%d, slot=%d\n", port, nslot);
return -1;

@ -20,6 +20,7 @@
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <complex.h>
#include "lte/base.h"
#include "ch_estimation/refsignal.h"
@ -110,9 +111,6 @@ int refsignal_init_LTEDL(refsignal_t *q, int port_id, int nslot,
memcpy(q->symbols_ref, lp, sizeof(int) * nof_ref_symbols);
DEBUG("Initializing %d CRS for LTE DL slot=%d, %d RE in %d symbols\n",
q->nof_refs, nslot, nof_refs_x_symbol, nof_ref_symbols);
q->refs = vec_malloc(q->nof_refs * sizeof(ref_t));
if (!q->refs) {
goto free_and_exit;
@ -127,7 +125,6 @@ int refsignal_init_LTEDL(refsignal_t *q, int port_id, int nslot,
c_init = 1024 * (7 * (ns + 1) + lp[l] + 1) * (2 * cell_id + 1)
+ 2 * cell_id + N_cp;
if (sequence_LTEPRS(&seq, 2 * 2 * MAX_PRB, c_init)) {
goto free_and_exit;
}
@ -142,13 +139,13 @@ int refsignal_init_LTEDL(refsignal_t *q, int port_id, int nslot,
__imag__ q->refs[idx(l,i)].simbol = (1 - 2 * (float) seq.c[2 * mp + 1]) / sqrt(2);
/* mapping to resource elements */
q->refs[idx(l,i)].freq_idx = refsignal_k(i, v, cell_id)+GUARD_RE(nof_prb);
q->refs[idx(l,i)].freq_idx = refsignal_k(i, v, cell_id);
q->refs[idx(l,i)].time_idx = lp[l];
/* print only first slot */
if (ns == 0) {
DEBUG("(%-2d,%2d) is mapped to (%-2d,%2d) (mp=%d, v=%d)\n",
l,i,q->refs[idx(l,i)].time_idx, q->refs[idx(l,i)].freq_idx-GUARD_RE(nof_prb), mp, v);
l,i,q->refs[idx(l,i)].time_idx, q->refs[idx(l,i)].freq_idx, mp, v);
}
}
}

@ -15,38 +15,61 @@
* You should have received a copy of the GNU Lesser General Public License
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "lte/base.h"
#include "utils/dft.h"
#include "lte/fft.h"
#include "utils/debug.h"
int lte_fft_init_(lte_fft_t *q, lte_cp_t cp_type, int symbol_sz, dft_dir_t dir) {
int lte_fft_init_(lte_fft_t *q, lte_cp_t cp_type, int nof_prb, dft_dir_t dir) {
int symbol_sz = lte_symbol_sz(nof_prb);
if (symbol_sz == -1) {
fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb);
return -1;
}
if (dft_plan_c2c(symbol_sz, dir, &q->fft_plan)) {
fprintf(stderr, "Error: Creating DFT plan\n");
return -1;
}
q->tmp = malloc(symbol_sz * sizeof(cf_t));
if (!q->tmp) {
perror("malloc");
return -1;
}
q->fft_plan.options = DFT_DC_OFFSET | DFT_MIRROR_POS | DFT_NORMALIZE;
q->nof_symbols = CP_NSYMB(cp_type);
q->symbol_sz = symbol_sz;
q->nof_symbols = CP_NSYMB(cp_type);
q->cp_type = cp_type;
q->nof_re = nof_prb * RE_X_RB;
q->nof_guards = ((symbol_sz - q->nof_re) / 2);
DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp_type=%s, nof_re=%d, nof_guards=%d\n",
dir==FORWARD?"FFT":"iFFT", q->symbol_sz, q->nof_symbols,
q->cp_type==CPNORM?"Normal":"Extended", q->nof_re, q->nof_guards);
return 0;
}
void lte_fft_free_(lte_fft_t *q) {
dft_plan_free(&q->fft_plan);
bzero(q, sizeof(lte_fft_t));
}
int lte_fft_init(lte_fft_t *q, lte_cp_t cp_type, int symbol_sz) {
return lte_fft_init_(q, cp_type, symbol_sz, FORWARD);
int lte_fft_init(lte_fft_t *q, lte_cp_t cp_type, int nof_prb) {
return lte_fft_init_(q, cp_type, nof_prb, FORWARD);
}
void lte_fft_free(lte_fft_t *q) {
lte_fft_free_(q);
}
int lte_ifft_init(lte_fft_t *q, lte_cp_t cp_type, int symbol_sz) {
return lte_fft_init_(q, cp_type, symbol_sz, BACKWARD);
int lte_ifft_init(lte_fft_t *q, lte_cp_t cp_type, int nof_prb) {
return lte_fft_init_(q, cp_type, nof_prb, BACKWARD);
}
void lte_ifft_free(lte_fft_t *q) {
lte_fft_free_(q);
}
@ -58,9 +81,10 @@ void lte_fft_run(lte_fft_t *q, cf_t *input, cf_t *output) {
int i;
for (i=0;i<q->nof_symbols;i++) {
input += CP_ISNORM(q->cp_type)?CP_NORM(i, q->symbol_sz):CP_EXT(q->symbol_sz);
dft_run_c2c(&q->fft_plan, input, output);
dft_run_c2c(&q->fft_plan, input, q->tmp);
memcpy(output, &q->tmp[q->nof_guards], q->nof_re * sizeof(cf_t));
input += q->symbol_sz;
output += q->symbol_sz;
output += q->nof_re;
}
}

@ -19,13 +19,11 @@
#include "lte/sequence.h"
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <assert.h>
#define Nc 1600
#define GOLDMAXLEN (Nc*10)
static int x1[GOLDMAXLEN];
static int x2[GOLDMAXLEN];
/*
@ -35,24 +33,37 @@ static int x2[GOLDMAXLEN];
*/
void generate_prs_c(sequence_t *q, unsigned int seed) {
int n;
unsigned int *x1;
unsigned int *x2;
assert(q->len + Nc + 31 < GOLDMAXLEN);
x1 = calloc(Nc + q->len + 31, sizeof(unsigned int));
if (!x1) {
perror("calloc");
return;
}
x2 = calloc(Nc + q->len + 31, sizeof(unsigned int));
if (!x2) {
free(x1);
perror("calloc");
return;
}
for (n = 0; n < 31; n++) {
x1[n] = 0;
x2[n] = (seed >> n) & 0x1;
}
x1[0] = 1;
for (n = 0; n < Nc + q->len; n++) {
x1[n + 31] = (x1[n + 3] + x1[n]) & 0x1;
x2[n + 31] = (x2[n + 3] + x2[n + 2] + x2[n]) & 0x1;
x2[n + 31] = (x2[n + 3] + x2[n + 2] + +x2[n+1] + x2[n]) & 0x1;
}
for (n = 0; n < q->len; n++) {
q->c[n] = (x1[n + Nc] + x2[n + Nc]) & 0x1;
}
free(x1);
free(x2);
}
int sequence_LTEPRS(sequence_t *q, int len, int seed) {

@ -40,39 +40,22 @@ int pbch_cp(cf_t *input, cf_t *output, int nof_prb, lte_cp_t cp, int cell_id, bo
if (put) {
ptr = input;
output += nof_prb * RE_X_RB / 2 - 36;
output += GUARD_RE(nof_prb);
} else {
ptr = output;
input += nof_prb * RE_X_RB / 2 - 36;
input += GUARD_RE(nof_prb);
}
/* symbol 0 & 1 */
for (i=0;i<2;i++) {
phch_cp_prb_ref(&input, &output, cell_id%3, 4, 6, put);
if (put) {
output += 2*GUARD_RE(nof_prb);
} else {
input += 2*GUARD_RE(nof_prb);
}
}
/* symbols 2 & 3 */
if (CP_ISNORM(cp)) {
for (i=0;i<2;i++) {
phch_cp_prb(&input, &output, 6);
if (put) {
output += 2*GUARD_RE(nof_prb);
} else {
input += 2*GUARD_RE(nof_prb);
}
}
} else {
phch_cp_prb(&input, &output, 6);
if (put) {
output += 2*GUARD_RE(nof_prb);
} else {
input += 2*GUARD_RE(nof_prb);
}
phch_cp_prb_ref(&input, &output, cell_id%3, 4, 6, put);
}
if (put) {
@ -324,8 +307,9 @@ int pbch_decode_frame(pbch_t *q, pbch_mib_t *mib, int src, int dst, int n, int n
*
* Returns 1 if successfully decoded MIB, 0 if not and -1 on error
*/
int pbch_decode(pbch_t *q, cf_t *slot1_symbols, pbch_mib_t *mib, int nof_prb, float ebno) {
int src, dst, res, nb;
int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t **ce, int nof_ports,
int nof_prb, float ebno, pbch_mib_t *mib) {
int src, dst, res, nb, nant;
int nof_symbols = (CP_ISNORM(q->cp)) ? PBCH_RE_CPNORM: PBCH_RE_CPEXT;
int nof_bits = 2 * nof_symbols;
@ -337,39 +321,52 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, pbch_mib_t *mib, int nof_prb, fl
return -1;
}
/* demodulate symbols */
demod_soft_sigma_set(&q->demod, ebno);
demod_soft_demodulate(&q->demod, q->pbch_symbols,
&q->pbch_llr[nof_bits * q->frame_idx], nof_symbols);
q->frame_idx++;
INFO("PBCH: %d frames in buffer\n", q->frame_idx);
/* We don't know where the 40 ms begin, so we try all combinations. E.g. if we received
* 4 frames, try 1,2,3,4 individually, 12, 23, 34 in pairs, 123, 234 and finally 1234.
* We know they are ordered.
*/
res = 0;
for (nb=0;nb<q->frame_idx && !res;nb++) {
for (dst=0;(dst<4-nb) && !res;dst++) {
for (src=0;src<q->frame_idx && !res;src++) {
DEBUG("Trying %d blocks at offset %d as subframe mod4 number %d\n", nb+1, src, dst);
res = pbch_decode_frame(q, mib, src, dst, nb+1, nof_bits);
/* Try decoding for 1 to nof_ports antennas */
for (nant=0;nant<nof_ports;nant++) {
/* pre-decoder & matched filter */
int i;
for (i=0;i<nof_symbols;i++) {
q->pbch_symbols[i] /= ce[0][i];
}
/* layer demapper */
//x = lte_pre_decoder_and_matched_filter(y_est, ce(1:n,:), "tx_diversity");
//d = lte_layer_demapper(x, 1, "tx_diversity");
/* demodulate symbols */
demod_soft_sigma_set(&q->demod, ebno);
demod_soft_demodulate(&q->demod, q->pbch_symbols,
&q->pbch_llr[nof_bits * q->frame_idx], nof_symbols);
q->frame_idx++;
INFO("PBCH: %d frames in buffer\n", q->frame_idx);
/* We don't know where the 40 ms begin, so we try all combinations. E.g. if we received
* 4 frames, try 1,2,3,4 individually, 12, 23, 34 in pairs, 123, 234 and finally 1234.
* We know they are ordered.
*/
res = 0;
for (nb=0;nb<q->frame_idx && !res;nb++) {
for (dst=0;(dst<4-nb) && !res;dst++) {
for (src=0;src<q->frame_idx && !res;src++) {
DEBUG("Trying %d blocks at offset %d as subframe mod4 number %d\n", nb+1, src, dst);
res = pbch_decode_frame(q, mib, src, dst, nb+1, nof_bits);
}
}
}
}
if (res) {
q->frame_idx = 0;
return 1;
} else {
/* make room for the next packet of radio frame symbols */
if (q->frame_idx == 4) {
memcpy(&q->pbch_llr[nof_bits], q->pbch_llr, nof_bits * 3 * sizeof(float));
q->frame_idx = 3;
if (res) {
q->frame_idx = 0;
return 1;
}
return 0;
}
/* If not found, make room for the next packet of radio frame symbols */
if (q->frame_idx == 4) {
memcpy(&q->pbch_llr[nof_bits], q->pbch_llr, nof_bits * 3 * sizeof(float));
q->frame_idx = 3;
}
return 0;
}

@ -171,7 +171,7 @@ int sync_run(sync_t *q, cf_t *input, int read_offset) {
INFO("SSS detected N_id_1=%d, slot_idx=%d, m0=%d, m1=%d\n",
q->N_id_1, q->slot_id, m0, m1);
return peak_pos[N_id_2];
return peak_pos[N_id_2] - 960;
} else {
return -1;
}

@ -14,8 +14,9 @@ function [ fs eps p_m w2] = find_pss( x, N_id_2, doplot, threshold)
w2=conv(x,ccf);
if (doplot)
plot(10*log10(abs(w2)./mean(abs(w2))));
axis([0 length(w2) 0 20])
%plot(10*log10(abs(w2)));%./mean(abs(w2))));
plot(abs(w2))
%axis([0 length(w2) 0 20])
end
[m i]=max(abs(w2));
fs=i-960;

Loading…
Cancel
Save