2 #include <aversive/wait.h>
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)
23 #define BUZZER_ON() PORTB |= _BV(BUZZER_BIT)
24 #define BUZZER_OFF() PORTB &= (~_BV(BUZZER_BIT))
27 #define RADIO_READ() (!!(PINB & (_BV(RADIO_BIT))))
30 #define BUTTON_IS_PRESSED() (!!(PINB & (_BV(BUTTON_BIT))))
33 #define LED_ON() PORTB |= _BV(LED_BIT)
34 #define LED_OFF() PORTB &= (~_BV(LED_BIT))
36 #define MODE_NO_FILTER 0
37 #define MODE_FILTER_THRES1 1
38 #define MODE_FILTER_THRES2 2
41 static uint32_t bitfield;
44 static int32_t fil_fond = 0;
45 static int32_t fil_harm1 = 0;
46 static int32_t fil_other = 0;
48 static int16_t fil_fond = 0;
49 static int16_t fil_harm1 = 0;
50 static int16_t fil_other = 0;
52 static int16_t pow_fond = 0;
53 static int16_t pow_harm1 = 0;
54 static int16_t pow_other = 0;
55 static int16_t cpt_filter = 0;
58 /* when compiled for host, we check that there is no saturation when
59 * applying the filter. This should not happen as the gain of the
61 int32_t saturate16(int32_t in)
65 printf("saturation\n");
67 if (fil_fond < -32768L) {
69 printf("saturation\n");
75 /* Apply the 3 filters on the bitfield. The results are stored in
76 * fil_fond, fil_harm1 and fil_other. */
77 static void apply_filters(void)
83 if (bitfield & (1UL << 0)) {
89 if (bitfield & (1UL << 1)) {
95 if (bitfield & (1UL << 2)) {
101 if (bitfield & (1UL << 3)) {
107 if (bitfield & (1UL << 4)) {
113 if (bitfield & (1UL << 5)) {
119 if (bitfield & (1UL << 6)) {
125 if (bitfield & (1UL << 7)) {
131 if (bitfield & (1UL << 8)) {
137 if (bitfield & (1UL << 9)) {
143 if (bitfield & (1UL << 10)) {
149 if (bitfield & (1UL << 11)) {
155 if (bitfield & (1UL << 12)) {
161 if (bitfield & (1UL << 13)) {
167 if (bitfield & (1UL << 14)) {
173 if (bitfield & (1UL << 15)) {
179 if (bitfield & (1UL << 16)) {
185 if (bitfield & (1UL << 17)) {
191 if (bitfield & (1UL << 18)) {
197 if (bitfield & (1UL << 19)) {
203 if (bitfield & (1UL << 20)) {
209 if (bitfield & (1UL << 21)) {
215 if (bitfield & (1UL << 22)) {
221 if (bitfield & (1UL << 23)) {
227 if (bitfield & (1UL << 24)) {
233 if (bitfield & (1UL << 25)) {
239 if (bitfield & (1UL << 26)) {
245 if (bitfield & (1UL << 27)) {
251 if (bitfield & (1UL << 28)) {
257 if (bitfield & (1UL << 29)) {
263 if (bitfield & (1UL << 30)) {
269 if (bitfield & (1UL << 31)) {
276 fil_fond = saturate16(fil_fond);
277 fil_harm1 = saturate16(fil_harm1);
278 fil_other = saturate16(fil_other);
282 /* Return abs(val) * 0.03125 + prev_out * 0.96875
283 * This is a simple "mean" filter. */
284 static inline void mean_pow(int16_t *state, int16_t val)
295 /* new += prev_out * 0.96875 */
313 #define MAX_CPT_FILTER 500
315 /* init timer (only on real hw, not on simulator which simulates an
317 static void init_timer(void)
319 #if defined(__AVR_ATtiny45__)
321 TCCR0B = (1 << CS01); /* clk/8 = 1Mhz */
325 /* wait new ech period (only on real hw, not on simulator which
326 * simulates an ATmega128). period=200 -> 5 khz */
327 static void wait_period(void)
329 #if defined(__AVR_ATtiny45__)
330 static uint8_t prev = 0;
336 } while (diff < 200);
341 /* return the input: on host, we use the table generated from the wav
342 * file, on the attiny, we use the real PIN input */
343 static uint8_t get_input(int i)
353 static void beep(void)
357 for (i = 0; i < 1000; i++) {
358 if (i < 250 && (i & 1))
367 The CPU runs at 8Mhz.
376 uint8_t mode = MODE_FILTER_THRES2;
379 uint8_t button = 0, button_filter = 0;
382 /* led and buzzer are outputs */
383 #if defined(__AVR_ATtiny45__)
384 DDRB |= (1 << LED_BIT) | (1 << BUZZER_BIT);
392 /* wait until 200us is elapsed since previous call (5Khz) */
398 if (BUTTON_IS_PRESSED() && button_filter < 10) {
400 if (button_filter == 10)
403 else if (!BUTTON_IS_PRESSED())
406 /* change mode if button is pressed */
411 if (mode >= MODE_MAX)
414 for (j = 0; j <= mode; j++)
417 /* reset input history */
422 /* push one bit in bitfield */
424 bitfield |= (uint32_t)get_input(i);
426 /* filter the input */
428 mean_pow(&pow_fond, fil_fond);
429 mean_pow(&pow_harm1, fil_harm1);
430 mean_pow(&pow_other, fil_other);
432 /* cpt_filter is increased when we consider that we are
433 * receiving the signal */
434 if ((pow_fond/3) > (pow_harm1/2) &&
435 (pow_fond/2) > pow_other &&
436 cpt_filter < MAX_CPT_FILTER)
438 else if (cpt_filter > 0)
443 case MODE_FILTER_THRES1:
444 /* low threshold, some risk of false positive */
445 if (cpt_filter > 100)
448 case MODE_FILTER_THRES2:
450 if (cpt_filter > 250)
459 printf("%d fil_fond=%d fil_harm1=%d fil_other=%d\n",
460 i, fil_fond, fil_harm1, fil_other);
461 printf("%d pow_fond=%d pow_harm1=%d pow_other=%d "
462 "cpt_filter=%d detected=%d\n",
463 i, pow_fond, pow_harm1, pow_other, cpt_filter, detected);
470 /* if filtering is disabled, just copy the radio input
472 if (mode == MODE_NO_FILTER) {
478 /* with filtering enabled, output a square signal at
479 * 625 hz if beacon is detected */
481 if ((detected == 1) && (i & 4))
491 /* exit when all samples are processed */