Rev 791 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 791 | Rev 931 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | // *************************************************************** |
1 | // *************************************************************** |
2 | // ** Spektrum Diversity v1.3 - use up to 4 satellite receivers ** |
2 | // ** Spektrum Diversity v2.0 - use up to 4 satellite receivers ** |
3 | // *************************************************************** |
3 | // *************************************************************** |
4 | // ** Target: An Atmel ATtiny2313 (RC-Oscillator @ 8 MHz) ** |
4 | // ** Target: An Atmel ATtiny2313 (RC-Oscillator @ 8 MHz) ** |
5 | // ** controls a 74HC151 Multiplexer ** |
5 | // ** controls a 74HC151 Multiplexer ** |
6 | // *************************************************************** |
6 | // *************************************************************** |
7 | // ** It monitors the data from 4 satellite receivers and ** |
7 | // ** It monitors the data from 4 satellite receivers and ** |
8 | // ** connects a valid one to the output via the multiplexer ** |
8 | // ** connects a valid one to the output via the multiplexer ** |
9 | // *************************************************************** |
9 | // *************************************************************** |
10 | // ** LED-Modes during startup ** |
10 | // ** LED-Modes during startup ** |
11 | // ** ************************ ** |
11 | // ** ************************ ** |
12 | // ** LED fast flash: Waiting for first datapulse ** |
12 | // ** LED fast flash: Waiting for first signal ** |
13 | // ** ** |
13 | // ** ** |
14 | // ** LED-Modes during operation ** |
14 | // ** LED-Modes during operation ** |
15 | // ** ************************** ** |
15 | // ** ************************** ** |
16 | // ** LED OFF: Everything is fine ** |
16 | // ** LED flash 1x - 4x: Shows which channel is active every 2s ** |
17 | // ** LED ON: FAILURE - The first selected sat had lost sync ** |
17 | // ** LED ON after flash: FAILURE - A used signal was lost ** |
18 | // ** ** |
18 | // ** ** |
19 | // ** LED-Modes after Self-Test and pressed button ** |
19 | // ** LED-Modes after Self-Test and pressed button ** |
20 | // ** ******************************************** ** |
20 | // ** ******************************************** ** |
21 | // ** LED flashes at 1 Hz: Everything is fine ** |
21 | // ** LED flashes at 1 Hz: Everything is fine ** |
22 | // ** LED flashes some times: Times flashed -> damaged Channel# ** |
22 | // ** LED flashes some times: Times flashed -> damaged Channel# ** |
Line 33... | Line 33... | ||
33 | 33 | ||
34 | 34 | ||
35 | #define LED_OFF PORTD |= 1 << PD0 |
35 | #define LED_OFF PORTD |= 1 << PD0 |
36 | #define LED_ON PORTD &= ~(1 << PD0) |
36 | #define LED_ON PORTD &= ~(1 << PD0) |
37 | 37 | ||
- | 38 | volatile unsigned char Timer0Event = 0; |
|
38 | volatile unsigned int TimerEvent; |
39 | volatile unsigned int Timer1Event; |
- | 40 | volatile unsigned char BlinkCode = 0; |
|
- | 41 | volatile unsigned char failure = 0; |
|
39 | 42 | ||
40 | unsigned char eedummy EEMEM; // Dummy-Variable for Address 0 in EEPROM |
43 | unsigned char eedummy EEMEM; // Dummy-Variable for Address 0 in EEPROM |
41 | unsigned char eecheck EEMEM; // Check-Variable |
44 | unsigned char eecheck EEMEM; // Check-Variable |
42 | unsigned char bind; // Bind-Pulse-Counter (in RAM) |
45 | unsigned char bind; // Bind-Pulse-Counter (in RAM) |
43 | unsigned char eebind EEMEM; // Bind-Pulse-Counter (in EEPROM) |
46 | unsigned char eebind EEMEM; // Bind-Pulse-Counter (in EEPROM) |
44 | 47 | ||
45 | 48 | ||
46 | 49 | ||
47 | ISR(TIMER1_OVF_vect) // Triggered every 8,192 msec |
50 | ISR(TIMER0_OVF_vect) // Triggered every 32,768 msec |
48 | { |
51 | { |
- | 52 | if (Timer0Event > 64) // Max. 64*32 msec = 2,097152 sec |
|
- | 53 | { |
|
- | 54 | Timer0Event = 0; |
|
- | 55 | LED_OFF; |
|
- | 56 | } |
|
- | 57 | ||
- | 58 | if(Timer0Event == 0 && BlinkCode > 0) LED_ON; |
|
- | 59 | else if(Timer0Event == 4 && BlinkCode > 0) LED_OFF; |
|
- | 60 | else if(Timer0Event == 8 && BlinkCode > 1) LED_ON; |
|
- | 61 | else if(Timer0Event == 12 && BlinkCode > 1) LED_OFF; |
|
- | 62 | else if(Timer0Event == 16 && BlinkCode > 2) LED_ON; |
|
- | 63 | else if(Timer0Event == 20 && BlinkCode > 2) LED_OFF; |
|
- | 64 | else if(Timer0Event == 24 && BlinkCode > 3) LED_ON; |
|
- | 65 | else if(Timer0Event == 28 && BlinkCode > 3) LED_OFF; |
|
- | 66 | else if(Timer0Event == 35 && failure == 1) LED_ON; |
|
- | 67 | else if(Timer0Event == 55 && failure == 1) LED_OFF; |
|
- | 68 | ||
49 | TimerEvent++; |
69 | Timer0Event++; |
50 | } |
70 | } |
51 | 71 | ||
52 | 72 | ||
- | 73 | ISR(TIMER1_OVF_vect) // Triggered every 8,192 msec |
|
- | 74 | { |
|
- | 75 | Timer1Event++; |
|
- | 76 | } |
|
- | 77 | ||
53 | 78 | ||
54 | void SelectSat(unsigned char sat) |
79 | void SelectSat(unsigned char sat) |
55 | { |
80 | { |
56 | PORTD = (PORTD & 0b1100111) | (sat << 3); // Select the input for 74HC151 |
81 | PORTD = (PORTD & 0b1100111) | (sat << 3); // Select the input for 74HC151 |
57 | _delay_us(10); // Wait for stable state |
82 | _delay_us(10); // Wait for stable state |
58 | } |
83 | } |
59 | 84 | ||
60 | 85 | ||
61 | 86 | ||
62 | void ResetTimer(void) |
87 | void ResetTimer1(void) |
63 | { |
88 | { |
64 | TCNT1H = 0; |
89 | TCNT1H = 0; |
65 | TCNT1L = 0; |
90 | TCNT1L = 0; |
66 | TimerEvent = 0; |
91 | Timer1Event = 0; |
67 | } |
92 | } |
68 | 93 | ||
69 | 94 | ||
70 | 95 | ||
71 | void Binding(void) // Binding sequence |
96 | void Binding(void) // Binding sequence (for Spektrum sats only) |
72 | { |
97 | { |
73 | unsigned char i = 0; |
98 | unsigned char i = 0; |
74 | 99 | ||
75 | DDRB = 0b11110000; // Sat-Pins to output |
100 | DDRB = 0b11110000; // Sat-Pins to output |
76 | _delay_ms(80); // Let them time to boot up |
101 | _delay_ms(80); // Let them time to boot up |
Line 161... | Line 186... | ||
161 | 186 | ||
162 | int main(void) |
187 | int main(void) |
163 | { |
188 | { |
164 | unsigned char i = 0; |
189 | unsigned char i = 0; |
165 | unsigned char active[4]; |
190 | unsigned char active[4]; |
- | 191 | unsigned char active_lo[4]; |
|
- | 192 | unsigned char active_hi[4]; |
|
166 | unsigned char sat = 99; |
193 | unsigned char sat = 99; |
167 | 194 | ||
- | 195 | ||
168 | DDRB = 0b00000000; // Port B Input for satellites and feedback |
196 | DDRB = 0b00000000; // Port B Input for satellites and feedback |
169 | DDRD = 0b0011001; // Port D Output for MUX and LED, Input for Switch & Test |
197 | DDRD = 0b0011001; // Port D Output for MUX and LED, Input for Switch & Test |
170 | PORTB = 0b11110000; // Port B Pullup's for (unused) satellites |
198 | PORTB = 0b11110000; // Port B Pullup's for (unused) satellites |
171 | PORTD = 0b1100001; // Port D Pullup's for Switch & Test, LED off |
199 | PORTD = 0b1100001; // Port D Pullup's for Switch & Test, LED off |
172 | 200 | ||
173 | for (i=0;i<4;i++) active[i] = 0; // Reset active-array |
- | |
174 | - | ||
175 | - | ||
176 | if (eeprom_read_byte(&eecheck) != 0x42) // Invalid Data in EEPROM -> initialize |
201 | if (eeprom_read_byte(&eecheck) != 0x42) // Invalid Data in EEPROM -> initialize |
177 | { |
202 | { |
178 | eeprom_write_byte(&eecheck, 0x42); |
203 | eeprom_write_byte(&eecheck, 0x42); |
179 | bind = 3; |
204 | bind = 3; |
180 | eeprom_write_byte(&eebind, bind); |
205 | eeprom_write_byte(&eebind, bind); |
Line 183... | Line 208... | ||
183 | 208 | ||
184 | 209 | ||
185 | if (!(PIND & (1<<PD5))) Testing(); // Initiate Self-Test when Test-Pad is low |
210 | if (!(PIND & (1<<PD5))) Testing(); // Initiate Self-Test when Test-Pad is low |
186 | if (!(PIND & (1<<PD6))) Binding(); // Initiate Binding when Bind-Button is pressed |
211 | if (!(PIND & (1<<PD6))) Binding(); // Initiate Binding when Bind-Button is pressed |
187 | 212 | ||
- | 213 | ||
- | 214 | for (i=0;i<4;i++) // Reset active-arrays |
|
- | 215 | { |
|
- | 216 | active[i] = 0; |
|
- | 217 | active_lo[i] = 0; |
|
- | 218 | active_hi[i] = 0; |
|
- | 219 | } |
|
- | 220 | ||
188 | _delay_ms(100); |
221 | _delay_ms(100); |
189 | 222 | ||
- | 223 | TCCR0B = ( 1 << CS00 ) | ( 1 << CS02 ); // Timer0 Prescaler = 1024 -> 32,768 msec |
|
190 | TCCR1B = ( 1 << CS10 ); // Timer1 Prescaler = 1 -> 8,192 msec |
224 | TCCR1B = ( 1 << CS10 ); // Timer1 Prescaler = 1 -> 8,192 msec |
191 | TIMSK = ( 1 << TOIE1 ); // Timer1 Overflow Interrupt Enable |
225 | TIMSK = ( 1 << TOIE0 ) | ( 1 << TOIE1 ); // Timer0+1 Overflow Interrupt Enable |
192 | sei(); // Global Interrupts enable |
226 | sei(); // Global Interrupts enable |
193 | 227 | ||
194 | ResetTimer(); |
228 | ResetTimer1(); |
195 | while(sat == 99) // Wait for first signal |
229 | while(sat == 99) // Wait for first signal |
196 | { |
230 | { |
197 | if (TimerEvent == 10) LED_ON; // Blink while waiting... |
231 | if (Timer1Event == 10) LED_ON; // Blink while waiting |
198 | if (TimerEvent == 20) |
232 | if (Timer1Event == 20) |
199 | { |
233 | { |
200 | LED_OFF; |
234 | LED_OFF; |
201 | TimerEvent = 0; |
235 | Timer1Event = 0; |
- | 236 | } |
|
- | 237 | ||
- | 238 | while(Timer1Event < 3) // Check active satellites (for 3*8=24ms) |
|
- | 239 | { |
|
- | 240 | for (i=0;i<4;i++) |
|
- | 241 | { |
|
- | 242 | if (PINB & (1<<(i+4))) active_hi[i] = 1; |
|
- | 243 | else active_lo[i] = 1; |
|
- | 244 | } |
|
202 | } |
245 | } |
203 | 246 | ||
204 | for (i=0;i<4;i++) // Select first active Satellite |
247 | for (i=0;i<4;i++) // When an input had low AND high signals, mark it as active |
205 | { |
248 | { |
- | 249 | if (active_lo[i] == 1 && active_hi[i] == 1) active[i] = 1; |
|
- | 250 | } |
|
- | 251 | ||
- | 252 | ||
- | 253 | for (i=0;i<4;i++) // Select first active satellite |
|
- | 254 | { |
|
206 | if (!(PINB & (1<<(i+4)))) |
255 | if (active[i] == 1) |
207 | { |
256 | { |
208 | active[i] = 1; |
257 | SelectSat(i); |
209 | sat = i; |
258 | sat = i; |
210 | SelectSat(sat); |
259 | BlinkCode = i+1; |
211 | break; |
260 | break; |
212 | } |
261 | } |
213 | } |
262 | } |
- | 263 | ||
214 | } |
264 | } |
215 | 265 | ||
- | 266 | ||
216 | LED_OFF; |
267 | |
217 | 268 | ||
218 | while(1) // Main-Loop |
269 | while(1) // Main-Loop |
219 | { |
270 | { |
220 | for (i=0;i<4;i++) active[i] = 0; // Reset active-array |
271 | for (i=0;i<4;i++) // Reset active-arrays |
221 | - | ||
222 | ResetTimer(); |
- | |
223 | while((PINB & 0b11110000) == 0b11110000) // Wait for first signal (SYNC to frame) |
- | |
224 | { |
272 | { |
- | 273 | active[i] = 0; |
|
- | 274 | active_lo[i] = 0; |
|
225 | if (TimerEvent > 3) break; // (max. 3*8=24ms) |
275 | active_hi[i] = 0; |
226 | } |
276 | } |
227 | 277 | ||
228 | ResetTimer(); |
278 | ResetTimer1(); |
229 | while(TimerEvent < 1) // Check active satellites (for 1*8=8ms) |
279 | while(Timer1Event < 3) // Check active satellites (for 3*8=24ms) |
230 | { |
280 | { |
231 | for (i=0;i<4;i++) |
281 | for (i=0;i<4;i++) |
232 | { |
282 | { |
233 | if (!(PINB & (1<<(i+4)))) |
283 | if (PINB & (1<<(i+4))) active_hi[i] = 1; |
234 | { |
- | |
235 | active[i] = 1; |
284 | else active_lo[i] = 1; |
236 | } |
- | |
237 | } |
285 | } |
238 | } |
286 | } |
239 | 287 | ||
- | 288 | ||
240 | if (active[sat] == 0) // Detect fail on active satellite |
289 | for (i=0;i<4;i++) // When an input had low AND high signals, mark it as active |
241 | { |
290 | { |
- | 291 | if (active_lo[i] == 1 && active_hi[i] == 1) active[i] = 1; |
|
- | 292 | } |
|
- | 293 | ||
- | 294 | ||
- | 295 | if (active[0] == 0 && active[1] == 0 && active[2] == 0 && active[3] == 0 && sat != 99) |
|
- | 296 | { |
|
- | 297 | failure = 1; // Set Failure-LED when the signal is lost completely |
|
- | 298 | BlinkCode = 0; |
|
- | 299 | sat = 99; |
|
- | 300 | } |
|
- | 301 | ||
- | 302 | ||
242 | for (i=0;i<4;i++) // Select lowest active satellite |
303 | for (i=0;i<4;i++) // Select active satellite (priorized) |
- | 304 | { |
|
- | 305 | if (active[i] == 1) |
|
243 | { |
306 | { |
244 | if (active[i] == 1) |
307 | SelectSat(i); |
245 | { |
- | |
- | 308 | if (sat != i) failure = 1; // Set Failure-LED when the active satellite changes |
|
246 | sat = i; |
309 | sat = i; |
247 | SelectSat(sat); |
310 | BlinkCode = i+1; |
248 | break; |
311 | break; |
249 | } |
- | |
250 | } |
312 | } |
251 | LED_ON; // Failure-LED ON |
- | |
252 | } |
313 | } |
253 | 314 | ||
- | 315 | ||
- | 316 | ||
254 | if (!(PIND & (1<<PD6))) LED_OFF; // Reset Failure-LED when Bind-Button is pressed |
317 | if (!(PIND & (1<<PD6))) failure = 0; // Reset Failure-LED when Bind-Button is pressed |
255 | } |
318 | } |
256 | 319 | ||
257 | } |
320 | } |