aboutsummaryrefslogtreecommitdiff
path: root/src/peripherals
diff options
context:
space:
mode:
Diffstat (limited to 'src/peripherals')
-rw-r--r--src/peripherals/timer.spec.ts36
-rw-r--r--src/peripherals/timer.ts8
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;
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.