@@ -238,12 +238,14 @@ function compToOverride(comp: CompBitsValue) {
238238}
239239
240240export class AVRTimer {
241+ private readonly MAX = this . config . bits === 16 ? 0xffff : 0xff ;
241242 private lastCycle = 0 ;
242243 private ocrA : u16 = 0 ;
243244 private nextOcrA : u16 = 0 ;
244245 private ocrB : u16 = 0 ;
245246 private nextOcrB : u16 = 0 ;
246247 private ocrUpdateMode = OCRUpdateMode . Immediate ;
248+ private tovUpdateMode = TOVUpdateMode . Max ;
247249 private icr : u16 = 0 ; // only for 16-bit timers
248250 private timerMode : TimerMode ;
249251 private topValue : TimerTopValue ;
@@ -403,10 +405,11 @@ export class AVRTimer {
403405
404406 private updateWGMConfig ( ) {
405407 const wgmModes = this . config . bits === 16 ? wgmModes16Bit : wgmModes8Bit ;
406- const [ timerMode , topValue , ocrUpdateMode ] = wgmModes [ this . WGM ] ;
408+ const [ timerMode , topValue , ocrUpdateMode , tovUpdateMode ] = wgmModes [ this . WGM ] ;
407409 this . timerMode = timerMode ;
408410 this . topValue = topValue ;
409411 this . ocrUpdateMode = ocrUpdateMode ;
412+ this . tovUpdateMode = tovUpdateMode ;
410413 }
411414
412415 count = ( reschedule = true ) => {
@@ -417,28 +420,34 @@ export class AVRTimer {
417420 const counterDelta = Math . floor ( delta / divider ) ;
418421 this . lastCycle += counterDelta * divider ;
419422 const val = this . tcnt ;
420- const { timerMode } = this ;
423+ const { timerMode, TOP } = this ;
421424 const phasePwm =
422425 timerMode === TimerMode . PWMPhaseCorrect || timerMode === TimerMode . PWMPhaseFrequencyCorrect ;
423- const limit = this . TOP + 1 ;
424426 const newVal = phasePwm
425427 ? this . phasePwmCount ( val , counterDelta )
426- : ( val + counterDelta ) % limit ;
427- const overflow = val + counterDelta >= limit ;
428+ : ( val + counterDelta ) % ( TOP + 1 ) ;
429+ const overflow = val + counterDelta > TOP ;
428430 // A CPU write overrides (has priority over) all counter clear or count operations.
429431 if ( ! this . tcntUpdated ) {
430432 this . tcnt = newVal ;
431433 this . timerUpdated ( ) ;
432434 }
433435
434- if ( ! phasePwm && this . ocrUpdateMode == OCRUpdateMode . Bottom && overflow ) {
435- // OCRUpdateMode.Top only occurs in Phase Correct modes, handled by phasePwmCount()
436- this . ocrA = this . nextOcrA ;
437- this . ocrB = this . nextOcrB ;
438- }
436+ if ( ! phasePwm ) {
437+ if ( this . ocrUpdateMode == OCRUpdateMode . Bottom && overflow ) {
438+ // OCRUpdateMode.Top only occurs in Phase Correct modes, handled by phasePwmCount()
439+ this . ocrA = this . nextOcrA ;
440+ this . ocrB = this . nextOcrB ;
441+ }
439442
440- if ( ( timerMode === TimerMode . Normal || timerMode === TimerMode . FastPWM ) && val > newVal ) {
441- cpu . setInterruptFlag ( this . OVF ) ;
443+ // OCRUpdateMode.Bottom only occurs in Phase Correct modes, handled by phasePwmCount().
444+ // Thus we only handle TOVUpdateMode.Top or TOVUpdateMode.Max here.
445+ if (
446+ ( newVal === TOP || overflow ) &&
447+ ( this . tovUpdateMode == TOVUpdateMode . Top || TOP === this . MAX )
448+ ) {
449+ cpu . setInterruptFlag ( this . OVF ) ;
450+ }
442451 }
443452 }
444453 if ( this . tcntUpdated ) {
@@ -492,11 +501,6 @@ export class AVRTimer {
492501
493502 if ( this . ocrA && value === this . ocrA ) {
494503 this . cpu . setInterruptFlag ( this . OCFA ) ;
495- if ( this . timerMode === TimerMode . CTC ) {
496- // Clear Timer on Compare Match (CTC) Mode
497- this . tcnt = 0 ;
498- this . cpu . setInterruptFlag ( this . OVF ) ;
499- }
500504 if ( this . compA ) {
501505 this . updateCompPin ( this . compA , 'A' ) ;
502506 }
0 commit comments