firmware/pwm_timer.c

Go to the documentation of this file.
00001 
00010 #include <avr/io.h>
00011 #include <avr/interrupt.h>
00012 #include <avr/pgmspace.h>
00013 
00014 #include "boolean.h"
00015 #include "message_queue.h"
00016 #include "pwm_timer.h"
00017 #include "config_pwm_timer_impl.h"
00018 
00020 typedef struct S_pwm_Timer_GlobalData {
00021     pwm_Channels_Message     message[2]; 
00022     pwm_Channels_Message*    pActive; 
00023     pwm_Channels_Message*    pRead; 
00024     pwm_Channels_StepCounter step; 
00025     pwm_Timer_Cycles         currentCycle; 
00026     Boolean                  readDone; 
00027 } pwm_Timer_GlobalData;
00028 
00029 static pwm_Timer_GlobalData m_data; 
00035 void pwm_Timer_init(void) {
00036     messageQueue_init();
00037     m_data.step=           0;
00038     m_data.currentCycle=   0;
00039     m_data.pActive=        &m_data.message[0];
00040     m_data.pRead=          &m_data.message[1];
00041     m_data.readDone=       False;
00042     m_data.pActive->step[0].cycle= pwm_Channels_Brightness_Max;
00043     m_data.pActive->step[0].field=      0;
00044     /* clk/64 prescaling, CTC mode */
00045     /* enable timer1 overflow (=output compare 1a) */
00046     TCCR1B= _BV(CS11) | _BV(CS10) | _BV(WGM12);
00047     TCCR1A= 0;
00048     TIMSK|= _BV(OCIE1A);
00049     /* load initial delay */
00050     OCR1A=  pwm_Timer_Cycles_Max;
00051     /* initialize output pin */
00052     DDRC = (1 << CHANNELS) - 1; // set all used channel-pins to output
00053     PORTC = 0;
00054     sei();
00055 }
00056 
00060 void pwm_Timer_cleanup(void) {
00061     messageQueue_cleanup();
00062 }
00063 
00067 void pwm_Timer_idle(void)
00068 {}
00069 
00079 static Boolean pwm_Timer_sleep(pwm_Timer_Cycles sleep) {
00080     Boolean sleepDone= False;
00081     if((sleep < pwm_Timer_Cycles_SleepMax)) {
00082         while (TCNT1 < sleep)
00083         {}
00084         sleepDone= True;
00085     } else {
00086         OCR1A= sleep;
00087     }
00088     return sleepDone;
00089 }
00090 
00095 static void pwm_Timer_switchLed(pwm_Channels_Bitfield field) {
00096     PORTC= field;
00097 }
00098 
00103 SIGNAL(SIG_OUTPUT_COMPARE1A) {
00104     pwm_Timer_Cycles sleep= pwm_Timer_Cycles_Max;
00105     OCR1A= pwm_Timer_Cycles_Max;
00106     sei();
00107     do {
00108         if((m_data.step == pwm_Channels_StepCounter_Max) || (m_data.currentCycle == pwm_Timer_Cycles_Max)) {
00109             /* end of current cycle reached*/ 
00110             if(m_data.readDone) {
00111                 /*
00112                   message received
00113                   start a new cycle with the new values
00114                   swap active message and message for reading
00115                   message for reading is free for further messages from queue
00116                 */
00117                 pwm_Channels_Message* pSwap= m_data.pActive;
00118                 m_data.pActive= m_data.pRead;
00119                 m_data.pRead=   pSwap;
00120                 m_data.readDone= False;
00121                 m_data.currentCycle= 0;
00122                 m_data.step= 0;
00123                 sleep= 0;
00124             } else {
00125                 /* could not read a new channels message in a whole cycle */
00126                 /* restart the cycle with the old values */
00127                 m_data.currentCycle= 0;
00128                 m_data.step= 0;
00129                 sleep= 0;
00130             }
00131         } else {
00132             /* process current step, go to next step */
00133             pwm_Timer_switchLed(m_data.pActive->step[m_data.step].field);
00134             sleep= m_data.pActive->step[m_data.step].cycle - m_data.currentCycle;
00135             m_data.currentCycle= m_data.pActive->step[m_data.step].cycle;
00136             m_data.step++;
00137         }
00138     } while(pwm_Timer_sleep(sleep));
00139 
00140     if(!m_data.readDone && (sleep > pwm_Timer_Cycles_ReadMin)) {
00141         /*
00142           free space for reading and enough time to read: try to read
00143         */
00144         if(messageQueue_read(m_data.pRead)) {
00145             m_data.readDone= True;
00146         }
00147     }
00148 }
00149 

Generated on Mon Oct 2 19:31:17 2006 for USB-LED-Fader by  doxygen 1.4.7