Fox Red Labs / Builds / Motor control, power and sensing
Time how fast a microcontroller reacts to an interrupt
Count the CPU cycles from an interrupt to the first line of its handler, on the MSPM0 L1306 with no wiring, or on the CC2340R5.
MediumNo wiring1 evening
Parts and steps
Your board
You need
- LP-MSPM0L1306 LaunchPad development kit Buy the board
- Micro-USB data cable power and programming
Find your board's debug probe serial number with TI's xdsdfu tool from CCStudio.TERMINAL
The scripts talk to one probe only.
/Applications/ti/ccs2101/ccs/ccs_base/common/uscif/xds110/xdsdfu -eYou should see: A line
Serial Num: <your serial>for the LaunchPad.Plug the LP-MSPM0L1306 into the Mac with the micro-USB cable.BENCH
No wires and no jumpers move.
You should see: The board powers up and shows its out-of-box demo.
Build the timing program at -O3.TERMINAL
It sets the CPU to 32 MHz, times loops and a GPIO toggle, then pends a spare interrupt, I2C1 on line 25, and reads SysTick on the handler's first line.
cd mspm0l1306/bench/timing ./build.sh O3You should see:
build-O3/timing.outandtiming.mapexist.Flash it, let it run 1.5 seconds, halt it and read the 11-word result struct from RAM.TERMINAL
Replace <serial> with your probe.
Replace <serial> before you run this.
PROBE=<serial> ./run.sh O3You should see:
** Verified OK **, then two lines of RAM words. The first word is 7141e001, which means the program finished. The second word, 01e84800, is the CPU clock: 32,000,000 Hz. On the second line the first word is the best interrupt time in cycles and the second is the worst:00000019 00000019, which is 25 and 25. The third is the sample count,000000c8, which is 200.Optional: repeat at -O2 and -Os to see that the compiler setting changes the answer.TERMINAL
Replace <serial> before you run this.
./build.sh O2 PROBE=<serial> ./run.sh O2 ./build.sh Os PROBE=<serial> ./run.sh OsYou should see: -O2 reads
0000001c 0000001c, which is 28 cycles. -Os reads00000019 00000019, which is 25 cycles.
You need
- LP-EM-CC2340R5 LaunchPad development kit Buy the board
- LP-XDS110ET debugger Buy the debug probe
Clip the LP-XDS110ET onto the LP-EM-CC2340R5's 20-pin edge, set the TGT VDD jumper to XDS, and plug the probe into the Mac with its USB-C cable.BENCH
You should see: The Mac sees the probe and two serial ports. The second one is
/dev/cu.usbmodem<serial>1.Build and check without touching the hardware.TERMINAL
The script also refuses to flash unless the generated boot configuration keeps the debug port, chip erase, flash program and return to factory all allowed.
cd cc2340r5/baremetal ./run.sh O3 --build-onlyYou should see: A memory summary and
CCFG OK: debug port, chip erase, flash program and return to factory all allowed.The -O3 image is 36.8 kB of flash.Build, flash with UniFlash and capture the serial report.TERMINAL
The script opens the serial port first, then flashes with
dslite.sh --mode flash ... -e -f -u build-O3/bench.hex, and stops capturing atBENCH DONEor after 300 seconds. The run includes CoreMark, so it takes a while../run.sh O3You should see: The report scrolls by, ending in
BENCH DONE. It is saved toresults/run-O3.txt. It containsR,irq_latency_best,29.00,1,...andR,irq_latency_worst_of_200,29.00,1,...andI,irq_samples,200.Optional: run the -Oz build too.TERMINAL
./run.sh OzYou should see:
R,irq_latency_best,28.00,1,..., the same 28 for the worst of 200.
Or hand it to a coding assistant
Paste this in a terminal. It hands off to an AI assistant.
git clone --depth 1 --filter=blob:none https://github.com/Fox-Red-Labs/fox-red-labs.git && cd fox-red-labs
./start.sh mspm0l1306 reaction-time --assistant claudegit clone --depth 1 --filter=blob:none https://github.com/Fox-Red-Labs/fox-red-labs.git && cd fox-red-labs
py start.py mspm0l1306 reaction-time --assistant claudeIt runs the steps above and reports what it saw.
Not Claude Code? Copy this prompt instead.
Or hand it to a coding assistant
Paste this in a terminal. It hands off to an AI assistant.
git clone --depth 1 --filter=blob:none https://github.com/Fox-Red-Labs/fox-red-labs.git && cd fox-red-labs
./start.sh cc2340r5 reaction-time --assistant claudegit clone --depth 1 --filter=blob:none https://github.com/Fox-Red-Labs/fox-red-labs.git && cd fox-red-labs
py start.py cc2340r5 reaction-time --assistant claudeIt runs the steps above and reports what it saw.
Not Claude Code? Copy this prompt instead.
If something goes wrong
| Nothing is listed | Replug the board with a data cable and close any serial window open on it. |
A script later says Probe ... missing | The serial number in step 1 does not match a connected board. |
| The compiler is not found | Change the SDK and CC lines at the top of build.sh. |
Verified OK does not appear | The flash failed: check the serial from step 1. |
| The first word is not 7141e001 | The program did not finish; run it again. |
More troubleshooting
| A number that differs by a few cycles is worth rerunning twice | Every saved run gave the same count on all 200 tries. |
Every fix for this board: the FAQ.
A flash later fails with The target failed to see a correctly formatted SWD header (error -615) | Unplug the USB cable, pull the probe off the board, press it back on and plug in again. That cleared it here. The likely cause is the seating. |
| The build fails | The last 30 lines of the build log print; a tool path in run.sh is the usual cause. |
| It says the serial port is not present | The board is not plugged in or SERIAL_DEV has the wrong serial. Do not add -v (verify) to the flash command: it reports a mismatch in the boot configuration area although the program ran. |
| At step 4 | The old program on the board repeats its report every 10 seconds, so make sure the capture holds this build's own I,optimization line before you trust a file. |
Every fix for this board: the FAQ.
What to build next
Every build. The code for all of them is in the GitHub repository.
Evidence and limitsInterrupt response in 25 to 36 cycles on four boards; one motor-control step in 0.585 µs on the AM13E230. Ran on 2 boards. Results, sources, timing and limits.
Measure it on the LP-MSPM0L1306
Expected result: The chip answers an interrupt in 25 cycles at -O3, the same on all 200 tries: about 0.8 microseconds at 32 MHz. At -O2 it is 28 cycles.
What this shows
- On an MSPM0 L1306 with no operating system, the time from raising an interrupt to the first line of its handler is 25 cycles at -Os and -O3 and 28 at -O2. It was the same on every one of 200 tries, so there is no jitter at this resolution.
- The same program shows what the operating system adds. Through Zephyr the same measurement reads 119 to 137 cycles, and under FreeRTOS 38 to 39. See the Zephyr and FreeRTOS projects.
- A GPIO toggle is one register write at 1.00 cycles at -O2 and -O3. It was not checked with a scope.
What this does not establish, and limits
What this does not establish
- Reaction time to an outside signal. The interrupt is raised in software by writing the pending bit, so the pin, input filter and any peripheral that would raise the interrupt are not in the number.
- A like-for-like number across chips. Each count includes one SysTick read, and a read pair costs 2 cycles. The timers, clocks and flash wait states differ per board.
- How long it takes a handler to do useful work: the number stops at the handler's first line.
- Pin speed. The one-cycle toggle is the CPU side only; no scope was on the bench.
Limits to keep in mind
- Interrupt line 25 (I2C1) is used because this chip's interrupt controller has only the 13 lines that have a peripheral; the program does not use I2C1 otherwise.
- The count includes one SysTick read of 2 cycles and the store that pends the interrupt.
- -O2 is 3 cycles slower than -Os and -O3 on interrupt entry. Why was not investigated.
Sources
Versions, sizes and timing
| Clock | 32 MHz SYSOSC; cycle counter is SysTick on the CPU clock (the Cortex-M0+ has no DWT counter) | the source |
|---|---|---|
| Interrupt entry, pend to handler | 25 / 25 (-Os), 28 / 28 (-O2), 25 / 25 (-O3) cycles best / worst of 200 | |
| GPIO toggle | 1.12 (-Os), 1.00 (-O2, -O3) cycles for one register write; 1.05 cycles per pass of a driver-call loop at -O2 and -O3 (13.00 at -Os) | |
| Other chips, same method | MSPM0 G3507 at 80 MHz: 29 to 36 cycles; CC2340R5 at 48 MHz: 28 to 29; LAUNCHXL-F2800137 at 120 MHz: 30 (code in RAM) to 32 (from flash) | the data (CSV) |
| Tools | TI Arm Clang 5.1.1.LTS, MSPM0 SDK 2.11.00.07, xPack OpenOCD 0.12.0-7, checked 2026-10-06 |
Evidence
- 2026-10-06: the timing program was built at -Os, -O2 and -O3 and run on an MSPM0 L1306; interrupt entry read 25, 28 and 25 cycles, the same on all 200 tries in each build.
- The saved RAM read-out of the -O3 build.
Other boards
- AM13E230Could work ran in part
- MSPM0G3507, F2800137could work
- CC2340R5ran another way
What the status words mean
Works ran here and did what it shouldCould work some of it ran; real porting effort is left; hover for whatNot for this chip the chip or its vendor software cannot; hover for why
Measure it on the LP-EM-CC2340R5
Expected result: The chip answers an interrupt in 29 cycles at -O3 and 28 at -Oz, about 0.6 microseconds at 48 MHz. It is the same on all 200 tries.
What this shows
- On a CC2340R5 with no operating system, the time from raising an interrupt to the first line of its handler is 29 cycles at -O3 and 28 at -Oz. It is the same on all 200 tries.
- Through Zephyr on the same chip the same measurement reads 48 to 60 cycles.
What this does not establish, and limits
What this does not establish
- Reaction time to an outside signal. The interrupt is pended through the NVIC by software, so no pin or peripheral is in the number.
- A like-for-like number across chips: each count includes one SysTick read, 5 cycles here. The timers, clocks and flash wait states differ per board.
- Run-to-run spread over many boards or sessions: each build was run once on one board.
Limits to keep in mind
- The interrupt is the radio block's line, LRFD IRQ0 on line 6. It matches the one the Zephyr run used. The handler is a direct vector installed with
HwiP_plug, with no wrapper. - The clock was read back as 48 MHz and a 0.3-second host-timed check gave 48.02 and 48.07 MHz.
- Verify (
-v) reports a mismatch at 0x4E020750 on every image flashed on this board; the program area verified and the program ran each time.
Sources
Versions, sizes and timing
| Interrupt entry, pend to handler | 29 cycles at -O3 and 28 at -Oz, best and worst of 200 identical; includes one 5-cycle SysTick read | README notes |
|---|---|---|
| Through Zephyr | 48 best, 60 worst of 200; includes a 9-cycle timer read quantized to 12 cycles | the data (CSV) |
| Under FreeRTOS | 39 cycles, with one run at 202 when an interrupt met the 1 ms tick; includes one counter read | the data (CSV) |
| Clock and flash | 48 MHz; flash wait states read live as 2 (1T) and 2 (2T); cache, prefetch and micropredictor on | README notes |
| Tools | F3 SDK 9.21.00.36, SysConfig 1.26.3, UniFlash 9.6.0, TI Arm Clang 5.1.1; macOS 15.7.9 | README notes |
Evidence
- 2026-10-05: the bare-metal benchmark was built at -O3 and -Oz and run once each on the CC2340R5; interrupt entry read 29 and 28 cycles, the same on all 200 tries in each. README notes
- The saved serial output of the -O3 run.
Other boards
- AM13E230Could work ran in part
- MSPM0G3507, F2800137ran another way
- MSPM0L1306could work
What the status words mean
Works ran here and did what it shouldCould work some of it ran; real porting effort is left; hover for whatNot for this chip the chip or its vendor software cannot; hover for why
Result grid
Details
a PWM trigger to the control code in 66 to 70 cyclesWorks ran here and did what it shouldShould work it builds; only naming, packaging or build glue is in the way; hover for whichCould work some of it ran; real porting effort is left; hover for whatNot for this chip the chip or its vendor software cannot; hover for why
Source files
- LP-EM-CC2340R5 baremetal notes (CC2340R5)
Get the code and tell us how it wentThe clone command, the board folder with its AGENTS.md, reports from others, and the three report forms.
Get the code
Clone the repository and open the board's folder below. AGENTS.md is a plain text file of notes for AI coding assistants, and llms.txt at the root indexes the site for one.
git clone https://github.com/Fox-Red-Labs/fox-red-labs.git
- LP-MSPM0G3507: folder
mspm0g3507/.- README: the board's lab notebook (what was run, in order)
- Notes for an AI coding assistant working in this repository: notes for an AI assistant; copy it into your own project if you use one
- FAQ: errors and fixes
The other 3 board folders
- LP-MSPM0L1306: folder
mspm0l1306/.- README: the board's lab notebook (what was run, in order)
- Notes for an AI coding assistant working in this repository: notes for an AI assistant; copy it into your own project if you use one
- FAQ: errors and fixes
- LP-EM-CC2340R5: folder
cc2340r5/.- README: the board's lab notebook (what was run, in order)
- Notes for an AI coding assistant working in this repository: notes for an AI assistant; copy it into your own project if you use one
- FAQ: errors and fixes
- LAUNCHXL-F2800137: folder
c2000-launchpad/.- README: the board's lab notebook (what was run, in order)
- Notes for an AI coding assistant working in this repository: notes for an AI assistant; copy it into your own project if you use one
- FAQ: errors and fixes
- LP-MSPM0L1306: folder
Code is BSD-3-Clause, writing is CC BY 4.0; third-party folders keep their own licenses.
Built it? Tell us
Built this, or got stuck? Report it on GitHub with a few short answers. Your report shows here in your words, marked as yours. A failure that repeats on the bench gets its fix here.