firmware/pwm_channels.c

Go to the documentation of this file.
00001 
00010 #include <stdlib.h>
00011 
00012 #include "pwm_channels.h"
00013 #include "pwm_timer.h"
00014 #include "config_pwm_timer_impl.h"
00015 #include "message_queue.h"
00016 
00018 typedef struct S_pwm_Channels_ChannelBrightness {
00019     pwm_Channels_Bitfield field; 
00020     pwm_Timer_Cycles      cycle; 
00021 } pwm_Channels_ChannelBrightness;
00022 
00026 void pwm_Channels_init(void) {
00027     pwm_Timer_init();
00028 }
00029 
00033 void pwm_Channels_cleanup(void) {
00034     pwm_Timer_cleanup();
00035 }
00036 
00043 static pwm_Channels_Message pwm_Channels_Message_get(pwm_Channels_ChannelBrightness channels[CHANNELS]) {
00044     int j; /* index of the current channel */
00045     pwm_Channels_StepCounter i= 0; /* index of the current step */
00046     pwm_Channels_Message message;
00047     /* first step: switch on all channels at cycle 0 */
00048     message.step[i].field = 0;
00049     for (j = 0; j < CHANNELS; j++) {
00050         message.step[i].field |= channels[j].field;
00051     }
00052     message.step[i].cycle= 0;
00053 
00054     for (j = 0; j < CHANNELS; j++) {
00055         if(channels[j].cycle == message.step[i].cycle) {
00056             /* if cycle for this channel is reached
00057                switch off channel in current step */
00058             message.step[i].field&= ~channels[j].field;
00059         } else {
00060             /* need another step for this channel:
00061                set end of the current step
00062                use copy of current step for next step
00063                and switch off this channel
00064             */
00065             message.step[i].cycle= channels[j].cycle;
00066             i++;
00067             message.step[i]= message.step[i-1];
00068             message.step[i].field&= ~channels[j].field;
00069         }
00070     }
00071     /* last step ends at pwm_Timer_Cycles_Max */
00072     message.step[i].cycle= pwm_Timer_Cycles_Max;
00073     return message;
00074 }
00075 
00081 pwm_Timer_Cycles pwm_Channels_BrightnessToCycles(pwm_Channels_Brightness brightness) {
00082     return brightness * brightness;
00083 }
00084 
00093 int pwm_Channels_CompareChannels(const void * cmp1, const void * cmp2) {
00094     return ((const pwm_Channels_ChannelBrightness*)cmp1)->cycle - ((const pwm_Channels_ChannelBrightness*)cmp2)->cycle;
00095 }
00096 
00102 void pwm_Channels_show(pwm_Channels channels) {
00103     int i;
00104     pwm_Channels_Message message;
00105     pwm_Channels_ChannelBrightness channel_brightness[CHANNELS];
00106     for (i = 0; i < CHANNELS; i++) {
00107         channel_brightness[i].field = 1 << i; // 1 << i equals 2^i: the channel i, uses the bit i
00108         channel_brightness[i].cycle = pwm_Channels_BrightnessToCycles(channels.channel[i]);
00109     }
00110 
00111     qsort(channel_brightness, CHANNELS, sizeof(pwm_Channels_ChannelBrightness), pwm_Channels_CompareChannels);
00112     message= pwm_Channels_Message_get(channel_brightness);
00113     while(!messageQueue_write(message)) {
00114         pwm_Timer_idle();
00115     }
00116 }
00117 

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