aboutsummaryrefslogtreecommitdiff
path: root/src/peripherals/spi.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/peripherals/spi.ts')
-rw-r--r--src/peripherals/spi.ts30
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() {