[En-Nut-Discussion] Low level timer functions
Harald Kipp
harald.kipp at egnite.de
Fri Jun 10 09:31:03 CEST 2005
Hi Ole,
How do we say in Germany? "Offer him a little finger and he will
pull off your arm." :-)
My problem with additional timer/counter functions is, that
it seems to be no easy solution for a hardware independent
layer. But I'd agree that even some AVR specific functions
will be helpful.
In the meantime I think I have a nice solution for the
crystal frequency detection, which no longer depends on
wait states of external RAM. 'counter' is an u_long and
just needs to be multiplied by 128 the get the frequency
in Hz.
Harald
/* Disable timer 0 interrupts. */
cbi(TIMSK, TOIE0);
cbi(TIMSK, OCIE0);
/* Select oscillator 1 (32.768 kHz). */
sbi(ASSR, AS0);
/* Reset counter register. */
outb(TCNT0, 0);
/* Set prescaler to 8. Overflow will occur every 62.5 ms. */
outb(TCCR0, _BV(CS01));
/* Wait for asynchronous busy clear. */
while ((inb(ASSR) & (_BV(TCN0UB) | _BV(OCR0UB) | _BV(TCR0UB))) != 0);
/* Clear interrupt flags. */
outb(TIFR, _BV(OCF0) | _BV(TOV0));
counter = 1;
NutEnterCritical();
__asm__ __volatile__("firstovf: \n\t"
"in %D0,%1 \n\t"
"andi %D0,1 \n\t"
"breq firstovf \n\t"
"out %1,%D0 \n\n"
/* This loop has 8 cycles. */
"nextovf: \n\t"
"sec \n\t"
"adc %A0,__zero_reg__ \n\t"
"adc %B0,__zero_reg__ \n\t"
"adc %C0,__zero_reg__ \n\t"
"in %D0,%1 \n\t"
"andi %D0,1 \n\t"
"breq nextovf \n\t"
"clr %D0 "
:"=d"(counter) /* Output */
:"I"(_SFR_IO_ADDR(TIFR)), "0"(counter) /* Input */
);
NutExitCritical();
More information about the En-Nut-Discussion
mailing list