Fixed PWM support
[cerebrum.git] / avr / pwm.c
blob90a4051184a003d97d4758ca4e1ab341f7296d4d
2 #include "pwm.h"
3 #include "led.h"
4 #include "util.h"
5 #ifdef HAS_PWM_SUPPORT
7 void pwm_loop(){
8 #ifdef PWM_ANIMATE
9 pwm_animate();
10 #endif//PWM_ANIMATE
13 void pwm_setup(){
14 //s/w "BCM"(<== "Binary Code Modulation") timer setup
15 TCCR0A |= _BV(WGM01);
16 TCCR0B |= _BV(CS02);
17 TIMSK0 |= _BV(OCIE0A);
18 OCR0A = 1;
19 pwm_output_setup();
22 ISR(TIMER0_COMPA_vect){
23 pwm_unset_outputs();
24 pwm_cycle<<=1;
25 if(!pwm_cycle){
26 pwm_cycle = 1;
28 uint8_t Q = 0;
29 Q |= (pwm_val[0] & pwm_cycle)?1:0;
30 Q |= (pwm_val[1] & pwm_cycle)?2:0;
31 Q |= (pwm_val[2] & pwm_cycle)?4:0;
32 Q |= (pwm_val[3] & pwm_cycle)?8:0;
33 Q |= (pwm_val[4] & pwm_cycle)?16:0;
34 Q |= (pwm_val[5] & pwm_cycle)?32:0;
35 Q |= (pwm_val[6] & pwm_cycle)?64:0;
36 Q |= (pwm_val[7] & pwm_cycle)?128:0;
37 pwm_set_outputs(Q);
38 TCNT0 = 0;
39 OCR0A = pwm_cycle;
42 uint8_t pwm_cycle = 1;
43 uint8_t pwm_val[8];
45 rgb_value_t hsv_to_rgb(hsv_value_t k){
46 int f;
47 long p, q, t;
48 rgb_value_t ret = {0, 0, 0};
50 if(k.s==0){
51 ret.r = ret.g = ret.b = k.v;
52 return ret;
55 f = ((k.h%60)*255)/60;
56 k.h /= 60;
58 p = (k.v * (256 - k.s))/256;
59 q = (k.v * ( 256 - (k.s * f)/256 ))/256;
60 t = (k.v * ( 256 - (k.s * ( 256 - f ))/256))/256;
62 switch(k.h){
63 case 0:
64 ret.r = k.v;
65 ret.g = t;
66 ret.b = p;
67 break;
68 case 1:
69 ret.r = q;
70 ret.g = k.v;
71 ret.b = p;
72 break;
73 case 2:
74 ret.r = p;
75 ret.g = k.v;
76 ret.b = t;
77 break;
78 case 3:
79 ret.r = p;
80 ret.g = q;
81 ret.b = k.v;
82 break;
83 case 4:
84 ret.r = t;
85 ret.g = p;
86 ret.b = k.v;
87 break;
88 default:
89 ret.r = k.v;
90 ret.g = p;
91 ret.b = q;
92 break;
94 return ret;
97 //The following algorithm is loosely based on http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB
98 //AND BROKEN
99 uint16_t c_ = (uint16_t)k.v * (uint16_t)k.s;
100 uint8_t c = c_>>8;
101 uint8_t m = k.v - c;
102 rgb_value_t ret = {0, 0, 0};
103 uint8_t branch;
104 uint8_t h_;
105 if(k.h<128){
106 if(k.h<85){
107 if(k.h<43){
108 h_ = k.h;
109 branch = 0;
110 }else{
111 h_ = 43-k.h;
112 branch = 1;
114 }else{
115 h_ = k.h-128;
116 branch = 2;
118 }else{
119 if(k.h<171){
120 h_ = 171-k.h;
121 branch = 3;
122 }else{
123 if(k.h<213){
124 h_ = k.h-171;
125 branch = 4;
126 }else{
127 h_ = 255-k.h;
128 branch = 5;
132 uint16_t x_ = c * (uint16_t)h_;
133 uint8_t x = x_>>8;
134 switch(branch){
135 case 0:
136 ret.r += c;
137 ret.g += x;
138 break;
139 case 1:
140 ret.r += x;
141 ret.g += c;
142 break;
143 case 2:
144 ret.g += c;
145 ret.b += x;
146 break;
147 case 3:
148 ret.g += x;
149 ret.b += c;
150 break;
151 case 4:
152 ret.r += x;
153 ret.b += c;
154 break;
155 case 5:
156 ret.r += c;
157 ret.b += x;
158 break;
160 return ret;
164 #else//HAS_PWM_SUPPORT
166 void pwm_setup(){}
167 void pwm_loop(){}
169 #endif//HAS_PWM_SUPPORT