aboutsummaryrefslogtreecommitdiff
path: root/src/peripherals/twi.ts
diff options
context:
space:
mode:
authorUri Shaked2020-12-09 15:55:12 +0200
committerGitHub2020-12-09 15:55:12 +0200
commitb2280efa5457685db66d6ce6b156f37d5e678204 (patch)
tree1857fe48d3e2d32a39cfe810a0dfdd7d96526b3a /src/peripherals/twi.ts
parenttest(cpu): improve test name (diff)
parentperf!: centeral timekeeping (diff)
downloadavr8js-b2280efa5457685db66d6ce6b156f37d5e678204.tar.gz
avr8js-b2280efa5457685db66d6ce6b156f37d5e678204.tar.bz2
avr8js-b2280efa5457685db66d6ce6b156f37d5e678204.zip
Merge pull request #71 from wokwi/interrupt-refactor
refactor: central interrupt handling #38
Diffstat (limited to 'src/peripherals/twi.ts')
-rw-r--r--src/peripherals/twi.ts41
1 files changed, 16 insertions, 25 deletions
diff --git a/src/peripherals/twi.ts b/src/peripherals/twi.ts
index 52258a6..000bd2a 100644
--- a/src/peripherals/twi.ts
+++ b/src/peripherals/twi.ts
@@ -1,5 +1,4 @@
-import { CPU } from '../cpu/cpu';
-import { avrInterrupt } from '../cpu/interrupt';
+import { AVRInterruptConfig, CPU } from '../cpu/cpu';
import { u8 } from '../types';
export interface TWIEventHandler {
@@ -96,19 +95,26 @@ export class NoopTWIEventHandler implements TWIEventHandler {
export class AVRTWI {
public eventHandler: TWIEventHandler = new NoopTWIEventHandler(this);
- private nextTick: (() => void) | null = null;
+ // Interrupts
+ private TWI: AVRInterruptConfig = {
+ address: this.config.twiInterrupt,
+ flagRegister: this.config.TWCR,
+ flagMask: TWCR_TWINT,
+ enableRegister: this.config.TWCR,
+ enableMask: TWCR_TWIE,
+ };
constructor(private cpu: CPU, private config: TWIConfig, private freqMHz: number) {
this.updateStatus(STATUS_TWI_IDLE);
this.cpu.writeHooks[config.TWCR] = (value) => {
+ this.cpu.data[config.TWCR] = value;
const clearInt = value & TWCR_TWINT;
- if (clearInt) {
- value &= ~TWCR_TWINT;
- }
+ this.cpu.clearInterruptByFlag(this.TWI, value);
+ this.cpu.updateInterruptEnable(this.TWI, value);
const { status } = this;
if (clearInt && value & TWCR_TWEN) {
const twdrValue = this.cpu.data[this.config.TWDR];
- this.nextTick = () => {
+ this.cpu.addClockEvent(() => {
if (value & TWCR_TWSTA) {
this.eventHandler.start(status !== STATUS_TWI_IDLE);
} else if (value & TWCR_TWSTO) {
@@ -121,27 +127,12 @@ export class AVRTWI {
const ack = !!(value & TWCR_TWEA);
this.eventHandler.readByte(ack);
}
- };
- this.cpu.data[config.TWCR] = value;
+ }, 0);
return true;
}
};
}
- tick() {
- if (this.nextTick) {
- this.nextTick();
- this.nextTick = null;
- }
- if (this.cpu.interruptsEnabled) {
- const { TWCR, twiInterrupt } = this.config;
- if (this.cpu.data[TWCR] & TWCR_TWIE && this.cpu.data[TWCR] & TWCR_TWINT) {
- avrInterrupt(this.cpu, twiInterrupt);
- this.cpu.data[TWCR] &= ~TWCR_TWINT;
- }
- }
- }
-
get prescaler() {
switch (this.cpu.data[this.config.TWSR] & TWSR_TWPS_MASK) {
case 0:
@@ -193,8 +184,8 @@ export class AVRTWI {
}
private updateStatus(value: u8) {
- const { TWCR, TWSR } = this.config;
+ const { TWSR } = this.config;
this.cpu.data[TWSR] = (this.cpu.data[TWSR] & ~TWSR_TWS_MASK) | value;
- this.cpu.data[TWCR] |= TWCR_TWINT;
+ this.cpu.setInterruptFlag(this.TWI);
}
}