Subversion Repositories Projects

Rev

Rev 64 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
64 walter 1
//############################################################################
2
// - PWM CTRL 
3
// - Main
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
 
17
volatile unsigned int PPM_SIGNAL = 1520;
18
volatile unsigned char PPM_NEW = 0;
19
volatile unsigned char TMR1OvF = 0;
20
volatile unsigned int  TMR1MS;
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;
27
 
28
uint16_t EEMEM EEPMIN=0x0000;
29
uint16_t EEMEM EEPMAX=0xffff;
30
uint16_t EEMEM EEPSIG=0xffff;
31
 
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
/*##############################################################################*/
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;
81
                        ppm = (PPM_SIGNAL * 3 + ppm) / 4;
82
                        PPM_SIGNAL = ppm;
83
                        if (PPM_NEW < 50) PPM_NEW++;
84
                }
85
 
86
        }
87
 
88
}
89
 
90
/*##############################################################################*/
91
SIGNAL(SIG_OVERFLOW0)
92
{
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;
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;
105
        unsigned char PORTB_BAK;
106
        unsigned char PORTD_BAK;       
107
 
108
        PORTB_BAK = PORTB;
109
        PORTD_BAK = PORTD;
110
 
111
        if (counter++ == 254)
112
        {
113
                PORTB_BAK LEDON (CH0_B | CH1_B | CH2_B);                //new cycle, output on
114
                PORTD_BAK LEDON (CH3_D | CH4_D | CH5_D);                //
65 walter 115
 
64 walter 116
                ch0_tmp = CH0;
117
                ch1_tmp = CH1;
118
                ch2_tmp = CH2;
119
                ch3_tmp = CH3;
120
                ch4_tmp = CH4;
121
                ch5_tmp = CH5;         
65 walter 122
 
64 walter 123
                counter = 0;
124
        }
125
 
126
        if (ch0_tmp == counter) PORTB_BAK LEDOFF CH0_B;         //channel value reached, output off
127
        if (ch1_tmp == counter) PORTB_BAK LEDOFF CH1_B;         //
128
        if (ch2_tmp == counter) PORTB_BAK LEDOFF CH2_B;         //
129
        if (ch3_tmp == counter) PORTD_BAK LEDOFF CH3_D;         //
130
        if (ch4_tmp == counter) PORTD_BAK LEDOFF CH4_D;         //
131
        if (ch5_tmp == counter) PORTD_BAK LEDOFF CH5_D;         //
132
 
133
        PORTB = PORTB_BAK;
134
        PORTD = PORTD_BAK;
135
 
136
        if (ms1++ == 32)
137
        {
138
                ms1=0;
139
                TMR1MS++;
140
        }
141
 
142
 
143
 
144
 
145
}
146
 
147
 
148
/*##############################################################################*/
149
unsigned int SetDelay (unsigned int t)
150
{
151
        unsigned char hi_byte;
152
        unsigned char lo_byte;  
153
 
154
        hi_byte = (TMR1MS >> 8);
155
        lo_byte = (TMR1MS & 0xff);
156
        if (hi_byte != (TMR1MS >> 8)) hi_byte = (TMR1MS >> 8);
157
 
158
        return(((hi_byte << 8) | lo_byte)  + t + 1);                                            
159
}
160
 
161
 
162
/*##############################################################################*/
163
char CheckDelay(unsigned int t)
164
{
165
        unsigned char hi_byte;
166
        unsigned char lo_byte;  
167
 
168
        hi_byte = (TMR1MS >> 8);
169
        lo_byte = (TMR1MS & 0xff);
170
        if (hi_byte != (TMR1MS >> 8)) hi_byte = (TMR1MS >> 8);
171
 
172
        return(((t - ((hi_byte << 8) | lo_byte)) & 0x8000) >> 9);
173
}
174
 
175
 
176
 
177
/*##############################################################################*/
178
void StartPWM(void)
179
{
180
        //Timer 0 Config
181
        TCCR0 = (0<<CS02)|(0<<CS01)|(1<<CS00);          // (@8MHz) =  1/8us Clk = 256/8 = 32us overflow
182
        TIMSK setbit (1<<TOIE0);                                                // enable Int
183
 
184
}
185
 
186
 
