> For the complete documentation index, see [llms.txt](https://dev.solid-run.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dev.solid-run.com/solidsense-aiot/solidsense-aiot-mcu.md).

# SolidSense AIOT — MCU firmware

The AIOT carries an **STM32U031C8** microcontroller alongside the i.MX8 SOM. It runs as an **I2C slave at address 0x18** and gives the SOM access to the peripherals that are wired to the MCU rather than to the SOM directly.

The SOM issues commands; the MCU executes them and returns a response.

### What it does

* **LED** — turn on, turn off, read state
* **IR presence sensor** (STHS34PF80) — presence and motion detection with a configurable threshold, reported through an interrupt line
* **Accelerometer** (ISM330DHCX) — wake-up on motion with a configurable threshold
* **GNSS** (u-blox MIA-M10) — reachable only from the MCU. The firmware passes the receiver's NMEA stream through to the SOM unchanged, so gpsd can consume it directly
* **Battery charger** (BQ25638) — power source, charge state, and an estimated state of charge
* **Real-time clock** — kept from GNSS by the MCU itself, with no involvement from the SOM. Runs from a 32.768 kHz crystal and survives an MCU reset
* **Interrupts** — a single read reports pending MCU, IR and accelerometer events

## Firmware and protocol reference

Source, protocol reference and build instructions:

[**https://github.com/SolidRun/ss-aiot-mcu**](https://github.com/SolidRun/ss-aiot-mcu)

The **README** in that repository is the authoritative description of the I2C interface — every command, its exact request and response length, the meaning of the status byte, the sensor threshold ranges, the GNSS passthrough, and the current known limitations. It is maintained alongside the firmware, so it always matches the code.

Deliberately not duplicated here: command bytes and payload formats. Read them from the README for the firmware revision you are actually running.

## Flashing

#### equipment

<table><thead><tr><th width="421.98046875">Part Name</th><th width="86.59765625">Qty.</th><th width="121.7578125">Picture</th></tr></thead><tbody><tr><td>USB-C Cable</td><td>1</td><td><p></p><p><img src="/files/9YKRB6BGbCUtvlELvz2y" alt="" data-size="original"></p></td></tr><tr><td>STLINK-V3</td><td>1</td><td><p></p><p><img src="/files/2y4n2eyP0oRO2LMPlOGY" alt="" data-size="original"></p></td></tr><tr><td>Micro USB-B Cable</td><td>1</td><td><p></p><p><img src="/files/Wpa2TmAFHwRt1J8hkFxX" alt="" data-size="original"></p></td></tr><tr><td>ST-LINK V3 SWD/JTAG programming cable (10/20-pin adapter set)</td><td>1</td><td><p></p><p><img src="/files/D9loBb7W5fCm8TyGreHq" alt="" data-size="original"></p></td></tr></tbody></table>

The flashing process requires a local computer with the following software installed:

STM32CubeProgrammer:

{% embed url="<https://www.st.com/en/development-tools/stm32cubeprog.html>" %}

#### Getting the firmware image

Build it from source — clone the repository above, import the project into STM32CubeIDE, and build. The `.hex` is produced in the build output directory.

{% file src="/files/wNtPSFfUy1t11EPLMiAI" %}

#### Preparing the AIOT for flashing

<figure><img src="/files/OjyA30xh22yyA8XgAUf5" alt=""><figcaption></figcaption></figure>

Connect STLINK-V3 (CN5) to the computer via micro USB.\
Connect the AIOT (J5006) to the STLINK (STDC14) using the ST-LINK V3 SWD/JTAG programming cable. Ensure that the cable is connected to the AIOT in the correct orientation, as shown in the image.

<img src="/files/BCmXYUx25aYgPBdL8tLQ" alt="" height="183" width="161">

Connect the AIOT to the computer using a USB cable.

Turn ON the AIOT using the designated switch.

#### Programming

Open STM32CubeProgrammer:

<img src="/files/EXLUBzXC07GMUYoZm01a" alt="" height="197" width="346">

Select Erasing & Programming from the left menu. (1)

Find the appropriate Port and connect. (2)

Load the appropriate HEX file. (3)

Verify the selections according to the image. (4)

Click Start Programming. (5)

After the successful completion message is displayed, you can proceed to the testing process.

### Quick check from Linux

The MCU should appear at `0x18`:

```
i2cdetect -y -r <bus>
```

Turn the LED on — a write-only command, and the easiest thing to confirm visually:

```
i2ctransfer -y <bus> w3@0x18 0x10 0x01 0x00
```

Read the charger status — a 3-byte payload, so the response is 5 bytes:

```
i2ctransfer -y <bus> w3@0x18 0x12 0x05 0x00 r5@0x18
```

**Read exactly `2 + DATA_LEN` bytes.** The MCU arms each response with an exact length and has nothing to send past it. Asking for more bytes than the response contains leaves the MCU holding SCL low, and the bus stays stuck for roughly ten seconds until the firmware's recovery timer releases it. The per-command lengths are in the README.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://dev.solid-run.com/solidsense-aiot/solidsense-aiot-mcu.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
