Subversion Repositories Projects

Rev

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
}