fix(rp2040,stm32): drive digital inputs from the real circuit, like AVR
Extend the source-backed SPICE-driven input fix to the Pico (RP2040) and STM32: a GP/PA pin wired to a rail or button now reads the right level from the solve, while floating event-part nets (encoder/keypad/dialer/dip/stepper) stay on the part layer. RP2040 just opts in (spiceDrivenInputs); STM32 opts in via the Stm32BridgeShim and connectDigitalInputsToMcu maps PA0/PC13 names to the linear pin setPinState expects (stm32PinNameToLinear).
This commit is contained in:
parent
e81450e348
commit
f4401cc2dd
|
|
@ -145,6 +145,12 @@ export class IdleSpinDetector {
|
||||||
export type RP2040I2CDevice = I2CDevice;
|
export type RP2040I2CDevice = I2CDevice;
|
||||||
|
|
||||||
export class RP2040Simulator {
|
export class RP2040Simulator {
|
||||||
|
// Digital inputs are driven from the SPICE solve (connectDigitalInputsToMcu)
|
||||||
|
// for source-backed nets, so digitalRead reflects real wiring (a GP pin wired
|
||||||
|
// to a rail / button reads the right level). Floating nets are left to the
|
||||||
|
// part layer, so event-driven parts (encoder/keypad/…) keep working. Mirrors
|
||||||
|
// the AVR fix; the connector + sourcedNets gating are board-agnostic.
|
||||||
|
readonly spiceDrivenInputs = true;
|
||||||
private rp2040: RP2040 | null = null;
|
private rp2040: RP2040 | null = null;
|
||||||
private running = false;
|
private running = false;
|
||||||
private animationFrame: number | null = null;
|
private animationFrame: number | null = null;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
*/
|
*/
|
||||||
import { useSimulatorStore, getBoardSimulator, getBoardPinManager } from '../../store/useSimulatorStore';
|
import { useSimulatorStore, getBoardSimulator, getBoardPinManager } from '../../store/useSimulatorStore';
|
||||||
import { useElectricalStore } from '../../store/useElectricalStore';
|
import { useElectricalStore } from '../../store/useElectricalStore';
|
||||||
|
import { isStm32BoardKind } from '../../types/board';
|
||||||
|
import { stm32PinNameToLinear } from '../Stm32Bridge';
|
||||||
|
|
||||||
// 3.3 V LVCMOS thresholds with a hysteresis band so a node hovering near the
|
// 3.3 V LVCMOS thresholds with a hysteresis band so a node hovering near the
|
||||||
// midpoint doesn't chatter. A pulled-up idle input sits at ~3.3 V and a
|
// midpoint doesn't chatter. A pulled-up idle input sits at ~3.3 V and a
|
||||||
|
|
@ -53,9 +55,13 @@ export function connectDigitalInputsToMcu(): () => void {
|
||||||
const pm = getBoardPinManager(board.id);
|
const pm = getBoardPinManager(board.id);
|
||||||
const driven = pm ? pm.getOutputPins() : new Set<number>();
|
const driven = pm ? pm.getOutputPins() : new Set<number>();
|
||||||
const prefix = `${board.id}:`;
|
const prefix = `${board.id}:`;
|
||||||
|
// STM32 names pins PA0/PC13/… and its PinManager + setPinState key on the
|
||||||
|
// linear pin (port*16+pin); every other board uses plain GPIO numbers.
|
||||||
|
const isStm32 = isStm32BoardKind(board.boardKind);
|
||||||
for (const [key, net] of pinNetMap) {
|
for (const [key, net] of pinNetMap) {
|
||||||
if (!key.startsWith(prefix)) continue;
|
if (!key.startsWith(prefix)) continue;
|
||||||
const gpio = gpioFromPinName(key.slice(prefix.length));
|
const pinName = key.slice(prefix.length);
|
||||||
|
const gpio = isStm32 ? stm32PinNameToLinear(pinName) : gpioFromPinName(pinName);
|
||||||
if (gpio < 0) continue;
|
if (gpio < 0) continue;
|
||||||
if (driven.has(gpio)) continue; // the MCU drives this pin (digitalWrite)
|
if (driven.has(gpio)) continue; // the MCU drives this pin (digitalWrite)
|
||||||
// Only drive pins whose net is backed by a real source/element (rail,
|
// Only drive pins whose net is backed by a real source/element (rail,
|
||||||
|
|
|
||||||
|
|
@ -600,6 +600,12 @@ function makePinPullHandler(boardId: string) {
|
||||||
// minus the ESP32-only WiFi / proxy-resync machinery. ──────────────────────
|
// minus the ESP32-only WiFi / proxy-resync machinery. ──────────────────────
|
||||||
class Stm32BridgeShim {
|
class Stm32BridgeShim {
|
||||||
pinManager: PinManager;
|
pinManager: PinManager;
|
||||||
|
// Digital inputs are driven from the SPICE solve (connectDigitalInputsToMcu)
|
||||||
|
// for source-backed nets — digitalRead reflects the real wiring instead of a
|
||||||
|
// part seed. The connector maps STM32 pin names (PA0, PC13) to the linear pin
|
||||||
|
// setPinState expects via stm32PinNameToLinear. Floating nets stay with the
|
||||||
|
// part layer. Mirrors the AVR / RP2040 fix.
|
||||||
|
readonly spiceDrivenInputs = true;
|
||||||
onSerialData: ((ch: string) => void) | null = null;
|
onSerialData: ((ch: string) => void) | null = null;
|
||||||
onPinChangeWithTime: ((pin: number, state: boolean, timeMs: number) => void) | null = null;
|
onPinChangeWithTime: ((pin: number, state: boolean, timeMs: number) => void) | null = null;
|
||||||
onBaudRateChange: ((baud: number) => void) | null = null;
|
onBaudRateChange: ((baud: number) => void) | null = null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue