5dd4f1db7562c91e319c18b100646952561c7901
[beacon-rx-433.git] / main.c
1 #include <aversive.h>
2 #include <aversive/wait.h>
3
4 #include <string.h>
5 #include <stdint.h>
6 #include <stdio.h>
7 #include <inttypes.h>
8
9 #ifdef HOST_VERSION
10 #if defined(WAV_NOISE)
11 #include "noise.wav.c"
12 #elif defined(WAV_TONE_HIGHNOISE)
13 #include "tone-highnoise.wav.c"
14 #elif defined(WAV_TONE_LOWNOISE)
15 #include "tone-lownoise.wav.c"
16 #elif defined(WAV_TONE)
17 #include "tone.wav.c"
18 #endif
19 #endif
20
21 /* port B */
22 #define BUZ_BIT   0
23 #define RADIO_BIT 2
24 #define LED_BIT   4
25
26 static uint32_t bitfield;
27
28 #ifdef HOST_VERSION
29 static int32_t fil_fond = 0;
30 static int32_t fil_harm1 = 0;
31 static int32_t fil_other = 0;
32 #else
33 static int16_t fil_fond = 0;
34 static int16_t fil_harm1 = 0;
35 static int16_t fil_other = 0;
36 #endif
37 static int16_t pow_fond = 0;
38 static int16_t pow_harm1 = 0;
39 static int16_t pow_other = 0;
40 static int16_t cpt_filter = 0;
41
42 #ifdef HOST_VERSION
43 /* when compiled for host, we check that there is no saturation when
44  * applying the filter. This should not happen as the gain of the
45  * filter is 1. */
46 int32_t saturate16(int32_t in)
47 {
48         if (in > 32767L) {
49                 in = 32767;
50                 printf("saturation\n");
51         }
52         if (fil_fond < -32768L) {
53                 in = -32768;
54                 printf("saturation\n");
55         }
56         return in;
57 }
58 #endif
59
60 /* Apply the 3 filters on the bitfield. The results are stored in
61  * fil_fond, fil_harm1 and fil_other. */
62 static void apply_filters(void)
63 {
64         fil_fond = 0;
65         fil_harm1 = 0;
66         fil_other = 0;
67
68         if (bitfield & (1UL << 0)) {
69                 fil_fond += -1781;
70                 fil_harm1 += -1217;
71                 fil_other += -1308;
72         }
73
74         if (bitfield & (1UL << 1)) {
75                 fil_fond += -1737;
76                 fil_harm1 += -1135;
77                 fil_other += -1830;
78         }
79
80         if (bitfield & (1UL << 2)) {
81                 fil_fond += -1024;
82                 fil_harm1 += 1922;
83                 fil_other += -446;
84         }
85
86         if (bitfield & (1UL << 3)) {
87                 fil_fond += 84;
88                 fil_harm1 += -60;
89                 fil_other += 1404;
90         }
91
92         if (bitfield & (1UL << 4)) {
93                 fil_fond += 1162;
94                 fil_harm1 += -1885;
95                 fil_other += 1790;
96         }
97
98         if (bitfield & (1UL << 5)) {
99                 fil_fond += 1791;
100                 fil_harm1 += 1235;
101                 fil_other += 306;
102         }
103
104         if (bitfield & (1UL << 6)) {
105                 fil_fond += 1725;
106                 fil_harm1 += 1113;
107                 fil_other += -1500;
108         }
109
110         if (bitfield & (1UL << 7)) {
111                 fil_fond += 986;
112                 fil_harm1 += -1933;
113                 fil_other += -1736;
114         }
115
116         if (bitfield & (1UL << 8)) {
117                 fil_fond += -141;
118                 fil_harm1 += 100;
119                 fil_other += -144;
120         }
121
122         if (bitfield & (1UL << 9)) {
123                 fil_fond += -1219;
124                 fil_harm1 += 1869;
125                 fil_other += 1605;
126         }
127
128         if (bitfield & (1UL << 10)) {
129                 fil_fond += -1819;
130                 fil_harm1 += -1288;
131                 fil_other += 1654;
132         }
133
134         if (bitfield & (1UL << 11)) {
135                 fil_fond += -1686;
136                 fil_harm1 += -1042;
137                 fil_other += -76;
138         }
139
140         if (bitfield & (1UL << 12)) {
141                 fil_fond += -842;
142                 fil_harm1 += 1972;
143                 fil_other += -1751;
144         }
145
146         if (bitfield & (1UL << 13)) {
147                 fil_fond += 424;
148                 fil_harm1 += -302;
149                 fil_other += -1478;
150         }
151
152         if (bitfield & (1UL << 14)) {
153                 fil_fond += 1660;
154                 fil_harm1 += -1750;
155                 fil_other += 708;
156         }
157
158         if (bitfield & (1UL << 15)) {
159                 fil_fond += 2416;
160                 fil_harm1 += 2399;
161                 fil_other += 2803;
162         }
163
164         if (bitfield & (1UL << 16)) {
165                 fil_fond += 2416;
166                 fil_harm1 += 2399;
167                 fil_other += 2803;
168         }
169
170         if (bitfield & (1UL << 17)) {
171                 fil_fond += 1660;
172                 fil_harm1 += -1750;
173                 fil_other += 708;
174         }
175
176         if (bitfield & (1UL << 18)) {
177                 fil_fond += 424;
178                 fil_harm1 += -302;
179                 fil_other += -1478;
180         }
181
182         if (bitfield & (1UL << 19)) {
183                 fil_fond += -842;
184                 fil_harm1 += 1972;
185                 fil_other += -1751;
186         }
187
188         if (bitfield & (1UL << 20)) {
189                 fil_fond += -1686;
190                 fil_harm1 += -1042;
191                 fil_other += -76;
192         }
193
194         if (bitfield & (1UL << 21)) {
195                 fil_fond += -1819;
196                 fil_harm1 += -1288;
197                 fil_other += 1654;
198         }
199
200         if (bitfield & (1UL << 22)) {
201                 fil_fond += -1219;
202                 fil_harm1 += 1869;
203                 fil_other += 1605;
204         }
205
206         if (bitfield & (1UL << 23)) {
207                 fil_fond += -141;
208                 fil_harm1 += 100;
209                 fil_other += -144;
210         }
211
212         if (bitfield & (1UL << 24)) {
213                 fil_fond += 986;
214                 fil_harm1 += -1933;
215                 fil_other += -1736;
216         }
217
218         if (bitfield & (1UL << 25)) {
219                 fil_fond += 1725;
220                 fil_harm1 += 1113;
221                 fil_other += -1500;
222         }
223
224         if (bitfield & (1UL << 26)) {
225                 fil_fond += 1791;
226                 fil_harm1 += 1235;
227                 fil_other += 306;
228         }
229
230         if (bitfield & (1UL << 27)) {
231                 fil_fond += 1162;
232                 fil_harm1 += -1885;
233                 fil_other += 1790;
234         }
235
236         if (bitfield & (1UL << 28)) {
237                 fil_fond += 84;
238                 fil_harm1 += -60;
239                 fil_other += 1404;
240         }
241
242         if (bitfield & (1UL << 29)) {
243                 fil_fond += -1024;
244                 fil_harm1 += 1922;
245                 fil_other += -446;
246         }
247
248         if (bitfield & (1UL << 30)) {
249                 fil_fond += -1737;
250                 fil_harm1 += -1135;
251                 fil_other += -1830;
252         }
253
254         if (bitfield & (1UL << 31)) {
255                 fil_fond += -1781;
256                 fil_harm1 += -1217;
257                 fil_other += -1308;
258         }
259
260 #ifdef HOST_VERSION
261         fil_fond = saturate16(fil_fond);
262         fil_harm1 = saturate16(fil_harm1);
263         fil_other = saturate16(fil_other);
264 #endif
265 }
266
267 /* Return abs(val) * 0.03125 + prev_out * 0.96875
268  * This is a simple "mean" filter. */
269 static inline void mean_pow(int16_t *state, int16_t val)
270 {
271         uint16_t new;
272
273         if (val > 0)
274                 new = val;
275         else
276                 new = -val;
277
278         new >>= 5;
279
280         /* new += prev_out * 0.96875 */
281         *state >>= 1;
282         new += *state;
283         *state >>= 1;
284         new += *state;
285         *state >>= 1;
286         new += *state;
287         *state >>= 1;
288         new += *state;
289         *state >>= 1;
290         new += *state;
291         *state >>= 1;
292         new += *state;
293
294         /* update state */
295         *state = new;
296 }
297
298 #define MAX_CPT_FILTER 500
299
300 /* init timer (only on real hw, not on simulator which simulates an
301  * ATmega128) */
302 static void init_timer(void)
303 {
304 #if defined(__AVR_ATtiny45__)
305         TCCR0A = 0;
306         TCCR0B = (1 << CS01); /* clk/8 = 1Mhz */
307 #endif
308 }
309
310 /* wait new ech period (only on real hw, not on simulator which
311  * simulates an ATmega128). period=200 -> 5 khz */
312 static void wait_period(void)
313 {
314 #if defined(__AVR_ATtiny45__)
315         static uint8_t prev = 0;
316         uint8_t cur, diff;
317
318         do {
319                 cur = TCNT0;
320                 diff = cur - prev;
321         } while (diff < 200);
322         prev = cur;
323 #endif
324 }
325
326 /* return the input: on host, we use the table generated from the wav
327  * file, on the attiny, we use the real PIN input */
328 static uint8_t get_input(int i)
329 {
330 #ifdef HOST_VERSION
331         return !!x[i];
332 #else
333         return !!(PINB & (1 << RADIO_BIT));
334 #endif
335 }
336
337 static void set_output(int16_t i)
338 {
339         int8_t detected = 0;
340
341         if (cpt_filter > 250)
342                 detected = 1;
343
344 #ifdef HOST_VERSION
345         printf("%d fil_fond=%d fil_harm1=%d fil_other=%d\n",
346                i, fil_fond, fil_harm1, fil_other);
347         printf("%d pow_fond=%d pow_harm1=%d pow_other=%d cpt_filter=%d detected=%d\n",
348                i, pow_fond, pow_harm1, pow_other, cpt_filter, detected);
349 #else
350         if (detected)
351                 PORTB |= (1 << LED_BIT);
352         else
353                 PORTB &= ~(1 << LED_BIT);
354
355         /* when we receive, output a square signal at 625 hz */
356         if ((detected == 1) && (i & 4))
357                 PORTB |= (1 << BUZ_BIT);
358         else
359                 PORTB &= ~(1 << BUZ_BIT);
360 #endif
361 }
362
363 /*
364   The CPU runs at 8Mhz.
365   Fe = 5Khz
366   Ffond = 500 hz
367   Fharm1 = 1500 hz
368   Fother = 1000 hz
369  */
370 int main(void)
371 {
372         int16_t i;
373
374         /* led and buzzer are outputs */
375 #if defined(__AVR_ATtiny45__)
376         DDRB |= (1 << LED_BIT) | (1 << BUZ_BIT);
377 #endif
378
379         i = 0;
380         init_timer();
381
382         while (1) {
383
384                 wait_period();
385
386                 /* push one bit in bitfield */
387                 bitfield <<= 1UL;
388                 bitfield |= (uint32_t)get_input(i);
389
390                 apply_filters();
391                 mean_pow(&pow_fond, fil_fond);
392                 mean_pow(&pow_harm1, fil_harm1);
393                 mean_pow(&pow_other, fil_other);
394
395                 /* cpt_filter is increased when we consider that we are
396                  * receiving the signal */
397                 if ((pow_fond/3) > (pow_harm1/2) &&
398                     (pow_fond/2) > pow_other &&
399                     cpt_filter < MAX_CPT_FILTER)
400                         cpt_filter += 2;
401                 else if (cpt_filter > 0)
402                         cpt_filter--;
403
404                 set_output(i);
405
406                 i ++;
407 #ifdef HOST_VERSION
408                 if (i >= sizeof(x))
409                         break;
410 #endif
411         }
412
413         return 0;
414 }