avr-fw-modules/cpu/at90can128/src/at90can_timer0.c

51 lines
1.1 KiB
C

#include <avr/io.h>
#include <cpu/cpu.h>
#include <sys/systick.h>
#ifdef __AVR_ATmega32__
#define TCCR0A TCCR0
#define OCR0A OCR0
#define TIMSK0 TIMSK
#define OCIE0A OCIE0
#endif
#define PRESCALER_LEVELS 5
int prescale_shift[] = { 0, 3, 6, 8, 10 };
uint32_t _st_prescale;
void systick_timer_init(uint32_t systick_us)
{
uint64_t clocks = ((uint64_t)systick_us) * ((uint64_t)__freq_cpu) / 1000000LL;
uint64_t ocr;
uint8_t n_prescaler;
for (n_prescaler=0;n_prescaler<PRESCALER_LEVELS;n_prescaler++){
ocr = clocks >> prescale_shift[ n_prescaler ];
if (ocr < 256){
break;
};
};
if (n_prescaler < PRESCALER_LEVELS) {
TCCR0A = _BV(WGM01) | ((n_prescaler + 1) & 0x07);
OCR0A = (uint8_t)ocr;
TIMSK0 |= _BV(OCIE0A);
_systick_us = 1000000LL * (1LL << prescale_shift[ n_prescaler ]) * (ocr + 1) / __freq_cpu;
_st_prescale = (1L << prescale_shift[ n_prescaler ]);
#if defined(DEBUG_SCHEDULING)
_ts_timer_resolution = ocr;
_ts_timer_cycles_per_increment = _st_prescale;
_ts_timer_increments_per_second = __freq_cpu / _ts_timer_cycles_per_increment;
#endif
};
};