Statistics
| Branch: | Tag: | Revision:

root / gnuradio-core / src / lib / general / gr_simple_correlator.cc @ c4763fb9

History | View | Annotate | Download (5.6 kB)

1 5d69a524 jcorgan
/* -*- c++ -*- */
2 5d69a524 jcorgan
/*
3 5d69a524 jcorgan
 * Copyright 2004 Free Software Foundation, Inc.
4 5d69a524 jcorgan
 * 
5 5d69a524 jcorgan
 * This file is part of GNU Radio
6 5d69a524 jcorgan
 * 
7 5d69a524 jcorgan
 * GNU Radio is free software; you can redistribute it and/or modify
8 5d69a524 jcorgan
 * it under the terms of the GNU General Public License as published by
9 937b719d eb
 * the Free Software Foundation; either version 3, or (at your option)
10 5d69a524 jcorgan
 * any later version.
11 5d69a524 jcorgan
 * 
12 5d69a524 jcorgan
 * GNU Radio is distributed in the hope that it will be useful,
13 5d69a524 jcorgan
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 5d69a524 jcorgan
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 5d69a524 jcorgan
 * GNU General Public License for more details.
16 5d69a524 jcorgan
 * 
17 5d69a524 jcorgan
 * You should have received a copy of the GNU General Public License
18 5d69a524 jcorgan
 * along with GNU Radio; see the file COPYING.  If not, write to
19 86f5c924 eb
 * the Free Software Foundation, Inc., 51 Franklin Street,
20 86f5c924 eb
 * Boston, MA 02110-1301, USA.
21 5d69a524 jcorgan
 */
22 5d69a524 jcorgan
23 5d69a524 jcorgan
#ifdef HAVE_CONFIG_H
24 5d69a524 jcorgan
#include "config.h"
25 5d69a524 jcorgan
#endif
26 5d69a524 jcorgan
27 5d69a524 jcorgan
#include <gr_simple_correlator.h>
28 5d69a524 jcorgan
#include <gr_simple_framer_sync.h>
29 5d69a524 jcorgan
#include <gr_io_signature.h>
30 5d69a524 jcorgan
#include <assert.h>
31 5d69a524 jcorgan
#include <stdexcept>
32 5d69a524 jcorgan
#include <gr_count_bits.h>
33 38ea3a57 eb
#include <string.h>
34 5d69a524 jcorgan
35 5d69a524 jcorgan
36 5d69a524 jcorgan
static const int THRESHOLD = 3;
37 5d69a524 jcorgan
38 5d69a524 jcorgan
gr_simple_correlator_sptr
39 5d69a524 jcorgan
gr_make_simple_correlator (int payload_bytesize)
40 5d69a524 jcorgan
{
41 5d69a524 jcorgan
  return gr_simple_correlator_sptr (new gr_simple_correlator (payload_bytesize));
42 5d69a524 jcorgan
}
43 5d69a524 jcorgan
44 5d69a524 jcorgan
gr_simple_correlator::gr_simple_correlator (int payload_bytesize)
45 5d69a524 jcorgan
  : gr_block ("simple_correlator",
46 5d69a524 jcorgan
              gr_make_io_signature (1, 1, sizeof (float)),
47 5d69a524 jcorgan
              gr_make_io_signature (1, 1, sizeof (unsigned char))),
48 5d69a524 jcorgan
    d_payload_bytesize (payload_bytesize),
49 5d69a524 jcorgan
    d_state (ST_LOOKING), d_osi (0),
50 5d69a524 jcorgan
    d_bblen ((payload_bytesize + GRSF_PAYLOAD_OVERHEAD) * GRSF_BITS_PER_BYTE),
51 5d69a524 jcorgan
    d_bitbuf (new unsigned char [d_bblen]),
52 5d69a524 jcorgan
    d_bbi (0)
