diff options
| author | Uri Shaked | 2020-12-09 00:51:13 +0200 |
|---|---|---|
| committer | Uri Shaked | 2020-12-09 00:51:58 +0200 |
| commit | 36c4134a26063248a2ef47f5ac8defe50d9476b1 (patch) | |
| tree | 44433290b0d684768216b33550a7af9a6fb4235f /src/peripherals/spi.ts | |
| parent | test(cpu): improve test name (diff) | |
| download | avr8js-36c4134a26063248a2ef47f5ac8defe50d9476b1.tar.gz avr8js-36c4134a26063248a2ef47f5ac8defe50d9476b1.tar.bz2 avr8js-36c4134a26063248a2ef47f5ac8defe50d9476b1.zip | |
refactor: central interrupt handling #38
Diffstat (limited to 'src/peripherals/spi.ts')
| -rw-r--r-- | src/peripherals/spi.ts | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/peripherals/spi.ts b/src/peripherals/spi.ts index 0c03c3f..f67143f 100644 --- a/src/peripherals/spi.ts +++ b/src/peripherals/spi.ts @@ -1,6 +1,5 @@ -import { CPU } from '../cpu/cpu'; +import { AVRInterruptConfig, CPU } from '../cpu/cpu'; import { u8 } from '../types'; -import { avrInterrupt } from '../cpu/interrupt'; export interface SPIConfig { spiInterrupt: u8; @@ -42,6 +41,15 @@ export class AVRSPI { private transmissionCompleteCycles = 0; private receivedByte: u8 = 0; + // Interrupts + private SPI: AVRInterruptConfig = { + address: this.config.spiInterrupt, + flagRegister: this.config.SPSR, + flagMask: SPSR_SPIF, + enableRegister: this.config.SPCR, + enableMask: SPCR_SPIE, + }; + constructor(private cpu: CPU, private config: SPIConfig, private freqMHz: number) { const { SPCR, SPSR, SPDR } = config; cpu.writeHooks[SPDR] = (value: u8) => { @@ -57,28 +65,26 @@ export class AVRSPI { } // Clear write collision / interrupt flags - cpu.data[SPSR] &= ~SPSR_WCOL & ~SPSR_SPIF; + cpu.data[SPSR] &= ~SPSR_WCOL; + this.cpu.clearInterrupt(this.SPI); this.receivedByte = this.onTransfer?.(value) ?? 0; this.transmissionCompleteCycles = this.cpu.cycles + this.clockDivider * bitsPerByte; return true; }; + cpu.writeHooks[SPSR] = (value: u8) => { + this.cpu.data[SPSR] = value; + this.cpu.clearInterruptByFlag(this.SPI, value); + }; } tick() { if (this.transmissionCompleteCycles && this.cpu.cycles >= this.transmissionCompleteCycles) { - const { SPSR, SPDR } = this.config; - this.cpu.data[SPSR] |= SPSR_SPIF; + const { SPDR } = this.config; this.cpu.data[SPDR] = this.receivedByte; + this.cpu.setInterruptFlag(this.SPI); this.transmissionCompleteCycles = 0; } - if (this.cpu.interruptsEnabled) { - const { SPSR, SPCR, spiInterrupt } = this.config; - if (this.cpu.data[SPCR] & SPCR_SPIE && this.cpu.data[SPSR] & SPSR_SPIF) { - avrInterrupt(this.cpu, spiInterrupt); - this.cpu.data[SPSR] &= ~SPSR_SPIF; - } - } } get isMaster() { |
