AVR8 Timer Extension

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would like to publish my first AVR8 project soon.

The aim is to software-extend the range of the hardware timer of an AVR8 to an arbitrary value.
Including OCRs, PWM modes, ICPs, IRQs etc.

Actually, the code was ready long time ago but I only extended one mode and one PWM channel so I would like to ask The Freaks if anyone knows of any complete extension of this type because if there is one ready-made then there is no point updating mine.

I did some initial searching in here but implementations I could find are buggy and either introduce jitter or require ridiculous IRQ delays/CPU time. Or both.

http://www.avrfreaks.net/index.p...
http://www.avrfreaks.net/index.p...
http://www.avrfreaks.net/index.p...
http://www.avrfreaks.net/index.p...

This implementation:

  • is written in C,
  • is IRQ-based,
  • does not access DDR/PIN/PORT registers,
  • has "0-tick error",
  • the permissible IRQ servicing delay time is constant and equal to TOV,
  • occupies <10% of CPU when extending 8-bit timer, prescaler set to 8,
  • occupies <0.5% of CPU when extending 16-bit timer, prescaler set to 1.

By "0-tick error" I mean that if I take an AVR with 8-bit and 16-bit hardware timers (m16) and run this extension on an 8-bit timer to software-extend it to 16-bit, with OC pin in some PWM mode, and compare generated PWM against regular 16-bit hardware timer with same mode, OCR values, prescalers, TOP etc, then both PWMs coincide (are exactly the same), even when OCR values are modified along the way, other IRQs are triggering, etc.

Any similar "0-tick error" extensions known?
batvx

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Danni made a 32bit timer here

http://www.mikrocontroller.net/topic/avr-timer-mit-32-bit

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the link.

Ignoring the lack of volatileness of t2_soft..

  if( (tifr & 1<<TOV2) && !(val & 0x80) ) // overflow prior reading TCNT2 ?
val += 256; // then add overflow

It makes an assumption the IRQ(TOV) is never delayed by more than TOV/2 but does not verify that in any way. Thus, it may work if you are lucky.

Another thing is that unfortunately that idea extends only one register of the timer (namely TCNT0) which trivializes the whole extension problem.

Full (or at least non-trivial) implementation requires resolution of events and that is not easy on AVRs. Here is the sketch of one of the IRQs resolving two events only:

//TIMER0_OVF vector has higher priority than COMP0 vector on ATMega16
ISR(TIMER0_OVF_vect){
assert(TCNT0 < IRQ_ACCEPTABLE_DELAY);

#if defined TM_OCR_IRQ
//Resolve the sequence
auto uint8_t TifrSample;
TifrSample = TIFR; //sample volatile variable
if( (TifrSample & _BV(OCF0)) && (TIMSK20 & _BV(OCF0)) ){ //if COMP IRQ is now pending
TIFR = _BV(OCF0); //clear pending IRQ and service it without entering vector
if((uint8_t)OCR0_latched > IRQ_THRESHOLD_HI){ //and COMP was triggered just before OVF
IRQ_COMP(); //First COMP
IRQ_TOV(); //Then TOV
}else{
IRQ_TOV(); //First TOV
IRQ_COMP(); //Then COMP
}
assert(!(TIFR & _BV(OCF0))); //no pending IRQs
}else
#endif //defined TM_OCR_IRQ
{
IRQ_TOV(); //Only TOV
}
assert(!(TIFR & _BV(TOVF))); //no pending IRQs
return;
}

veiyv
ndavj

EDIT: [url=http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=105036... post.[/url]
btvwp

No RSTDISBL, no fun!