2 * AE6HO EZ-Doppler firmware for onboard ATmega8 microcontroller
3 * Copyright 2006 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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 2, or (at your option)
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.
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.
26 * Timer0 is 8000 Hz time base
27 * PORTD.2 through PORTD.5 are doppler antenna array element enables.
28 * PORTB.0 is a diagnostic LED, set low to light up
30 * ADC6 is RSSI input - not yet used
35 #include <avr/interrupt.h>
36 #include <avr/signal.h>
40 #define turn_off_led() PORTB |= _BV(LED);
41 #define turn_on_led() PORTB &= ~_BV(LED);
47 #define ANTMASK ANT1|ANT2|ANT3|ANT4
50 #define BAUDRATE 250000
52 /* Assume these are all set to zero in startup code */
54 uint8_t rotate; /* Flag to indicate antennas should rotate or not */
55 uint8_t streaming; /* Flag to indicate continuous sampling */
56 uint8_t antennas; /* Holds shadow copy of PORTD antennas */
57 uint8_t speed; /* Holds samples per phase increment */
58 uint8_t phase; /* Holds rotation phase (measured in samples */
60 uint8_t audio_hi; /* High byte of ADC sample of audio */
61 uint8_t audio_lo; /* Low byte of ADC sample of audio */
63 uint8_t rx; /* Temporary holds received byte from USART */
64 uint8_t command; /* Temporary to hold command when getting operand */
65 uint8_t cmdbyte; /* Tracks bytes received in multi-byte commands */
69 /* Diagnostic port setup */
70 DDRB = _BV(LED); /* PB0 is output */
73 /* Antenna control port setup */
74 speed = 4; /* Todo: read from EEPROM */
75 antennas = ANT1; /* Start with antenna #1 */
76 PORTD = antennas; /* Set port value */
77 DDRD = ANTMASK; /* Set antenna enables as PORTD outputs */
80 ADMUX = _BV(REFS0)|ADCAIN; /* AVCC is reference, use ADC for audio input (ADC7) */
81 ADCSRA = _BV(ADEN)|_BV(ADIE)|0x07; /* Enable converter, prescale by 128, enable ADC interrupt */
84 UCSRA = 0; /* Normal asynchronous mode */
85 UCSRB = _BV(TXEN)|_BV(RXEN)|_BV(RXCIE); /* Enable transmitter and receiver, and receiver interrupts */
86 UCSRC = _BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0); /* 8N1 format */
87 UBRRH = 0; /* Set baud rate prescaler to 3 */
88 UBRRL = 3; /* To get 250000 bps */
90 /* Set up 8000 Hz time base */
91 timer_enable_int(_BV(TOIE0)); /* Turn on Timer0 output overflow interrupt */
92 TCCR0 = _BV(CS01); /* Clock Timer0 from CLK/8 */
94 sei(); /* Let 'er rip! */
98 /* Timer0 overflow interrupt handler
100 * Creates 8000 Hz time base, or 125us budget
103 SIGNAL(SIG_OVERFLOW0)
105 /* Reload Timer0 samples to 8, results in 8000 Hz overflow interrupt */
109 /* Kick-off an audio sample conversion, will interrupt 104us later */
112 /* Write the first byte of previous sample and enable UDRIE */
117 if (!rotate) /* Skip rotating antenna if not started */
120 /* Increment antenna phase and see if antenna need to be rotated */
121 if (++phase == speed) {
124 /* Sequence antenna array elements */
134 /* ADC conversion complete interrupt handler
136 * Read value and store. Assume prior sample has been handled.
145 /* USART data transmit holding register empty interrupt handler
147 * First byte is always sent from timer interrupt
148 * So second byte gets sent here with UDRIE disabled
151 SIGNAL(SIG_UART_DATA)
153 /* Write second byte of previous sample and disable UDRIE */
154 UDR = audio_hi | (antennas << 2);
155 UCSRB &= ~_BV(UDRIE);
158 /* USART receive complete interrupt handler
160 * Received bytes are commands, with one or two bytes of operands following
163 SIGNAL(SIG_UART_RECV)
168 if (rx == EZDOP_CMD_ROTATE) /* Start rotation */
170 else if (rx == EZDOP_CMD_STOP) /* Stop rotation */
172 else if (rx == EZDOP_CMD_RATE) { /* Set rotation rate */
176 else if (rx == EZDOP_CMD_STREAM) /* Stream audio samples */
178 else if (rx == EZDOP_CMD_STROFF) /* Stop streaming */
181 turn_on_led(); /* Unknown command */
183 else if (cmdbyte == 1) {
184 if (command == EZDOP_CMD_RATE) { /* Operand is number of samples per phase increment */
189 turn_on_led(); /* Bogus command state */
192 turn_on_led(); /* Bogus command state */