dc22-wp-badge-firmware/fw_attiny88/src/timer.h

110 lines
2.5 KiB
C

/*
* timer.h
*
* Created: 5/21/2014 10:45:08 PM
* Author: true
*/
#ifndef TIMER_H_
#define TIMER_H_
#include "led.h"
#define TIMER0_COMPARE 62 - 1
#define TIMER1_COMPARE 252 - 1 // divisible by 63 which is set every other round for timer0
uint8_t timer1_mode;
/* prototypes */
/* implementations */
inline static void timer0_init()
{
// make sure timer is enabled
PRR &= ~PRTIM0;
// enable timer with prescale divider /64, enable TOP mode
TCCR0A = _BV(CTC0) | (_BV(CS00) | _BV(CS01) | ~(_BV(CS02)));
// set TOP level to be 62 to 63 counts; this will result in 2KHz cycle @8MHz
OCR0A = TIMER0_COMPARE;
// clear timer
TCNT0 = 0;
// and enable OCA interrupt (we don't use overflow interrupt as we are in TOP mode)
TIMSK0 = _BV(OCIE0A);
}
#define timer0_set_compare(x) OCR0A = x
inline static void timer1_init()
{
// make sure timer is enabled
PRR &= ~PRTIM1;
// clear PWM OCx
OCR1AH = 0xff; // sets temp register to 0xff
OCR1AL = 0xff;
OCR1BL = 0xff;
// clear timer
TCNT1H = 0; // sets temp register to 0
TCNT1L = 0;
// enable timer OC1 and OC2 clear on match / set at TOP, set to fast PWM mode 14 (ICR1 compare), prescaler off
// note: in PWM mode 14, pin PB0 can only be used as an output... =(
TCCR1A = (_BV(COM1A1)) | (_BV(COM1B1)) | (_BV(WGM11) | ~(_BV(WGM10)));
TCCR1B = (_BV(WGM12) | _BV(WGM13)) | (_BV(CS10));
TCCR1C = 0;
// store timer1 mode to allow enabling / disabling timer
timer1_mode = TCCR1A;
// set ICR compare to result in a PWM rate of 8MHz / 252, or 32256Hz
// This is 16 PWM updates per timer0 63-count period (16.25 per 62-count period)
// In practice we don't get the first PWM output, so we get:
// 15/16 PWM / (x) LEDs = 31.25% max duty for 3 LED, 23.43% max duty for 4 LED
ICR1L = TIMER1_COMPARE;
// set OC pins as outputs
DDRB |= (_BV(DDB2) | _BV(DDB1));
// disable interrupts
TIMSK1 = 0;
}
inline void timer1_pwm_reinit()
{
// enable pwm output on OCx pins
TCCR1A = (_BV(COM1A1)) | (_BV(COM1B1)) | (_BV(WGM11) | ~(_BV(WGM10)));
// set OC pins as outputs
DDRB |= (_BV(DDB2) | _BV(DDB1));
}
inline void timer1_set(uint16_t set)
{
TCNT1 = set;
}
#define timer1_disable() TCCR1A = 0
#define timer1_enable() TCCR1A = timer1_mode;
#ifdef LED_COMMON_ANODE
#define timer1_set_oca(v) OCR1AL = TIMER1_COMPARE - v
#define timer1_set_ocb(v) OCR1BL = TIMER1_COMPARE - v
#else
#define timer1_set_oca(v) OCR1AL = TIMER1_COMPARE
#define timer1_set_ocb(v) OCR1BL = TIMER1_COMPARE
#endif
#endif /* TIMER_H_ */