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 | ||
Line -... | Line 35... | ||
- | 35 | #define LED_OFF PORTD |= 1 << PD0 |
|
35 | #define LED_OFF PORTD |= 1 << PD0 |
36 | #define LED_ON PORTD &= ~(1 << PD0) |
- | 37 | ||
- | 38 | volatile unsigned char Timer0Event = 0; |
|
Line 36... | Line 39... | ||
36 | #define LED_ON PORTD &= ~(1 << PD0) |
39 | volatile unsigned int Timer1Event; |
37 | 40 | volatile unsigned char BlinkCode = 0; |
|
38 | volatile unsigned int TimerEvent; |
41 | volatile unsigned char failure = 0; |
39 | 42 | ||
Line 40... | Line 43... | ||
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 |
- | 45 | unsigned char bind; // Bind-Pulse-Counter (in RAM) |
|
- | 46 | unsigned char eebind EEMEM; // Bind-Pulse-Counter (in EEPROM) |
|
- | 47 | ||
- | 48 | ||
- | 49 | ||
- | 50 | ISR(TIMER0_OVF_vect) // Triggered every 32,768 msec |
|
- | 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; |
|
42 | unsigned char bind; // Bind-Pulse-Counter (in RAM) |
62 | else if(Timer0Event == 16 && BlinkCode > 2) LED_ON; |
43 | unsigned char eebind EEMEM; // Bind-Pulse-Counter (in EEPROM) |
63 | else if(Timer0Event == 20 && BlinkCode > 2) LED_OFF; |
Line -... | Line 64... | ||
- | 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 | ||
Line 44... | Line 69... | ||
44 | 69 | Timer0Event++; |
|
45 | 70 | } |
|
46 | 71 | ||
47 | ISR(TIMER1_OVF_vect) // Triggered every 8,192 msec |
72 | |
48 | { |
73 | ISR(TIMER1_OVF_vect) // Triggered every 8,192 msec |
Line 49... | Line 74... | ||
49 | TimerEvent++; |
74 | { |
50 | } |
75 | Timer1Event++; |
51 | 76 | } |
|
52 | 77 | ||
53 | 78 | ||
54 | void SelectSat(unsigned char sat) |
79 | void SelectSat(unsigned char sat) |
Line 55... | Line 80... | ||
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 |
Line 58... | Line 83... | ||
58 | } |
83 | } |
59 | 84 | ||
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; |
- | 190 | unsigned char active[4]; |
|
- | 191 | unsigned char active_lo[4]; |
|
165 | unsigned char active[4]; |
192 | unsigned char active_hi[4]; |
Line -... | Line 193... | ||
- | 193 | unsigned char sat = 99; |
|
166 | unsigned char sat = 99; |
194 | |
167 | 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 |
Line 170... | Line -... | ||
170 | PORTB = 0b11110000; // Port B Pullup's for (unused) satellites |
- | |
171 | PORTD = 0b1100001; // Port D Pullup's for Switch & Test, LED off |
- | |
172 | - | ||
173 | for (i=0;i<4;i++) active[i] = 0; // Reset active-array |
198 | PORTB = 0b11110000; // Port B Pullup's for (unused) satellites |
174 | 199 | PORTD = 0b1100001; // Port D Pullup's for Switch & Test, LED off |
|
175 | 200 | ||
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 | { |
Line 183... | Line 208... | ||
183 | 208 | ||
184 | 209 | ||
Line -... | Line 210... | ||
- | 210 | if (!(PIND & (1<<PD5))) Testing(); // Initiate Self-Test when Test-Pad is low |
|
- | 211 | if (!(PIND & (1<<PD6))) Binding(); // Initiate Binding when Bind-Button is pressed |
|
- | 212 | ||
- | 213 | ||
- | 214 | for (i=0;i<4;i++) // Reset active-arrays |
|
- | 215 | { |
|
- | 216 | active[i] = 0; |
|
- | 217 | active_lo[i] = 0; |
|
185 | if (!(PIND & (1<<PD5))) Testing(); // Initiate Self-Test when Test-Pad is low |
218 | active_hi[i] = 0; |
Line -... | Line 219... | ||
- | 219 | } |
|
186 | if (!(PIND & (1<<PD6))) Binding(); // Initiate Binding when Bind-Button is pressed |
220 | |
187 | 221 | _delay_ms(100); |
|
188 | _delay_ms(100); |
222 | |
Line 189... | Line 223... | ||
189 | 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 | { |
- | 231 | if (Timer1Event == 10) LED_ON; // Blink while waiting |
|
- | 232 | if (Timer1Event == 20) |
|
- | 233 | { |
|
- | 234 | LED_OFF; |
|
- | 235 | Timer1Event = 0; |
|
- | 236 | } |
|
- | 237 | ||
- | 238 | while(Timer1Event < 3) // Check active satellites (for 3*8=24ms) |
|
- | 239 | { |
|
197 | if (TimerEvent == 10) LED_ON; // Blink while waiting... |
240 | for (i=0;i<4;i++) |
Line 198... | Line 241... | ||
198 | if (TimerEvent == 20) |
241 | { |
199 | { |
242 | if (PINB & (1<<(i+4))) active_hi[i] = 1; |
- | 243 | else active_lo[i] = 1; |
|
- | 244 | } |
|
- | 245 | } |
|
- | 246 | ||
- | 247 | for (i=0;i<4;i++) // When an input had low AND high signals, mark it as active |
|
- | 248 | { |
|
200 | LED_OFF; |
249 | if (active_lo[i] == 1 && active_hi[i] == 1) active[i] = 1; |
201 | TimerEvent = 0; |
250 | } |
202 | } |
251 | |
203 | 252 | ||
204 | for (i=0;i<4;i++) // Select first active Satellite |
253 | for (i=0;i<4;i++) // Select first active satellite |
205 | { |
254 | { |
206 | if (!(PINB & (1<<(i+4)))) |
255 | if (active[i] == 1) |
207 | { |
256 | { |
- | 257 | SelectSat(i); |
|
208 | active[i] = 1; |
258 | sat = i; |
Line -... | Line 259... | ||
- | 259 | BlinkCode = i+1; |
|
209 | sat = i; |
260 | break; |
Line 210... | Line 261... | ||
210 | SelectSat(sat); |
261 | } |
211 | break; |
262 | } |
212 | } |
263 | |
213 | } |
- | |
214 | } |
- | |
215 | - | ||
216 | LED_OFF; |
264 | } |
- | 265 | ||
- | 266 | ||
217 | 267 | ||
218 | while(1) // Main-Loop |
268 | |
219 | { |
269 | while(1) // Main-Loop |
220 | for (i=0;i<4;i++) active[i] = 0; // Reset active-array |
270 | { |
221 | 271 | for (i=0;i<4;i++) // Reset active-arrays |
|
222 | ResetTimer(); |
272 | { |
223 | while((PINB & 0b11110000) == 0b11110000) // Wait for first signal (SYNC to frame) |
273 | active[i] = 0; |
224 | { |
274 | active_lo[i] = 0; |
225 | if (TimerEvent > 3) break; // (max. 3*8=24ms) |
275 | active_hi[i] = 0; |
226 | } |
- | |
227 | 276 | } |
|
228 | ResetTimer(); |
- | |
229 | while(TimerEvent < 1) // Check active satellites (for 1*8=8ms) |
277 | |
230 | { |
278 | ResetTimer1(); |
Line -... | Line 279... | ||
- | 279 | while(Timer1Event < 3) // Check active satellites (for 3*8=24ms) |
|
231 | for (i=0;i<4;i++) |
280 | { |
232 | { |
281 | for (i=0;i<4;i++) |
- | 282 | { |
|
- | 283 | if (PINB & (1<<(i+4))) active_hi[i] = 1; |
|
- | 284 | else active_lo[i] = 1; |
|
- | 285 | } |
|
- | 286 | } |
|
- | 287 | ||
- | 288 | ||
- | 289 | for (i=0;i<4;i++) // When an input had low AND high signals, mark it as active |
|
- | 290 | { |
|
- | 291 | if (active_lo[i] == 1 && active_hi[i] == 1) active[i] = 1; |
|
- | 292 | } |
|
- | 293 | ||
233 | if (!(PINB & (1<<(i+4)))) |
294 | |
- | 295 | if (active[0] == 0 && active[1] == 0 && active[2] == 0 && active[3] == 0 && sat != 99) |
|
- | 296 | { |
|
234 | { |
297 | failure = 1; // Set Failure-LED when the signal is lost completely |
235 | active[i] = 1; |
298 | BlinkCode = 0; |
236 | } |
- | |
- | 299 | sat = 99; |
|
237 | } |
300 | } |
238 | } |
301 | |
239 | 302 | ||
240 | if (active[sat] == 0) // Detect fail on active satellite |
- | |
241 | { |
303 | for (i=0;i<4;i++) // Select active satellite (priorized) |
242 | for (i=0;i<4;i++) // Select lowest active satellite |
- | |
243 | { |
304 | { |
Line -... | Line 305... | ||
- | 305 | if (active[i] == 1) |
|
- | 306 | { |
|
244 | if (active[i] == 1) |
307 | SelectSat(i); |
245 | { |
308 | if (sat != i) failure = 1; // Set Failure-LED when the active satellite changes |
Line 246... | Line 309... | ||
246 | sat = i; |
309 | sat = i; |