8 unsigned char mode, state, probe_steps;
9 uint16_t mode_pwm[N_PWMLED_MODES];
12 pwmled_t pwmleds[N_PWMLEDS];
14 #define PWMLED2_TESTING_WITH_350MA_LED
16 #define SENSE_MOHM 33 /* 0.033 Ohm */
17 #define MA_MOHM_GAIN_TO_ADC(ma, mohm, gain) (\
18 ((unsigned long)(ma))*(mohm) /* voltage at sensing resistor in uV */ \
19 /(1100000UL/gain/1024UL) /* voltage of ADC reading == 1 */ \
22 static uint16_t adc_max[N_PWMLEDS] = {
23 MA_MOHM_GAIN_TO_ADC( 400, SENSE_MOHM, 20),
24 MA_MOHM_GAIN_TO_ADC( 30, SENSE_MOHM, 20),
25 #ifdef PWMLED2_TESTING_WITH_350MA_LED
26 MA_MOHM_GAIN_TO_ADC( 400, SENSE_MOHM, 1)
28 MA_MOHM_GAIN_TO_ADC(2500, SENSE_MOHM, 1)
32 static uint16_t adc_vals[N_PWMLEDS*N_PWMLED_MODES] = {
34 MA_MOHM_GAIN_TO_ADC( 20, SENSE_MOHM, 20),
35 MA_MOHM_GAIN_TO_ADC( 50, SENSE_MOHM, 20),
36 MA_MOHM_GAIN_TO_ADC( 100, SENSE_MOHM, 20),
37 MA_MOHM_GAIN_TO_ADC( 350, SENSE_MOHM, 20),
41 MA_MOHM_GAIN_TO_ADC( 5, SENSE_MOHM, 20),
42 MA_MOHM_GAIN_TO_ADC( 12, SENSE_MOHM, 20),
43 MA_MOHM_GAIN_TO_ADC( 16, SENSE_MOHM, 20),
44 MA_MOHM_GAIN_TO_ADC( 20, SENSE_MOHM, 20),
49 #ifdef PWMLED2_TESTING_WITH_350MA_LED
50 MA_MOHM_GAIN_TO_ADC( 100, SENSE_MOHM, 1),
51 MA_MOHM_GAIN_TO_ADC( 140, SENSE_MOHM, 1),
52 MA_MOHM_GAIN_TO_ADC( 250, SENSE_MOHM, 1),
53 MA_MOHM_GAIN_TO_ADC( 350, SENSE_MOHM, 1),
55 MA_MOHM_GAIN_TO_ADC( 150, SENSE_MOHM, 1),
56 MA_MOHM_GAIN_TO_ADC( 350, SENSE_MOHM, 1),
57 MA_MOHM_GAIN_TO_ADC( 700, SENSE_MOHM, 1),
58 MA_MOHM_GAIN_TO_ADC(2400, SENSE_MOHM, 1),
67 // The above are constructed so that the following work:
68 #define ST_IS_ON(s) ((s) & 0x02)
69 #define ST_CAN_SET_MODE(s) ((s) & 0x01)
75 for (i = 0; i < N_PWMLEDS; i++) {
76 pwmled_t *led = pwmleds + i;
78 led->target = adc_vals[i*N_PWMLED_MODES];
81 led->state = ST_PROBING;
84 for (j = 0; j < N_PWMLED_MODES; j++)
89 void pwmled_set_mode(unsigned char n, unsigned char mode)
91 pwmled_t *led = pwmleds + n;
93 if (!ST_CAN_SET_MODE(led->state))
96 if (led->mode) // save the previous state
97 led->mode_pwm[led->mode - 1] = led->pwm;
104 if (mode > 0 && mode <= N_PWMLED_MODES) {
105 led->target = adc_vals[n*N_PWMLED_MODES + mode - 1];
107 led->pwm = led->mode_pwm[mode - 1];
109 pwm_set(n, led->pwm);
116 void pwmled_adc(unsigned char n, uint16_t adcval)
118 pwmled_t *led = pwmleds + n;
119 int16_t sum, pwm_div;
122 if (!ST_IS_ON(led->state))
125 // FIXME: test for maximum adcval value (adc_max[n])
127 sum = led->err_sum += (int16_t)(led->target) - (int16_t)adcval;
129 // FIXME: try to work faster during probing
130 pwm_div = 64; //led->state == ST_PROBING ? (1 << 5) : (1 << 8);
133 if (sum >= pwm_div) {
134 uint16_t diff = sum/pwm_div;
136 led->err_sum -= diff * pwm_div;
138 } else if (sum <= -pwm_div) {
139 uint16_t diff = (-sum)/pwm_div;
141 if (led->pwm >= diff)
142 led->pwm -= (int16_t)diff;
145 led->err_sum += diff * pwm_div;
148 if (led->state == ST_PROBING) {
149 if (led->pwm == old_pwm) {
150 if (led->probe_steps < 10)
153 led->probe_steps = 0;
156 if (led->probe_steps >= 10 || old_pwm > led->pwm) {
158 led->mode_pwm[led->mode - 1] = led->pwm;
160 if (led->mode < N_PWMLED_MODES) {
161 led->probe_steps = 0;
165 led->target = adc_vals[n*N_PWMLED_MODES+led->mode-1];
175 for (i = 0; i < N_PWMLED_MODES; i++)
176 log_word(led->mode_pwm[i]);
183 if (led->pwm == old_pwm)
186 if (led->pwm > (PWM_MAX << PWM_STEP_SHIFT)/2) {
188 led->state = ST_DISABLED;
195 pwm_set(n, led->pwm);