@@ -238,12 +238,14 @@ function compToOverride(comp: CompBitsValue) {
238
238
}
239
239
240
240
export class AVRTimer {
241
+ private readonly MAX = this . config . bits === 16 ? 0xffff : 0xff ;
241
242
private lastCycle = 0 ;
242
243
private ocrA : u16 = 0 ;
243
244
private nextOcrA : u16 = 0 ;
244
245
private ocrB : u16 = 0 ;
245
246
private nextOcrB : u16 = 0 ;
246
247
private ocrUpdateMode = OCRUpdateMode . Immediate ;
248
+ private tovUpdateMode = TOVUpdateMode . Max ;
247
249
private icr : u16 = 0 ; // only for 16-bit timers
248
250
private timerMode : TimerMode ;
249
251
private topValue : TimerTopValue ;
@@ -403,10 +405,11 @@ export class AVRTimer {
403
405
404
406
private updateWGMConfig ( ) {
405
407
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 ] ;
407
409
this . timerMode = timerMode ;
408
410
this . topValue = topValue ;
409
411
this . ocrUpdateMode = ocrUpdateMode ;
412
+ this . tovUpdateMode = tovUpdateMode ;
410
413
}
411
414
412
415
count = ( reschedule = true ) => {
@@ -417,28 +420,34 @@ export class AVRTimer {
417
420
const counterDelta = Math . floor ( delta / divider ) ;
418
421
this . lastCycle += counterDelta * divider ;
419
422
const val = this . tcnt ;
420
- const { timerMode } = this ;
423
+ const { timerMode, TOP } = this ;
421
424
const phasePwm =
422
425
timerMode === TimerMode . PWMPhaseCorrect || timerMode === TimerMode . PWMPhaseFrequencyCorrect ;
423
- const limit = this . TOP + 1 ;
424
426
const newVal = phasePwm
425
427
? 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 ;
428
430
// A CPU write overrides (has priority over) all counter clear or count operations.
429
431
if ( ! this . tcntUpdated ) {
430
432
this . tcnt = newVal ;
431
433
this . timerUpdated ( ) ;
432
434
}
433
435
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
+ }
439
442
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
+ }
442
451
}
443
452
}
444
453
if ( this . tcntUpdated ) {
@@ -492,11 +501,6 @@ export class AVRTimer {
492
501
493
502
if ( this . ocrA && value === this . ocrA ) {
494
503
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
- }
500
504
if ( this . compA ) {
501
505
this . updateCompPin ( this . compA , 'A' ) ;
502
506
}
0 commit comments