Subversion Repositories Projects

Rev

Rev 56 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
28 walter 1
//############################################################################
51 walter 2
// - PWM CTRL 
3
// - Main
28 walter 4
// - ATMEGA8 mit 8MHz
5
// - Nur für den privaten Gebrauch
6
// - Keine Garantie auf Fehlerfreiheit
7
// - Kommerzielle Nutzung nur mit meiner Zustimmung
8
// - walter Meyer @ www.freakware.de
9
// - 11.12.2007
10
// - Make sure Fuses are programmed for internal 8 MHz RC Oscilator
11
//############################################################################*/
12
 
13
#include "main.h"
14
#include "uart.h"
15
#include "twislave.h"
16
 
57 walter 17
volatile unsigned int PPM_SIGNAL = 1520;
55 walter 18
volatile unsigned char PPM_NEW = 0;
28 walter 19
volatile unsigned char TMR1OvF = 0;
51 walter 20
volatile unsigned int  TMR1MS;
55 walter 21
volatile unsigned char CH0;
22
volatile unsigned char CH1;
23
volatile unsigned char CH2;
24
volatile unsigned char CH3;
25
volatile unsigned char CH4;
26
volatile unsigned char CH5;
52 walter 27
 
56 walter 28
uint16_t EEMEM EEPMIN=0x0000;
29
uint16_t EEMEM EEPMAX=0xffff;
30
uint16_t EEMEM EEPSIG=0xffff;
52 walter 31
 
56 walter 32
 
33
//led kennlinie, (noch nicht implementiert, nur vorbereitet)
34
unsigned char kl[256]={
35
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
36
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
37
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
38
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
39
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
40
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
41
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
42
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
43
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
44
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
45
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
46
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
47
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
48
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
49
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
50
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
51
};
52
 
53
 
54
 
55 walter 55
/*##############################################################################*/
28 walter 56
SIGNAL(SIG_OVERFLOW1)
57
{
58
        TMR1OvF++;
59
}
60
 
61
 
62
SIGNAL(SIG_INPUT_CAPTURE1)
63
{
64
        static unsigned int pos_ICR;
65
        static unsigned int ppm;
66
 
67
        if ((TCCR1B & (1<<ICES1)) != 0)                                         //rising edge
68
        {
69
                TCCR1B &= ~(1<<ICES1);                                                          //set falling egde
70
                TMR1OvF = 0;
71
                pos_ICR = ICR1;
72
        }
73
        else                                                                                    //falling edge
74
        {
75
                TCCR1B |= (1<<ICES1);                                                           //set rising egde
76
                ppm = (ICR1 - pos_ICR + (int) TMR1OvF * 65536);
77
                if ((ppm > 600) && (ppm < 2400))
78
                {
79
                        if (ppm > 2100) ppm = 2100;
80
                        if (ppm < 900) ppm = 900;
55 walter 81
                        ppm = (PPM_SIGNAL * 3 + ppm) / 4;
82
                        PPM_SIGNAL = ppm;
83
                        if (PPM_NEW < 50) PPM_NEW++;
28 walter 84
                }
85
 
86
        }
87
 
88
}
89
 
55 walter 90
/*##############################################################################*/
28 walter 91
SIGNAL(SIG_OVERFLOW0)
92
{
52 walter 93
        // this function is called every 32us,
94
        // it is very important that it's execution time is as short as possible
95
        // currently it's about 20us
96
 
97
        static unsigned char counter = 254;
98
        static unsigned char ms1 = 0;
55 walter 99
        static unsigned char ch0_tmp = 0;
100
        static unsigned char ch1_tmp = 0;
101
        static unsigned char ch2_tmp = 0;
102
        static unsigned char ch3_tmp = 0;
103
        static unsigned char ch4_tmp = 0;
104
        static unsigned char ch5_tmp = 0;
28 walter 105
        unsigned char PORTB_BAK;
106
        unsigned char PORTD_BAK;       
107
 
108
        PORTB_BAK = PORTB;
109
        PORTD_BAK = PORTD;
110
 
51 walter 111
        if (counter++ == 254)
28 walter 112
        {
55 walter 113
                PORTB_BAK LEDON (CH0_B | CH1_B | CH2_B);                //new cycle, output on
114
                PORTD_BAK LEDON (CH3_D | CH4_D | CH5_D);                //
115
                ch0_tmp = CH0;
116
                ch1_tmp = CH1;
117
                ch2_tmp = CH2;
118
                ch3_tmp = CH3;
119
                ch4_tmp = CH4;
120
                ch5_tmp = CH5;         
51 walter 121
                counter = 0;
28 walter 122
        }
123
 
55 walter 124
        if (ch0_tmp == counter) PORTB_BAK LEDOFF CH0_B;         //channel value reached, output off
125
        if (ch1_tmp == counter) PORTB_BAK LEDOFF CH1_B;         //
126
        if (ch2_tmp == counter) PORTB_BAK LEDOFF CH2_B;         //
127
        if (ch3_tmp == counter) PORTD_BAK LEDOFF CH3_D;         //
128
        if (ch4_tmp == counter) PORTD_BAK LEDOFF CH4_D;         //
129
        if (ch5_tmp == counter) PORTD_BAK LEDOFF CH5_D;         //
51 walter 130
 
131
        PORTB = PORTB_BAK;
132
        PORTD = PORTD_BAK;
54 walter 133
 
51 walter 134
        if (ms1++ == 32)
28 walter 135
        {
51 walter 136
                ms1=0;
137
                TMR1MS++;
28 walter 138
        }
51 walter 139
 
28 walter 140
 
141
 
142
 
51 walter 143
}
28 walter 144
 
