Subversion Repositories Projects

Rev

Go to most recent revision | 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
}