Rev 776 | Rev 780 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
778 | - | 1 | // ************************************************************* |
2 | // ** Spektrum Diversity - use up to 4 satellite receivers ** |
||
3 | // ************************************************************* |
||
4 | // ** Target: An Atmel ATtiny2313 (RC-Oscillator @ 8 MHz) ** |
||
5 | // ** controls a 74HC151 Multiplexer ** |
||
6 | // ************************************************************* |
||
7 | // ** It monitors the data from 4 satellite receivers and ** |
||
8 | // ** connects a valid one to the output via the multiplexer ** |
||
9 | // ************************************************************* |
||
10 | // ** LED-Modes during startup (in chronological order) ** |
||
11 | // ** ************************ ** |
||
12 | // ** LED fast blink: Waiting for first datapulse ** |
||
13 | // ** LED slow blink: Waiting 3 seconds while counting sat's ** |
||
14 | // ** LED flashes: Indicates the number of active sat's ** |
||
15 | // ** ** |
||
16 | // ** LED-Modes during operation ** |
||
17 | // ** ************************** ** |
||
18 | // ** LED OFF: Everything is fine ** |
||
19 | // ** LED ON: FAILURE - The first selected sat had lost sync ** |
||
20 | // ** ** |
||
21 | // ** LED-Modes during Self-Test ** |
||
22 | // ** ************************** ** |
||
23 | // ** LED flashes at 1 Hz: Everything is fine ** |
||
24 | // ** LED flashes some times: FAILURE ** |
||
25 | // ************************************************************* |
||
26 | // ** (c) 2010-0xFFFF Stefan Pendsa ** |
||
27 | // ** License: don't know - use it and have fun ** |
||
28 | // ************************************************************* |
||
775 | - | 29 | |
30 | #include <avr/io.h> |
||
31 | #include <avr/interrupt.h> |
||
32 | #include <util/delay.h> |
||
33 | |||
776 | - | 34 | #define LED_OFF PORTD |= 1 << PORTD0 |
35 | #define LED_ON PORTD &= ~(1 << PORTD0) |
||
775 | - | 36 | |
37 | volatile unsigned int TimerEvent; |
||
38 | |||
39 | |||
778 | - | 40 | |
41 | ISR(TIMER1_OVF_vect) // Triggered every 8,192 msec |
||
42 | { |
||
43 | TimerEvent++; |
||
44 | } |
||
45 | |||
46 | |||
47 | |||
775 | - | 48 | void SelectSat(unsigned char sat) |
49 | { |
||
776 | - | 50 | PORTD = (PORTD & 0b00000001) | (sat<<3); // Select the Input for 74HC151 |
775 | - | 51 | } |
52 | |||
778 | - | 53 | |
54 | |||
775 | - | 55 | void ResetTimer(void) |
56 | { |
||
57 | TCNT1H = 0; |
||
58 | TCNT1L = 0; |
||
59 | TimerEvent = 0; |
||
60 | } |
||
61 | |||
62 | |||
778 | - | 63 | |
776 | - | 64 | void Binding(void) // Binding sequence for DX7 |
65 | { |
||
66 | unsigned char i = 0; |
||
775 | - | 67 | |
776 | - | 68 | DDRB = 0b11110000; // Sat-Pins to output |
69 | _delay_ms(80); // Let them boot up |
||
70 | |||
71 | for (i=0;i<3;i++) // send three negative 100µs pulses to all sat's |
||
72 | { |
||
73 | PORTB = 0b00000000; |
||
74 | _delay_us(100); |
||
75 | PORTB = 0b11110000; |
||
76 | _delay_us(100); |
||
77 | } |
||
78 | |||
79 | _delay_ms(1000); |
||
80 | DDRB = 0b00000000; // Sat-Pins to input after 1sec |
||
81 | } |
||
82 | |||
83 | |||
778 | - | 84 | |
776 | - | 85 | void Testing(void) // Self Test |
775 | - | 86 | { |
778 | - | 87 | unsigned char error = 0; |
776 | - | 88 | unsigned char i = 0; |
89 | |||
778 | - | 90 | DDRB = 0b11110000; // Port B Output for satellites, Input for feedback |
776 | - | 91 | |
778 | - | 92 | PORTB = 0b01010000; // Test Pattern |
93 | SelectSat(0); |
||
94 | if (!(PINB & (1<<PB3))) error++; |
||
95 | SelectSat(1); |
||
96 | if (PINB & (1<<PB3)) error++; |
||
97 | SelectSat(2); |
||
98 | if (!(PINB & (1<<PB3))) error++; |
||
99 | SelectSat(3); |
||
100 | if (PINB & (1<<PB3)) error++; |
||
776 | - | 101 | |
778 | - | 102 | PORTB = 0b10100000; // Another (inverted) Test Pattern |
103 | SelectSat(0); |
||
104 | if (PINB & (1<<PB3)) error++; |
||
105 | SelectSat(1); |
||
106 | if (!(PINB & (1<<PB3))) error++; |
||
107 | SelectSat(2); |
||
108 | if (PINB & (1<<PB3)) error++; |
||
109 | SelectSat(3); |
||
110 | if (!(PINB & (1<<PB3))) error++; |
||
111 | |||
112 | DDRB = 0b00000000; // Port B Input again |
||
113 | |||
776 | - | 114 | while(1) // Never return |
115 | { |
||
778 | - | 116 | if (error == 0) // When no error occured -> LED flashes at 1 Hz |
776 | - | 117 | { |
118 | LED_ON; |
||
119 | _delay_ms(100); |
||
120 | LED_OFF; |
||
778 | - | 121 | _delay_ms(900); |
776 | - | 122 | } |
778 | - | 123 | else |
124 | { |
||
125 | for (i=0;i<error;i++) // When error occured -> Flash once for every error |
||
126 | { |
||
127 | LED_ON; |
||
128 | _delay_ms(100); |
||
129 | LED_OFF; |
||
130 | _delay_ms(400); |
||
131 | } |
||
132 | _delay_ms(1000); |
||
133 | } |
||
134 | |||
776 | - | 135 | } |
778 | - | 136 | |
776 | - | 137 | } |
138 | |||
139 | |||
775 | - | 140 | |
141 | int main(void) |
||
142 | { |
||
143 | unsigned char i = 0; |
||
776 | - | 144 | unsigned char j = 0; |
145 | unsigned char active[4]; |
||
146 | unsigned char sat = 4; |
||
775 | - | 147 | |
778 | - | 148 | DDRB = 0b00000000; // Port B Input for satellites and feedback |
149 | DDRD = 0b0011001; // Port D Output for MUX and LED, Input for Switch & Test |
||
150 | PORTB = 0b11110000; // Port B Pullup's for (unused) satellites |
||
151 | PORTD = 0b1100001; // Port D Pullup's for Switch & Test, LED on |
||
775 | - | 152 | |
776 | - | 153 | for (i=0;i<4;i++) active[i] = 0; // Reset active-array |
154 | |||
778 | - | 155 | if (!(PIND & (1<<PD5))) Testing(); // Initiate Self-Test when Test-Pad is low |
776 | - | 156 | if (!(PIND & (1<<PD6))) Binding(); // Initiate Binding when Bind-Button is pressed |
157 | |||
158 | TCCR1B = ( 1 << CS10 ); // Timer1 Prescaler = 1 -> 8,192 msec |
||
775 | - | 159 | TIMSK = ( 1 << TOIE1 ); // Timer1 Overflow Interrupt Enable |
160 | sei(); // Global Interrupts enable |
||
161 | |||
162 | ResetTimer(); |
||
776 | - | 163 | while((PINB & 0b11110000) == 0b11110000) // Wait for first signal (SYNC to frame) |
775 | - | 164 | { |
165 | if (TimerEvent == 10) LED_ON; // Blink while waiting... |
||
166 | if (TimerEvent == 20) |
||
167 | { |
||
168 | LED_OFF; |
||
169 | TimerEvent = 0; |
||
170 | } |
||
171 | } |
||
172 | LED_OFF; |
||
173 | |||
174 | ResetTimer(); |
||
778 | - | 175 | while(1) // Check active satellites for 5 seconds |
775 | - | 176 | { |
177 | if (TimerEvent == 20) LED_ON; // Blink (slower) while waiting... |
||
178 | if (TimerEvent == 40) |
||
179 | { |
||
180 | LED_OFF; |
||
181 | TimerEvent = 0; |
||
182 | j++; |
||
183 | } |
||
184 | |||
776 | - | 185 | for (i=0;i<4;i++) |
775 | - | 186 | { |
776 | - | 187 | if (!(PINB & (1<<(i+4)))) |
775 | - | 188 | { |
189 | active[i] = 1; |
||
776 | - | 190 | if (sat == 4) // Select first active satellite (only once) |
775 | - | 191 | { |
192 | sat = i; |
||
193 | SelectSat(i); |
||
194 | } |
||
195 | |||
196 | } |
||
197 | } |
||
198 | |||
778 | - | 199 | if (j == 16) break; // 16 * 40 * 8ms = ~5sec |
775 | - | 200 | } |
201 | |||
202 | LED_OFF; |
||
203 | _delay_ms(1000); |
||
204 | |||
776 | - | 205 | for (i=0;i<4;i++) // Flash once for every active satellite |
775 | - | 206 | { |
207 | if (active[i] == 1) |
||
208 | { |
||
209 | LED_ON; |
||
776 | - | 210 | _delay_ms(100); |
775 | - | 211 | LED_OFF; |
778 | - | 212 | _delay_ms(400); |
775 | - | 213 | } |
214 | } |
||
215 | |||
216 | |||
217 | |||
218 | |||
219 | while(1) // Main-Loop |
||
220 | { |
||
778 | - | 221 | for (i=0;i<4;i++) active[i] = 0; // Reset active-array |
222 | |||
775 | - | 223 | ResetTimer(); |
776 | - | 224 | while((PINB & 0b11110000) == 0b11110000) // Wait for first signal (SYNC to frame) |
775 | - | 225 | { |
226 | if (TimerEvent > 3) break; // (max. 3*8=24ms) |
||
227 | } |
||
228 | |||
229 | ResetTimer(); |
||
230 | while(TimerEvent < 1) // Check active satellites (for 1*8=8ms) |
||
231 | { |
||
232 | |||
776 | - | 233 | for (i=0;i<4;i++) |
775 | - | 234 | { |
776 | - | 235 | if (!(PINB & (1<<(i+4)))) |
775 | - | 236 | { |
237 | active[i] = 1; |
||
238 | } |
||
239 | } |
||
240 | } |
||
241 | |||
242 | if (active[sat] == 0) // Detect fail on active satellite |
||
243 | { |
||
778 | - | 244 | LED_ON; // Failure-LED ON |
776 | - | 245 | for (i=0;i<4;i++) // Select lowest active satellite |
775 | - | 246 | { |
247 | if (active[i] == 1) |
||
248 | { |
||
249 | sat = i; |
||
250 | SelectSat(sat); |
||
251 | break; |
||
252 | } |
||
253 | } |
||
254 | } |
||
776 | - | 255 | |
778 | - | 256 | if (!(PIND & (1<<PD6))) LED_OFF; // Reset Failure-LED when Bind-Button is pressed |
775 | - | 257 | } |
776 | - | 258 | |
775 | - | 259 | } |