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