X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=bike-lights.git;a=blobdiff_plain;f=firmware%2Fpwm.c;h=27c8d0d0187d6e9a3f3e2a78448aefa7f0438843;hp=d68eeb2c3fdf370f69f32a8aa10b1afd68ff48a9;hb=65c3ad96cf307c3b77b36e6f6a2af5201c213a3c;hpb=7f7665a5234d4d5cbd94fed9be55862772f3dc12 diff --git a/firmware/pwm.c b/firmware/pwm.c index d68eeb2..27c8d0d 100644 --- a/firmware/pwm.c +++ b/firmware/pwm.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -7,12 +8,15 @@ #define PWM_STEP_SHIFT 2 /* sub-LSB precision */ #define PWM_TOP (((PWM_MAX) + (4 << (PWM_STEP_SHIFT))) >> (PWM_STEP_SHIFT)) -#if PWM_TOP > 0x1FF +#if PWM_TOP > 0x3FF #error PWM_TOP too high #endif +volatile unsigned char channels_running; + static uint16_t pwm[N_PWMLEDS]; static volatile unsigned char step; +static unsigned char pll_enabled; static void enable_pll() { @@ -24,6 +28,8 @@ static void enable_pll() while ((PLLCSR & _BV(PLOCK)) == 0) ; PLLCSR |= _BV(PCKE); + + pll_enabled = 1; } void init_pwm() @@ -31,12 +37,12 @@ void init_pwm() int i; step = 0; + channels_running = 0; + pll_enabled = 0; for (i = 0; i < N_PWMLEDS; i++) pwm[i] = 0; - enable_pll(); - // PWM channel D is inverted, ... TCCR1C = _BV(COM1D1) | _BV(COM1D0) | _BV(PWM1D); // PWM channels A and B are not @@ -76,6 +82,7 @@ void pwm_off(unsigned char n) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { pwm[n] = 0; + channels_running &= ~(1 << n); switch (n) { case 0: DDRB &= ~_BV(PB1); break; @@ -119,6 +126,12 @@ void pwm_set(unsigned char n, uint16_t stride) ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { pwm[n] = stride; + channels_running |= (1 << n); + + if (!pll_enabled) { + power_timer1_enable(); + enable_pll(); + } pwm_update_hw(n); @@ -142,3 +155,15 @@ void pwm_timer() pwm_update_hw(i); } +void pwm_disable_if_not_needed() +{ + if (channels_running) + return; + + pll_enabled = 0; + DDRB &= ~(_BV(PB1) | _BV(PB3) | _BV(PB5)); + PLLCSR &= ~(_BV(PLLE) | _BV(PCKE)); + + power_timer1_disable(); +} +