Subversion Repositories Projects

Rev

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
}