187
/*##############################################################################*/
188
void StartPPM(void)
189
{
190
 
191
        //Timer1 Config
192
        TCCR1A =        (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|
193
                                (0<<FOC1A) |(0<<FOC1B) |(0<<WGM10) |(0<<WGM11);                
194
    TCCR1B =    (1<<ICNC1)|(1<<ICES1)|(0<<WGM13)|
195
                                (0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);                               //ICP_POS_FLANKE
196
 
197
        // interrupts
198
        TIMSK |=        (1<<TICIE1)|(1<<TOIE1);                                                                 //ICP_INT_ENABLE and TIMER1_INT_ENABLE
199
 
200
}
201
 
202
 
203
/*##############################################################################*/
204
unsigned int GetPPM(void)
205
{
206
        //this routines seems to be nesseccary, as reading a 16 bit value
207
        //on a 8 bit machine is not atomic, so if an interrupt apears between reading
208
        //low and high byte of the 16 bit value a wrong result is possible
209
 
210
        unsigned char temp_hi;
211
        unsigned char temp_lo;  
212
 
213
        temp_hi = (PPM_SIGNAL >> 8);
214
        temp_lo = (PPM_SIGNAL & 0xff);
215
        if (temp_hi != (PPM_SIGNAL >> 8)) temp_hi = (PPM_SIGNAL >> 8);
216
        return( (temp_hi << 8) | temp_lo);                                            
217
 
218
}
219
 
220
 
221
/*##############################################################################*/
222
// MAIN
223
/*##############################################################################*/
224
int main (void)
225
{
226
 
227
        #define STEP            256
228
        #define MUL                     1
229
        #define REDUCE          2
230
 
231
        #define EEPSIGNATURE    0x55aa
232
 
233
        #define inimin          1200
234
        #define inimax          1800    
235
 
236
        unsigned int    ppm;
237
        signed int              color; 
65 walter 238
        volatile unsigned int   setupdly;
239
        volatile unsigned int   ppmtodly;      
240
        volatile unsigned int   flashdly;
241
 
242
        volatile unsigned int   dly1;
243
 
244
        unsigned char   flags;
245
 
64 walter 246
        unsigned char   setup;
247
        unsigned int    lmax;
248
        unsigned int    lmin;
249
        unsigned int    max;
250
        unsigned int    min;
65 walter 251
        unsigned char   temp;
64 walter 252
        signed long             temp1; 
253
        signed long             temp2;         
254
 
65 walter 255
        flags = 0;
256
 
64 walter 257
    DDRB  = (CH0_B|CH1_B|CH2_B);
258
    PORTB = 0x00;
259
 
260
    DDRC  = (ledred);
261
    PORTC = 0x00;
262
 
263
    DDRD  = (ledgreen|CH3_D|CH4_D|CH5_D);
264
    PORTD = 0x00;
265
 
65 walter 266
        CH0 = 0xFF;             //PORTB RGBLED red
267
        CH1 = 0xFF;             //PORTB RGBLED green
268
        CH2 = 0xFF;             //PORTB RGBLED blue
269
        CH3 = 0;       
64 walter 270
        CH4 = 0;
271
        CH5 = 0;       
272
 
273
        lmax = 0x0000;
274
        lmin = 0xffff;
275
 
65 walter 276
        StartUART();
64 walter 277
        StartPPM();
278
        //StartI2C();
279
        StartPWM();
280
        sei();
281
 
282
        min = inimin;                                                                                           //default min 
283
        max = inimax;                                                                                           //default max
284
 
285
        if (eeprom_read_word(&EEPSIG) != EEPSIGNATURE)                          //check eep if signature is there
286
        {
287
                eeprom_write_word(&EEPMIN, min);                                                //no, write initial min
288
                eeprom_write_word(&EEPMAX, max);                                                //and max values
289
                eeprom_write_word(&EEPSIG, EEPSIGNATURE);                               //along with eep signature
290
        }
291
        else
292
        {
293
 
294
                min = eeprom_read_word(&EEPMIN);                                                //signature ok
295
                max = eeprom_read_word(&EEPMAX);                                                //read min and max
296
        }
297
 
298
 
299
        setup = 0;                                                                                                      //reset setup toggle counter
65 walter 300
        temp = (1<<0);
64 walter 301
        setupdly = SetDelay(5000);
65 walter 302
        ppmtodly = SetDelay(2000);     
303
        flashdly = SetDelay(200);                                                              
64 walter 304
 
305
    while (1)
306
        {
307
 
308
                if (PPM_NEW > 20)                                                                               //ppm Signal ok 
309
                {
310
                        PORTC clrbit ledred;
311
                        ppm = GetPPM();                        
312
                        ppmtodly = SetDelay(500);                                                       //reset timeout                 
313
                        if (lmax < ppm) lmax=ppm;                                                       //update impulse max 
314
                        if (lmin > ppm) lmin=ppm;                                                       //and min boundarys
315
                }
316
                else
317
                {
318
                        PORTC setbit ledred;                                                            //ppm signal not ok
319
                        ppm = min;                                                                                      //set ppm to minimum
320
                }
321
 
322
 
323
                if (CheckDelay(ppmtodly))                                                               //timeout 
324
                {
325
                        ppmtodly = SetDelay(5000);             
326
                        PPM_NEW = 0;                                                                            //set ppm signal not ok
327
                }      
328
 
329
 
330
                if (setup < 6)
331
                {
332
                        if ((ppm > 1600) && ((setup&1)==0)) setup++;            //
333
                        if ((ppm < 1400) && ((setup&1)==1)) setup++;            //
334
 
335
                        if (CheckDelay(flashdly))                                                      
336
                        {      
65 walter 337
                                CH0 = (temp & (1<<0)) * 255;
338
                                CH1 = (temp & (1<<1)) * 255;
339
                                CH2 = (temp & (1<<2)) * 255;
340
                                CH3 = (temp & (1<<3)) * 255;                           
341
                                CH4 = (temp & (1<<4)) * 255;
342
                                CH5 = (temp & (1<<5)) * 255;                           
343
                                temp <<= 1;
344
                                if (temp == (1<<6)) temp = (1<<0);
345
 
346
                                /*
347
                                CH0 = CH0 ^ 0xff;                                                               //invert brightness
64 walter 348
                                CH1 = CH1 ^ 0xff;
349
                                CH2 = CH2 ^ 0xff;
65 walter 350
                                CH3 = CH3 ^ 0xff;
351
                                CH4 = CH4 ^ 0xff;
352
                                CH5 = CH5 ^ 0xff;
353
                                */
354
 
355
                                flashdly = SetDelay(100);                                                              
64 walter 356
                        }
357
                }
358
 
359
                if (setup == 6)                                                                                 //if stick is toggled 6 times 
360
                {                                                                                                               //within setup timeout
361
                        PORTD setbit ledgreen;                                                          //store ppm min and max 
362
                        setupdly = SetDelay(3000);                                                      //for 2000ms
363
                        eeprom_write_word(&EEPMIN, lmin);                                       //in eeprom
364
                        eeprom_write_word(&EEPMAX, lmax);      
365
                        min = lmin;                                                                                    
366
                        max = lmax;
367
                        setup = 7;                                                                                      //enter PWM toggle mode
368
 
369
                }
370
 
371
 
372
                if (setup == 7)
373
                {
374
                        if (CheckDelay(flashdly))                                                       //each 25ms toggle PWM's 
375
                        {      
65 walter 376
                                CH0 = CH0 ^ 0xff;                                                               //invert brightness
64 walter 377
                                CH1 = CH1 ^ 0xff;
378
                                CH2 = CH2 ^ 0xff;
65 walter 379
                                CH3 = CH3 ^ 0xff;
380
                                CH4 = CH4 ^ 0xff;
381
                                CH5 = CH5 ^ 0xff;
382
 
64 walter 383
                                flashdly = SetDelay(25);                                                               
384
                        }
385
 
386
                }
387
 
65 walter 388
                if ((CheckDelay(setupdly)) && setup < 8)                                //setup timeout reached
64 walter 389
                {
390
                        setup = 8;                                                                                      //lockdown setup
391
                        PORTD clrbit ledgreen;
65 walter 392
                        CH0 = 0;                                                                                        //start CH3
393
                        CH1 = 85;                                                                                       //CH4
394
                        CH2 = 170;                                                                                      //and CH4 with about 120° phase shift
395
 
396
                        flags = 0;
397
                        dly1 = SetDelay(100);                                                                                  
64 walter 398
                }
399
 
400
 
401
                if (setup == 8)
402
                {
403
 
65 walter 404
 
405
/************************************************************************************/                 
406
/* control CH3, CH4 and CH5     (RGB LED) */
407
/************************************************************************************/                 
408
 
409
                        temp1 = ((long)STEP * 7 * 40000) / ((max-REDUCE) - (min+REDUCE));
64 walter 410
                        temp2 = (((int)ppm - ((int)min+REDUCE)) * temp1);
65 walter 411
                        color = temp2 / 40000;
64 walter 412
 
413
                        if (color < 0) color = 0;
65 walter 414
                        if (color > ((STEP*7)+1)) color = ((STEP*7)+1);
64 walter 415
 
416
 
417
                        //printf("p %u  ",ppm);
418
                        //printf("pm %u  ",(min+REDUCE));
419
                        //printf("t1 %li  ",temp1);
420
                        //printf("t2 %li  ",temp2);
421
                        //printf("c %i\n  ",color);                                     
422
 
423
 
65 walter 424
                        // Farbablauf: off > red > purple > blue > cyan > green > yellow > white
64 walter 425
                        if ((color >= (STEP * 0)) && (color < (STEP * 1)))
426
                        {
65 walter 427
                                CH3 = MUL * ((color - (STEP * 0)));                             //fade in red > red (red only)
428
                                CH4 = 0;
429
                                CH5 = 0;
64 walter 430
                        }
431
                        if ((color >= (STEP * 1)) && (color < (STEP * 2)))
432
                        {
65 walter 433
                                CH3 = ((STEP-1) * MUL);
434
                                CH4 = 0;
435
                                CH5 = MUL * ((color - (STEP * 1)));                             //fade in blue > purple (red + blue)
64 walter 436
                        }
437
                        if ((color >= (STEP * 2)) && (color < (STEP * 3)))
438
                        {
65 walter 439
                                CH3 = MUL * ((STEP - 1) - (color - (STEP * 2)));        //fade out red > blue (blue only)
440
                                CH4 = 0;
441
                                CH5 = ((STEP-1) * MUL);
64 walter 442
                        }
443
                        if ((color >= (STEP * 3)) && (color < (STEP * 4)))
444
                        {
65 walter 445
                                CH3 = 0;
446
                                CH4 = MUL * ((color - (STEP * 3)));                             //fade in green > cyan (blue + green)
447
                                CH5 = ((STEP-1) * MUL);
64 walter 448
                        }
449
                        if ((color >= (STEP * 4)) && (color < (STEP * 5)))
450
                        {
65 walter 451
                                CH3 = 0;
452
                                CH4 = ((STEP-1) * MUL);
453
                                CH5 = MUL * ((STEP - 1) - (color - (STEP * 4)));        //fade out blue > green (green only)
64 walter 454
                        }
455
                        if ((color >= (STEP * 5)) && (color < (STEP * 6)))
456
                        {
65 walter 457
                                CH3 = MUL * ((color - (STEP * 5)));                             //fade in red > yellow (green + red)
458
                                CH4 = ((STEP-1) * MUL);
459
                                CH5 = 0;
64 walter 460
                        }
65 walter 461
                        if ((color >= (STEP * 6)) && (color < (STEP * 7)))
64 walter 462
                        {
65 walter 463
                                CH3 = ((STEP-1) * MUL);
464
                                CH4 = ((STEP-1) * MUL);
465
                                CH5 = MUL * ((color - (STEP * 1)));                             //fade in blue > purple (red + blue)
64 walter 466
                        }
65 walter 467
 
468
                        if (color >= (STEP * 7))  
469
                        {
470
                                CH3 = ((STEP-1) * MUL);
471
                                CH4 = ((STEP-1) * MUL);
472
                                CH5 = ((STEP-1) * MUL);
473
                        }
474
 
475
/************************************************************************************/                 
476
/* control CH0, CH1 and CH2     */
477
/************************************************************************************/                 
478
 
479
                        if (CheckDelay(dly1))                                           //timeout reached ?
480
                        {      
481
 
482
                                if ((flags & (1<<0))==0)                                //check if up or down
483
                                {
484
                                        if (CH0++ == 254)                                       //run CH0 up to 255
485
                                        {
486
                                                flags setbit (1<<0);                    //255 reached next time go down
487
 
488
                                        }
489
                                }
490
                                else                                                                    //run down
491
                                {
492
                                        if (CH0-- == 1)                                 //run CH0 down to 0
493
                                        {
494
                                                flags clrbit (1<<0);                    //0 reached next time go up
495
                                        }
496
 
497
                                }
498
 
499
 
500
                                if ((flags & (1<<1))==0)                                //same for CH1
501
                                {
502
                                        if (CH1++ == 254)
503
                                        {
504
                                                flags setbit (1<<1);
505
                                        }
506
                                }
507
                                else
508
                                {
509
                                        if (CH1-- == 1)
510
                                        {
511
                                                flags clrbit (1<<1);
512
                                        }
513
 
514
                                }
515
 
516
 
517
                                if ((flags & (1<<2))==0)                                //and same for CH2
518
                                {
519
                                        if (CH2++ == 254)
520
                                        {
521
                                                flags setbit (1<<2);
522
                                        }
523
                                }
524
                                else
525
                                {
526
                                        if (CH2-- == 1)
527
                                        {
528
                                                flags clrbit (1<<2);
529
                                        }
530
 
531
                                }
532
 
533
 
534
                                dly1 = SetDelay(1);                                             //set next timeout in 25ms                                                                                      
535
 
536
//                              printf("ch3:%i\n",CH0);
537
                        }
538
 
64 walter 539
                }
540
 
541
        }
542
 
543
}
544