From 83ca8d75e21d286096c749b7608f847220260b77 Mon Sep 17 00:00:00 2001 From: piotr Date: Mon, 1 Jun 2009 22:14:14 +0200 Subject: program now works for osr from 2,3,4,5,6 and almost for osr==7) --- src/lib/gsm_constants.h | 9 +++-- src/lib/gsm_receiver_cf.cc | 93 ++++++++++++++++++++++++---------------------- src/lib/gsm_receiver_cf.h | 36 ++++++++++++++---- 3 files changed, 83 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index d08df17..1e449b3 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -6,7 +6,9 @@ //Burst timing #define TAIL_BITS 3 -#define GUARD_BITS 8.25 +#define GUARD_BITS 8 +#define GUARD_FRACTIONAL 0.25 //fractional part of guard period +#define GUARD_PERIOD GUARD_BITS + GUARD_FRACTIONAL #define DATA_BITS 58 //size of 1 data block in normal burst #define N_TRAIN_BITS 26 #define N_SYNC_BITS 64 @@ -14,9 +16,9 @@ #define FCCH_BITS USEFUL_BITS #define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS) -#define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156) +#define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156 bits) #define TS_PER_FRAME 8 -#define FRAME_BITS (TS_PER_FRAME * TS_BITS) +#define FRAME_BITS (TS_PER_FRAME * TS_BITS + 2) // 156.25 * 8 #define FCCH_POS TAIL_BITS #define SYNC_POS 39 #define TRAIN_POS 58 @@ -24,6 +26,7 @@ #define FCCH_HITS_NEEDED (USEFUL_BITS - 4) #define FCCH_MAX_MISSES 1 +#define FCCH_MAX_FREQ_OFFSET 100 #define CHAN_IMP_RESP_LENGTH 5 diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index e4d2696..127c674 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -36,7 +36,7 @@ #include #define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) -#define SYNC_SEARCH_RANGE 60 +#define SYNC_SEARCH_RANGE 30 //TODO !! - move this methods to some else place @@ -70,7 +70,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_counter(0), d_fcch_start_pos(0), d_freq_offset(0), - d_state(first_fcch_search) + d_state(first_fcch_search), + d_burst_nr(osr) // d_fcch_count(0), //!! // d_x_temp(0),//!! // d_x2_temp(0)//!! @@ -128,19 +129,35 @@ gsm_receiver_cf::general_work(int noutput_items, } break; - case sch_search: + case sch_search: { + gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; + int t1, t2, t3; + int burst_start = 0; + unsigned char output_binary[BURST_SIZE]; + if (find_sch_burst(in, ninput_items[0], out)) { - d_channel_conf.set_multiframe_type(0, multiframe_51); - d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); - d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); - d_burst_nr++; - d_state = synchronized; + burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); + detect_burst(in, chan_imp_resp, burst_start, output_binary); + if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { + DCOUT("sch burst_start: " << burst_start); + d_burst_nr.set(t1, t2, t3, 0); + DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); + d_channel_conf.set_multiframe_type(0, multiframe_51); + d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); + d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); + d_burst_nr++; + consume_each(burst_start + BURST_SIZE * d_OSR); + d_state = synchronized; + } else { + d_state = next_fcch_search; + } } else { d_state = sch_search; } break; + } - //in this state receiver is synchronized and it processes bursts according to burst type for given burst number + //in this state receiver is synchronized and it processes bursts according to burst type for given burst number case synchronized: { gr_complex chan_imp_resp[100];//!! burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); @@ -152,20 +169,20 @@ gsm_receiver_cf::general_work(int noutput_items, switch (b_type) { case fcch_burst: { int ii; - int first_sample = (GUARD_BITS+TAIL_BITS) *d_OSR; - int last_sample = first_sample+USEFUL_BITS*d_OSR; + int first_sample = ceil((GUARD_PERIOD + 2*TAIL_BITS) * d_OSR)+1; + int last_sample = first_sample + USEFUL_BITS * d_OSR; double phase_sum = 0; for (ii = first_sample; ii < last_sample; ii++) { - double phase_diff = compute_phase_diff(in[ii], in[ii-1]) * d_OSR; -// std::cout << "phase_diff: " << phase_diff << "\n"; + double phase_diff = compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR; phase_sum += phase_diff; } - //std::cout << "phase_sum: " << phase_sum << "\n"; - -// double freq_offset = compute_freq_offset(phase_sum, USEFUL_BITS-TAIL_BITS); -// d_freq_offset -= freq_offset; -// set_frequency(d_freq_offset); -// std::cout << "freq_offset: " << d_freq_offset << "\n"; + double freq_offset = compute_freq_offset(phase_sum, last_sample - first_sample); + if(abs(freq_offset) > FCCH_MAX_FREQ_OFFSET){ + d_freq_offset -= freq_offset; + set_frequency(d_freq_offset); + DCOUT("adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); + } + } break; case sch_burst: { @@ -174,15 +191,15 @@ gsm_receiver_cf::general_work(int noutput_items, detect_burst(in, chan_imp_resp, burst_start, output_binary); if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { // d_burst_nr.set(t1, t2, t3, 0); - printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); - offset = burst_start - GUARD_BITS * d_OSR; + DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); + offset = burst_start - floor((GUARD_PERIOD) * d_OSR); + DCOUT(offset); to_consume += offset; } - std::cout << offset << std::endl; } break; case normal_burst: - + break; case rach_burst: @@ -194,7 +211,8 @@ gsm_receiver_cf::general_work(int noutput_items, } d_burst_nr++; - to_consume += floor(TS_BITS * d_OSR); + + to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); consume_each(to_consume); } break; @@ -315,6 +333,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) d_fcch_start_pos = d_counter + start_pos; freq_offset = compute_freq_offset(best_sum, FCCH_HITS_NEEDED); d_freq_offset -= freq_offset; + DCOUT("freq_offset: " << d_freq_offset); end = true; result = true; @@ -345,7 +364,7 @@ double gsm_receiver_cf::compute_freq_offset(double best_sum, unsigned denominato // d_x2_temp += freq_offset * freq_offset; // d_mean = d_x_temp / d_fcch_count; - DCOUT("freq_offset: " << freq_offset); //" best_sum: " << best_sum +// DCOUT("freq_offset: " << freq_offset); //" best_sum: " << best_sum // DCOUT("wariance: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; @@ -368,19 +387,16 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl bool end = false; bool result = false; int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; - gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; + // vector_complex correlation_buffer; // vector_float power_buffer; // vector_float window_energy_buffer; enum states { - start, reach_sch, find_sch_start, detect_and_decode_sch, search_not_finished, sch_found + start, reach_sch, search_not_finished, sch_found } sch_search_state; sch_search_state = start; - int t1, t2, t3; - int burst_start = 0; - unsigned char output_binary[BURST_SIZE]; while (!end) { switch (sch_search_state) { @@ -389,7 +405,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl if (d_counter < sample_nr_near_sch_start) { sch_search_state = reach_sch; } else { - sch_search_state = find_sch_start; + sch_search_state = sch_found; } break; @@ -402,26 +418,13 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl sch_search_state = search_not_finished; break; - case find_sch_start: - burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - sch_search_state = detect_and_decode_sch; - break; - case detect_and_decode_sch: - detect_burst(in, chan_imp_resp, burst_start, output_binary); - decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc); - d_burst_nr.set(t1, t2, t3, 0); - - printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); - to_consume += burst_start + BURST_SIZE * d_OSR; - sch_search_state = sch_found; - break; - case search_not_finished: result = false; end = true; break; case sch_found: + to_consume = 0; result = true; end = true; break; diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 98df34d..cc3fc15 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -32,6 +32,7 @@ //TODO !! - move this classes to some other place #include #include +#include typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type; typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; @@ -85,20 +86,30 @@ class multiframe_configuration class burst_counter { private: + const int d_OSR; uint32_t d_t1, d_t2, d_t3, d_timeslot_nr; + double d_first_sample_offset; + double d_offset; public: - burst_counter(): + burst_counter(int osr): + d_OSR(osr), d_t1(0), d_t2(0), d_t3(0), - d_timeslot_nr(0) { + d_timeslot_nr(0), + d_first_sample_offset(0), + d_offset(0) { } - burst_counter(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr): + burst_counter(int osr, uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr): + d_OSR(osr), d_t1(t1), d_t2(t2), d_t3(t3), - d_timeslot_nr(timeslot_nr) { + d_timeslot_nr(timeslot_nr), + d_offset(0) { + double first_sample_position = (get_frame_nr()*8+timeslot_nr)*TS_BITS; + d_first_sample_offset = first_sample_position - floor(first_sample_position); } burst_counter & operator++(int) { @@ -113,6 +124,10 @@ class burst_counter d_t2 = (d_t2 + 1) % 26; d_t3 = (d_t3 + 1) % 51; } + + d_first_sample_offset += GUARD_FRACTIONAL * d_OSR; + d_offset = floor(d_first_sample_offset); + d_first_sample_offset = d_first_sample_offset - d_offset; return (*this); } @@ -121,6 +136,9 @@ class burst_counter d_t2 = t2; d_t3 = t3; d_timeslot_nr = timeslot_nr; + double first_sample_position = (get_frame_nr()*8+timeslot_nr)*TS_BITS; + d_first_sample_offset = first_sample_position - floor(first_sample_position); + d_offset = 0; } uint32_t get_t1() { @@ -140,7 +158,11 @@ class burst_counter } uint32_t get_frame_nr() { - return (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3; + return (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3; + } + + unsigned get_offset(){ + return (unsigned)d_offset; } }; @@ -180,7 +202,7 @@ burst_type channel_configuration::get_burst_type(burst_counter burst_nr) uint32_t timeslot_nr = burst_nr.get_timeslot_nr(); multiframe_type m_type = d_timeslots_descriptions[timeslot_nr].get_type(); uint32_t nr; - + switch (m_type) { case multiframe_26: nr = burst_nr.get_t2(); @@ -227,7 +249,7 @@ class gsm_receiver_cf : public gr_block gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst gr_feval_dd *d_tuner; - int d_counter; + unsigned d_counter; //variables used to store result of the find_fcch_burst fuction int d_fcch_start_pos; -- cgit v1.2.3