Subversion Repositories Projects

Rev

Rev 51 | Rev 53 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

//############################################################################
// - PWM CTRL
// - Main
// - ATMEGA8 mit 8MHz
// - Nur für den privaten Gebrauch
// - Keine Garantie auf Fehlerfreiheit
// - Kommerzielle Nutzung nur mit meiner Zustimmung
// - walter Meyer @ www.freakware.de
// - 11.12.2007
// - Make sure Fuses are programmed for internal 8 MHz RC Oscilator
//############################################################################*/

#include "main.h"
#include "uart.h"
#include "twislave.h"

volatile unsigned int ppm_signal = 1500;
volatile unsigned char ppm_new = 0;
volatile unsigned char TMR1OvF = 0;
volatile unsigned int  TMR1MS;
volatile unsigned char ch0;
volatile unsigned char ch1;
volatile unsigned char ch2;
volatile unsigned char ch3;
volatile unsigned char ch4;
volatile unsigned char ch5;
volatile unsigned char ch0_tmp;
volatile unsigned char ch1_tmp;
volatile unsigned char ch2_tmp;
volatile unsigned char ch3_tmp;
volatile unsigned char ch4_tmp;
volatile unsigned char ch5_tmp;


unsigned int timer;

SIGNAL(SIG_OVERFLOW1)
{
        TMR1OvF++;
}


SIGNAL(SIG_INPUT_CAPTURE1)
{
        static unsigned int pos_ICR;
        static unsigned int ppm;
       
        if ((TCCR1B & (1<<ICES1)) != 0)                                         //rising edge
        {
                TCCR1B &= ~(1<<ICES1);                                                          //set falling egde
                TMR1OvF = 0;
                pos_ICR = ICR1;
        }
        else                                                                                    //falling edge
        {
                TCCR1B |= (1<<ICES1);                                                           //set rising egde
                ppm = (ICR1 - pos_ICR + (int) TMR1OvF * 65536);
                if ((ppm > 600) && (ppm < 2400))
                {
                        if (ppm > 2100) ppm = 2100;
                        if (ppm < 900) ppm = 900;
                        ppm = (ppm_signal * 7 + ppm) / 8;
                        ppm_signal = ppm;
                        ppm_new = 1;
                }
               
        }

}





SIGNAL(SIG_OVERFLOW0)
{
        // this function is called every 32us,
        // it is very important that it's execution time is as short as possible
        // currently it's about 20us

        static unsigned char counter = 254;
        static unsigned char ms1 = 0;
        unsigned char PORTB_BAK;
        unsigned char PORTD_BAK;       

        PORTB_BAK = PORTB;
        PORTD_BAK = PORTD;

        if (counter++ == 254)
        {
                PORTB_BAK LEDON (CH0_B | CH1_B | CH2_B);
                PORTD_BAK LEDON (CH3_D | CH4_D | CH5_D);       
                ch0_tmp = ch0;
                ch1_tmp = ch1;
                ch2_tmp = ch2;
                ch3_tmp = ch3;
                ch4_tmp = ch4;
                ch5_tmp = ch5;         
                counter = 0;
        }

        if (ch0_tmp == counter) PORTB_BAK LEDOFF CH0_B;
        if (ch1_tmp == counter) PORTB_BAK LEDOFF CH1_B;
        if (ch2_tmp == counter) PORTB_BAK LEDOFF CH2_B;
        if (ch3_tmp == counter) PORTD_BAK LEDOFF CH3_D;
        if (ch4_tmp == counter) PORTD_BAK LEDOFF CH4_D;
        if (ch5_tmp == counter) PORTD_BAK LEDOFF CH5_D;
       
        PORTB = PORTB_BAK;
        PORTD = PORTD_BAK;

        if (ms1++ == 32)
        {
                ms1=0;
                TMR1MS++;
        }
       



}



unsigned int SetDelay (unsigned int t)
{
        unsigned char temp_hi;
        unsigned char temp_lo;  

        temp_hi = (TMR1MS >> 8);
        temp_lo = (TMR1MS & 0xff);
        if (temp_hi != (TMR1MS >> 8)) temp_hi = (TMR1MS >> 8);

        return(((temp_hi << 8) | temp_lo)  + t + 1);                                            

}


