modelPartialMcuCore

Programmable core without its sync point: Python program, electrical stage of each pin, power-on - the boards instantiate McuCore, which adds the sync point, cf. requirements.md decisions "Refactoring du socle des cartes" and "Radios micro:bit"

Extends from PartialMcuSettings (User parameters of a microcontroller (program, file system, execution time, debugging, electrical stages of the pins) - declared once, shared by the boards (MCU, RPi_Pico, MicroBit_v2) and their core Internal.Boards.McuCore).

Information

The programmable core, minus its sync point: embedded Python interpreter (PyRuntime), one electrical stage Internal.Boards.PinBridge per pin, power-on logic. The boards instantiate McuCore, which adds the sync point (PyRuntime_sync). Its parameters are those of the board that contains it (Internal.Boards.PartialMcuSettings), plus the pin table (nPins, pinIds, pinCaps, boardProfile) set by the board.

  • Pins pin[nPins]: push-pull outputs fed by vdd — their high level is the voltage of vdd, and their current is drawn from it.
  • Supply vdd/gnd: the core draws ICore while supplied.
  • Power-on: powerGood = vdd above VPowerOn (down to VPowerOff, hysteresis) and run high (internal pull-up, may stay unconnected). The program starts at the first supplied sync point, time.ticks_ms() counting from there; a later loss stops it for good (no restart), pins in high impedance.
  • ADC reference vref: high impedance input.
  • Temperature sensor (hasTempSensor): an extra ADC channel at the end of the pin table (pseudo-pin 30, ADC(4) on the pico profile), 0.706 V at 27 °C, −1.721 mV/°C.

See requirements.md, decisions "Carte Raspberry Pi Pico et alimentation" and "Refactoring du socle des cartes".

Parameters

