aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiotr <Piotr Krysik pkrysik@elka.pw.edu.pl>2014-02-08 14:15:27 +0100
committerpiotr <Piotr Krysik pkrysik@elka.pw.edu.pl>2014-02-08 14:15:27 +0100
commit7c82b1730f134f24cf9842ca0efb14da53da0a9f (patch)
tree650bb3334100ad4148562346861ad44737f0d227
parent7e3b0dbfc8e415190b13b6c3efbc314a43a0f3bc (diff)
Improved synchronization, added message output with bursts
-rw-r--r--grc/CMakeLists.txt4
-rw-r--r--grc/gsm_receiver.xml38
-rw-r--r--grc/gsm_receiver_hier.xml11
-rw-r--r--include/gsm/CMakeLists.txt3
-rw-r--r--lib/CMakeLists.txt1
-rw-r--r--lib/gsm_constants.h2
-rw-r--r--lib/receiver_impl.cc72
-rw-r--r--lib/receiver_impl.h2
-rwxr-xr-xpython/receiver_hier.py6
-rw-r--r--swig/gsm_swig.i3
10 files changed, 61 insertions, 81 deletions
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index c3f7dea..f2f4b75 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -18,6 +18,6 @@
# Boston, MA 02110-1301, USA.
install(FILES
- gsm_receiver.xml
- gsm_receiver_hier.xml DESTINATION share/gnuradio/grc/blocks
+ gsm_receiver_hier.xml
+ gsm_bursts_printer.xml DESTINATION share/gnuradio/grc/blocks
)
diff --git a/grc/gsm_receiver.xml b/grc/gsm_receiver.xml
deleted file mode 100644
index 7a0e3aa..0000000
--- a/grc/gsm_receiver.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0"?>
-<block>
- <name>receiver</name>
- <key>gsm_receiver</key>
- <category>gsm</category>
- <import>import gsm</import>
- <make>gsm.receiver($tuner, $osr)</make>
- <!-- Make one 'param' node for every Parameter you want settable from the GUI.
- Sub-nodes:
- * name
- * key (makes the value accessible as $keyname, e.g. in the make node)
- * type -->
- <param>
- <name>...</name>
- <key>...</key>
- <type>...</type>
- </param>
-
- <!-- Make one 'sink' node per input. Sub-nodes:
- * name (an identifier for the GUI)
- * type
- * vlen
- * optional (set to 1 for optional inputs) -->
- <sink>
- <name>in</name>
- <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
- </sink>
-
- <!-- Make one 'source' node per output. Sub-nodes:
- * name (an identifier for the GUI)
- * type
- * vlen
- * optional (set to 1 for optional inputs) -->
- <source>
- <name>out</name>
- <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
- </source>
-</block>
diff --git a/grc/gsm_receiver_hier.xml b/grc/gsm_receiver_hier.xml
index 247cfcb..23eadc9 100644
--- a/grc/gsm_receiver_hier.xml
+++ b/grc/gsm_receiver_hier.xml
@@ -13,7 +13,7 @@
</param>
<param>
- <name>Oversampling ration</name>
+ <name>Oversampling ratio</name>
<key>osr</key>
<value>4</value>
<type>int</type>
@@ -23,10 +23,9 @@
<name>in</name>
<type>complex</type>
</sink>
-
<source>
- <name>out</name>
- <type>float</type>
- <vlen>142</vlen>
+ <name>bursts</name>
+ <type>message</type>
+ <optional>1</optional>
</source>
-</block> \ No newline at end of file
+</block>
diff --git a/include/gsm/CMakeLists.txt b/include/gsm/CMakeLists.txt
index aad938f..c7f4fb3 100644
--- a/include/gsm/CMakeLists.txt
+++ b/include/gsm/CMakeLists.txt
@@ -22,5 +22,6 @@
########################################################################
install(FILES
api.h
- receiver.h DESTINATION include/gsm
+ receiver.h
+ bursts_printer.h DESTINATION include/gsm
)
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 8d4c721..1139353 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -30,6 +30,7 @@ list(APPEND gsm_sources
receiver_config.cc
viterbi_detector.cc
sch.c
+ bursts_printer_impl.cc
)
add_library(gnuradio-gsm SHARED ${gsm_sources})
diff --git a/lib/gsm_constants.h b/lib/gsm_constants.h
index 11913f1..964c1cf 100644
--- a/lib/gsm_constants.h
+++ b/lib/gsm_constants.h
@@ -34,7 +34,7 @@
#define CHAN_IMP_RESP_LENGTH 5
-#define MAX_SCH_ERRORS 5 //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state
+#define MAX_SCH_ERRORS 10 //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state
typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy, dummy_or_normal} burst_type;
typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type;
diff --git a/lib/receiver_impl.cc b/lib/receiver_impl.cc
index f11290c..90eccc2 100644
--- a/lib/receiver_impl.cc
+++ b/lib/receiver_impl.cc
@@ -64,7 +64,7 @@ receiver::make(feval_dd * tuner, int osr)
receiver_impl::receiver_impl(feval_dd * tuner, int osr)
: gr::block("receiver",
gr::io_signature::make(1, 1, sizeof(gr_complex)),
- gr::io_signature::make(0, 1, 142 * sizeof(float))),
+ gr::io_signature::make(0, 0, 0)),
d_OSR(osr),
d_chan_imp_length(CHAN_IMP_RESP_LENGTH),
d_tuner(tuner),
@@ -75,6 +75,7 @@ receiver_impl::receiver_impl(feval_dd * tuner, int osr)
d_burst_nr(osr),
d_failed_sch(0)
{
+
int i;
gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0));
for (i = 0; i < TRAIN_SEQ_NUM; i++)
@@ -92,6 +93,7 @@ receiver_impl::receiver_impl(feval_dd * tuner, int osr)
gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint);
}
+ message_port_register_out(pmt::mp("bursts"));
}
/*
@@ -117,6 +119,7 @@ receiver_impl::general_work(int noutput_items,
//float *out = (float *) output_items[0];
int produced_out = 0; //how many output elements were produced - this isn't used yet
//probably the gsm receiver will be changed into sink so this variable won't be necessary
+
switch (d_state)
{
//bootstrapping
@@ -145,7 +148,7 @@ receiver_impl::general_work(int noutput_items,
if (abs(prev_freq_offset - d_freq_offset) > FCCH_MAX_FREQ_OFFSET)
{
//set_frequency(d_freq_offset); //call set_frequncy only frequency offset change is greater than some value
- DCOUT("Freq offset " << d_freq_offset);
+ COUT("Freq offset " << d_freq_offset);
}
//produced_out = 0;
d_state = sch_search;
@@ -161,7 +164,7 @@ receiver_impl::general_work(int noutput_items,
case sch_search:
{
- DCOUT("SCH search") ;
+ DCOUT("SCH search");
vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR);
int t1, t2, t3;
int burst_start = 0;
@@ -220,17 +223,17 @@ receiver_impl::general_work(int noutput_items,
double freq_offset = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it
d_freq_offset_vals.push_front(freq_offset);
- //process_normal_burst(d_burst_nr, fc_fb);
+ send_burst(d_burst_nr, fc_fb);
if (d_freq_offset_vals.size() >= 10)
{
double sum = std::accumulate(d_freq_offset_vals.begin(), d_freq_offset_vals.end(), 0);
double mean_offset = sum / d_freq_offset_vals.size(); //compute mean
d_freq_offset_vals.clear();
+ DCOUT("mean offset" << mean_offset);
if (abs(mean_offset) > FCCH_MAX_FREQ_OFFSET)
{
- d_freq_offset -= mean_offset; //and adjust frequency if it have changed beyond
+ //d_freq_offset -= mean_offset; //and adjust frequency if it have changed beyond
//set_frequency(d_freq_offset); //some limit
- DCOUT("mean_offset: " << mean_offset);
DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n");
}
}
@@ -241,14 +244,14 @@ receiver_impl::general_work(int noutput_items,
int t1, t2, t3, d_ncc, d_bcc;
burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response
detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits
- //process_normal_burst(d_burst_nr, output_binary);
+ send_burst(d_burst_nr, output_binary);
if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) //and decode SCH data
{
// d_burst_nr.set(t1, t2, t3, 0); //but only to check if burst_start value is correct
d_failed_sch = 0;
DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3);
offset = burst_start - floor((GUARD_PERIOD) * d_OSR); //compute offset from burst_start - burst should start after a guard period
- DCOUT(offset);
+ DCOUT("offset: "<<offset);
to_consume += offset; //adjust with offset number of samples to be consumed
}
else
@@ -259,8 +262,8 @@ receiver_impl::general_work(int noutput_items,
d_state = first_fcch_search; //TODO: this isn't good, the receiver is going wild when it goes back to next_fcch_search from here
d_freq_offset_vals.clear();
d_freq_offset=0;
- set_frequency(0);
- DCOUT("many sch decoding errors");
+ //set_frequency(0);
+ DCOUT("Re-Synchronization");
}
}
}
@@ -271,34 +274,33 @@ receiver_impl::general_work(int noutput_items,
float normal_corr_max; //if it's normal burst
burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc); //get channel impulse response for given training sequence number - d_bcc
detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits
- process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
+ send_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
break;
}
case dummy_or_normal:
{
unsigned int normal_burst_start;
float dummy_corr_max, normal_corr_max;
+ DCOUT("Dummy");
get_norm_chan_imp_resp(input, &channel_imp_resp[0], &dummy_corr_max, TS_DUMMY);
+ DCOUT("Normal");
normal_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc);
- //COUT("normal_corr_max: " << normal_corr_max << " dummy_corr_max:" << dummy_corr_max);
+ DCOUT("normal_corr_max: " << normal_corr_max << " dummy_corr_max:" << dummy_corr_max);
if (normal_corr_max > dummy_corr_max)
{
detect_burst(input, &channel_imp_resp[0], normal_burst_start, output_binary);
- //if (!output_binary[0] && !output_binary[1] && !output_binary[2]) {
- // COUT("Normal burst");
- process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
- //}
+ send_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
}
else
{
- //process_normal_burst(d_burst_nr, dummy_burst);
+ send_burst(d_burst_nr, dummy_burst);
}
}
case rach_burst:
break;
case dummy:
- //process_normal_burst(d_burst_nr, dummy_burst);
+ send_burst(d_burst_nr, dummy_burst);
break;
case empty: //if it's empty burst
break; //do nothing
@@ -367,14 +369,14 @@ bool receiver_impl::find_fcch_burst(const gr_complex *input, const int nitems)
break;
- case search: // search for positive samples
+ case search: // search for positive samples
sample_number++;
if (sample_number > nitems - FCCH_HITS_NEEDED * d_OSR) //if it isn't possible to find FCCH because
{
- //there's too few samples left to look into,
+ //there's too few samples left to look into,
to_consume = sample_number; //don't do anything with those samples which are left
- //and consume only those which were checked
+ //and consume only those which were checked
fcch_search_state = search_fail;
}
else
@@ -725,7 +727,7 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex *
float energy = 0;
int search_center = (int)((TRAIN_POS + GUARD_PERIOD) * d_OSR);
- int search_start_pos = search_center + 1;
+ int search_start_pos = search_center + 1 - 5*d_OSR;
// int search_start_pos = search_center - d_chan_imp_length * d_OSR;
int search_stop_pos = search_center + d_chan_imp_length * d_OSR + 2 * d_OSR;
@@ -764,7 +766,7 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex *
}
//!why doesn't this work
int strongest_window_nr_new = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin();
- strongest_window_nr = 3; //! so I have to override it here
+ strongest_window_nr = strongest_window_nr_new-d_OSR; //! so I have to override it here
max_correlation = 0;
for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++)
@@ -778,7 +780,7 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex *
// d_channel_imp_resp.push_back(correlation);
chan_imp_resp[ii] = correlation;
}
-
+
*corr_max = max_correlation;
// We want to use the first sample of the impulse response, and the
// corresponding samples of the received signal.
@@ -796,20 +798,26 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex *
//COUT("Poczatek ###############################");
//std::cout << " burst_start: " << burst_start << " center: " << ((float)(search_start_pos + strongest_window_nr + chan_imp_resp_center)) / d_OSR << " stronegest window nr: " << strongest_window_nr << "\n";
//COUT("burst_start_new: " << (search_start_pos + strongest_window_nr_new - TRAIN_POS * d_OSR));
- burst_start=(search_start_pos + strongest_window_nr_new - TRAIN_POS * d_OSR);
+ DCOUT("strongest_window_nr_new: " << strongest_window_nr);
+ burst_start=(search_start_pos + strongest_window_nr - TRAIN_POS * d_OSR);
+
+ DCOUT("burst_start: " << burst_start);
return burst_start;
}
-void receiver_impl::process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary)
+void receiver_impl::send_burst(burst_counter burst_nr, const unsigned char * burst_binary)
{
int ii;
- //std::cout << "fn:" <<burst_nr.get_frame_nr() << " ts" << burst_nr.get_timeslot_nr() << " ";
- for(ii=0; ii<148; ii++)
- {
- std::cout << std::setprecision(1) << static_cast<int>(burst_binary[ii]) << "";
- }
- std::cout << std::endl;
+
+ static const int nelements = 148;
+ pmt::pmt_t burst = pmt::make_s8vector(nelements, 0); // Initializes all 64 elements to 0
+
+ size_t vec_size;
+ int8_t *burst_elements = pmt::s8vector_writable_elements(burst, vec_size); // Returns pointer, vec_size is set to 64
+
+ memcpy(burst_elements, burst_binary, nelements);
+ message_port_pub(pmt::mp("bursts"), burst);
}
//TODO: this shouldn't be here also - the same reason
void receiver_impl::configure_receiver()
diff --git a/lib/receiver_impl.h b/lib/receiver_impl.h
index 6fb1778..40ce91d 100644
--- a/lib/receiver_impl.h
+++ b/lib/receiver_impl.h
@@ -189,7 +189,7 @@ namespace gr {
/**
*
*/
- void process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary);
+ void send_burst(burst_counter burst_nr, const unsigned char * burst_binary);
/**
*
diff --git a/python/receiver_hier.py b/python/receiver_hier.py
index 1737d41..2b2f9ab 100755
--- a/python/receiver_hier.py
+++ b/python/receiver_hier.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
+import weakref
import gsm
from gnuradio.eng_option import eng_option
from gnuradio import gr, gru, blocks
@@ -22,6 +23,9 @@ class receiver_hier(gr.hier_block2):
gr.io_signature(1, 1, 142*gr.sizeof_float))
#set rates
gsm_symb_rate = 1625000/6.0
+
+ self.message_port_register_hier_in("bursts")
+
self.input_rate = input_rate
self.osr = osr
self.sps = input_rate / gsm_symb_rate / osr
@@ -33,6 +37,8 @@ class receiver_hier(gr.hier_block2):
self.interpolator = self._set_interpolator()
self.receiver = self._set_receiver()
self.connect(self, self.filtr, self.interpolator, self.receiver, self)
+ self.msg_connect(self.receiver, "bursts", weakref.proxy(self), "bursts")
+
def _set_filter(self):
filter_cutoff = 125e3
diff --git a/swig/gsm_swig.i b/swig/gsm_swig.i
index e1c3613..5aaf16d 100644
--- a/swig/gsm_swig.i
+++ b/swig/gsm_swig.i
@@ -9,8 +9,11 @@
%{
#include "gsm/receiver.h"
+#include "gsm/bursts_printer.h"
%}
%include "gsm/receiver.h"
GR_SWIG_BLOCK_MAGIC2(gsm, receiver);
+%include "gsm/bursts_printer.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer);