2011-07-20 15:32:52 +00:00
/*
Copyright 2011 Jun Wako < wakojun @ gmail . com >
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2010-10-29 06:17:18 +00:00
# include <avr/io.h>
# include <avr/interrupt.h>
# include <stdint.h>
2014-06-16 02:12:45 +00:00
# include "timer_avr.h"
2010-10-29 06:17:18 +00:00
# include "timer.h"
2011-09-17 13:39:50 +00:00
// counter resolution 1ms
2012-10-05 17:23:12 +00:00
// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
2012-09-02 14:47:18 +00:00
volatile uint32_t timer_count = 0 ;
2010-10-29 06:17:18 +00:00
void timer_init ( void )
{
2011-09-17 13:39:50 +00:00
// Timer0 CTC mode
TCCR0A = 0x02 ;
# if TIMER_PRESCALER == 1
TCCR0B = 0x01 ;
# elif TIMER_PRESCALER == 8
TCCR0B = 0x02 ;
# elif TIMER_PRESCALER == 64
TCCR0B = 0x03 ;
# elif TIMER_PRESCALER == 256
TCCR0B = 0x04 ;
# elif TIMER_PRESCALER == 1024
2010-10-29 06:17:18 +00:00
TCCR0B = 0x05 ;
2011-09-17 13:39:50 +00:00
# else
# error "Timer prescaler value is NOT vaild."
# endif
OCR0A = TIMER_RAW_TOP ;
TIMSK0 = ( 1 < < OCIE0A ) ;
2010-10-29 06:17:18 +00:00
}
inline
void timer_clear ( void )
{
2011-01-28 15:44:05 +00:00
uint8_t sreg = SREG ;
2010-10-29 06:17:18 +00:00
cli ( ) ;
timer_count = 0 ;
2011-01-28 15:44:05 +00:00
SREG = sreg ;
2010-10-29 06:17:18 +00:00
}
inline
uint16_t timer_read ( void )
{
2012-09-02 14:47:18 +00:00
uint32_t t ;
uint8_t sreg = SREG ;
cli ( ) ;
t = timer_count ;
SREG = sreg ;
return ( t & 0xFFFF ) ;
}
inline
uint32_t timer_read32 ( void )
{
uint32_t t ;
2010-10-29 06:17:18 +00:00
2011-01-28 15:44:05 +00:00
uint8_t sreg = SREG ;
2010-10-29 06:17:18 +00:00
cli ( ) ;
t = timer_count ;
2011-01-28 15:44:05 +00:00
SREG = sreg ;
2010-10-29 06:17:18 +00:00
return t ;
}
inline
uint16_t timer_elapsed ( uint16_t last )
{
2012-09-02 14:47:18 +00:00
uint32_t t ;
uint8_t sreg = SREG ;
cli ( ) ;
t = timer_count ;
SREG = sreg ;
return TIMER_DIFF_16 ( ( t & 0xFFFF ) , last ) ;
}
inline
uint32_t timer_elapsed32 ( uint32_t last )
{
uint32_t t ;
2010-10-29 06:17:18 +00:00
2011-01-28 15:44:05 +00:00
uint8_t sreg = SREG ;
2010-10-29 06:17:18 +00:00
cli ( ) ;
t = timer_count ;
2011-01-28 15:44:05 +00:00
SREG = sreg ;
2010-10-29 06:17:18 +00:00
2012-09-02 14:47:18 +00:00
return TIMER_DIFF_32 ( t , last ) ;
2010-10-29 06:17:18 +00:00
}
2011-09-17 13:39:50 +00:00
// excecuted once per 1ms.(excess for just timer count?)
ISR ( TIMER0_COMPA_vect )
2010-10-29 06:17:18 +00:00
{
timer_count + + ;
}