Subversion Repositories Projects

Rev

Rev 52 | Rev 54 | 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 int    ppm;
        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)
        {

/*
        #define step    128
        #define mul             2

                if ((ppm >= (step * 0)  && (ppm < (step * 1))) ch0 = mul * ((ppm - (step * 0)));
                if ((ppm >= (step * 1)) && (ppm < (step * 2))) ch1 = mul * ((ppm - (step * 1)));
                if ((ppm >= (step * 2)) && (ppm < (step * 3))) ch0 = mul * ((step - 1) - (ppm - (step * 2)));
                if ((ppm >= (step * 3)) && (ppm < (step * 4))) ch2 = mul * ((ppm - (step * 3)));
                if ((ppm >= (step * 4)) && (ppm < (step * 5))) ch1 = mul * ((step - 1) - (ppm - (step * 4)));
                if ((ppm >= (step * 5)) && (ppm < (step * 6))) ch0 = mul * ((ppm - (step * 5)));
                if ((ppm >= (step * 6)) && (ppm < (step * 7))) ch2 = mul * ((step - 1) - (ppm - (step * 6)));

                //printf("%d ",ppm);
*/


                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));


        }


}