diff options
Diffstat (limited to 'src/peripherals/avrdx-slpctrl.ts')
| -rw-r--r-- | src/peripherals/avrdx-slpctrl.ts | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/peripherals/avrdx-slpctrl.ts b/src/peripherals/avrdx-slpctrl.ts index 1e75c12..307810e 100644 --- a/src/peripherals/avrdx-slpctrl.ts +++ b/src/peripherals/avrdx-slpctrl.ts @@ -1,14 +1,23 @@ // AVR-Dx SLPCTRL - Sleep Controller -// Handles the SLEEP instruction by fast-forwarding to the next clock event. import type { CPU } from 'avr8js/cpu/cpu'; const CTRLA = 0; const SEN_bm = 0x01; -// const SMODE_gm = 0x06; +const SMODE_gm = 0x06; + +export const SMODE_IDLE_gc = 0x00; +export const SMODE_STDBY_gc = 0x02; +export const SMODE_PDOWN_gc = 0x04; + + +export type SMODE = typeof SMODE_IDLE_gc | typeof SMODE_STDBY_gc | typeof SMODE_PDOWN_gc; +export type SleepCallback = (mode: SMODE) => void; export class AVRDxSLPCTRL { sleepUntil: number = 0; + sleeping: null | SMODE = null; + callbacks: SleepCallback[]; constructor(private cpu: CPU, private base: number) { // CTRLA - sleep mode + sleep enable @@ -21,15 +30,28 @@ export class AVRDxSLPCTRL { cpu.onSleep = () => { this.handleSleep(); }; + + this.callbacks = []; } private handleSleep() { const ctrla = this.cpu.data[this.base + CTRLA]; - if (!(ctrla & SEN_bm)) return; // sleep not enabled + if (!(ctrla & SEN_bm)) return; + + const mode = ctrla & SMODE_gm; + this.sleeping = mode as SMODE; const nextEvent = (this.cpu as any).nextClockEvent; if (nextEvent) { this.sleepUntil = nextEvent.cycles; } + + for (const cb of this.callbacks) { + cb(mode as SMODE); + } + } + + onSleep(cb: SleepCallback) { + this.callbacks.push(cb); } } |