53 5d69a524 jcorgan
{
54 5d69a524 jcorgan
  d_avbi = 0;
55 5d69a524 jcorgan
  d_accum = 0.0;
56 5d69a524 jcorgan
  d_avg = 0.0;
57 5d69a524 jcorgan
  for (int i = 0; i < AVG_PERIOD; i++)
58 5d69a524 jcorgan
    d_avgbuf[i] = 0.0;
59 5d69a524 jcorgan
60 5d69a524 jcorgan
#ifdef DEBUG_SIMPLE_CORRELATOR
61 5d69a524 jcorgan
  d_debug_fp = fopen("corr.log", "w");
62 5d69a524 jcorgan
#endif
63 5d69a524 jcorgan
  enter_looking ();
64 5d69a524 jcorgan
65 5d69a524 jcorgan
}
66 5d69a524 jcorgan
67 5d69a524 jcorgan
gr_simple_correlator::~gr_simple_correlator ()
68 5d69a524 jcorgan
{
69 5d69a524 jcorgan
#ifdef DEBUG_SIMPLE_CORRELATOR
70 5d69a524 jcorgan
  fclose(d_debug_fp);
71 5d69a524 jcorgan
#endif  
72 5d69a524 jcorgan
  delete [] d_bitbuf;
73 5d69a524 jcorgan
}
74 5d69a524 jcorgan
   
75 5d69a524 jcorgan
76 5d69a524 jcorgan
void
77 5d69a524 jcorgan
gr_simple_correlator::enter_looking ()
78 5d69a524 jcorgan
{
79 5d69a524 jcorgan
  fflush (stdout);
80 5d69a524 jcorgan
  // fprintf (stderr, ">>> enter_looking\n");
81 5d69a524 jcorgan
  d_state = ST_LOOKING;
82 5d69a524 jcorgan
  for (int i = 0; i < OVERSAMPLE; i++)
83 5d69a524 jcorgan
    d_shift_reg[i] = 0;
84 5d69a524 jcorgan
  d_osi = 0;
85 5d69a524 jcorgan
86 5d69a524 jcorgan
  d_avbi = 0;
87 5d69a524 jcorgan
  d_avg = d_avg * 0.5;
88 5d69a524 jcorgan
  d_accum = 0;
89 5d69a524 jcorgan
  for (int i = 0; i < AVG_PERIOD; i++)
90 5d69a524 jcorgan
    d_avgbuf[i] = 0.0;
91 5d69a524 jcorgan
}
92 5d69a524 jcorgan
93 5d69a524 jcorgan
void
94 5d69a524 jcorgan
gr_simple_correlator::enter_under_threshold ()
95 5d69a524 jcorgan
{
96 5d69a524 jcorgan
  fflush (stdout);
97 5d69a524 jcorgan
  // fprintf (stderr, ">>> enter_under_threshold\n");
98 5d69a524 jcorgan
  d_state = ST_UNDER_THRESHOLD;
99 5d69a524 jcorgan
  d_transition_osi = d_osi;
100 5d69a524 jcorgan
}
101 5d69a524 jcorgan
102 5d69a524 jcorgan
void
103 5d69a524 jcorgan
gr_simple_correlator::enter_locked ()
104 5d69a524 jcorgan
{
105 5d69a524 jcorgan
  d_state = ST_LOCKED;
106 5d69a524 jcorgan
  int delta = sub_index (d_osi, d_transition_osi);
107 5d69a524 jcorgan
  d_center_osi = add_index (d_transition_osi, delta/2);
108 5d69a524 jcorgan
  d_center_osi = add_index (d_center_osi, 3);   // FIXME
109 5d69a524 jcorgan
  d_bbi = 0;
110 5d69a524 jcorgan
  fflush (stdout);
111 5d69a524 jcorgan
  // fprintf (stderr, ">>> enter_locked  d_center_osi = %d\n", d_center_osi);
112 5d69a524 jcorgan
113 5d69a524 jcorgan
  d_avg = std::max(-1.0, std::min(1.0, d_accum * (1.0/AVG_PERIOD)));
114 5d69a524 jcorgan
  // fprintf(stderr, ">>> enter_locked  d_avg = %g\n", d_avg);
115 5d69a524 jcorgan
}
116 5d69a524 jcorgan
117 5d69a524 jcorgan
static void
118 5d69a524 jcorgan
packit (unsigned char *pktbuf, const unsigned char *bitbuf, int bitcount)
119 5d69a524 jcorgan
{
120 5d69a524 jcorgan
  for (int i = 0; i < bitcount; i += 8){
121 5d69a524 jcorgan
    int t = bitbuf[i+0] & 0x1;
122 5d69a524 jcorgan
    t = (t << 1) | (bitbuf[i+1] & 0x1);
123 5d69a524 jcorgan
    t = (t << 1) | (bitbuf[i+2] & 0x1);
124 5d69a524 jcorgan
    t = (t << 1) | (bitbuf[i+3] & 0x1);
125 5d69a524 jcorgan
    t = (t << 1) | (bitbuf[i+4] & 0x1);
126 5d69a524 jcorgan
    t = (t << 1) | (bitbuf[i+5] & 0x1);
127 5d69a524 jcorgan
    t = (t << 1) | (bitbuf[i+6] & 0x1);
128 5d69a524 jcorgan
    t = (t << 1) | (bitbuf[i+7] & 0x1);
129 5d69a524 jcorgan
    *pktbuf++ = t;
130 5d69a524 jcorgan
  }
131 5d69a524 jcorgan
}
132 5d69a524 jcorgan
133 5d69a524 jcorgan
void
134 5d69a524 jcorgan
gr_simple_correlator::update_avg(float x)
135 5d69a524 jcorgan
{
136 5d69a524 jcorgan
  d_accum -= d_avgbuf[d_avbi];
137 5d69a524 jcorgan
  d_avgbuf[d_avbi] = x;
138 5d69a524 jcorgan
  d_accum += x;
139 5d69a524 jcorgan
  d_avbi = (d_avbi + 1) & (AVG_PERIOD-1);
140 5d69a524 jcorgan
}
141 5d69a524 jcorgan
  
