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