blob: b3a793402d51bc2204d937755f3e24c47f072077 [file] [log] [blame]
ptrkrysik32c21162015-04-04 14:01:52 +02001
ptrkrysikf8c7e832015-04-04 12:28:20 +02002/* -*- c++ -*- */
3/*
4 * @file
5 * @author Piotr Krysik <ptrkrysik@gmail.com>
6 * @section LICENSE
7 *
8 * Gr-gsm is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3, or (at your option)
11 * any later version.
12 *
13 * Gr-gsm is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with gr-gsm; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <sch.h>
29#include "clock_offset_control_impl.h"
30
31namespace gr
32{
33namespace gsm
34{
35clock_offset_control::sptr
Piotr Krysik09826732016-07-15 13:14:24 +020036clock_offset_control::make(float fc, float samp_rate)
ptrkrysikf8c7e832015-04-04 12:28:20 +020037{
38 return gnuradio::get_initial_sptr
Piotr Krysik09826732016-07-15 13:14:24 +020039 (new clock_offset_control_impl(fc, samp_rate));
ptrkrysikf8c7e832015-04-04 12:28:20 +020040}
41
42
43/*
44 * The private constructor
45 */
Piotr Krysik09826732016-07-15 13:14:24 +020046clock_offset_control_impl::clock_offset_control_impl(float fc, float samp_rate)
ptrkrysikf8c7e832015-04-04 12:28:20 +020047 : gr::block("clock_offset_control",
48 gr::io_signature::make(0, 0, 0),
ptrkrysik32c21162015-04-04 14:01:52 +020049 gr::io_signature::make(0, 0, 0))
ptrkrysikf8c7e832015-04-04 12:28:20 +020050
51{
52 message_port_register_in(pmt::mp("measurements"));
53 set_msg_handler(pmt::mp("measurements"), boost::bind(&clock_offset_control_impl::process_measurement, this, _1));
Piotr Krysik09826732016-07-15 13:14:24 +020054 message_port_register_out(pmt::mp("ctrl"));
ptrkrysikf8c7e832015-04-04 12:28:20 +020055
56 set_fc(fc);
Piotr Krysik09826732016-07-15 13:14:24 +020057 set_samp_rate(samp_rate);
ptrkrysikf8c7e832015-04-04 12:28:20 +020058 d_alfa = 0.3;
59 d_ppm_estimate = -1e6;
60 d_last_ppm_estimate = -1e6;
61 d_first_measurement = true;
62 d_counter = 0;
63 d_last_state = "";
ptrkrysik32c21162015-04-04 14:01:52 +020064 d_current_time = 0;
65 d_last_fcch_time = 0;
66 d_first_time = true;
ptrkrysikf8c7e832015-04-04 12:28:20 +020067}
68
69/*
70 * Our virtual destructor.
71 */
72clock_offset_control_impl::~clock_offset_control_impl()
73{
74}
75
76void clock_offset_control_impl::set_fc(float fc)
77{
78 d_fc = fc;
79}
80
Piotr Krysik09826732016-07-15 13:14:24 +020081void clock_offset_control_impl::set_samp_rate(float samp_rate)
82{
83 d_samp_rate = samp_rate;
84}
85
ptrkrysikf8c7e832015-04-04 12:28:20 +020086void clock_offset_control_impl::process_measurement(pmt::pmt_t msg)
87{
88 if(pmt::is_tuple(msg))
89 {
90 std::string key = pmt::symbol_to_string(pmt::tuple_ref(msg,0));
ptrkrysik32c21162015-04-04 14:01:52 +020091 if(key == "current_time")
92 {
93 d_current_time = pmt::to_double(pmt::tuple_ref(msg,1));
94 if(d_first_time==true)
95 {
96 d_last_fcch_time = d_current_time;
97 d_first_time = false;
98 }
99 else
100 if((d_current_time - d_last_fcch_time) > 0.5 && d_last_state == "fcch_search")
101 {
102 timed_reset();
103 }
104 }
105 else
ptrkrysikf8c7e832015-04-04 12:28:20 +0200106 if(key == "freq_offset")
107 {
108 float freq_offset = pmt::to_double(pmt::tuple_ref(msg,1));
109 float ppm = -freq_offset/d_fc*1.0e6;
110 std::string state = pmt::symbol_to_string(pmt::tuple_ref(msg,2));
111 d_last_state = state;
Piotr Krysik09826732016-07-15 13:14:24 +0200112 if(std::abs(ppm) < 100.0) //safeguard against flawed measurements
ptrkrysikf8c7e832015-04-04 12:28:20 +0200113 {
ptrkrysikf8c7e832015-04-04 12:28:20 +0200114
Piotr Krysik09826732016-07-15 13:14:24 +0200115 if(state == "fcch_search")
ptrkrysikf8c7e832015-04-04 12:28:20 +0200116 {
Piotr Krysik09826732016-07-15 13:14:24 +0200117 send_ctrl_messages(ppm);
118 d_last_fcch_time = d_current_time;
119 }
120 else
121 if (state == "synchronized")
ptrkrysikf8c7e832015-04-04 12:28:20 +0200122 {
Piotr Krysik09826732016-07-15 13:14:24 +0200123 d_last_fcch_time = d_current_time;
124 if(d_first_measurement)
ptrkrysikf8c7e832015-04-04 12:28:20 +0200125 {
Piotr Krysik09826732016-07-15 13:14:24 +0200126 d_ppm_estimate = ppm;
127 d_first_measurement = false;
128 }
129 else
130 {
131 d_ppm_estimate = (1-d_alfa)*d_ppm_estimate+d_alfa*ppm;
132 }
133
134 if(d_counter == 5)
135 {
136 d_counter = 0;
137 if(std::abs(d_last_ppm_estimate-d_ppm_estimate) > 0.1)
138 {
139// pmt::pmt_t msg_ppm = pmt::from_double(ppm);
140// message_port_pub(pmt::intern("ppm"), msg_ppm);
141 send_ctrl_messages(ppm);
142 d_last_ppm_estimate = d_ppm_estimate;
143 }
144 }
145 else
146 {
147 d_counter=d_counter+1;
ptrkrysikf8c7e832015-04-04 12:28:20 +0200148 }
149 }
150 else
Piotr Krysik09826732016-07-15 13:14:24 +0200151 if(state == "sync_loss")
ptrkrysikf8c7e832015-04-04 12:28:20 +0200152 {
Piotr Krysik09826732016-07-15 13:14:24 +0200153 reset();
154// pmt::pmt_t msg_ppm = pmt::from_double(0.0);
155// message_port_pub(pmt::intern("ppm"), msg_ppm);
156 send_ctrl_messages(0);
ptrkrysikf8c7e832015-04-04 12:28:20 +0200157 }
Piotr Krysik09826732016-07-15 13:14:24 +0200158 }
ptrkrysikf8c7e832015-04-04 12:28:20 +0200159 }
160 }
161}
162
Piotr Krysik09826732016-07-15 13:14:24 +0200163void clock_offset_control_impl::send_ctrl_messages(float ppm)
164{
165// pmt::pmt_t msg_ppm = pmt::from_double(ppm);
166// message_port_pub(pmt::intern("ctrl"), msg_ppm);
167// d_last_fcch_time = d_current_time;
168
169 pmt::pmt_t msg_set_phase_inc = pmt::cons(pmt::intern("set_phase_inc"), pmt::from_double(2*M_PI*d_fc/d_samp_rate*ppm/1.0e6));
170 message_port_pub(pmt::intern("ctrl"), msg_set_phase_inc);
171
172 pmt::pmt_t msg_set_resamp_ratio = pmt::cons(pmt::intern("set_resamp_ratio"), pmt::from_double(1+ppm/1.0e6));
173 message_port_pub(pmt::intern("ctrl"), msg_set_resamp_ratio);
174}
175
ptrkrysikf8c7e832015-04-04 12:28:20 +0200176void clock_offset_control_impl::timed_reset()
177{
178 reset();
Piotr Krysik09826732016-07-15 13:14:24 +0200179 send_ctrl_messages(0);
ptrkrysikf8c7e832015-04-04 12:28:20 +0200180}
181
ptrkrysikf8c7e832015-04-04 12:28:20 +0200182void clock_offset_control_impl::reset()
183{
184 d_ppm_estimate = -1e6;
185 d_counter = 0;
186 d_first_measurement = true;
187}
188
189} /* namespace gsm */
190} /* namespace gr */
191