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