145
 
55 walter 146
/*##############################################################################*/
51 walter 147
unsigned int SetDelay (unsigned int t)
148
{
55 walter 149
        unsigned char hi_byte;
150
        unsigned char lo_byte;  
28 walter 151
 
55 walter 152
        hi_byte = (TMR1MS >> 8);
153
        lo_byte = (TMR1MS & 0xff);
154
        if (hi_byte != (TMR1MS >> 8)) hi_byte = (TMR1MS >> 8);
28 walter 155
 
55 walter 156
        return(((hi_byte << 8) | lo_byte)  + t + 1);                                            
51 walter 157
}
28 walter 158
 
159
 
55 walter 160
/*##############################################################################*/
51 walter 161
char CheckDelay(unsigned int t)
162
{
55 walter 163
        unsigned char hi_byte;
164
        unsigned char lo_byte;  
51 walter 165
 
55 walter 166
        hi_byte = (TMR1MS >> 8);
167
        lo_byte = (TMR1MS & 0xff);
168
        if (hi_byte != (TMR1MS >> 8)) hi_byte = (TMR1MS >> 8);
51 walter 169
 
55 walter 170
        return(((t - ((hi_byte << 8) | lo_byte)) & 0x8000) >> 9);
28 walter 171
}
172
 
173
 
174
 
175
/*##############################################################################*/
51 walter 176
void StartPWM(void)
28 walter 177
{
55 walter 178
        //Timer 0 Config
28 walter 179
        TCCR0 = (0<<CS02)|(0<<CS01)|(1<<CS00);          // (@8MHz) =  1/8us Clk = 256/8 = 32us overflow
180
        TIMSK setbit (1<<TOIE0);                                                // enable Int
181
 
182
}
183
 
184
 
