1 /* -*- c++ -*- */
2 /*
3  * Copyright 2004,2010,2013 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include "check_lfsr_32k_s_impl.h"
28 #include <gnuradio/io_signature.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 
32 namespace gr {
33 namespace blocks {
34 
make()35 check_lfsr_32k_s::sptr check_lfsr_32k_s::make()
36 {
37     return gnuradio::get_initial_sptr(new check_lfsr_32k_s_impl());
38 }
39 
check_lfsr_32k_s_impl()40 check_lfsr_32k_s_impl::check_lfsr_32k_s_impl()
41     : sync_block("check_lfsr_32k",
42                  io_signature::make(1, 1, sizeof(short)),
43                  io_signature::make(0, 0, 0)),
44       d_state(SEARCHING),
45       d_history(0),
46       d_ntotal(0),
47       d_nright(0),
48       d_runlength(0),
49       d_index(0)
50 {
51     lfsr_32k lfsr;
52 
53     for (int i = 0; i < BUFSIZE; i++)
54         d_buffer[i] = lfsr.next_short();
55 
56     enter_SEARCHING();
57 }
58 
~check_lfsr_32k_s_impl()59 check_lfsr_32k_s_impl::~check_lfsr_32k_s_impl() {}
60 
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)61 int check_lfsr_32k_s_impl::work(int noutput_items,
62                                 gr_vector_const_void_star& input_items,
63                                 gr_vector_void_star& output_items)
64 {
65     unsigned short* in = (unsigned short*)input_items[0];
66 
67     for (int i = 0; i < noutput_items; i++) {
68         unsigned short x = in[i];
69         unsigned short expected;
70 
71         switch (d_state) {
72         case MATCH0:
73             if (x == d_buffer[0])
74                 enter_MATCH1();
75             break;
76 
77         case MATCH1:
78             if (x == d_buffer[1])
79                 enter_MATCH2();
80             else
81                 enter_MATCH0();
82             break;
83 
84         case MATCH2:
85             if (x == d_buffer[2])
86                 enter_LOCKED();
87             else
88                 enter_MATCH0();
89             break;
90 
91         case LOCKED:
92             expected = d_buffer[d_index];
93             d_index = d_index + 1;
94             if (d_index >= BUFSIZE)
95                 d_index = 0;
96 
97             if (x == expected)
98                 right();
99             else {
100                 wrong();
101                 log_error(expected, x);
102                 if (wrong_three_times())
103                     enter_SEARCHING();
104             }
105             break;
106 
107         default:
108             abort();
109         }
110 
111         d_ntotal++;
112     }
113 
114     return noutput_items;
115 }
116 
enter_SEARCHING()117 void check_lfsr_32k_s_impl::enter_SEARCHING()
118 {
119     d_state = SEARCHING;
120     wrong(); // reset history
121     wrong();
122     wrong();
123 
124     d_runlength = 0;
125     d_index = 0; // reset LFSR to beginning
126 
127     if (0)
128         fprintf(stdout,
129                 "check_lfsr_32k: enter_SEARCHING at offset %8ld (0x%08lx)\n",
130                 d_ntotal,
131                 d_ntotal);
132 
133     enter_MATCH0();
134 }
135 
enter_MATCH0()136 void check_lfsr_32k_s_impl::enter_MATCH0() { d_state = MATCH0; }
137 
enter_MATCH1()138 void check_lfsr_32k_s_impl::enter_MATCH1() { d_state = MATCH1; }
139 
enter_MATCH2()140 void check_lfsr_32k_s_impl::enter_MATCH2() { d_state = MATCH2; }
141 
enter_LOCKED()142 void check_lfsr_32k_s_impl::enter_LOCKED()
143 {
144     d_state = LOCKED;
145     right(); // setup history
146     right();
147     right();
148 
149     d_index = 3; // already matched first 3 items
150 
151     if (0)
152         fprintf(stdout,
153                 "check_lfsr_32k: enter_LOCKED at offset %8ld (0x%08lx)\n",
154                 d_ntotal,
155                 d_ntotal);
156 }
157 
log_error(unsigned short expected,unsigned short actual)158 void check_lfsr_32k_s_impl::log_error(unsigned short expected, unsigned short actual)
159 {
160     if (0)
161         fprintf(stdout,
162                 "check_lfsr_32k: expected %5d (0x%04x) got %5d (0x%04x) offset %8ld "
163                 "(0x%08lx)\n",
164                 expected,
165                 expected,
166                 actual,
167                 actual,
168                 d_ntotal,
169                 d_ntotal);
170 }
171 
172 } /* namespace blocks */
173 } /* namespace gr */
174