110 lines
2.5 KiB
C
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_ */ |