Skip to content

Commit 14dfcef

Browse files
committed
fix(timer): Output Compare issue #74
output compare doesn't work when the OCR register (OCRnA/OCRnB) equals to 0 fix #74
1 parent d9b757e commit 14dfcef

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

src/peripherals/timer.spec.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ describe('timer', () => {
112112
cpu.tick();
113113
const tcnt = cpu.readData(TCNT0);
114114
expect(tcnt).toEqual(0);
115-
expect(cpu.data[TIFR0]).toEqual(TOV0);
115+
expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0);
116116
});
117117

118118
it('should clear the TOV flag when writing 1 to the TOV bit, and not trigger the interrupt', () => {
@@ -124,9 +124,9 @@ describe('timer', () => {
124124
cpu.tick();
125125
cpu.cycles = 2;
126126
cpu.tick();
127-
expect(cpu.data[TIFR0]).toEqual(TOV0);
127+
expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0);
128128
cpu.writeData(TIFR0, TOV0);
129-
expect(cpu.data[TIFR0]).toEqual(0);
129+
expect(cpu.data[TIFR0] & TOV0).toEqual(0);
130130
});
131131

132132
it('should set TOV if timer overflows in FAST PWM mode', () => {
@@ -142,7 +142,7 @@ describe('timer', () => {
142142
cpu.tick();
143143
const tcnt = cpu.readData(TCNT0);
144144
expect(tcnt).toEqual(0);
145-
expect(cpu.data[TIFR0]).toEqual(TOV0);
145+
expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0);
146146
});
147147

148148
it('should generate an overflow interrupt if timer overflows and interrupts enabled', () => {
@@ -202,7 +202,7 @@ describe('timer', () => {
202202
cpu.data[SREG] = 0x0; // SREG: --------
203203
cpu.cycles = 2;
204204
cpu.tick();
205-
expect(cpu.data[TIFR0]).toEqual(TOV0);
205+
expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0);
206206
expect(cpu.pc).toEqual(0);
207207
expect(cpu.cycles).toEqual(2);
208208
});
@@ -218,7 +218,24 @@ describe('timer', () => {
218218
cpu.data[SREG] = 0x80; // SREG: I-------
219219
cpu.cycles = 2;
220220
cpu.tick();
221-
expect(cpu.data[TIFR0]).toEqual(TOV0);
221+
expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0);
222+
expect(cpu.pc).toEqual(0);
223+
expect(cpu.cycles).toEqual(2);
224+
});
225+
226+
it('should set OCF0A/B flags when OCRA/B == 0 and the timer equals to OCRA (issue #74)', () => {
227+
const cpu = new CPU(new Uint16Array(0x1000));
228+
new AVRTimer(cpu, timer0Config);
229+
cpu.writeData(TCNT0, 0xff);
230+
cpu.writeData(OCR0A, 0x0);
231+
cpu.writeData(OCR0B, 0x0);
232+
cpu.writeData(TCCR0A, 0x0); // WGM: Normal
233+
cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
234+
cpu.cycles = 1;
235+
cpu.tick();
236+
cpu.cycles = 2;
237+
cpu.tick();
238+
expect(cpu.data[TIFR0] & (OCF0A | OCF0B)).toEqual(OCF0A | OCF0B);
222239
expect(cpu.pc).toEqual(0);
223240
expect(cpu.cycles).toEqual(2);
224241
});

src/peripherals/timer.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,9 @@ export class AVRTimer {
299299
this.countingUp = true;
300300
this.tcntUpdated = true;
301301
this.cpu.updateClockEvent(this.count, 0);
302-
this.timerUpdated();
302+
if (this.divider) {
303+
this.timerUpdated();
304+
}
303305
};
304306
this.cpu.writeHooks[config.OCRA] = (value: u8) => {
305307
this.nextOcrA = (this.highByteTemp << 8) | value;
@@ -498,14 +500,13 @@ export class AVRTimer {
498500

499501
private timerUpdated() {
500502
const value = this.tcnt;
501-
502-
if (this.ocrA && value === this.ocrA) {
503+
if (value === this.ocrA) {
503504
this.cpu.setInterruptFlag(this.OCFA);
504505
if (this.compA) {
505506
this.updateCompPin(this.compA, 'A');
506507
}
507508
}
508-
if (this.ocrB && value === this.ocrB) {
509+
if (value === this.ocrB) {
509510
this.cpu.setInterruptFlag(this.OCFB);
510511
if (this.compB) {
511512
this.updateCompPin(this.compB, 'B');

0 commit comments

Comments
 (0)