Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
26 | walter | 1 | //############################################################################ |
2 | // - PPM2PentaxIR Main |
||
3 | // - ATMEGA8 mit 8MHz |
||
4 | // - Nur für den privaten Gebrauch |
||
5 | // - Keine Garantie auf Fehlerfreiheit |
||
6 | // - Kommerzielle Nutzung nur mit meiner Zustimmung |
||
7 | // - walter Meyer @ www.freakware.de |
||
8 | // - 30.11.2007 |
||
9 | // - Make sure Fuses are programmed for internal 8 MHz RC Oscilator |
||
10 | //############################################################################*/ |
||
11 | |||
12 | #include "main.h" |
||
13 | #include "uart.h" |
||
14 | #include "twislave.h" |
||
15 | |||
16 | volatile unsigned int ppm_signal = 1500; |
||
17 | volatile unsigned char ppm_new = 0; |
||
18 | volatile unsigned char TMR1OvF = 0; |
||
19 | volatile unsigned char IRstate = 0; |
||
20 | volatile unsigned char IRdat = 0; |
||
21 | volatile unsigned char TMR65ms = 0; |
||
22 | |||
23 | |||
24 | |||
25 | SIGNAL(SIG_OVERFLOW1) |
||
26 | { |
||
27 | TMR1OvF++; |
||
28 | TMR65ms++; |
||
29 | } |
||
30 | |||
31 | |||
32 | SIGNAL(SIG_INPUT_CAPTURE1) |
||
33 | { |
||
34 | static unsigned int pos_ICR; |
||
35 | static unsigned int ppm; |
||
36 | |||
37 | if ((TCCR1B & (1<<ICES1)) != 0) //rising edge |
||
38 | { |
||
39 | TCCR1B &= ~(1<<ICES1); //set falling egde |
||
40 | TMR1OvF = 0; |
||
41 | pos_ICR = ICR1; |
||
42 | } |
||
43 | else //falling edge |
||
44 | { |
||
45 | TCCR1B |= (1<<ICES1); //set rising egde |
||
46 | ppm = (ICR1 - pos_ICR + (int) TMR1OvF * 65536); |
||
47 | if ((ppm > 600) && (ppm < 2400)) |
||
48 | { |
||
49 | if (ppm > 2100) ppm = 2100; |
||
50 | if (ppm < 900) ppm = 900; |
||
51 | ppm = (ppm_signal * 7 + ppm) / 8; |
||
52 | ppm_signal = ppm; |
||
53 | ppm_new = 1; |
||
54 | } |
||
55 | |||
56 | } |
||
57 | |||
58 | } |
||
59 | |||
60 | |||
61 | |||
62 | /*##############################################################################*/ |
||
63 | void StartIRModulation(void) |
||
64 | { |
||
65 | //Timer1 Config for generation the 38Khz IR Modulation |
||
66 | TCCR2 = (0<<FOC2)|(0<<WGM20)|(0<<COM21)|(0<<COM20)| |
||
67 | (1<<WGM21) |(0<<CS22) |(0<<CS21) |(1<<CS20); |
||
68 | |||
69 | OCR2 = 108; //~38Khz @ 8Mhz |
||
70 | |||
71 | //Timer 0 Config for getting right timing for IR Pattern |
||
72 | TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00); // clk(@8MHz) / 1024 = 128us / clk (resolution) |
||
73 | TIMSK &= ~(1<<TOIE0); // |
||
74 | |||
75 | } |
||
76 | |||
77 | |||
78 | SIGNAL(SIG_OVERFLOW0) |
||
79 | { |
||
80 | static unsigned char IRbit; |
||
81 | |||
82 | switch (IRstate) |
||
83 | { |
||
84 | case 1: |
||
85 | TCCR2 setbit (1<<COM20); |
||
86 | IRstate = 2; |
||
87 | IRbit = 0; |
||
88 | TCNT0 = 255 - (13000 / 128); |
||
89 | break; |
||
90 | case 2: |
||
91 | TCCR2 clrbit (1<<COM20); |
||
92 | IRstate = 3; |
||
93 | if ((IRdat & 0x40) == 0) TCNT0 = 255 - (1000 / 128); |
||
94 | else TCNT0 = 255 - (3000 / 128); |
||
95 | break; |
||
96 | case 3: |
||
97 | TCCR2 setbit (1<<COM20); |
||
98 | TCNT0 = 255 - (1000 / 128); |
||
99 | IRdat = IRdat << 1; |
||
100 | IRbit++; |
||
101 | if (IRbit < 7) IRstate = 2; |
||
102 | else |
||
103 | { |
||
104 | IRstate = 4; |
||
105 | IRbit = 0; |
||
106 | } |
||
107 | break; |
||
108 | case 4: |
||
109 | TCCR2 clrbit (1<<COM20); |
||
110 | TCNT0 = 255 - (25000 / 128); |
||
111 | if (IRbit < 20) IRstate = 4; |
||
112 | else IRstate = 5; |
||
113 | IRbit++; |
||
114 | break; |
||
115 | default: |
||
116 | TIMSK &= ~(1<<TOIE0); |
||
117 | IRstate = 0; |
||
118 | break; |
||
119 | |||
120 | } |
||
121 | |||
122 | } |
||
123 | |||
124 | |||
125 | |||
126 | |||
127 | |||
128 | /*##############################################################################*/ |
||
129 | void SendIRSignal(unsigned char txbyte) |
||
130 | { |
||
131 | while (IRstate != 0) {} //IR already in action ?, if so, wait |
||
132 | IRstate = 1; //initial State |
||
133 | IRdat = txbyte; //copy IR Data |
||
134 | TIFR &= TOV0; //set TMR0 Int Flag |
||
135 | TIMSK setbit (1<<TOIE0); //Enable TMR0 Int |
||
136 | } |
||
137 | |||
138 | |||
139 | |||
140 | |||
141 | |||
142 | |||
143 | |||
144 | /*##############################################################################*/ |
||
145 | void StartPPM(void) |
||
146 | { |
||
147 | |||
148 | //global timer1 Config |
||
149 | TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)| |
||
150 | (0<<FOC1A) |(0<<FOC1B) |(0<<WGM10) |(0<<WGM11); |
||
151 | TCCR1B = (1<<ICNC1)|(1<<ICES1)|(0<<WGM13)| |
||
152 | (0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10); //ICP_POS_FLANKE |
||
153 | |||
154 | // interrupts |
||
155 | TIMSK |= (1<<TICIE1)|(1<<TOIE1); //ICP_INT_ENABLE and TIMER1_INT_ENABLE |
||
156 | |||
157 | } |
||
158 | |||
159 | |||
160 | int GetPPM(void) |
||
161 | { |
||
162 | //this routines seems to be nesseccary, as reading a 16 bit value |
||
163 | //on a 8 bit machine is not atomic, so if an interrupt apears between reading |
||
164 | //low and high byte of the 16 bit value a wrong result is possible |
||
165 | |||
166 | unsigned char intmask; |
||
167 | unsigned int ppm_temp; |
||
168 | |||
169 | intmask = TIMSK; //backup interupt enable bits |
||
170 | TIMSK &= ~(1<<TICIE1); //disable ppm interrupt |
||
171 | ppm_temp = ppm_signal; |
||
172 | TIMSK = intmask; //restore interupt enable bits |
||
173 | return(ppm_temp); //return ppm_signal |
||
174 | |||
175 | } |
||
176 | |||
177 | |||
178 | /*##############################################################################*/ |
||
179 | // MAIN |
||
180 | /*##############################################################################*/ |
||
181 | int main (void) |
||
182 | { |
||
183 | |||
184 | DDRC = (1<<ledred); |
||
185 | PORTC = 0x00; |
||
186 | DDRD = (1<<ledgreen); |
||
187 | PORTD = 0x00; |
||
188 | DDRB = (1<<1)|(1<<2)|(1<<3); |
||
189 | PORTB = 0x00; |
||
190 | |||
191 | |||
192 | //StartUART(); |
||
193 | StartPPM(); |
||
194 | StartI2C(); |
||
195 | StartIRModulation(); |
||
196 | sei(); |
||
197 | |||
198 | |||
199 | while (1) |
||
200 | { |
||
201 | //printf("%d ",ppm_signal); |
||
202 | if (ppm_new == 1) |
||
203 | { |
||
204 | ppm_new = 0; |
||
205 | if (GetPPM() > 1750) |
||
206 | { |
||
207 | SendIRSignal(ZOOM); |
||
208 | PORTC |= (1<<ledred); |
||
209 | while (GetPPM() > 1650) {} |
||
210 | PORTC &= ~(1<<ledred); |
||
211 | } |
||
212 | |||
213 | if (GetPPM() < 1250) |
||
214 | { |
||
215 | PORTD |= (1<<ledgreen); |
||
216 | SendIRSignal(TRIGGER); |
||
217 | TMR65ms = 0; //reset 65ms Timer |
||
218 | while (GetPPM() < 1350) |
||
219 | { |
||
220 | if (TMR65ms > 15 * 1) break; //about 1 sec. repeat time |
||
221 | } |
||
222 | PORTD &= ~(1<<ledgreen); |
||
223 | } |
||
224 | |||
225 | } |
||
226 | |||
227 | if (I2C_IN == TRIGGER) |
||
228 | { |
||
229 | PORTD |= (1<<ledgreen); |
||
230 | SendIRSignal(TRIGGER); |
||
231 | PORTD &= ~(1<<ledgreen); |
||
232 | } |
||
233 | |||
234 | if (I2C_IN == ZOOM) |
||
235 | { |
||
236 | PORTD |= (1<<ledred); |
||
237 | SendIRSignal(ZOOM); |
||
238 | PORTD &= ~(1<<ledred); |
||
239 | } |
||
240 | |||
241 | |||
242 | } |
||
243 | |||
244 | |||
245 | } |