feat: Enhance Arduino pin tracing in DynamicComponent; update LittleFS WASM initialization; mark subproject commits as dirty

This commit is contained in:
David Montero Crespo 2026-04-13 11:06:03 -03:00
parent c65acdb1dc
commit 67a8373c80
3 changed files with 49 additions and 20 deletions

View File

@ -204,28 +204,50 @@ export const DynamicComponent: React.FC<DynamicComponentProps> = ({
let cleanupSimulationEvents: (() => void) | undefined;
if (logic && logic.attachEvents && simulator) {
// Helper to find Arduino pin connected to a component pin
// Helper to find Arduino pin connected to a component pin.
// Traces through passive components (resistors) so that a circuit like
// LED-cathode → resistor → GND returns -1 (GND) instead of null.
const getArduinoPin = (componentPinName: string): number | null => {
const state = useSimulatorStore.getState();
const wires = state.wires.filter(
w => (w.start.componentId === id && w.start.pinName === componentPinName) ||
(w.end.componentId === id && w.end.pinName === componentPinName)
);
for (const w of wires) {
// Find which endpoint connects to a board component
const boardEndpoint = isBoardComponent(w.start.componentId) ? w.start :
isBoardComponent(w.end.componentId) ? w.end : null;
if (boardEndpoint) {
// Use the board's actual kind for pin mapping (instance ID may differ from kind,
// e.g. board ID 'arduino-uno' after switching to 'raspberry-pi-pico')
const boardKind = state.boards.find((b) => b.id === boardEndpoint.componentId)?.boardKind
?? boardEndpoint.componentId;
const pin = boardPinToNumber(boardKind, boardEndpoint.pinName);
if (pin !== null) return pin;
// Passive component metadataIds that are electrically transparent.
const PASSIVE = new Set(['resistor', 'resistor-us']);
// Depth-limited BFS: trace from (fromId, fromPin) through wires,
// traversing through passive components to reach a board pin.
const trace = (fromId: string, fromPin: string, depth: number): number | null => {
if (depth > 6) return null;
const wires = state.wires.filter(
w => (w.start.componentId === fromId && w.start.pinName === fromPin) ||
(w.end.componentId === fromId && w.end.pinName === fromPin)
);
for (const w of wires) {
const selfEp = (w.start.componentId === fromId && w.start.pinName === fromPin) ? w.start : w.end;
const otherEp = selfEp === w.start ? w.end : w.start;
if (isBoardComponent(otherEp.componentId)) {
// Direct board connection
const boardKind = state.boards.find((b) => b.id === otherEp.componentId)?.boardKind
?? otherEp.componentId;
const pin = boardPinToNumber(boardKind, otherEp.pinName);
if (pin !== null) return pin;
} else {
// Intermediate passive component — traverse through it
const comp = state.components.find(c => c.id === otherEp.componentId);
if (comp && PASSIVE.has(comp.metadataId)) {
// Resistors have two pins; find the other one to continue tracing
const otherPin = otherEp.pinName === '1' ? '2' : '1';
const result = trace(otherEp.componentId, otherPin, depth + 1);
if (result !== null) return result;
}
}
}
}
return null;
return null;
};
return trace(id, componentPinName, 0);
};
cleanupSimulationEvents = logic.attachEvents(el, simulator, getArduinoPin, id);

View File

@ -8,6 +8,11 @@
import { get as idbGet, set as idbSet } from 'idb-keyval';
import createLittleFS from 'littlefs';
// ?url tells Vite to return the correct asset URL for the WASM binary
// (without this, Emscripten fetches 'littlefs.wasm' relative to the bundle
// which resolves to the SPA index.html — causing the "expected magic word" error)
// @ts-ignore — Vite ?url import, no type declaration needed
import littlefsWasmUrl from 'littlefs/dist/littlefs.wasm?url';
// Flash geometry (matches rp2040js and MicroPython defaults)
const FLASH_START_ADDRESS = 0x10000000;
@ -68,8 +73,9 @@ export async function loadUserFiles(
// Create a backing buffer for the LittleFS filesystem
const fsBuffer = new Uint8Array(MICROPYTHON_FS_BLOCK_COUNT * MICROPYTHON_FS_BLOCK_SIZE);
// Initialize the littlefs WASM module
const lfs = await createLittleFS({});
// Initialize the littlefs WASM module.
// locateFile redirects Emscripten's internal fetch to the Vite-resolved asset URL.
const lfs = await createLittleFS({ locateFile: () => littlefsWasmUrl });
// Register flash read/write callbacks for the WASM module
const flashRead = lfs.addFunction(

View File

@ -20,6 +20,7 @@ export default defineConfig({
},
},
},
assetsInclude: ['**/*.wasm'],
optimizeDeps: {
include: ['avr8js', 'rp2040js', '@wokwi/elements', 'littlefs'],
},