Skip to content

Commit 8c15d5d

Browse files
committed
fix(spi): setting SPIE doesn't fire pending interrupt
1 parent 2c1aef1 commit 8c15d5d

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/peripherals/spi.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,28 @@ describe('SPI', () => {
203203
expect(cpu.pc).toEqual(0x22); // SPI Ready interrupt
204204
});
205205

206+
it('should fire a pending SPI interrupt when SPIE flag is set', () => {
207+
const cpu = new CPU(new Uint16Array(1024));
208+
new AVRSPI(cpu, spiConfig, FREQ_16MHZ);
209+
210+
cpu.writeData(SPCR, SPE | MSTR);
211+
cpu.writeData(SPDR, 0x50);
212+
cpu.data[SREG] = 0x80; // SREG: I-------
213+
214+
// Wait for transfer to complete (8 bits * 8 cycles per bit = 64).
215+
cpu.cycles += 64;
216+
cpu.tick();
217+
218+
expect(cpu.data[SPSR] & SPIF).toEqual(SPIF);
219+
expect(cpu.pc).toEqual(0); // Interrupt not taken (yet)
220+
221+
// Enable the interrupt (SPIE)
222+
cpu.writeData(SPCR, SPE | MSTR | SPIE);
223+
cpu.tick();
224+
expect(cpu.pc).toEqual(0x22); // SPI Ready interrupt
225+
expect(cpu.data[SPSR] & SPIF).toEqual(0);
226+
});
227+
206228
it('should should only update SPDR when tranfer finishes (double buffering)', () => {
207229
const cpu = new CPU(new Uint16Array(1024));
208230
const spi = new AVRSPI(cpu, spiConfig, FREQ_16MHZ);

src/peripherals/spi.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ export class AVRSPI {
7878
}, cyclesToComplete);
7979
return true;
8080
};
81+
cpu.writeHooks[SPCR] = (value: u8) => {
82+
this.cpu.updateInterruptEnable(this.SPI, value);
83+
};
8184
cpu.writeHooks[SPSR] = (value: u8) => {
8285
this.cpu.data[SPSR] = value;
8386
this.cpu.clearInterruptByFlag(this.SPI, value);

0 commit comments

Comments
 (0)