From 5f604897b4f9a6f0602034f83c70105d94d073e6 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Tue, 18 Jun 2013 17:36:41 +0200 Subject: [PATCH] PWMLED: proof-of-concept brightness setting In order to save space for patterns, we set the brightness independently from pattern. Each brightness has only two levels for PWMLED 0 and 2, and one for PWMLED 1. Patterns can then use two-bit values for each PWMLED (one-bit for PWMLED 1), with the following meaning: 0: off 1: level 1 2: level 2 3: also level 2, with a separate state stored. This can be used for saving regulation value for a single current level with and without other outputs running, or with different levels of other output. This is in order to avoid flicker when one PWMLED (usually the front one) is steady on, and the others are blinking. --- firmware/lights.h | 8 +++++++ firmware/pwmled.c | 56 +++++++++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/firmware/lights.h b/firmware/lights.h index a3dbb63..25e2233 100644 --- a/firmware/lights.h +++ b/firmware/lights.h @@ -61,6 +61,14 @@ void susp_tmr(); void init_pwmled(); void pwmled_adc(unsigned char n, uint16_t adcval); void pwmled_set_mode(unsigned char n, unsigned char mode); +void pwmled_set_brightness(uint16_t brightness); +#define PWMLED_BRIGHTNESS(l0_lo, l0_hi, l1, l2_lo, l2_hi) ( \ + (uint16_t)(l0_lo) \ + | ((uint16_t)(l0_hi) << 3) \ + | ((uint16_t)(l1) << 6) \ + | ((uint16_t)(l2_lo) << 9) \ + | ((uint16_t)(l2_hi) << 12) \ + ) /* gpio.c */ void init_gpio(); diff --git a/firmware/pwmled.c b/firmware/pwmled.c index 27bdc0e..b8f702a 100644 --- a/firmware/pwmled.c +++ b/firmware/pwmled.c @@ -42,36 +42,28 @@ static uint16_t adc_max[N_PWMLEDS] = { #endif }; -static uint16_t adc_vals[N_PWMLEDS*N_PWMLED_MODES] = { -#ifdef TESTING_FW - /* pwmled0 */ +static uint16_t adc_targets_0[] = { MA_GAIN_TO_ADC( 50, 20), MA_GAIN_TO_ADC( 100, 20), + MA_GAIN_TO_ADC( 200, 20), MA_GAIN_TO_ADC( 350, 20), - /* pwmled1 */ +}; + +static uint16_t adc_targets_1[] = { MA_GAIN_TO_ADC( 5, 20), MA_GAIN_TO_ADC( 10, 20), MA_GAIN_TO_ADC( 20, 20), - /* pwmled2 */ +}; + +static uint16_t adc_targets_2[] = { MA_GAIN_TO_ADC( 50, 1), - MA_GAIN_TO_ADC( 80, 1), - MA_GAIN_TO_ADC( 150, 1) -#else - /* pwmled0 */ - MA_GAIN_TO_ADC( 50, 20), - MA_GAIN_TO_ADC( 100, 20), - MA_GAIN_TO_ADC( 350, 20), - /* pwmled1 */ - MA_GAIN_TO_ADC( 5, 20), - MA_GAIN_TO_ADC( 10, 20), - MA_GAIN_TO_ADC( 23, 20), - /* pwmled2 */ - MA_GAIN_TO_ADC( 150, 1), - MA_GAIN_TO_ADC( 300, 1), - MA_GAIN_TO_ADC(1500, 1) -#endif + MA_GAIN_TO_ADC( 100, 1), + MA_GAIN_TO_ADC( 200, 1), + MA_GAIN_TO_ADC( 350, 1), }; +static uint16_t adc_vals[N_PWMLEDS*N_PWMLED_MODES]; + #define ST_DISABLED 0 #define ST_OFF 1 #define ST_PROBING 2 @@ -99,6 +91,8 @@ void init_pwmled() led->err_sums[j] = 0; } } + + pwmled_set_brightness(PWMLED_BRIGHTNESS(0, 2, 1, 0, 2)); } void pwmled_set_mode(unsigned char n, unsigned char mode) @@ -128,6 +122,26 @@ void pwmled_set_mode(unsigned char n, unsigned char mode) } } +void pwmled_set_brightness(uint16_t brightness) +{ + unsigned char i; + + adc_vals[0] = adc_targets_0[brightness & 0x7]; + adc_vals[1] = adc_targets_0[(brightness >> 3) & 0x7]; + adc_vals[2] = adc_vals[1]; + + adc_vals[3] = adc_targets_1[(brightness >> 6) & 0x7]; + adc_vals[4] = adc_vals[3]; + adc_vals[5] = adc_vals[3]; + + adc_vals[6] = adc_targets_2[(brightness >> 9) & 0x7]; + adc_vals[7] = adc_targets_2[(brightness >> 12) & 0x7]; + adc_vals[8] = adc_vals[7]; + + for (i = 0; i < N_PWMLEDS; i++) + pwmleds[i].err_sum = 0; +} + #define PWMLED_PROBE_STEADY_COUNT 10 static inline unsigned char pwmled_probed_ok(unsigned char n, uint16_t old_pwm) -- 2.39.3