diff options
| author | Apexo | 2026-04-02 20:58:40 +0200 |
|---|---|---|
| committer | Apexo | 2026-04-02 20:58:40 +0200 |
| commit | 873c1b2a584a58fc89f0f85e772b653271c8e9c5 (patch) | |
| tree | f4c72b31c800d601d2d092fa058cc7e0561bb394 | |
| parent | ADC: stop conversion when disabled via CTRLA (diff) | |
| download | anduril-sim-873c1b2a584a58fc89f0f85e772b653271c8e9c5.tar.gz anduril-sim-873c1b2a584a58fc89f0f85e772b653271c8e9c5.tar.bz2 anduril-sim-873c1b2a584a58fc89f0f85e772b653271c8e9c5.zip | |
ADC: stop when going to sleep (except idle)
| -rw-r--r-- | src/lights/d3aa.ts | 2 | ||||
| -rw-r--r-- | src/peripherals/avrdx-adc.ts | 7 | ||||
| -rw-r--r-- | src/peripherals/avrdx-slpctrl.ts | 28 |
3 files changed, 32 insertions, 5 deletions
diff --git a/src/lights/d3aa.ts b/src/lights/d3aa.ts index 29dc249..21eea86 100644 --- a/src/lights/d3aa.ts +++ b/src/lights/d3aa.ts @@ -134,7 +134,7 @@ export class D3AA { this.portA = new AVRDxPort(this.cpu, 0x0400 + DATA_MEMORY_OFFSET, 0x00 + DATA_MEMORY_OFFSET, 8); this.portC = new AVRDxPort(this.cpu, 0x0440 + DATA_MEMORY_OFFSET, 0x08 + DATA_MEMORY_OFFSET, 29); this.portD = new AVRDxPort(this.cpu, 0x0460 + DATA_MEMORY_OFFSET, 0x0C + DATA_MEMORY_OFFSET, 24); - this.adc = new AVRDxADC(this.cpu, 0x0600 + DATA_MEMORY_OFFSET, 26, this.vref); + this.adc = new AVRDxADC(this.cpu, 0x0600 + DATA_MEMORY_OFFSET, 26, this.vref, this.slpctrl); this.dac = new AVRDxDAC(this.cpu, 0x06A0 + DATA_MEMORY_OFFSET); this.nvmctrl = new AVRDxNVMCTRL(this.cpu, 0x1000 + DATA_MEMORY_OFFSET, 0x1400 + DATA_MEMORY_OFFSET, 256, this.ccp); this.sigrow = new AVRDxSIGROW(this.cpu, 0x1104 + DATA_MEMORY_OFFSET); diff --git a/src/peripherals/avrdx-adc.ts b/src/peripherals/avrdx-adc.ts index ed49ce6..716c4c7 100644 --- a/src/peripherals/avrdx-adc.ts +++ b/src/peripherals/avrdx-adc.ts @@ -3,6 +3,7 @@ import type { CPU, AVRInterruptConfig } from 'avr8js/cpu/cpu'; import type { AVRDxVREF } from './avrdx-vref'; +import { SMODE_IDLE_gc, type AVRDxSLPCTRL } from './avrdx-slpctrl'; const CTRLA = 0x0000; const CTRLB = 0x0001; @@ -72,7 +73,7 @@ export class AVRDxADC { private readonly resrdyIrq: AVRInterruptConfig; - constructor(private cpu: CPU, private base: number, resrdyIrqNo: number, private vref: AVRDxVREF) { + constructor(private cpu: CPU, private base: number, resrdyIrqNo: number, private vref: AVRDxVREF, private slpctrl: AVRDxSLPCTRL) { this.resrdyIrq = { address: resrdyIrqNo * 2, // vector 26, word addr 0x34 flagRegister: base + INTFLAGS, @@ -117,6 +118,10 @@ export class AVRDxADC { // RES registers - read only (but firmware can read them) cpu.writeHooks[base + RESL] = () => true; // ignore writes cpu.writeHooks[base + RESH] = () => true; + + slpctrl.onSleep((mode) => { + if (mode !== SMODE_IDLE_gc) this.stop(); + }); } private stop() { 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); } } |
