Subversion Repositories Projects

Rev

Rev 780 | Rev 931 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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