From 7f7665a5234d4d5cbd94fed9be55862772f3dc12 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Fri, 7 Dec 2012 23:03:55 +0100 Subject: [PATCH] pwm.c: publish only PWM_MAX as non-internal value The TOP value of Timer/Counter 1 is computed inside pwm.c and it is purely internal to this module. --- firmware/lights.h | 11 ++++++----- firmware/pwm.c | 20 +++++++++++++------- firmware/pwmled.c | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/firmware/lights.h b/firmware/lights.h index 4a23436..fe8b59f 100644 --- a/firmware/lights.h +++ b/firmware/lights.h @@ -27,11 +27,12 @@ void init_adc(); void susp_adc(); /* pwm.c */ -#define PWM_MAX 0x1E4 /* This should be different than ADC frequency 125 kHz */ -#define PWM_STEP_SHIFT 2 /* second parameter of pwm_set is shifted by - * PWM_STEP_SHIFT bits to the right before setting - * into HW */ - +/* + * The real Timer/Counter 1 frequency should not be too close to the + * A/D converter frequency (125 kHz). Note that this is not the Top + * value of T/C 1, it is shifted by PWM_STEP_SHIFT as described in pwm.c + */ +#define PWM_MAX 0x780 void init_pwm(); void susp_pwm(); void pwm_off(unsigned char n); diff --git a/firmware/pwm.c b/firmware/pwm.c index 56fb088..d68eeb2 100644 --- a/firmware/pwm.c +++ b/firmware/pwm.c @@ -5,6 +5,12 @@ #include "lights.h" +#define PWM_STEP_SHIFT 2 /* sub-LSB precision */ +#define PWM_TOP (((PWM_MAX) + (4 << (PWM_STEP_SHIFT))) >> (PWM_STEP_SHIFT)) +#if PWM_TOP > 0x1FF +#error PWM_TOP too high +#endif + static uint16_t pwm[N_PWMLEDS]; static volatile unsigned char step; @@ -38,11 +44,11 @@ void init_pwm() TCCR1D = 0; TCCR1B = _BV(CS10); // no clock prescaling - TC1H = PWM_MAX >> 8; - OCR1C = PWM_MAX & 0xFF; // TOP value + TC1H = PWM_TOP >> 8; + OCR1C = PWM_TOP & 0xFF; // TOP value - TC1H = PWM_MAX >> 8; // PWM3 is inverted - OCR1D = PWM_MAX & 0xFF; + TC1H = PWM_TOP >> 8; // PWM3 is inverted + OCR1D = PWM_TOP & 0xFF; TC1H = 0x00; OCR1B = OCR1A = 0; // initial stride is 0 @@ -85,7 +91,7 @@ static void pwm_update_hw(unsigned char n) uint16_t stride = (pwm[n] + step) >> PWM_STEP_SHIFT; if (n == 2) - stride = PWM_MAX - stride; + stride = PWM_TOP - stride; hi = stride >> 8; lo = stride & 0xFF; @@ -108,8 +114,8 @@ static void pwm_update_hw(unsigned char n) void pwm_set(unsigned char n, uint16_t stride) { - if (((stride + (1 << PWM_STEP_SHIFT)) >> PWM_STEP_SHIFT) >= PWM_MAX) - stride = PWM_MAX << PWM_STEP_SHIFT; + if (stride > PWM_MAX) + stride = PWM_MAX; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { pwm[n] = stride; diff --git a/firmware/pwmled.c b/firmware/pwmled.c index 076d032..d85087e 100644 --- a/firmware/pwmled.c +++ b/firmware/pwmled.c @@ -204,7 +204,7 @@ void pwmled_adc(unsigned char n, uint16_t adcval) sum -= led->pwm << shift; led->err_sum = sum; - if (led->pwm > (PWM_MAX << PWM_STEP_SHIFT)-5) { + if (led->pwm >= PWM_MAX) { pwmled_err(n); return; } -- 2.39.3