char CheckDelay(unsigned int t)
{
        unsigned char temp_hi;
        unsigned char temp_lo;  

        temp_hi = (TMR1MS >> 8);
        temp_lo = (TMR1MS & 0xff);
        if (temp_hi != (TMR1MS >> 8)) temp_hi = (TMR1MS >> 8);

        return(((t - ((temp_hi << 8) | temp_lo)) & 0x8000) >> 9);

}




/*##############################################################################*/
void StartPWM(void)
{
        //Timer 0 Config for getting right timing for IR Pattern
        TCCR0 = (0<<CS02)|(0<<CS01)|(1<<CS00);          // (@8MHz) =  1/8us Clk = 256/8 = 32us overflow
        TIMSK setbit (1<<TOIE0);                                                // enable Int

}



/*##############################################################################*/
void StartPPM(void)
{
       
        //global timer1 Config
        TCCR1A =        (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|
                                (0<<FOC1A) |(0<<FOC1B) |(0<<WGM10) |(0<<WGM11);                
    TCCR1B =    (1<<ICNC1)|(1<<ICES1)|(0<<WGM13)|
                                (0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);                               //ICP_POS_FLANKE

        // interrupts
        TIMSK |=        (1<<TICIE1)|(1<<TOIE1);                                                                 //ICP_INT_ENABLE and TIMER1_INT_ENABLE

}



/*##############################################################################*/
int GetPPM(void)
{
        //this routines seems to be nesseccary, as reading a 16 bit value
        //on a 8 bit machine is not atomic, so if an interrupt apears between reading
        //low and high byte of the 16 bit value a wrong result is possible
       
        unsigned char intmask;
        unsigned int  ppm_temp;

        intmask = TIMSK;                                //backup interupt enable bits
        TIMSK &= ~(1<<TICIE1);                  //disable ppm interrupt
        ppm_temp = ppm_signal;
        TIMSK = intmask;                                //restore interupt enable bits
        return(ppm_temp);                               //return ppm_signal

}


/*##############################################################################*/
// MAIN
/*##############################################################################*/
int main (void)
{
        unsigned int    i;
        unsigned char   colorState;
        unsigned char   nextcolorState=0;

    DDRB  = (CH0_B|CH1_B|CH2_B);
    PORTB = 0x00;

    DDRC  = (ledred);
    PORTC = 0x00;

    DDRD  = (ledgreen|CH3_D|CH4_D|CH5_D);
    PORTD = 0x00;

        ch0 = 0;
        ch1 = 0;
        ch2 = 0;
        ch3 = 0;
        ch4 = 0;
        ch5 = 0;       

        //StartUART();
        StartPPM();
        //StartI2C();
        StartPWM();
        sei();


        // Farbablauf: rot > Violett > blau > tuerkis > gruen > gelb >


        colorState = 0;
   
    while (1)
        {

                //printf("%d ",ppm_signal);

                for (i=0; i<=255; i++)
                {
                        switch(colorState)
                        {
                        case 0:
                                ch0 = i;                                //fade in (ch0) red
                                nextcolorState = 2;
                                break;

                        case 2:
                                ch1 = i;                                //fade in (ch1) blue to get pure purple (red + blue)
                                nextcolorState = 4;
                                break;

                        case 4:
                                ch0 = 255 - i;                  //fade out (ch0) red to get pure blue
                                nextcolorState = 6;
                                break;

                        case 6:
                                ch2 = i;                                //fade in  (ch2) green to get pure cyan (blue + green)
                                nextcolorState = 8;                            
                                break;

                        case 8:
                                ch1 = 255 - i;                  //fade out (ch1) blue to get pure green
                                nextcolorState = 10;
                                break;

                        case 10:
                                ch0 = i;                                //fade in  (ch0) red to get yellow pure (green + red)
                                nextcolorState = 12;                           
                                break;

                        case 12:
                                ch2 = 255 - i;                  //fade out (ch2) green to get pure red
                                nextcolorState = 0;
                                break;
                        }


                        timer = SetDelay(5);            //wait 10ms
                        while (!CheckDelay(timer));
                }
                       
                colorState = nextcolorState;

                timer = SetDelay(3);                    //hold pure colors for additional 3ms
                while (!CheckDelay(timer));


        }


}



/*
 170 00fa 1F92                  push __zero_reg__
 171 00fc 0F92                  push __tmp_reg__
 172 00fe 0FB6                  in __tmp_reg__,__SREG__
 173 0100 0F92                  push __tmp_reg__
 174 0102 1124                  clr __zero_reg__
 175 0104 2F93                  push r18
 176 0106 3F93                  push r19
 177 0108 8F93                  push r24
 178 010a 9F93                  push r25
 181 010c 38B3                  in r19,56-0x20
 184 010e 22B3                  in r18,50-0x20
 187 0110 8091 0000             lds r24,counter.1797
 188 0114 8F5F                  subi r24,lo8(-(1))
 189 0116 8093 0000             sts counter.1797,r24
 190 011a 8F3F                  cpi r24,lo8(-1)
 191 011c 01F4                  brne .L15
 193 011e 3E60                  ori r19,lo8(14)
 195 0120 2863                  ori r18,lo8(56)
 197 0122 8091 0000             lds r24,ch0
 198 0126 8093 0000             sts ch0_tmp,r24
 200 012a 8091 0000             lds r24,ch1
 201 012e 8093 0000             sts ch1_tmp,r24
 203 0132 8091 0000             lds r24,ch2
 204 0136 8093 0000             sts ch2_tmp,r24
 206 013a 8091 0000             lds r24,ch3
 207 013e 8093 0000             sts ch3_tmp,r24
 209 0142 8091 0000             lds r24,ch4
 210 0146 8093 0000             sts ch4_tmp,r24
 212 014a 8091 0000             lds r24,ch5
 213 014e 8093 0000             sts ch5_tmp,r24
 215 0152 1092 0000             sts counter.1797,__zero_reg__
 218 0156 8091 0000             lds r24,ch0_tmp
 219 015a 9091 0000             lds r25,counter.1797
 220 015e 8917                  cp r24,r25
 221 0160 01F4                  brne .L17
 222 0162 377F                  andi r19,lo8(-9)
 225 0164 8091 0000             lds r24,ch1_tmp
 226 0168 8917                  cp r24,r25
 227 016a 01F4                  brne .L19
 228 016c 3B7F                  andi r19,lo8(-5)
 231 016e 8091 0000             lds r24,ch2_tmp
 232 0172 8917                  cp r24,r25
 233 0174 01F4                  brne .L21
 234 0176 3D7F                  andi r19,lo8(-3)
 237 0178 8091 0000             lds r24,ch3_tmp
 238 017c 8917                  cp r24,r25
 239 017e 01F4                  brne .L23
 240 0180 277F                  andi r18,lo8(-9)
 243 0182 8091 0000             lds r24,ch4_tmp
 244 0186 8917                  cp r24,r25
 245 0188 01F4                  brne .L25
 246 018a 2F7E                  andi r18,lo8(-17)
 249 018c 8091 0000             lds r24,ch5_tmp
 250 0190 8917                  cp r24,r25
 251 0192 01F4                  brne .L27
 252 0194 2F7D                  andi r18,lo8(-33)
 255 0196 38BB                  out 56-0x20,r19
 257 0198 22BB                  out 50-0x20,r18
 259 019a 8091 0000             lds r24,ms1.1798
 260 019e 8F5F                  subi r24,lo8(-(1))
 261 01a0 8093 0000             sts ms1.1798,r24
 262 01a4 8132                  cpi r24,lo8(33)
 263 01a6 01F4                  brne .L31
 265 01a8 1092 0000             sts ms1.1798,__zero_reg__
 267 01ac 8091 0000             lds r24,TMR1MS
 268 01b0 9091 0000             lds r25,(TMR1MS)+1
 269 01b4 0196                  adiw r24,1
 270 01b6 9093 0000             sts (TMR1MS)+1,r25
 271 01ba 8093 0000             sts TMR1MS,r24
 274 01be 9F91                  pop r25
 275 01c0 8F91                  pop r24
 276 01c2 3F91                  pop r19
 277 01c4 2F91                  pop r18
 278 01c6 0F90                  pop __tmp_reg__
 279 01c8 0FBE                  out __SREG__,__tmp_reg__
 280 01ca 0F90                  pop __tmp_reg__
 281 01cc 1F90                  pop __zero_reg__
 282 01ce 1895                  reti
 */