TypeNameDefaultDescription
Modelica.Units.SI.TimetickPeriod (from PartialMcuSettings)0.1Period of the minimal sync point (output freshness if the script never sleeps)
IntegernPinsNumber of pins of the core (external pins, internal pins of the board, on-board LED) - at most 31 (MAX_PINS on the C side, minus the temperature sensor)
Integer[nPins]pinIdsGPIO number of each pin, as written in the script
Integer[nPins]pinCapsCapabilities of each pin: sum of 1 = digital (Pin, PWM), 2 = wired to a connector (UART, I2C, I2CTarget), 4 = ADC input
StringboardProfile"generic"Board profile read by the machine shim: "generic" (MCU), "pico" (RPi_Pico) or "microbit" (MicroBit_v2)
BooleanhasTempSensorfalseOn-chip temperature sensor, read by machine.ADC(4) on the pico profile
Modelica.Units.NonSI.Temperature_degCdieTemperature27Temperature of the chip, read by the temperature sensor
Modelica.Units.SI.CurrentICore0.02Current drawn from vdd by the core and its flash while supplied (pins excluded)
Modelica.Units.SI.VoltageVPowerOn1.8Voltage of vdd above which the core starts (power-on reset)
Modelica.Units.SI.VoltageVPowerOff1.6Voltage of vdd below which a running core stops for good (brown-out)
Modelica.Units.SI.ResistanceRRunPullUp50e3Internal pull-up of the RUN pin to vdd
StringinstanceNamegetInstanceName()Name shown in the log and given to the copy of the flash: that of the board containing the core, set by it
Python script
StringscriptPath (from PartialMcuSettings)Modelica.Utilities.Files.loadResource("modelica://MicroPythonMCU/Resources/Scripts/MCU/demo.py")Path of the user script (.py) - with an active file system, run after boot.py instead of main.py; empty = main.py from the flash
BooleanaddScriptDirToPath (from PartialMcuSettings)trueMake the .py files next to the script importable (e.g. import my_module) - mimics the real Pico (flash root folder on sys.path)
StringlibraryPath (from PartialMcuSettings)""Optional: a .py file from a shared library folder to make importable (the folder containing this file is added to the module search path) - leave empty if unused
File system › Simulated flash
BooleanfsEnabled (from PartialMcuSettings)falseEnable the file system (simulated flash) - disabled: open() and os raise OSError
StringfsSource (from PartialMcuSettings)""Initial image of the flash (folder: data, boot.py, main.py, lib/), copied at each simulation and never modified - any file of the folder, the folder path or a modelica:// URI; empty = blank flash, only the script runs
StringfsWorkspace (from PartialMcuSettings)"."Workspace: folder where each simulation creates its copy, named <instance>_<FS name>_<date>_<time> (created if missing) - "." or relative path = from the simulation folder; full path of the copy shown in the log
BooleanfsOpenExplorer (from PartialMcuSettings)trueOpen Windows Explorer on the copy at the end of the simulation
Execution time
Modelica.Units.SI.TimegpioOpTime (from PartialMcuSettings)5e-6Execution time of a pin access (Pin.value(), on(), off()): two writes without sleep() give a pulse of this width (bit-banging) - order of magnitude of MicroPython on RP2040; 0 = instantaneous accesses
Modelica.Units.SI.TimehangWarningTime (from PartialMcuSettings)10Real (wall-clock) time after which a warning is logged if the script does not let the simulation advance (loop without sleep() nor pin access, or with gpioOpTime = 0) - the simulation keeps waiting; 0 = no warning
Debugging
BooleandebugEnabled (from PartialMcuSettings)falseDebug the program with VS Code: at the start of the simulation, the microcontroller waits until VS Code attaches (debugpy, Run and Debug > attach to localhost:debugPort); simulated time stays frozen while the program is paused - one microcontroller per model
IntegerdebugPort (from PartialMcuSettings)5678Local TCP port on which the debugger (debugpy) listens - the port of the VS Code attach configuration
Electrical › Logic levels
Modelica.Units.SI.VoltageVOL (from PartialMcuSettings)Interfaces.VOLLogic low voltage
Modelica.Units.SI.VoltageVIH (from PartialMcuSettings)Interfaces.VIHThreshold above which an input reads high
Modelica.Units.SI.VoltageVIL (from PartialMcuSettings)Interfaces.VILThreshold below which an input reads low
Electrical › Output stages
Modelica.Units.SI.ResistanceROut (from PartialMcuSettings)Interfaces.ROutOutput series resistance (drive strength)
Electrical › Input stages
Modelica.Units.SI.ResistanceRPullUp (from PartialMcuSettings)Interfaces.RPullInternal pull-up resistor to the supply, switched on by Pin(n, mode, Pin.PULL_UP) and by I2C() on SCL/SDA
Modelica.Units.SI.ResistanceRPullDown (from PartialMcuSettings)Interfaces.RPullInternal pull-down resistor to GND, switched on by Pin(n, mode, Pin.PULL_DOWN)
Modelica.Units.SI.ConductanceGOff (from PartialMcuSettings)Interfaces.GOffLeakage of a pin that does not drive its line (input, released I2C line), towards GND: 1e-9 S = 1 GOhm

Connectors

TypeNameDefaultDescription
Modelica.Electrical.Analog.Interfaces.PositivePin[nPins]pinPins of the core, in the order of pinIds
Modelica.Electrical.Analog.Interfaces.PositivePinvddSupply of the core and of its pins (IOVDD): high level of the outputs, pull-ups, consumption ICore
Modelica.Electrical.Analog.Interfaces.NegativePingndGround
Modelica.Electrical.Analog.Interfaces.PositivePinvrefReference voltage of the ADC: read_u16() = 65535 at this voltage
Modelica.Electrical.Analog.Interfaces.PositivePinrunEnable (RUN), pulled up to vdd inside the core: to ground, the core is stopped for good - may stay unconnected
Interfaces.DisplayLinkOutputDisplay0Logical link to an educational display peripheral (machine.Display(0).write())

Components

TypeNameDefaultDescription
BooleanpowerGoodThe core is supplied (vdd above the power-on threshold, RUN high): its program starts the first time this becomes true and stops for good when it falls back. start = false: pins in high impedance during the initialization, where they are all inputs anyway (see pre(powerGood) below)
BooleansupplyOkvdd above the power-on threshold, with hysteresis
BooleanrunHighRUN high