185
/*##############################################################################*/
186
void StartPPM(void)
187
{
188
 
55 walter 189
        //Timer1 Config
28 walter 190
        TCCR1A =        (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|
191
                                (0<<FOC1A) |(0<<FOC1B) |(0<<WGM10) |(0<<WGM11);                
192
    TCCR1B =    (1<<ICNC1)|(1<<ICES1)|(0<<WGM13)|
193
                                (0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);                               //ICP_POS_FLANKE
194
 
195
        // interrupts
196
        TIMSK |=        (1<<TICIE1)|(1<<TOIE1);                                                                 //ICP_INT_ENABLE and TIMER1_INT_ENABLE
197
 
198
}
199
 
200
 
52 walter 201
/*##############################################################################*/
54 walter 202
unsigned int GetPPM(void)
28 walter 203
{
204
        //this routines seems to be nesseccary, as reading a 16 bit value
205
        //on a 8 bit machine is not atomic, so if an interrupt apears between reading
206
        //low and high byte of the 16 bit value a wrong result is possible
207
 
54 walter 208
        unsigned char temp_hi;
209
        unsigned char temp_lo;  
28 walter 210
 
55 walter 211
        temp_hi = (PPM_SIGNAL >> 8);
212
        temp_lo = (PPM_SIGNAL & 0xff);
213
        if (temp_hi != (PPM_SIGNAL >> 8)) temp_hi = (PPM_SIGNAL >> 8);
54 walter 214
        return( (temp_hi << 8) | temp_lo);                                            
28 walter 215
 
216
}
217
 
218
 
219
/*##############################################################################*/
220
// MAIN
221
/*##############################################################################*/
222
int main (void)
223
{
54 walter 224
 
55 walter 225
        #define STEP            256
226
        #define MUL                     1
56 walter 227
        #define REDUCE          2
54 walter 228
 
56 walter 229
        #define EEPSIGNATURE    0x55aa
54 walter 230
 
57 walter 231
        #define inimin          1200
232
        #define inimax          1800    
233
 
53 walter 234
        unsigned int    ppm;
55 walter 235
        signed int              color; 
54 walter 236
        unsigned int    setupdly;
237
        unsigned int    ppmtodly;      
55 walter 238
        unsigned int    flashdly;
239
        unsigned char   setup;
54 walter 240
        unsigned int    lmax;
241
        unsigned int    lmin;
242
        unsigned int    max;
243
        unsigned int    min;
57 walter 244
        signed long             temp1; 
245
        signed long             temp2;         
28 walter 246
 
51 walter 247
    DDRB  = (CH0_B|CH1_B|CH2_B);
248
    PORTB = 0x00;
249
 
250
    DDRC  = (ledred);
28 walter 251
    PORTC = 0x00;
51 walter 252
 
253
    DDRD  = (ledgreen|CH3_D|CH4_D|CH5_D);
28 walter 254
    PORTD = 0x00;
255
 
55 walter 256
        CH0 = 0;
257
        CH1 = 0;
258
        CH2 = 0;
259
        CH3 = 0;
260
        CH4 = 0;
261
        CH5 = 0;       
28 walter 262
 
54 walter 263
        lmax = 0x0000;
264
        lmin = 0xffff;
265
 
57 walter 266
//      StartUART();
28 walter 267
        StartPPM();
51 walter 268
        //StartI2C();
28 walter 269
        StartPWM();
270
        sei();
271
 
57 walter 272
        min = inimin;                                                                                           //default min 
273
        max = inimax;                                                                                           //default max
274
 
275
        if (eeprom_read_word(&EEPSIG) != EEPSIGNATURE)                          //check eep if signature is there
54 walter 276
        {
56 walter 277
                eeprom_write_word(&EEPMIN, min);                                                //no, write initial min
278
                eeprom_write_word(&EEPMAX, max);                                                //and max values
279
                eeprom_write_word(&EEPSIG, EEPSIGNATURE);                               //along with eep signature
54 walter 280
        }
281
        else
282
        {
57 walter 283
 
56 walter 284
                min = eeprom_read_word(&EEPMIN);                                                //signature ok
285
                max = eeprom_read_word(&EEPMAX);                                                //read min and max
54 walter 286
        }
51 walter 287
 
57 walter 288
 
55 walter 289
        setup = 0;                                                                                                      //reset setup toggle counter
56 walter 290
        setupdly = SetDelay(5000);
54 walter 291
        ppmtodly = SetDelay(5000);     
56 walter 292
        flashdly = SetDelay(1000);                                                             
28 walter 293
 
294
    while (1)
295
        {
51 walter 296
 
55 walter 297
                if (PPM_NEW > 20)                                                                               //ppm Signal ok 
54 walter 298
                {
299
                        PORTC clrbit ledred;
55 walter 300
                        ppm = GetPPM();                        
301
                        ppmtodly = SetDelay(500);                                                       //reset timeout                 
302
                        if (lmax < ppm) lmax=ppm;                                                       //update impulse max 
303
                        if (lmin > ppm) lmin=ppm;                                                       //and min boundarys
54 walter 304
                }
305
                else
306
                {
55 walter 307
                        PORTC setbit ledred;                                                            //ppm signal not ok
308
                        ppm = min;                                                                                      //set ppm to minimum
54 walter 309
                }
310
 
55 walter 311
 
312
                if (CheckDelay(ppmtodly))                                                               //timeout 
54 walter 313
                {
55 walter 314
                        ppmtodly = SetDelay(5000);             
315
                        PPM_NEW = 0;                                                                            //set ppm signal not ok
316
                }      
317
 
318
 
319
                if (setup < 6)
320
                {
321
                        if ((ppm > 1600) && ((setup&1)==0)) setup++;            //
322
                        if ((ppm < 1400) && ((setup&1)==1)) setup++;            //
323
 
56 walter 324
                        if (CheckDelay(flashdly))                                                      
55 walter 325
                        {      
326
                                CH0 = CH0 ^ 0xff;
327
                                CH1 = CH1 ^ 0xff;
328
                                CH2 = CH2 ^ 0xff;
329
                                flashdly = SetDelay(250);                                                              
330
                        }
54 walter 331
                }
28 walter 332
 
55 walter 333
                if (setup == 6)                                                                                 //if stick is toggled 6 times 
334
                {                                                                                                               //within setup timeout
335
                        PORTD setbit ledgreen;                                                          //store ppm min and max 
56 walter 336
                        setupdly = SetDelay(3000);                                                      //for 2000ms
337
                        eeprom_write_word(&EEPMIN, lmin);                                       //in eeprom
338
                        eeprom_write_word(&EEPMAX, lmax);      
55 walter 339
                        min = lmin;                                                                                    
54 walter 340
                        max = lmax;
56 walter 341
                        setup = 7;                                                                                      //enter PWM toggle mode
55 walter 342
 
56 walter 343
                }
344
 
345
 
346
                if (setup == 7)
347
                {
348
                        if (CheckDelay(flashdly))                                                       //each 25ms toggle PWM's 
55 walter 349
                        {      
350
                                CH0 = CH0 ^ 0xff;
351
                                CH1 = CH1 ^ 0xff;
352
                                CH2 = CH2 ^ 0xff;
353
                                flashdly = SetDelay(25);                                                               
354
                        }
56 walter 355
 
54 walter 356
                }
55 walter 357
 
358
                if (CheckDelay(setupdly))                                                               //setup timeout reached
54 walter 359
                {
56 walter 360
                        setup = 8;                                                                                      //lockdown setup
54 walter 361
                        PORTD clrbit ledgreen;
362
                }
53 walter 363
 
54 walter 364
 
56 walter 365
                if (setup == 8)
51 walter 366
                {
54 walter 367
 
57 walter 368
 
369
 
370
                        temp1 = ((long)STEP * 6 * 20000) / ((max-REDUCE) - (min+REDUCE));
371
                        temp2 = (((int)ppm - ((int)min+REDUCE)) * temp1);
372
                        color = temp2 / 20000;
373
 
55 walter 374
                        if (color < 0) color = 0;
57 walter 375
                        if (color > ((STEP*6)+1)) color = ((STEP*6)+1);
376
 
55 walter 377
 
57 walter 378
                        //printf("p %u  ",ppm);
379
                        //printf("pm %u  ",(min+REDUCE));
380
                        //printf("t1 %li  ",temp1);
381
                        //printf("t2 %li  ",temp2);
382
                        //printf("c %i\n  ",color);                                     
56 walter 383
 
57 walter 384
 
55 walter 385
                        // Farbablauf: rot > Violett > blau > tuerkis > gruen > gelb >
386
                        if ((color >= (STEP * 0)) && (color < (STEP * 1)))
387
                        {
388
                                CH0 = MUL * ((color - (STEP * 0)));                             //fade in red > red (red only)
389
                                CH1 = 0;
390
                                CH2 = 0;
391
                        }
392
                        if ((color >= (STEP * 1)) && (color < (STEP * 2)))
393
                        {
394
                                CH0 = ((STEP-1) * MUL);
395
                                CH1 = 0;
396
                                CH2 = MUL * ((color - (STEP * 1)));                             //fade in blue > purple (red + blue)
397
                        }
398
                        if ((color >= (STEP * 2)) && (color < (STEP * 3)))
399
                        {
400
                                CH0 = MUL * ((STEP - 1) - (color - (STEP * 2)));        //fade out red > blue (blue only)
401
                                CH1 = 0;
402
                                CH2 = ((STEP-1) * MUL);
403
                        }
404
                        if ((color >= (STEP * 3)) && (color < (STEP * 4)))
405
                        {
406
                                CH0 = 0;
407
                                CH1 = MUL * ((color - (STEP * 3)));                             //fade in green > cyan (blue + green)
408
                                CH2 = ((STEP-1) * MUL);
409
                        }
410
                        if ((color >= (STEP * 4)) && (color < (STEP * 5)))
411
                        {
412
                                CH0 = 0;
413
                                CH1 = ((STEP-1) * MUL);
414
                                CH2 = MUL * ((STEP - 1) - (color - (STEP * 4)));        //fade out blue > green (green only)
415
                        }
416
                        if ((color >= (STEP * 5)) && (color < (STEP * 6)))
417
                        {
418
                                CH0 = MUL * ((color - (STEP * 5)));                             //fade in red > yellow (green + red)
419
                                CH1 = ((STEP-1) * MUL);
420
                                CH2 = 0;
421
                        }
422
                        if (color >= (STEP * 6))  
423
                        {
424
                                CH0 = ((STEP-1) * MUL);                                                 //fade in red > yellow (green + red)
425
                                CH1 = ((STEP-1) * MUL);
426
                                CH2 = 0;
427
                        }
428
                }
51 walter 429
 
430
 
28 walter 431
        }
432
 
433
}
52 walter 434