]> www.fi.muni.cz Git - tinyboard.git/blobdiff - projects/step-up-1/pwm.c
Experimental step-up driver for chain of 5630 LEDs.
[tinyboard.git] / projects / step-up-1 / pwm.c
diff --git a/projects/step-up-1/pwm.c b/projects/step-up-1/pwm.c
new file mode 100644 (file)
index 0000000..b93a4fa
--- /dev/null
@@ -0,0 +1,74 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/power.h>
+#include <util/delay.h>
+#include <util/atomic.h>
+
+#include "lights.h"
+
+/*
+ * Single PWM channel on OC1B (pin PB4 of Tiny45).
+ * Counts from 0 to 0xFF, without OCR1C compare.
+ */
+
+volatile unsigned char pwm_enabled;
+
+static void inline enable_pll()
+{
+       /* Async clock */
+       PLLCSR = _BV(PLLE) | _BV(LSM);
+
+       /* Synchronize to the phase lock */
+       _delay_us(100);
+       while ((PLLCSR & _BV(PLOCK)) == 0)
+               ;
+       PLLCSR |= _BV(PCKE);
+}
+
+void init_pwm()
+{
+       pwm_enabled = 0;
+       power_timer1_enable();
+
+       TCCR1 = _BV(CTC1) | _BV(CS11);  // pll_clk/2
+       GTCCR = _BV(COM1B1) | _BV(PWM1B);
+
+       OCR1C = PWM_MAX;
+       OCR1B = 0;              // initial stride is 0
+
+       DDRB &= ~(_BV( PB4 ));
+       PORTB &= ~_BV(PB4); // set to zero
+}
+
+void susp_pwm()
+{
+       DDRB &= ~(_BV( PB4 ));
+       PORTB &= ~(_BV( PB4 ));
+       TCCR1 = 0;
+       TIMSK = 0;
+       TIFR = 0;
+
+       PLLCSR &= ~(_BV(PLLE) | _BV(PCKE));
+}
+
+void pwm_off()
+{
+       OCR1B = 0;
+       DDRB &= ~_BV(PB4);
+
+       PLLCSR &= ~(_BV(PLLE) | _BV(PCKE));
+       power_timer1_disable();
+       pwm_enabled = 0;
+}
+
+void pwm_set(uint8_t stride)
+{
+       OCR1B = stride;
+
+       if (!pwm_enabled) {
+               power_timer1_enable();
+               enable_pll();
+               DDRB |= _BV(PB4);
+               pwm_enabled = 1;
+       }
+}