<!-- Generated by tools/render_ports.py from site/data/ports.json. Edit the data, not this file. -->
# Start with your code: what ran on a TI development kit

Coming from STM32, Arduino, ESPHome, MicroPython, Zephyr or another vendor's SDK? Pick yours below.

57 ports run on 15 TI kits and 2 other boards. Plus 64 chip-to-chip tests inside TI's families (51 run on the board): [portability/matrix.csv](../portability/matrix.csv). Site page: [site/ports.html](../site/ports.html).

Terms: [vocab](vocab.md). 1 kB = 1,024 bytes.

Contents: [An ESPHome, Arduino, MicroPython or Zephyr project](#an-esphome-arduino-micropython-or-zephyr-project) · [Code written for another chip or tool](#code-written-for-another-chip-or-tool) · [One TI chip to another](#one-ti-chip-to-another) · [How a port is made](#how-a-port-is-made) · [Questions people ask](#questions-people-ask) · [Hand the folder and its AGENTS.md to your coding assistant](#hand-the-folder-and-its-agentsmd-to-your-coding-assistant)

## An ESPHome, Arduino, MicroPython or Zephyr project

Copy a card's files, run its command and compare with what you see.

### ESPHome

**ESPHome Zigbee device on the LP-EM-CC2755P10** · Works · LP-EM-CC2755P10

You get: An ESPHome YAML with cc27xx: builds and flashes a Zigbee device that joins Home Assistant on the LP-EM-CC2755P10.

Copy these files: [ports/esphome-ti](../ports/esphome-ti)

Run this command:

```bash
cd ports/esphome-ti
python3.12 -m venv venv && ./venv/bin/pip install "cbor2<6" esphome==2026.9.1
./venv/bin/esphome compile frl-cc27xx.yaml
./venv/bin/esphome upload frl-cc27xx.yaml
```

You see: The device appears in ZHA, Home Assistant's built-in Zigbee support, with an LED switch and a chip temperature sensor.

Measured: A repeat compile takes 27 s and the image is 262.7 kB of flash with 124.4 kB of RAM free. The LED switches at a median of 85 to 92.5 ms.

Limits: Zigbee only, no Wi-Fi. After a second flash, remove the old device from Home Assistant first, or it does not rejoin.

[See the run](../site/project-esphome.html#e192)

**ESPHome Zigbee device on the LP-EM-CC2340R5** · Works · LP-EM-CC2340R5

You get: The same YAML with cc23xx: runs a Zigbee end device on the LP-EM-CC2340R5.

Copy these files: [ports/esphome-ti](../ports/esphome-ti)

Run this command:

```bash
cd ports/esphome-ti
python3.12 -m venv venv && ./venv/bin/pip install "cbor2<6" esphome==2026.9.1
./venv/bin/esphome compile frl-cc23xx.yaml
./venv/bin/esphome upload frl-cc23xx.yaml
```

You see: The end device joins Home Assistant's Zigbee integration (ZHA) with an LED switch and a chip temperature sensor.

Measured: The image is 219.9 kB of flash, with 4.0 kB of the chip's 36 kB of RAM free. Over five runs 93 of 100 commands passed.

Limits: Zigbee only, no Wi-Fi. As a router it needs the heap cut by 2 kB, and the chip temperature reads about 10 C low.

[See the run](../site/project-esphome.html#e191)

**ESPHome Wi-Fi device on the LP-EM-CC35X1** · Works · LP-EM-CC35X1

You get: A Wi-Fi ESPHome device runs on the LP-EM-CC35X1 with ESPHome's native API: a client on the board got 20 of 20 switch commands confirmed.

Copy these files: [ports/esphome-ti](../ports/esphome-ti)

Run this command:

```bash
cd ports/esphome-ti
python3.12 -m venv venv && ./venv/bin/pip install "cbor2<6" esphome==2026.9.1
read -p "Wi-Fi name: " SSID && read -s -p "Wi-Fi password: " WIFIPW
printf 'wifi_ssid: "%s"\nwifi_password: "%s"\n' "$SSID" "$WIFIPW" > secrets.yaml
./venv/bin/esphome compile frl-cc35xx.yaml
./venv/bin/esphome upload frl-cc35xx.yaml
```

You see: The board joins Wi-Fi after a reset and logs "[I][wifi]: Connected" on its serial port at 115200 baud.

Measured: A repeat compile takes 23 s. A 24-hour soak confirmed 5,616 of 5,620 commands and rode out 22 access-point drops.

Limits: Home Assistant has not adopted the board.

[See the run](../site/project-esphome.html#e193)

### Arduino

**Arduino sketches on the LP-EM-CC2340R5 and LP-MSPM0G3519 through the Zephyr-based core: Blink and AnalogReadSerial** · Works · LP-EM-CC2340R5, LP-MSPM0G3519

You get: Arduino's stock Blink and AnalogReadSerial run unchanged on the LP-EM-CC2340R5 and LP-MSPM0G3519 through the Zephyr-based core.

Copy these files: [portability/arduino/zephyr/README.md#take-it-with-you](../portability/arduino/zephyr/README.md#take-it-with-you)

Run this command:

```bash
export AM=$HOME/zr-arduino ZP=$HOME/zephyrproject TC=$HOME/zephyr-toolchain
git init "$AM" && git -C "$AM" remote add origin https://github.com/zephyrproject-rtos/ArduinoCore-zephyr.git
git -C "$AM" fetch --depth 1 origin af5b8610f9be6d7b962e2ba6dd8e6859697c44ff && git -C "$AM" checkout FETCH_HEAD
mkdir -p "$AM/zephyr/blobs" && cp -R third-party/arduino/ArduinoCore-API/api "$AM/zephyr/blobs/ArduinoCore-API"
git -C "$AM" apply "$PWD/portability/arduino/zephyr/serial-blocking-write.patch"
portability/arduino/zephyr/build-cc2340r5.sh Blink
```

You see: Blink toggles the board's LED pin; AnalogReadSerial prints 10-bit readings at 9600 baud on the probe's serial port.

Measured: Images are 22.8 to 38.3 kB of flash and 4.8 to 6.1 kB of RAM. On the LP-MSPM0G3519, Wire reads the touch controller 100 of 100 times and SPI loopback returns 256 of 256 bytes.

[See the run](../site/project-arduino.html)

**Arduino display libraries on the LP-MSPM0G3507** · Works · LP-MSPM0G3507

You get: Arduino_GFX's graphics test draws on an ST7796S screen on the LP-MSPM0G3507, through a 649-line Arduino API layer under the unmodified libraries.

Copy these files: [portability/arduino](../portability/arduino)

Run this command:

```bash
portability/arduino/build.sh
```

Measured: Four Arduino programs built and two ran. The libraries' files are unmodified.

Limits: The touch chip answers software I2C but not the chip's I2C block. This is a layer for your own build, not an Arduino IDE board.

[See the run](../site/project-arduino.html)

**uLisp Lisp interpreter on the LP-MSPM0G5187, LP-MSPM0G3507 and LP-MSPM0G3519** · Works · LP-MSPM0G5187, LP-MSPM0G3507, LP-MSPM0G3519

You get: uLisp, an Arduino sketch, gives a Lisp prompt on the LP-MSPM0G5187's serial port: 19 of 19 REPL (type-and-run loop) checks pass.

Copy these files: [ports/ulisp](../ports/ulisp)

Run this command:

```bash
ports/ulisp/build.sh
```

Measured: The image is 98.8 kB of flash and 23.1 kB of RAM. (tak 18 12 6) takes 7.5 s at 80 MHz.

Limits: Analog read, tone, SPI and I2C are stubs. The same source builds for the LP-MSPM0G3507 and LP-MSPM0G3519 and is flashed only on the LP-MSPM0G5187.

[See the run](../site/project-ulisp.html)

### MicroPython

**MicroPython 1.29.0 on the LP-EM-CC2340R5 through upstream's Zephyr port** · Works · LP-EM-CC2340R5

You get: MicroPython's own Zephyr port runs on the 36 kB LP-EM-CC2340R5: a >>> prompt, with Pin, ADC, PWM, SPI and I2C from Python.

Copy these files: [ports/micropython/zephyr-cc2340r5/README.md#take-it-with-you](../ports/micropython/zephyr-cc2340r5/README.md#take-it-with-you)

Run this command:

```bash
export MP=$HOME/micropython ZP=$HOME/zephyrproject TC=$HOME/zephyr-toolchain OUT=$PWD/out/build-mp-cc2340r5
git clone --depth 1 --branch v1.29.0 https://github.com/micropython/micropython.git "$MP"
ports/micropython/zephyr-cc2340r5/build.sh
```

You see: The probe's serial port at 115200 baud shows the banner "MicroPython v1.29.0 ... zephyr-lp_em_cc2340r5 with cc2340r5" and a >>> prompt; print(1+1) prints 2.

Measured: The image is 174.8 kB of flash and 29.9 kB of RAM with a 20 kB heap; the stock settings overflow the RAM by 46.8 kB. Pin.irq saw 10 of 10 edges.

Limits: PWM duty_u16 needs a one-line patch, which is in the folder. SPI data is unchecked without a loopback wire, and no I2C device was on the bus.

[See the run](../site/project-micropython.html)

**MicroPython 1.29.0 on the LP-MSPM33C321A through upstream's Zephyr port** · Works · LP-MSPM33C321A

You get: MicroPython's own Zephyr port runs with its stock prj.conf on the LP-MSPM33C321A: a >>> prompt, Pin, float math and SPI from Python.

Copy these files: [ports/micropython/zephyr-mspm33c321a/README.md#take-it-with-you](../ports/micropython/zephyr-mspm33c321a/README.md#take-it-with-you)

Run this command:

```bash
cd ports/micropython/zephyr-mspm33c321a
git clone --depth 1 --branch v1.29.0 https://github.com/micropython/micropython.git mp
./zephyr-tree.sh "$PWD/zw" uart
MP="$PWD/mp" ZW="$PWD/zw" OUT="$PWD/out" KIND=uart ./build.sh
```

You see: The probe's serial port at 115200 baud shows the banner "MicroPython v1.29.0 ... zephyr-lp_mspm33c321a with mspm33c321a" and a >>> prompt; print(1+1) prints 2.

Measured: The image is 292.3 kB of flash and 83.6 kB of RAM with a 48 kB heap.

Limits: I2C reads hang until a hardware reset. The chip has no Zephyr ADC or PWM driver.

[See the run](../site/project-micropython.html)

**MicroPython 1.29.0 on the LP-MSPM0G3519 and LP-MSPM0G3507** · Works · LP-MSPM0G3519, LP-MSPM0G3507

You get: A new MicroPython port boots on the LP-MSPM0G3519 with the MicroPython banner and drives a 3.5 inch touch screen from Python.

Copy these files: [ports/micropython](../ports/micropython)

Run this command:

```bash
ports/micropython/build_all.sh
```

Measured: The full build uses 174 kB of flash and leaves 119 kB of heap free. Hardware SPI fills 320 by 480 pixels in 147 ms and the touch chip reads in 1.43 ms.

Limits: The LP-MSPM0G3507 gets a 73 kB minimal build, because the full build does not fit its 128 kB. There is no file system, so the Python files are re-sent after each reset.

[See the run](../site/project-micropython.html)

### Zephyr

**Zephyr on the AM62L's Cortex-A53: from on-chip SRAM, and on one core beside Linux** · Works · TMDS62LEVM (AM62L)

You get: Zephyr's upstream am62l_evm board runs with no DDR, no TF-A and no TIFS: a 124 KB hello world in the 144 KB of on-chip SRAM, started over JTAG at EL3. A second build runs on A53 core 1 from DDR, started by a PSCI call from U-Boot, and keeps ticking while Linux boots and runs on core 0 with no hypervisor.

Copy these files: [am62l-evm/zephyr](../am62l-evm/zephyr)

Run this command: [See the folder's README](../am62l-evm/zephyr/README.md)

You see: UART0 prints *** Booting Zephyr OS build a915b2f12675 *** and Hello World! am62l_evm/am62l3/a53 with the DDR never initialized; beside Linux, /dev/mem reads tick lines from core 1's console ring.

Measured: 124 KB image in a 144 KB SRAM map, 20 KB spare. Beside Linux: 44.0 kB in DDR, started by PSCI CPU_ON, 66 console bytes in 3 s while Linux runs; 552.5 mW for the board with both.

Limits: One core, UART0 only, no peripheral beyond the timer. The SRAM image was loaded by the debugger, so this shows the chip runs it, not that a product starts that way.

[See the run](../site/project-run-zephyr.html#e199)

**Zephyr in 4 kB of RAM on the LP-MSPM0L1306** · Works · LP-MSPM0L1306

You get: Zephyr runs on the LP-MSPM0L1306 in 4 kB of RAM: hello_world, blinky and CoreMark.

Copy these files: [mspm0l1306/zephyr](../mspm0l1306/zephyr)

Run this command:

```bash
cd mspm0l1306/zephyr
./build.sh blinky
```

You see: hello_world and blinky run on the board; the console is UART0 at 115200 baud.

Measured: Standard CoreMark fits with 16 bytes of RAM left and scores 1.87 per MHz. It needs the board file, a corrected GPIO driver, hand-written UART pins and one heap setting.

Limits: Most other Zephyr samples need 6 to 17 kB of RAM and do not fit.

[See the run](../site/project-run-zephyr.html#e6)

**Zephyr on the LP-AM13E230** · Works · LP-AM13E230

You get: Zephyr's hello_world reaches main and an image toggles the LED on the LP-AM13E230.

Copy these files: [am13e230/zephyr](../am13e230/zephyr)

Run this command: [See the write-up](../docs/experiments/2026-10-09-am13e230-zephyr-upstream.md)

Limits: Zephyr has no LED, GPIO or serial driver for this chip, so Zephyr's own blinky does not build. The build clones Zephyr's main branch, so a later checkout can differ from the one that ran (commit 11808e9ea).

[See the run](../site/project-run-zephyr.html#e36)

## Code written for another chip or tool

Examples, libraries and models written for another vendor's chip or for a general computer, running on a TI kit.

### From STM32

**Five STM32CubeG0 examples through TI's migration skill on the LP-MSPM0G3507: 3 ran as written, 2 after fixes** · Works · LP-MSPM0G3507

You get: TI's migration skill (a tool inside CCStudio that rewrites ST code for a TI chip) moved five STM32CubeG0 examples to the LP-MSPM0G3507: 3 ran as written, 2 after fixes.

Copy these files: mspm0g3507/stm32-port-eval

Run this command:

```bash
git clone --filter=blob:none --no-checkout https://github.com/STMicroelectronics/STM32CubeG0.git "$HOME/cube"
cd "$HOME/cube"
git sparse-checkout set --no-cone '/.gitmodules' '/Projects/NUCLEO-G071RB/Examples/GPIO/GPIO_IOToggle/' '/Projects/NUCLEO-G071RB/Examples/GPIO/GPIO_EXTI/' '/Projects/NUCLEO-G071RB/Examples_LL/USART/USART_Communication_Tx_VCP_Init/' '/Projects/NUCLEO-G071RB/Examples/ADC/ADC_MultiChannelSingleConversion/' '/Projects/NUCLEO-G071RB/Examples/TIM/TIM_PWMOutput/'
git checkout 446ebe396489ca75679caa80887d7257efe92e3d
git submodule update --init --depth 1 Drivers/BSP/STM32G0xx_Nucleo
WS=$HOME/ccs-workspace
mkdir -p "$WS/.claude/skills"
cp -R "/Applications/ti/ccs2101/ccs/Code Composer Studio.app/Contents/Resources/ai/skills.alpha/ti-ccstudio-migrate-to-ti" "$WS/.claude/skills/"
# deletes a leftover merge marker (line 92) in the skill's SysConfig instructions
sed -i '' '92d' "$WS/.claude/skills/ti-ccstudio-migrate-to-ti/agents/sysconfig-configurator.md"
```

You see: The skill ships in CCStudio 21.0.1's skills.alpha folder, for evaluation. Open CCStudio on that workspace, run /ti-ccstudio-migrate-to-ti ~/cube/Projects/NUCLEO-G071RB/Examples/GPIO/GPIO_IOToggle MSPM0G3507. The first example blinks LED1 on the LP-MSPM0G3507.

Measured: GPIO toggle, serial port and PWM channel 4 ran as written. The button interrupt needed one fix and the ADC with DMA three: the button polarity, the DMA source address and the DMA sample count.

Limits: Button presses come from the debugger, and the STM32 originals are not on the bench.

See the run

**STM32 UART Xmodem bootloader (ferenc-nemeth/stm32-bootloader) on the LP-MSPM0G3519** · Works · LP-MSPM0G3519

You get: ferenc-nemeth's STM32 Xmodem bootloader takes an application over UART on the LP-MSPM0G3519, writes it to flash and jumps to it.

Copy these files: [ports/stm32-bootloader](../ports/stm32-bootloader)

Run this command:

```bash
cd ports/stm32-bootloader/boards/mspm0g3519 && make
```

You see: tools/run_g3519.sh runs 6 checks over the console, and all 6 pass; the application then runs from flash at 0x00010000.

Measured: A 4.4 kB update takes 1.54 s with the erase. Across six builds the bootloader takes 3.0 to 3.2 kB of flash and 2.1 to 4.1 kB of RAM.

Limits: The STM32 original is not on the bench, so there is no number from the original side.

See the run

**STM32 UART DMA receive with idle-line interrupt (MaJerle stm32-usart-uart-dma-rx-tx) on TI boards** · Works · NUCLEO-U083RC, LP-MSPM0G3519, LP-MSPM0G5187, LP-MSPM0L1306, LP-MSPM0C1104, LP-MSPM33C321A, LP-AM13E230, ESP32-C6-DevKitC-1

You get: MaJerle's STM32 UART DMA example answers every test packet at 115200 baud on the LP-MSPM0G3519, G5187, L1306, C1104 and MSPM33C321A.

Copy these files: [ports/stm32-usart-dma-rx-tx](../ports/stm32-usart-dma-rx-tx)

Run this command: [See the folder's README](../ports/stm32-usart-dma-rx-tx/README.md)

Measured: Boards answer 2,246 to 2,294 packets a second, against 2,259 on the NUCLEO-U083RC original. The L1306 uses 636 B of its 4 kB of RAM and the C1104 632 B of 1 kB.

Limits: The LP-AM13E230 passes five of six checks. No TI UART tested has the idle-line event, and at 921600 baud the C1104 and MSPM33C321A lose 152 to 452 of 500 packets. Each board folder builds its image; flashing is not scripted.

[See the run](../site/project-print-a-message.html#e232)

**ST STM32G4 HAL examples on the LP-AM13E230** · Works · LP-AM13E230

You get: ST's STM32G4 HAL GPIO and UART examples run on the LP-AM13E230 through TI's HAL layer, with 3 and 7 lines added to ST's main.c.

Copy these files: [am13e230/stm32g4-hal](../am13e230/stm32g4-hal)

Run this command: [See the folder's README](../am13e230/stm32g4-hal/README.md)

Measured: Two small TI-side shims of 13 and 50 lines carry them.

Limits: The layer has no clock tree, timer or ADC, so ST's timer examples stop at the first compile. Delays count CPU cycles, not milliseconds.

[See the run](../site/project-print-a-message.html#e34)

### From other vendors' SDKs

**Renesas FSP examples (UART, ADC, I2C, GPT timer) on the LP-MSPM0G3519** · Works · LP-MSPM0G3519

You get: Four of five Renesas FSP examples (FSP is Renesas's driver layer) run on the LP-MSPM0G3519 on a layer that maps FSP calls onto DriverLib, TI's register-level driver library.

Copy these files: [portability/fsp-on-mspm0/README.md#take-it-with-you](../portability/fsp-on-mspm0/README.md#take-it-with-you)

Run this command:

```bash
portability/fsp-on-mspm0/build.sh iic_master
```

You see: The example reads the touch controller at 0x38 on the Waveshare panel and prints on the serial port at 115200 baud.

Measured: sci_uart, adc and gpt run with no edit, and iic_master with five constants changed for the touch controller. Flash use is 12.4 to 15.5 kB.

Limits: The fifth example, timer-triggered ADC, runs up to its DMA chain, and its two-group DMA transfer does not complete. The unchanged iic_master reports a missing ADXL345.

[See the run](../ports/renesas-ra-fsp/README.md)

**Raspberry Pi Pico SDK examples on the LP-MSPM0G3519** · Works · LP-MSPM0G3519

You get: Raspberry Pi pico-examples (serial hello, I2C bus scan, blink, PWM fade, ADC read) run unchanged on the LP-MSPM0G3519 over a thin layer on DriverLib.

Copy these files: [portability/pico-on-mspm0/README.md#take-it-with-you](../portability/pico-on-mspm0/README.md#take-it-with-you)

Run this command:

```bash
export PICO_SDK=$HOME/pico-sdk OUT=$PWD/out/pico
git clone --depth 1 --branch 2.3.1 https://github.com/raspberrypi/pico-sdk.git "$PICO_SDK"
portability/pico-on-mspm0/build.sh bus_scan
```

You see: bus_scan finds the touch controller at 0x38 and nothing else; hello_serial prints "Hello, world!" once a second on the probe's serial port.

Measured: The layer is 316 lines plus 81 lines of board files. The five examples take 1.8 to 10.6 kB of flash.

Limits: There is no PIO equivalent.

[See the run](../ports/pico-sdk/README.md)

**Cmsemicon CMS32 examples on the LP-MSPM0L1306** · Works · LP-MSPM0L1306

You get: Cmsemicon CMS32 examples run on the LP-MSPM0L1306 through one glue layer: 34 of 34 ran; 21 checked, 13 show nothing a probe can see.

Copy these files: [ports/cms32](../ports/cms32)

Run this command:

```bash
cd ports/cms32
./build.sh systick
./run.sh systick 4
```

You see: The board's serial output is logged and its pins are read five times.

Measured: 29 of the 34 run with their main.c exactly as Cmsemicon shipped it. One glue layer and one pin-map file cover all of them.

Limits: The window-watchdog example resets the chip every few ms and locks the debugger out.

[See the run](../ports/cms32/README.md)

**Nordic's nRF Blinky and UART services on the LP-EM-CC2340R5** · Works · LP-EM-CC2340R5

You get: TI's basic_ble with two 8-line service descriptions shows Nordic's LED Button and UART services to a Mac on the LP-EM-CC2340R5.

Copy these files: [ports/nordic-apps/README.md#take-it-with-you](../ports/nordic-apps/README.md#take-it-with-you)

Run this command:

```bash
ports/nordic-apps/build.sh
```

Measured: A Mac finds the board by either service 0.17 to 0.69 s after flashing. An LED write answers in 24.3 ms median and UART echo in 24.2 ms, with 60 of 60 lines identical.

Limits: A Mac was the only client.

[See the run](../ports/nordic-apps/README.md)

### Programs, libraries and models

**BitNetMCU handwriting AI on MSPM0** · Works · LP-MSPM0G3507, LP-MSPM0L1306

You get: BitNetMCU handwriting models read all 10 test digits right on the LP-MSPM0G3507 and LP-MSPM0L1306, the same answers as on a Mac.

Copy these files: [ports/bitnetmcu](../ports/bitnetmcu)

Run this command:

```bash
cd ports/bitnetmcu/mspm0
./build.sh g3507 cnn_64 O3 32
./run.sh build-g3507-cnn_64-O3-32
```

You see: run.sh flashes the board, runs it and prints the answers, the cycle count and the stack depth.

Measured: At 32 MHz the most accurate model (99.55% on MNIST) takes 2.64M cycles on the LP-MSPM0G3507, 3.5% fewer than the author's 2.74M on the CH32V002. The 64-wide model also runs in the LP-MSPM0L1306's 4 kB of RAM.

[See the run](../site/project-handwritten-digits.html)

**BitNetMCU on a C2000 control chip (LAUNCHXL-F2800137)** · Works · LAUNCHXL-F2800137

You get: BitNetMCU's 64-wide CNN reads all 10 test digits right on the LAUNCHXL-F2800137.

Copy these files: [ports/bitnetmcu/c2000](https://github.com/Fox-Red-Labs/fox-red-labs/tree/main/ports/bitnetmcu/c2000)

Run this command:

```bash
ports/bitnetmcu/c2000/build.sh RAM
```

You see: All 10 test digits come out right.

Measured: 2.55M cycles from RAM (21.3 ms) and 2,897,585 from flash (24.1 ms) at 120 MHz, 6.7% fewer than the author's CH32V002 count.

Limits: The C28x has no 8-bit type, so the port needed three code fixes.

[See the run](../site/project-handwritten-digits.html)

**BitNetMCU in 1 kB of RAM on the LP-MSPM0C1104** · Works · LP-MSPM0C1104

You get: The 1k handwriting model reads all 10 test digits right in 804 B of RAM on the LP-MSPM0C1104.

Copy these files: [ports/bitnetmcu/mspm0](https://github.com/Fox-Red-Labs/fox-red-labs/tree/main/ports/bitnetmcu/mspm0)

Run this command: [See the write-up](../docs/experiments/2026-10-08-mspm0c1104-1kb-ram.md)

Limits: The 16-channel CNN links but overruns the stack and never finishes. `mspm0c1104/prebuild.sh bitnet` builds the LP-MSPM0C1104 images; flashing them and reading the answers back are not scripted for this board.

[See the run](../site/project-handwritten-digits.html#e14)

**minmea GPS sentence parser on MSPM0** · Works · LP-MSPM0G3507, LP-MSPM0G3519

You get: minmea, an NMEA GPS parser, runs on the LP-MSPM0G3519 with its files unchanged and a 21-line shim for one missing call.

Copy these files: [ports/minmea](../ports/minmea)

Run this command:

```bash
cd ports/minmea
bash build.sh shim
```

You see: No LED or serial output. After flashing, a debugger read of the globals gives g_rmc_ok 1, g_gga_ok 1, g_ts_ok 1, g_sats 8 and g_ts 764426119.

Measured: The shim takes 5.7 kB of flash. Seven of the eight values read back over the debugger match; latitude reads 481172 against 481173 because the test app truncates a float.

Limits: The test app has no LED or serial output; you read the results with a debugger.

[See the run](../ports/minmea/README.md)

**h264bsd video decoder on TI microcontrollers** · Works · LP-MSPM33C321A, LP-AM13E230

You get: h264bsd, an H.264 baseline decoder, runs unmodified on the LP-MSPM33C321A and LP-AM13E230 with every frame checksum equal to the Mac's.

Copy these files: [portability/h264](https://github.com/Fox-Red-Labs/fox-red-labs/tree/main/portability/h264)

Run this command:

```bash
portability/h264/build_host.sh
```

You see: The script prints one H264R line per stream: the Mac side of the frame checksums.

Measured: 176x144 runs at 57 frames per second on the LP-MSPM33C321A (240x240 at 33). The LP-AM13E230 reaches 86.

Limits: Baseline streams only; main-profile streams are refused.

[See the run](../portability/h264/SOURCE.md)

**Post-quantum key exchange and signatures on the LP-CC1354P10-1** · Works · LP-CC1354P10-1

You get: ML-KEM-768 key exchange and ML-DSA-44 signatures pass NIST's known-answer vectors on the LP-CC1354P10-1.

Copy these files: [portability/pqc-join](../portability/pqc-join)

Run this command:

```bash
cc1354p10/pqc-join/build.sh -O3
```

You see: The run prints "key check  Mac d01a2f61  board d01a2f61  MATCH" and then "board> DECRYPTED (76 bytes, tag ok)".

Measured: ML-KEM-768 takes 21 to 29 ms per step and ML-DSA-44 50 ms to verify and 154 ms on average to sign; every step passes NIST's known-answer vectors.

[See the run](../site/project-post-quantum.html)

**llama2.c (TinyStories 260K, int8) on the LP-MSPM33C321A** · Works · LP-MSPM33C321A

You get: llama2.c's TinyStories model writes a short story on the LP-MSPM33C321A, with token ids equal to the Cortex-M33 emulator run.

Copy these files: [ports/llama2c](../ports/llama2c)

Run this command:

```bash
cd ports/llama2c
PYTHON=python3 ./build.sh O2
```

Measured: It writes 128 tokens at 21.2 per second at 160 MHz. The weights use 543.6 kB of the 1 MB flash.

Limits: It runs 128 steps and one checkpoint shape. The first 39 tokens equal the Mac build and the rest differ in library math.

[See the run](../ports/llama2c/README.md)

**Fixed-weight DSP (FIR, filter bank, DFT) on the LP-MSPM0G5187** · Works · LP-MSPM0G5187

You get: A 64-tap FIR filter runs on the LP-MSPM0G5187's NPU (its neural-network accelerator), compiled with NNC, TI's neural-network compiler, 29.7 times faster than the same graph on the CPU, with byte-for-byte equal output.

Copy these files: [mspm0g5187/npu-dsp](../mspm0g5187/npu-dsp)

Run this command:

```bash
mspm0g5187/npu-dsp/build.sh
```

Measured: The 64-tap FIR takes 0.566 ms for 4 x 256 outputs, 5.8 times faster than one hand-written C channel. A filter bank, a strided FIR, a max-pool and comparator, and a DFT matrix ran too.

Limits: Output channels must be a multiple of 4. The DFT reaches 0.26 multiply-adds per cycle.

[See the run](../site/project-small-ai-model.html#e241)

**Rust (embassy-mspm0) on the LP-MSPM0L1306** · Works · LP-MSPM0L1306

You get: A Rust blinky and a serial hello run on the LP-MSPM0L1306 with embassy-mspm0.

Copy these files: [ports/rust-mspm0](../ports/rust-mspm0)

Run this command:

```bash
cd ports/rust-mspm0/l1306 && cargo build --release
```

You see: LED1 (red, PA0) blinks once a second, and the serial port at 115200 baud prints "Hello from Rust on MSPM0L1306".

Measured: The blinky takes 2.6 kB of flash and 112 bytes of static RAM, and the hello 3.7 kB and 148 bytes. The build takes 107 s cold and 3 s after a change.

Limits: Only GPIO, the timer and the blocking UART ran.

[See the run](../ports/rust-mspm0/README.md)

**DNS ad blocker (sinkhole) on the LP-EM-CC35X1** · Works · LP-EM-CC35X1

You get: The LP-EM-CC35X1 answers DNS on UDP port 53: names on a blocklist get 0.0.0.0 and the rest is forwarded to your gateway.

Copy these files: [ports/dns-sinkhole](../ports/dns-sinkhole)

Run this command:

```bash
cd ports/dns-sinkhole
curl -fsS -o hosts.txt https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
python3 gen_blocklist.py hosts.txt -o blocklist.bin
export WIFI_ENV=$HOME/.config/dns-sinkhole-wifi.env
mkdir -p "$(dirname "$WIFI_ENV")" && read -s -p "Wi-Fi password: " PW && echo "WIFI_PASSWORD=$PW" > "$WIFI_ENV"
APP=full BLOCKLIST=$PWD/blocklist.bin ./build.sh
RUN=$PWD/out/dns/build-full
cd /Applications/ti/simplelink_wifi_toolbox_macos_4_3_23
./simplelink-wifi-toolbox programmer -i XDS110 programming --tool_settings "$RUN/ex/freertos/ticlang/toolbox/tool_settings.json"
```

You see: Set BOARD_IP to the address the board prints on its console. Then dig @$BOARD_IP doubleclick.net returns 0.0.0.0, and dig @$BOARD_IP www.python.org returns the real address.

Measured: A blocked name is answered in a median of 6 ms and a forwarded one in 70 ms. The 357 kB table holds 71,492 names and the application slot has room for about 304,000.

Limits: IPv4 and UDP only, exact-name match, no TCP fallback.

[See the run](../site/project-dns-ad-blocker.html#e236)

**wasm3 (WebAssembly interpreter) on the LP-MSPM0G3519, LP-MSPM0G3507 and LP-MSPM33C321A** · Works · LP-MSPM0G3519, LP-MSPM0G3507, LP-MSPM33C321A

You get: wasm3 runs a WebAssembly module on the LP-MSPM0G3519 and prints PASS on the serial line.

Copy these files: [ports/wasm3](../ports/wasm3)

Run this command:

```bash
ports/wasm3/build_all.sh
```

Measured: fib(20) runs 43.5 times and a 20,000-pass loop 28.9 times slower than the same C. The heap stays flat at 6.9 kB of 16 kB over 14 passes.

Limits: Only the LP-MSPM0G3519 is flashed; the other two kits build.

[See the run](../ports/wasm3/README.md)

### Standards, radios and tools

**Zigbee smoke and CO alarm on the LP-EM-CC2340R5** · Works · LP-EM-CC2340R5

You get: A Zigbee smoke and CO alarm joins Home Assistant as one device on the LP-EM-CC2340R5, with no custom Home Assistant code.

Copy these files: [cc2340r5/zigbee-alarm](../cc2340r5/zigbee-alarm)

Run this command:

```bash
cc2340r5/zigbee-alarm/build.sh
```

You see: The device appears in Home Assistant's Zigbee integration (ZHA) as "Fox Red Labs FRL-ALARM"; sending SMOKE 1 on its serial port turns the Smoke sensor on.

Measured: 20 of 20 changes landed for each sensor, median 38 ms for smoke and 56 ms for CO. The image is 210.8 kB of flash and 25.8 kB of RAM.

Limits: In sleepy mode TI's sleep call stops the UART receiver.

[See the run](../site/project-alarm-listener.html)

**Sub-1 GHz CC1407P radio on an LP-MSPM0G5187, heard by an LP-CC1354P10-1** · Works · LP-MSPM0G5187, LP-CC1354P10-1

You get: TI's CC1407P sub-1 GHz radio driver runs unchanged on the LP-MSPM0G5187, and an LP-CC1354P10-1 receives its packets: 21,658 of 21,658.

Copy these files: [mspm0g5187/radio](../mspm0g5187/radio)

Run this command:

```bash
RADIO_APP=radio_tx RADIO_CFLAGS=-DHB_INT_POLL mspm0g5187/radio/build.sh
```

You see: The sender's serial port prints a line such as: tx FRL n=12 t=24.80C rh=36.9% lux=207.20 -> sent status=16 ev=0x0000004c sent=12 failed=0

Measured: An LP-CC1354P10-1 running rfPacketRx received 21,658 of 21,658 packets over 6 h 15 min at 915 MHz with no checksum errors. All 23 PHY (radio signal format) profiles sent, each rate within 3.4% of TI's figure.

Limits: One PHY (SUN O-QPSK 0) fails the checksum. The OFDM (multi-carrier) modes are transmit-only.

[See the run](../site/project-radio-range.html)

**FreeRTOS in 4 kB of RAM on the LP-MSPM0L1306** · Works · LP-MSPM0L1306

You get: FreeRTOS runs on the LP-MSPM0L1306 in 4 kB of RAM: the blink uses 1 kB.

Run this command:

```bash
cd mspm0l1306/freertos
./build.sh blink
```

Measured: 11 small tasks fit with static allocation and smaller stacks.

Limits: TI's own settings file for this board needs 5.4 kB and does not link.

[See the run](../site/project-run-freertos.html#e8)

**OpenOCD flash driver for the LP-EM-CC2340R5 and LP-EM-CC2755P10** · Works · LP-EM-CC2340R5, LP-EM-CC2755P10

You get: OpenOCD erases, writes, verifies and restarts a blink on the LP-EM-CC2340R5 over the XDS110, with no CCStudio or UniFlash.

Copy these files: [ports/openocd-cc23xx](../ports/openocd-cc23xx)

Run this command:

```bash
FRL=$PWD
git clone https://github.com/openocd-org/openocd.git "$HOME/openocd" && cd "$HOME/openocd" && git checkout bb5a52da599c3dac61ddc51d2fa8c1166ee795d0
git apply "$FRL/ports/openocd-cc23xx/0001-flash-nor-cc23xx-ti-cc23xx-cc27xx.patch"
./bootstrap && ./configure --enable-cmsis-dap --enable-cmsis-dap-v2 --enable-xds110 --disable-werror && make -j8
```

You see: On the LP-EM-CC2340R5, openocd -f board/ti_lp_em_cc2340r5.cfg -c "program blink.hex verify reset exit" erases, writes, verifies and restarts the blink, and the LED pin toggles.

Measured: It programs TI's blink in 0.37 s. A 511 kB image writes in 10.5 s and reads back identical.

Limits: On the LP-EM-CC2755P10 the driver builds and has no board result. Chip erase and CCFG changes are refused.

[See the run](../site/project-build-from-terminal.html#e206)

**TI's MSPM0 DriverLib examples built and run with GCC** · Works · LP-MSPM0G3507, LP-MSPM0L1306

You get: TI's MSPM0 DriverLib examples build and run with GCC from a terminal: all 224 no-RTOS examples with a GCC makefile built unchanged.

Copy these files: [portability/toolchains/gcc-mspm0](../portability/toolchains/gcc-mspm0)

Run this command:

```bash
portability/toolchains/gcc-mspm0/run.sh LP_MSPM0L1306
```

Measured: The 224 are 136 for the LP-MSPM0G3507 and 88 for the LP-MSPM0L1306. On the L1306, all 87 that TI Arm Clang also ran ran from GCC with no fault, and code is a median 15% larger.

Limits: The compiler is GCC 12.2 from the Zephyr SDK. Arm GNU 9-2019-q4, the version TI's makefiles name, is not used.

[See the run](../site/portability-proven.html#works-with)

**Matter smoke and CO alarm over Thread on the LP-EM-CC2755P10** · Works · LP-EM-CC2755P10

You get: TI's Matter lighting app rebuilt as a smoke and CO alarm boots on the LP-EM-CC2755P10, exposes the smoke alarm cluster and changes state from a UART line 20 of 20 times.

Copy these files: [cc2755p10/matter-smoke](../cc2755p10/matter-smoke)

Run this command:

```bash
cd cc2755p10/matter-smoke
./build.sh sub
./build.sh sdk
./build.sh smoke
```

Measured: The 797 kB image changes state from a UART line 20 of 20 times, median 41 ms.

Limits: Does not commission into Thread or Apple Home.

[See the run](../site/project-alarm-listener.html)

**Matter thermostat over Wi-Fi on the LP-EM-CC35X1** · Works · LP-EM-CC35X1

You get: A Matter thermostat and occupancy sensor runs on the LP-EM-CC35X1, pairs into Apple Home and takes setpoint changes from the phone.

Copy these files: [cc35x1/matter](../cc35x1/matter)

Run this command:

```bash
cc35x1/matter/build-thermostat.sh "$PWD/cc35x1/matter"
```

Measured: The image is 1.7 MB.

Limits: Apple Home was the only controller used. The board must be fully erased before the first flash.

[See the run](../site/project-matter-device.html#e169)

**ESP32-BLE-Gamepad (a Bluetooth HID gamepad library) on TI, ST and C2000 boards** · Works · LP-MSPM0G3519, LAUNCHXL-F2800137, LP-EM-CC2340R5, LP-EM-CC35X1, NUCLEO-U083RC

You get: The ESP32-BLE-Gamepad descriptor and reports match the library's output byte for byte on four boards, and 15 of 15 button changes from the LP-EM-CC2340R5 reached a Mac as gamepad reports.

Copy these files: [ports/esp32-ble-gamepad](../ports/esp32-ble-gamepad)

Run this command: [See the folder's README](../ports/esp32-ble-gamepad/README.md)

Measured: Flash is 9.9 kB on the LP-MSPM0G3519, 3.6 kB on the NUCLEO-U083RC and 8.1 kB of code on the LAUNCHXL-F2800137. The LP-EM-CC2340R5 image is 189.4 kB of flash and 33.8 kB of its 36 kB of RAM.

Limits: Only the LP-EM-CC2340R5 was paired with a Mac. Its Mac connect takes 31.3 s because macOS waits out its pairing timeout. The build script does not flash: write build/basic_ble.hex with UniFlash, then set your serial ports at the top of check/gp_serial.py.

[See the run](../site/project-bluetooth-sensor.html#e230)

### Games, codecs and synths

**liblc3 (LC3, the Bluetooth LE Audio codec) on the LP-MSPM33C321A and LP-MSPM0G3519** · Works · LP-MSPM33C321A, LP-MSPM0G3519

You get: liblc3 (LC3, the Bluetooth LE Audio codec) encodes and decodes frames on the LP-MSPM33C321A with the CRC-32 of every frame equal to the Mac build.

Copy these files: [ports/lc3](../ports/lc3)

Run this command: [README: 1 step](../ports/lc3/README.md)

Measured: Encode takes 198k cycles at 16 kHz and 387,683 at 48 kHz on the 160 MHz Cortex-M33, which is 12.4 to 24.2 percent of real time. Decode takes 4.6 to 10.5 percent.

Limits: Codec only: a generated signal, no radio and no audio output. The Cortex-M0+ build for the LP-MSPM0G3519 links, and its numbers come from an emulator.

[See the run](../ports/lc3/README.md)

**minimp3 MP3 decoder on the LP-MSPM33C321A and LP-MSPM0G3519** · Works · LP-MSPM33C321A, LP-MSPM0G3519

You get: minimp3 decodes MP3 clips bit-exact against the Mac on the LP-MSPM33C321A and LP-MSPM0G3519.

Copy these files: [ports/minimp3](../ports/minimp3)

Run this command: [README: 1 step](../ports/minimp3/README.md)

Measured: A 5-second stereo clip decodes in 0.151 times real time on the LP-MSPM33C321A. On the LP-MSPM0G3519, which has no float unit, the same clip takes 9.84 times real time.

Limits: Decode only; no audio plays. The LP-MSPM0G3519 cannot keep up in real time.

[See the run](../ports/minimp3/README.md)

**2048 and Minesweeper on the LP-MSPM0G3519 with a 3.5 inch touch display** · Works · LP-MSPM0G3519, LP-MSPM0G3507, LP-MSPM33C321A

You get: 2048 and Minesweeper run on the LP-MSPM0G3519 with a 3.5 inch touch display.

Copy these files: [ports/touch-games](../ports/touch-games)

Run this command:

```bash
bash ports/touch-games/build.sh g3519
```

You see: The board boots to a two-button menu: 2048 (swipe) and Minesweeper (tap to dig, long press to flag).

Measured: A swipe in 2048 takes 32.6 ms at 40 MHz SPI and a one-cell tap in Minesweeper 1.09 ms. 2048 was played on the panel with working touch.

Limits: A person did not check Minesweeper by finger or the touch axes. The SPI clock is above the panel's rating.

[See the run](../site/project-arcade.html)

**Doom engine (doomgeneric and rp2040-doom's design) on the LP-EM-CC35X1 and the LP-MSPM33C321A** · Works · LP-EM-CC35X1, LP-MSPM33C321A

You get: The rp2040-doom design plays all three shareware demos on the LP-EM-CC35X1 and the LP-MSPM33C321A, with frame checksums equal to a Cortex-M33 emulator.

Copy these files: [ports/doom](../ports/doom)

Run this command: [README: 2 steps](../ports/doom/README.md)

Measured: 39.2 frames per second on the LP-EM-CC35X1 and 22.7 on the LP-MSPM33C321A's Educational BoosterPack screen. The converted game data is 1.7 MB, read in place from flash.

Limits: No sound, and the stick and buttons were driven by a script. The stock doomgeneric engine stops on zone memory in all three demos on the LP-EM-CC35X1.

[See the run](../site/project-speed-test.html#e235)

**Peanut-GB Game Boy emulator on MSPM0 and MSPM33** · Works · LP-MSPM0G3507, LP-MSPM0G3519, LP-MSPM0G5187, LP-MSPM33C321A

You get: Peanut-GB plays Tobu Tobu Girl on the LP-MSPM33C321A with the Educational BoosterPack screen at the console's own speed.

Copy these files: [ports/peanut-gb](../ports/peanut-gb)

Run this command:

```bash
bash ports/peanut-gb/build_target.sh mspm33c321a rom
```

Measured: 160 MHz, a table scaler, DMA rows and one frame in two drawn gave 0 late frames in 8,167. The first image ran at 8 to 13 percent of real speed.

Limits: No sound or cartridge saving. A person did not judge the stick and buttons.

[See the run](../site/project-arcade.html)

**CHIP-8 interpreter and the chip8-test-suite on the LP-MSPM0G3519 touch panel** · Works · LP-MSPM0G3519

You get: A CHIP-8 interpreter runs the chip8-test-suite ROMs on the LP-MSPM0G3519 touch panel, with the frame buffer equal to the host's for five of six.

Copy these files: [ports/chip8](../ports/chip8)

Run this command:

```bash
ports/chip8/build.sh
```

Measured: It executes 526 thousand instructions per second and redraws the 64 x 32 screen at 5x in 14.2 ms. The play image is 13.5 kB of flash and 10.4 kB of RAM.

Limits: No sound, and CHIP-8 only. A person did not press the touch keypad.

[See the run](../site/project-arcade.html)

**libopus 1.5.2 (Opus, RFC 6716) on the LP-MSPM33C321A** · Works · LP-MSPM33C321A

You get: libopus encodes and decodes voice and music on the LP-MSPM33C321A, with packets and PCM equal to a Mac build in 12 of 12 runs.

Copy these files: [ports/opus](../ports/opus)

Run this command: [README: 1 step](../ports/opus/README.md)

Measured: CELT 48 kHz 10 ms encodes in 29 to 54 percent of real time at 160 MHz and decodes in 17 to 22 percent.

Limits: Codec only: mono, a generated signal, no radio or audio output. The Mac reference must use the same multiply macros as the board.

[See the run](../ports/opus/README.md)

**Plaits synthesis engines (Mutable Instruments, MIT) on the LP-MSPM33C321A** · Works · LP-MSPM33C321A

You get: All 24 Plaits synthesis engines render bit-exact against the Mac on the LP-MSPM33C321A.

Copy these files: [ports/plaits](../ports/plaits)

Run this command: [README: 1 step](../ports/plaits/README.md)

Measured: A block costs 10.7 to 34.5 percent of real time at 160 MHz with the FPU on. With the FPU off the same core needs 149 to 1,140 percent.

Limits: Synthesis only: the sound goes to a RAM buffer, with no DAC or MIDI input and no listening test.

[See the run](../ports/plaits/README.md)

## One TI chip to another

The same source moved between MSPM0, MSPM33, CC23xx, CC27xx, CC35xx, C2000, AM13 and radar chips. The map lists every test.

**TI's Jailhouse hypervisor on the AM62L: bare-metal and Linux cells beside Linux** · Works · TMDS62LEVM (AM62L)

You get: TI's documented Jailhouse flow from Linux SDK 12.01.00.05.03 ran as written on the AM62L EVM: the hypervisor enabled in 0.27 s, the uart and gic demo cells printed within a second, and a second Linux reached a login about 20 s after its cell started.

Copy these files: [am62l-evm/tools](https://github.com/Fox-Red-Labs/fox-red-labs/tree/main/am62l-evm/tools)

Run this command: [README: 2 steps](../docs/experiments/2026-10-22-am62l-jailhouse.md)

You see: UART1 (the FT4232's port B) prints the uart-demo and gic-demo lines, then a second Linux login prompt, while the first Linux stays at its prompt on UART0.

Measured: Hypervisor enable 0.27 s; demo cells print within 1 s; Linux cell to login about 20 s; disable 0.09 s.

Limits: No Zephyr cell, no cell-to-cell message traffic, no timing beyond these.

[See the run](../site/project-run-zephyr.html#e212)

**MSPM0 examples moved up and down the family** · Works · LP-MSPM0L1306, LP-MSPM0G3507, LP-MSPM0C1104

You get: MSPM0 examples move between family members with only the SysConfig device changed (SysConfig is TI's pin and peripheral setup tool): all 133 images that built and write nothing outside main flash and SRAM ran on the LP-MSPM0L1306.

Copy these files: [portability/families/mspm0](../portability/families/mspm0)

Run this command: [README: 1 step](../portability/everywhere/README.md)

Measured: With only the device changed, 101 of 170 LP-MSPM0L1306 examples build for the G3507. Of 153 ported images that built from the G3507 and C1104, 133 wrote nothing outside main flash and SRAM.

Limits: One G-series clock setting stops 136 of the moves the other way. The sweep's scripts run from a scratch folder with a copy of the SDK; there is no one-line command.

[See the run](../site/portability.html)

**MSPM0 examples on the LP-MSPM33C321A** · Works · LP-MSPM33C321A

You get: MSPM0 DriverLib examples run on the LP-MSPM33C321A: 39 of the 40 ported ones ran without a fault.

Copy these files: [portability/everywhere](../portability/everywhere)

Run this command:

```bash
portability/everywhere/crossbuild_mspm0_mspm33.sh "$PWD/out/m33-work" "$PWD/out/m33-results.jsonl"
```

Measured: Dropped in, 20 of 82 build. With each example's own SysConfig file ported, 43 of 83 build, 40 were run, and 54 of the 62 failures are names spelled differently across the two SDKs.

Limits: 1 of the 40 ran into a hard fault.

[See the run](../site/portability.html)

**MSPM0 DriverLib programs on the LP-AM13E230** · Works · LP-AM13E230

You get: MSPM0 DriverLib GPIO, UART and timer PWM programs run on the LP-AM13E230 with their app code unchanged and a 13-line shim header.

Copy these files: [portability/shim/mspm0_on_am13e230](../portability/shim/mspm0_on_am13e230)

Run this command:

```bash
portability/shim/mspm0_on_am13e230/build.sh gpio
```

Measured: All 53 lines of app code are unchanged. Of 43 translated SysConfig files, 20 build and 14 of 14 tried ran clean.

[See the run](../site/project-pwm-dim.html#e148)

**MSP430FR2433 code examples on the LP-MSPM0L1306** · Works · LP-MSPM0L1306

You get: Three MSP430FR2433 FRAM examples ran on the LP-MSPM0L1306: a persistent counter, a watchdog wake from LPM3 and a UART echo in LPM3.

Copy these files: [ports/msp430-to-mspm0](../ports/msp430-to-mspm0)

Run this command:

```bash
cd ports/msp430-to-mspm0
./build_l1306.sh lpm3-wake
```

Measured: The counter survived 17 software resets, a program load and a power-off. A bus-clock UART echoed a 190-byte burst.

Limits: On the LP-AM13E230 the three examples build only, and the deep-sleep test locks the debugger out.

[See the run](../ports/msp430-to-mspm0/README.md)

**MCU+ SDK examples on the IWRL6432BOOST radar** · Works · IWRL6432BOOST

You get: MCU+ SDK examples build in a radar SDK project, and uart_echo and gpio_led_blink ran on the IWRL6432BOOST.

Copy these files: [portability/everywhere/mcuplus-compat](../portability/everywhere/mcuplus-compat)

Run this command: [See the folder's README](../portability/everywhere/mcuplus-compat/README.md)

Measured: In a radar SDK project 11 of 23 app files build as they are and 19 of 23 with one generated header; uart_echo and gpio_led_blink ran on the IWRL6432BOOST.

Limits: The radar SDK spells some driver calls the older way. The script builds only; the runs on the board were flashed by hand.

[See the run](../site/portability.html)

**A radar frame parser on the LP-AM13E230 and SK-TDA4VM** · Works · LP-AM13E230, SK-TDA4VM

You get: A radar frame parser in 882 bytes of C gives the same output on the LP-AM13E230 and SK-TDA4VM as the Mac parser.

Copy these files: [portability/everywhere/host-radar](../portability/everywhere/host-radar)

Run this command:

```bash
cd portability/everywhere/host-radar
cc -O2 -std=c99 host_main.c tlv_parser.c -o radar_host
./radar_host ../../../iwrl6432boost/captures/2026-10-10-shipped-uart-60s.bin
```

You see: One line per radar frame, identical to the Mac reference parser (231 lines for the 60-second capture).

Measured: 62 of 62 frame lines match the Mac's parser on a real capture on the LP-AM13E230, and all 231 frames match on the SK-TDA4VM.

Limits: It reads a recorded capture and is not connected to a live radar.

[See the run](../site/project-print-a-message.html#e149)

**An MSPM0 FFT example on the SK-TDA4VM** · Works · SK-TDA4VM

You get: TI's MSPM0 FFT example runs unedited on the SK-TDA4VM and prints the same peak as on an R5F core and on a Mac.

Copy these files: [portability/everywhere/host-fft](../portability/everywhere/host-fft)

Run this command: [README: 1 step](../portability/everywhere/host-fft/README.md)

Measured: The peak is bin 5, value 4023, PASS.

[See the run](../site/portability.html)

**C2000 current-loop code on the LP-AM13E230** · Works · LP-AM13E230, LAUNCHXL-F2800137

You get: The same current-loop step, trigger to new PWM, runs about twice as fast on the LP-AM13E230 as on the LAUNCHXL-F2800137.

Copy these files: c2000-launchpad/bench/ctrl

Run this command: [See the write-up](../docs/experiments/2026-10-11-current-loop-three-mcus.md)

Measured: 1.33 us on the LP-AM13E230 and 2.58 us on the LAUNCHXL-F2800137. One FOC step is 117 cycles (0.585 us) on the AM13E230 with its math unit.

Limits: The build and run commands cover the LAUNCHXL-F2800137; the repository has no build command for the LP-AM13E230 half.

[See the run](../site/project-speed-test.html#e138)

**TI AM13 Hall FOC adapted to DRV8376EVM** · Works · LP-AM13E230

You get: TI's Hall FOC firmware drives a motor closed loop through a DRV8376EVM, unloaded at 12.4 V, on the LP-AM13E230.

Copy these files: [am13e230/foc-drv8376](../am13e230/foc-drv8376)

Run this command:

```bash
am13e230/foc-drv8376/build.sh
```

Limits: Runs unloaded only. Loaded starts, speeds below 20 Hz and reversals on the observers do not run.

[See the run](../am13e230/foc-drv8376/README.md)

## How a port is made

Every port followed the same five steps.

1. Find the calls. Build the other project for the TI chip as it is. List every missing function, header and type the compiler names. That list is the whole job.
2. Write a thin layer, not a fork. Answer those calls in one shim file on the TI side (388 lines for ESPHome's Zigbee code, 30 lines for MSPM0 apps on the CC2340R5, 13 lines for MSPM0 on the AM13E230). Leave the other project's files as they shipped, so its updates still apply.
3. Build with the vendor's own tools. Use TI's compiler, SDK and SysConfig, from one command or the other project's own command (esphome compile). For a plain-C library with no peripheral, start from ports/minmea/build.sh: the SDK's startup file and linker file, no SysConfig. Record flash and RAM from the map file.
4. Run it and check one thing a person would notice. The LED switched from Home Assistant, the digit read right, the packet received. For a library with no LED or serial output, read its result variables with a debugger or add a UART print. Built is not ran, and ran is not checked. Each card says which one happened.
5. Write down where it stopped. Failures stay on the page with the exact error and the cause, whether a tool or the chip.

## Questions people ask

### Is there an Arduino IDE board package for MSPM0?

No. There is a layer for your own build, and Arduino sketches run through Zephyr on the LP-EM-CC2340R5 and the LP-MSPM0G3519. You cannot pick a TI board in the Arduino IDE.

### Which kit should I buy first?

The LP-MSPM0G3519 runs the most cards on this page: 15 of 57. Next come the LP-MSPM33C321A with 13 and the LP-MSPM0G3507 with 11. For ESPHome, take an LP-EM-CC35X1 for Wi-Fi, or an LP-EM-CC2340R5 or LP-EM-CC2755P10 for Zigbee only. The Board menu above lists the cards for any kit.

### Which kit runs ESPHome on Wi-Fi?

The LP-EM-CC35X1, with the cc35xx platform. The LP-EM-CC2340R5 and LP-EM-CC2755P10 cards are Zigbee only.

### How many of the Cmsemicon examples show output?

21 of the 34 have a result checked on a pin or serial line: serial text, a toggling pin or a CRC match. The other 13 ran without crashing and show nothing a probe can see.

### Do all the Renesas FSP examples run on the LP-MSPM0G3519?

Four of five. The timer-triggered ADC example runs up to its DMA chain, and its two-group DMA transfer does not complete. The unchanged I2C example reports a missing ADXL345 and prints 65535 for every axis, so it needs five constants changed for the touch controller.

### Does MicroPython I2C work on the LP-MSPM33C321A?

I2C opens and writes, and every read hangs until a hardware reset. Pin, float math and SPI work, and Zephyr has no ADC or PWM driver for this chip.

### Can I move an STM32 HAL project to MSPM0?

Yes, with TI's migration skill. On the LP-MSPM0G3507 it moved STM32CubeG0 examples for GPIO, UART, ADC with DMA and PWM: 3 of 5 ran as written and 2 after corrections. I2C, SPI and timers were not run.

### Can ESPHome run on a TI chip?

Yes, through the external platforms in ports/esphome-ti. cc27xx for the LP-EM-CC2755P10 and cc23xx for the LP-EM-CC2340R5 run ESPHome Zigbee devices that join Home Assistant. cc35xx gives the LP-EM-CC35X1 a Wi-Fi ESPHome device with the native API. You run esphome compile and esphome upload as usual, and TI's compiler and SDK do the build underneath. The cc27xx and cc23xx platforms are Zigbee only.

### Does MicroPython run on a TI chip?

Yes. MicroPython's own Zephyr port runs on the LP-EM-CC2340R5 and the LP-MSPM33C321A with a >>> prompt. A new MicroPython port boots on the LP-MSPM0G3519 and drives a touch screen from Python.

### Does Zephyr run on TI chips that have no upstream board?

On the LP-MSPM0L1306, yes: with the board file and a fixed GPIO driver it runs CoreMark in 4 kB of RAM. On the LP-AM13E230 it boots and toggles an LED, and Zephyr's own blinky does not build because Zephyr has no GPIO or serial driver for that chip.

### Does Rust run on MSPM0?

Yes. A Rust blinky and a serial hello run on the LP-MSPM0L1306 with the community embassy-mspm0 crate.

### Can I run another vendor's example code on a TI microcontroller?

Often, with a thin layer. 34 Cmsemicon CMS32 examples ran on an LP-MSPM0L1306 with most of their main.c files untouched, and ST's STM32G4 HAL GPIO and UART examples run on the LP-AM13E230 through TI's HAL layer. Timers, clocks and ADCs are where layers stop.

### How much MSPM0 code moves to TI's wireless chips or to other MSPM0 parts unchanged?

Inside MSPM0, most examples move with a SysConfig device change (all 133 ported images that built ran on the L1306). To the CC2340R5, 0 of 10 driver examples build unchanged and 10 of 10 with a 47-line shim. The Move across TI chips page lists every test.

### Can I use an AI coding assistant for a port like this?

Yes. Give it the folder and the board's AGENTS.md. The prompt at the bottom of the page does that.

### Does TI's CC1407P radio host driver work on a C2000 chip like the TMS320F2800137?

Not as shipped. It fails to compile with 524 errors (no uint8_t, and a packed attribute the C2000 compiler rejects). With both worked around it compiles, but 11 of its 12 message structs come out a different size from the bytes on the SPI wire, because the C28x has no 8-bit byte. A field-by-field packer gives the right transmit bytes (17 of 17 cases equal to an Arm host, no radio attached), and the driver does not call it. On MSPM0 hosts it runs: 21,658 of 21,658 packets on an LP-MSPM0G5187.

## Hand the folder and its AGENTS.md to your coding assistant

Open a clone of the repository in your coding assistant and paste this, with the two blanks in angle brackets filled in.

```text
Port <project or library> to the <TI board, for example LP-MSPM0G3507>. Read AGENTS.md first: it lists the board folders (the LP-MSPM0G3507's is mspm0g3507/) and how the repository is laid out. Then read docs/ports.md and that board folder's AGENTS.md and FAQ.md. Check that TI's compiler and the board's SDK are installed in the folders the board README names; if not, run bash mac-setup/bootstrap.sh --check and tell me what it reports. Follow the method in docs/ports.md: build the project unchanged for the TI chip and list every missing call, answer them in one shim file without editing the project's own files, build with TI's tools from one command (for a plain-C library, start from ports/minmea/build.sh) and report flash and RAM, then tell me how to check it on the board and the one thing I should see. If it stops, give me the exact error and where it stopped.
```

## Status words

- **Works**: ran on the development kit and did what it should.
