diff options
| author | Uri Shaked | 2021-10-29 13:04:38 +0300 |
|---|---|---|
| committer | Uri Shaked | 2021-10-29 13:04:38 +0300 |
| commit | 4eaf664653e7f2f4397f24d881ec4bf2032473ce (patch) | |
| tree | 864dece0fdae6e37f8f8c38af27bd02b2749469f /src/peripherals | |
| parent | 0.18.4 (diff) | |
| download | avr8js-4eaf664653e7f2f4397f24d881ec4bf2032473ce.tar.gz avr8js-4eaf664653e7f2f4397f24d881ec4bf2032473ce.tar.bz2 avr8js-4eaf664653e7f2f4397f24d881ec4bf2032473ce.zip | |
fix(timer): setting TCNT doesn't update OCRA #111
Diffstat (limited to '')
| -rw-r--r-- | src/peripherals/timer.spec.ts | 36 | ||||
| -rw-r--r-- | src/peripherals/timer.ts | 8 |
2 files changed, 44 insertions, 0 deletions
diff --git a/src/peripherals/timer.spec.ts b/src/peripherals/timer.spec.ts index 1afca4c..27ef7fb 100644 --- a/src/peripherals/timer.spec.ts +++ b/src/peripherals/timer.spec.ts @@ -1209,6 +1209,42 @@ describe('timer', () => { expect(cpu.readData(R19)).toEqual(0x6); expect(cpu.readData(R20)).toEqual(0x7); }); + + it('should update OCR1A when setting TCNT to 0 (issue #111)', () => { + const { program, instructionCount } = asmProgram(` + CLR r1 ; r1 is our zero register + LDI r16, 0x0 ; OCR1AH = 0x0; + STS 0x89, r1 + LDI r16, 0x8 ; OCR1AL = 0x8; + STS 0x88, r16 + ; Set waveform generation mode (WGM) to PWM Phase/Frequency Correct mode (9) + LDI r16, 0x01 ; TCCR1A = (1 << WGM10); + STS 0x80, r16 + LDI r16, 0x11 ; TCCR1B = (1 << WGM13) | (1 << CS00); + STS 0x81, r16 + STS 0x85, r1 ; TCNT1H = 0x0; + STS 0x84, r1 ; TCNT1L = 0x0; + + LDI r16, 0x5 ; OCR1AL = 0x5; // TCNT1 should read 0x0 + STS 0x88, r16 ; // TCNT1 should read 0x2 (going up) + STS 0x84, r1 ; TCNT1L = 0x0; + LDS r17, 0x84 ; // TCNT1 should read 0x1 (going up) + LDS r18, 0x84 ; // TCNT1 should read 0x3 (going up) + LDS r19, 0x84 ; // TCNT1 should read 0x5 (going down) + LDS r20, 0x84 ; // TCNT1 should read 0x3 (going down) + `); + + const cpu = new CPU(program); + new AVRTimer(cpu, timer1Config); + + const runner = new TestProgramRunner(cpu); + runner.runInstructions(instructionCount); + + expect(cpu.readData(R17)).toEqual(0x1); + expect(cpu.readData(R18)).toEqual(0x3); + expect(cpu.readData(R19)).toEqual(0x5); + expect(cpu.readData(R20)).toEqual(0x3); + }); }); describe('External clock', () => { diff --git a/src/peripherals/timer.ts b/src/peripherals/timer.ts index b597d07..53777e2 100644 --- a/src/peripherals/timer.ts +++ b/src/peripherals/timer.ts @@ -576,6 +576,14 @@ export class AVRTimer { if (this.tcntUpdated) { this.tcnt = this.tcntNext; this.tcntUpdated = false; + if ( + (this.tcnt === 0 && this.ocrUpdateMode === OCRUpdateMode.Bottom) || + (this.tcnt === this.TOP && this.ocrUpdateMode === OCRUpdateMode.Top) + ) { + this.ocrA = this.nextOcrA; + this.ocrB = this.nextOcrB; + this.ocrC = this.nextOcrC; + } } if (this.updateDivider) { const { CS } = this; |
