machine — functions related to the hardware

The machine module contains specific functions related to the hardware on a particular board. Most functions in this module allow to achieve direct and unrestricted access to and control of hardware blocks on a system (like CPU, timers, buses, etc.).

Memory access

The module exposes three subscriptable objects used for raw memory access. Each behaves like a sparse array indexed by byte address: value = memN[addr] reads, memN[addr] = value writes. The address is always a byte address, regardless of the access width.

machine.mem8

Subscriptable 8-bit memory accessor. mem8[addr] reads an int in the range 0-255 from the byte at addr; mem8[addr] = value writes the low 8 bits of value. addr must be aligned to 1 byte (any address).

machine.mem16

Subscriptable 16-bit (halfword) memory accessor. mem16[addr] reads an int in the range 0-65535; mem16[addr] = value writes the low 16 bits. addr must be aligned to 2 bytes.

machine.mem32

Subscriptable 32-bit (word) memory accessor. mem32[addr] reads an int in the range 0-0xFFFFFFFF; mem32[addr] = value writes the low 32 bits. addr must be aligned to 4 bytes.

Example use (registers are specific to an STM32H7 microcontroller – on the OpenMV Cam H7 / H7 Plus / Pure Thermal the header pin P0 is wired to PB15):

import machine
from micropython import const

GPIOB = const(0x58020400)
GPIO_BSRR = const(0x18)
GPIO_IDR = const(0x10)

# set P0 (PB15) high via the GPIOB bit-set/reset register
machine.mem32[GPIOB + GPIO_BSRR] = 1 << 15

# read P0 (PB15) directly out of the GPIOB input-data register
value = (machine.mem32[GPIOB + GPIO_IDR] >> 15) & 1

Miscellaneous functions

machine.unique_id() bytes

Return a bytes object containing a unique identifier for this board. The value is read out of the MCU’s hardware (typically the factory-programmed device serial number), so it is stable across reboots and differs from one board to the next.

The length depends on the MCU family – 12 bytes on STM32, 8 bytes on the mimxrt and alif ports. If your application needs a fixed-length ID, slice or hash the returned value.

machine.time_pulse_us(pin: Pin, pulse_level: int, timeout_us: int = 1000000, /) int

Measure the width of a single pulse on pin and return its duration in microseconds.

pin must be configured as a digital input.

pulse_level is the pulse polarity to time: 1 for a high pulse, 0 for a low pulse.

The function works in two phases. First, if the pin is not already at pulse_level, it waits for the pin to transition to pulse_level (the start of the pulse). Then it measures the time the pin stays at pulse_level before transitioning back (the end of the pulse). The measured time is returned in microseconds.

timeout_us bounds each phase independently (so a worst-case call lasts up to 2 * timeout_us). On timeout the function returns a negative value identifying which phase timed out:

  • -2 – timed out waiting for the leading edge (the pin never reached pulse_level).

  • -1 – timed out waiting for the trailing edge (the pulse was longer than timeout_us).

machine.bitstream(pin: Pin, encoding: int, timing: tuple, data: bytes, /) None

Transmits data by bit-banging the specified pin. The encoding argument specifies how the bits are encoded, and timing is an encoding-specific timing specification.

The supported encodings are:

  • 0 for “high low” pulse duration modulation. This will transmit 0 and 1 bits as timed pulses, starting with the most significant bit. The timing must be a four-tuple of nanoseconds in the format (high_time_0, low_time_0, high_time_1, low_time_1). For example, (400, 850, 800, 450) is the timing specification for WS2812 RGB LEDs at 800kHz.

Timing accuracy is hardware-dependent; faster MCUs produce tighter pulses (typically tens of nanoseconds).

Note

For controlling WS2812 / NeoPixel strips, see the neopixel module for a higher-level API.

Constants

The constants below are returned by reset_cause() and identify why the MCU last reset. Available on the STM32 and mimxrt ports; the alif port (OpenMV Cam AE3) does not currently expose reset-cause constants and its reset_cause() always returns 0.

machine.PWRON_RESET: int

Reset caused by power being applied to the chip. STM32 and mimxrt ports.

machine.WDT_RESET: int

Reset caused by the watchdog timer expiring. STM32 and mimxrt ports.

machine.SOFT_RESET: int

Reset caused by soft_reset() (the Python interpreter restarted without a hardware reset). STM32 and mimxrt ports.

machine.HARD_RESET: int

Reset caused by the NRST pin being asserted (external reset button). STM32 ports only.

machine.DEEPSLEEP_RESET: int

Reset caused by waking from deep-sleep. STM32 ports only.

Classes