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