From 8c15d5d1a3bdeb1f4c95248fc35b9ebe0a6aa235 Mon Sep 17 00:00:00 2001 From: Uri Shaked Date: Fri, 22 Oct 2021 04:44:33 +0300 Subject: fix(spi): setting SPIE doesn't fire pending interrupt --- src/peripherals/spi.spec.ts | 22 ++++++++++++++++++++++ src/peripherals/spi.ts | 3 +++ 2 files changed, 25 insertions(+) diff --git a/src/peripherals/spi.spec.ts b/src/peripherals/spi.spec.ts index f323b88..9e6dac5 100644 --- a/src/peripherals/spi.spec.ts +++ b/src/peripherals/spi.spec.ts @@ -203,6 +203,28 @@ describe('SPI', () => { expect(cpu.pc).toEqual(0x22); // SPI Ready interrupt }); + it('should fire a pending SPI interrupt when SPIE flag is set', () => { + const cpu = new CPU(new Uint16Array(1024)); + new AVRSPI(cpu, spiConfig, FREQ_16MHZ); + + cpu.writeData(SPCR, SPE | MSTR); + cpu.writeData(SPDR, 0x50); + cpu.data[SREG] = 0x80; // SREG: I------- + + // Wait for transfer to complete (8 bits * 8 cycles per bit = 64). + cpu.cycles += 64; + cpu.tick(); + + expect(cpu.data[SPSR] & SPIF).toEqual(SPIF); + expect(cpu.pc).toEqual(0); // Interrupt not taken (yet) + + // Enable the interrupt (SPIE) + cpu.writeData(SPCR, SPE | MSTR | SPIE); + cpu.tick(); + expect(cpu.pc).toEqual(0x22); // SPI Ready interrupt + expect(cpu.data[SPSR] & SPIF).toEqual(0); + }); + it('should should only update SPDR when tranfer finishes (double buffering)', () => { const cpu = new CPU(new Uint16Array(1024)); const spi = new AVRSPI(cpu, spiConfig, FREQ_16MHZ); diff --git a/src/peripherals/spi.ts b/src/peripherals/spi.ts index 9707307..7b753ab 100644 --- a/src/peripherals/spi.ts +++ b/src/peripherals/spi.ts @@ -78,6 +78,9 @@ export class AVRSPI { }, cyclesToComplete); return true; }; + cpu.writeHooks[SPCR] = (value: u8) => { + this.cpu.updateInterruptEnable(this.SPI, value); + }; cpu.writeHooks[SPSR] = (value: u8) => { this.cpu.data[SPSR] = value; this.cpu.clearInterruptByFlag(this.SPI, value); -- cgit v1.2.3