142 5d69a524 jcorgan
143 5d69a524 jcorgan
int
144 5d69a524 jcorgan
gr_simple_correlator::general_work (int noutput_items,
145 5d69a524 jcorgan
                                    gr_vector_int &ninput_items,
146 5d69a524 jcorgan
                                    gr_vector_const_void_star &input_items,
147 5d69a524 jcorgan
                                    gr_vector_void_star &output_items)
148 5d69a524 jcorgan
{
149 5d69a524 jcorgan
  const float *in = (const float *) input_items[0];
150 5d69a524 jcorgan
  unsigned char *out = (unsigned char *) output_items[0];
151 5d69a524 jcorgan
152 5d69a524 jcorgan
  
153 5d69a524 jcorgan
  int n = 0;
154 5d69a524 jcorgan
  int nin = ninput_items[0];
155 5d69a524 jcorgan
  int decision;
156 5d69a524 jcorgan
  int hamming_dist;
157 5d69a524 jcorgan
158 5d69a524 jcorgan
  struct debug_data {
159 5d69a524 jcorgan
    float        raw_data;
160 5d69a524 jcorgan
    float        sampled;
161 5d69a524 jcorgan
    float         enter_locked;
162 5d69a524 jcorgan
  } debug_data;
163 5d69a524 jcorgan
164 5d69a524 jcorgan
  while (n < nin){
165 5d69a524 jcorgan
166 5d69a524 jcorgan
#ifdef DEBUG_SIMPLE_CORRELATOR
167 5d69a524 jcorgan
    debug_data.raw_data = in[n];
168 5d69a524 jcorgan
    debug_data.sampled = 0.0;
169 5d69a524 jcorgan
    debug_data.enter_locked = 0.0;
170 5d69a524 jcorgan
#endif
171 5d69a524 jcorgan
172 5d69a524 jcorgan
    switch (d_state){
173 5d69a524 jcorgan
174 5d69a524 jcorgan
    case ST_LOCKED:
175 5d69a524 jcorgan
      if (d_osi == d_center_osi){
176 5d69a524 jcorgan
177 5d69a524 jcorgan
#ifdef DEBUG_SIMPLE_CORRELATOR
178 5d69a524 jcorgan
        debug_data.sampled = 1.0;
179 5d69a524 jcorgan
#endif
180 5d69a524 jcorgan
        decision = slice (in[n]);
181 5d69a524 jcorgan
        
182 5d69a524 jcorgan
        d_bitbuf[d_bbi] = decision;
183 5d69a524 jcorgan
        d_bbi++;
184 5d69a524 jcorgan
        if (d_bbi >= d_bblen){
185 5d69a524 jcorgan
          // printf ("got whole packet\n");
186 5d69a524 jcorgan
          unsigned char pktbuf[d_bblen/GRSF_BITS_PER_BYTE];
187 5d69a524 jcorgan
          packit (pktbuf, d_bitbuf, d_bbi);
188 5d69a524 jcorgan
          printf ("seqno %3d\n", pktbuf[0]);
189 5d69a524 jcorgan
          memcpy (out, &pktbuf[GRSF_PAYLOAD_OVERHEAD], d_payload_bytesize);
190 5d69a524 jcorgan
          enter_looking ();
191 5d69a524 jcorgan
          consume_each (n + 1);
192 5d69a524 jcorgan
          return d_payload_bytesize;
193 5d69a524 jcorgan
        }
194 5d69a524 jcorgan
      }
195 5d69a524 jcorgan
      break;
196 5d69a524 jcorgan
197 5d69a524 jcorgan
    case ST_LOOKING:
198 5d69a524 jcorgan
    case ST_UNDER_THRESHOLD:
199 5d69a524 jcorgan
      update_avg(in[n]);
200 5d69a524 jcorgan
      decision = slice (in[n]);
201 5d69a524 jcorgan
      d_shift_reg[d_osi] = (d_shift_reg[d_osi] << 1) | decision;
202 5d69a524 jcorgan
203 5d69a524 jcorgan
      hamming_dist = gr_count_bits64 (d_shift_reg[d_osi] ^ GRSF_SYNC);
204 5d69a524 jcorgan
      // printf ("%2d  %d\n", hamming_dist, d_osi);
205 5d69a524 jcorgan
206 5d69a524 jcorgan
      if (d_state == ST_LOOKING && hamming_dist <= THRESHOLD){
207 5d69a524 jcorgan
        // We're seeing a good PN code, remember location
208 5d69a524 jcorgan
        enter_under_threshold ();
209 5d69a524 jcorgan
      }
210 5d69a524 jcorgan
      else if (d_state == ST_UNDER_THRESHOLD && hamming_dist > THRESHOLD){
211 5d69a524 jcorgan
        // no longer seeing good PN code, compute center of goodness
212 5d69a524 jcorgan
        enter_locked ();
213 5d69a524 jcorgan
        debug_data.enter_locked = 1.0;
214 5d69a524 jcorgan
      }
215 5d69a524 jcorgan
      break;
216 5d69a524 jcorgan
217 5d69a524 jcorgan
    default:
218 5d69a524 jcorgan
      assert (0);
219 5d69a524 jcorgan
    }
220 5d69a524 jcorgan
      
221 5d69a524 jcorgan
#ifdef DEBUG_SIMPLE_CORRELATOR
222 5d69a524 jcorgan
    fwrite(&debug_data, sizeof (debug_data), 1, d_debug_fp);
223 5d69a524 jcorgan
#endif
224 5d69a524 jcorgan
225 5d69a524 jcorgan
    d_osi = add_index (d_osi, 1);
226 5d69a524 jcorgan
    n++;
227 5d69a524 jcorgan
  }
228 5d69a524 jcorgan
229 5d69a524 jcorgan
  consume_each (n);
230 5d69a524 jcorgan
  return 0;
231 5d69a524 jcorgan
}