Fox Red Labs / Builds / Smart home and radio
Press the LaunchPad's two buttons and a Mac sees a game controller
An CC2340R5 advertises as a Bluetooth LE gamepad.
MediumNo wiring1 evening (estimate, not timed)
Parts and steps
You need
- LP-EM-CC2340R5 LaunchPad development kit Buy the gamepad: its radio sends the reports and BTN-1 and BTN-2 are the buttons
- LP-XDS110ET debugger Buy powers and programs the board (an LP-XDS110 also works)
- A computer with Bluetooth LE pairs with the gamepad, builds the image and runs the reader page; tested on a Mac
Build the live gamepad image.TERMINAL
Build the image with the two buttons switched on.
LIVE=1names the boardCC2340R5 Gamepadand sends BTN-1 and BTN-2 as buttons 1 and 2. Without it the build sends the library's fixed test pattern asESP32 BLE Gamepad. The script only builds; it never flashes.LIVE=1 bash ports/esp32-ble-gamepad/boards/cc2340r5/build.shYou should see: The last line is
built: .../basic_ble.hex (NOT flashed).Flash the .hex without verify.TERMINAL
Clip the probe onto the board, plug it into the Mac, and flash the
.hexfrom thecc2340r5folder (cd cc2340r5). Leave out-v: on CC23xx, verify reads the boot configuration area and reportsValues at address 0x4E020750 do not match. Do not flash the.bin. SWD is the debug connection the probe uses. This command is assembled from the board's flash line and this build's output path./Applications/ti/uniflash_9.6.0/dslite.sh --mode flash -c CC2340R5.ccxml -f -u ../ports/esp32-ble-gamepad/boards/cc2340r5/build/freertos/ticlang/basic_ble.hexYou should see: UniFlash reports success and the board restarts as a Bluetooth gamepad (flash time not recorded for this image).
Pair, and accept the prompt.COMPUTER
On a Mac, open System Settings, Bluetooth, and press Connect beside
CC2340R5 Gamepad. Accept the pairing request when it appears. Then open System Settings, Game Controllers.
You should see: Bluetooth shows
CC2340R5 Gamepadas Connected, and Game Controllers lists it with a green Connected status, as in the picture, with no driver or app installed.Open the reader page.BROWSER
In a new terminal at the repository root, serve the site folder and open the reader page (
site/bench/gamepad.html) in Chrome or Edge. The browser hands a gamepad to a page only after a button press, so press BTN-1 once with the page open. No gamepad? The page's Replay the capture button plays the Mac's recorded run.python3 -m http.server 8000 --directory site open -a "Google Chrome" http://localhost:8000/bench/gamepad.htmlYou should see: The page shows a drawn controller and, once it sees the gamepad, its name. The reader page lists every change it sees.
Press BTN-1 and BTN-2.LAUNCHPAD
Press BTN-1, then BTN-2, then both together.
You should see: Checked by eye: button 1 lit red in the reader while BTN-1 was down, button 2 while BTN-2 was down, and both for both. A HID report logger on the Mac received reports starting
03 01,03 02and03 03for these three states and03 00on release (03is the report ID, the second byte the button bitmask).
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 ble-gamepad --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 ble-gamepad --assistant claudeIt runs the steps above and reports what it saw.
Not Claude Code? Copy this prompt instead.
Make it yours
With an AI assistant
You should see: After you flash and pair again, BTN-2 lights button 3 in the reader instead of button 2.
By hand
Open ports/esp32-ble-gamepad/boards/cc2340r5/board/hid_gamepad.c. In HidGp_loopStep (the FRL_LIVE branch) change frl_gp_press(&loopGp, FRL_BUTTON_2) and frl_gp_release(&loopGp, FRL_BUTTON_2) to use 3, then run steps 1 and 2 again.
You should see: BTN-2 lights button 3 in the reader.
If something goes wrong
make stops at once with sysconfig_cli.sh: not found | Name your folders on the same line, for example SDK=<sdk folder> SYSCFG=<sysconfig_cli.sh> CLANG=<ti-cgt-armllvm folder> LIVE=1 bash ports/esp32-ble-gamepad/boards/cc2340r5/build.sh. |
You see Error -615 or The target failed to see a correctly formatted SWD header | Press the probe firmly onto the board's debug pins and replug USB. |
You see Values at address 0x4E020750 do not match | You flashed the .bin or used -v; flash the .hex without -v. |
| The connect hangs about 30 seconds and then drops | The pairing was not accepted: macOS waits out a 30 s timeout and passes no input. Remove the device and connect again, and accept the request this time. |
The page says No gamepad yet | Press a button once with the page in front: the browser reveals a gamepad only after input. Use Chrome or Edge. |
More troubleshooting
| Nothing lights | Check the board shows as Connected in Bluetooth settings, then press a button once with the reader in front. |
| The Mac still shows button 2 | It is running the old image: confirm the flash finished and remove and pair the device again. |
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 limitsThe CC2340R5's two buttons reached a Mac as game-controller input: 15 of 15 button changes received, with the same report bytes as the ESP32 library. Ran on 1 board. Results, sources, timing and limits.
Expected result: After flashing and accepting the pairing request, a Mac lists the LaunchPad under Game Controllers and receives BTN-1 and BTN-2 as buttons 1 and 2 of a gamepad.
What this shows
- A LaunchPad can be a Bluetooth LE game controller: 15 of 15 button changes arrived at a Mac as HID input reports, and macOS lists the board under Game Controllers with no driver.
- The report bytes are the ESP32-BLE-Gamepad library's: the default build's 96-byte descriptor (the report layout the gamepad announces to the host) and four test reports match the library's output on an ESP32-C6, 5 of 5 lines; the LIVE build was not re-run against it.
What this does not establish, and limits
What this does not establish
- Latency and battery life were not measured.
Limits to keep in mind
- Only the two buttons are live; the report also has joystick axes and a directional pad (hat) that nothing moves.
- Pairing has to be accepted once, or macOS waits a 30 s timeout and receives no input.
- The reader page's live view was checked by eye once, in Chrome, and not recorded.
- Only macOS 15.7.9 on one Intel Mac was tried. Windows, Linux, Android and iOS are not tested, and the reader page needs Chrome or Edge.
- Whether pairing survives a reflash was not tested. The step 6 change is untested.
Sources
Why this board
It has a Bluetooth LE radio and two user buttons on the board.
Versions, sizes and timing
| Button changes received by the Mac | 15 of 15, reports 03 01, 03 02, 03 03, 03 00 | |
|---|---|---|
| Report bytes against the ESP32-C6 library output | descriptor and 4 test reports, 5 of 5 lines identical | ESP32 Bluetooth gamepad port matrix notes |
| Image size (default build; the LIVE build's size was not recorded) | 189.4 kB flash; 33.8 kB of 36 kB static RAM | README notes |
| Button read interval | 20 ms, one notification per change | the source |
| Software | SimpleLink Low Power F3 SDK 9.21.00.36, TI Arm Clang 5.1.1.LTS, SysConfig 1.28.0, Intel Mac, macOS 15.7.9 | README notes |
Evidence
- On 2026-10-20 a Mac paired with the board as
CC2340R5 Gamepadand listed it under Game Controllers with no driver. Fifteen button changes (each button alone, then both) arrived as input reports on the Mac's HID interface, 15 of 15, none missed. - The report bytes match the ESP32-BLE-Gamepad library's own output on an ESP32-C6: the 96-byte descriptor and four test reports, 5 of 5 lines identical. ESP32 Bluetooth gamepad port matrix notes
- On 2026-10-20 the reader page open in Chrome lit buttons 1 and 2 as BTN-1 and BTN-2 were pressed. Checked by eye; no recording. the page
Other boards
- CC2755P10own example and patch
- MSPM0G3507, MSPM0L1306, F2800137Not for this chip no radio
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
Works 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
Experiments (1)
| Status | What was tried | Result |
|---|---|---|
| Works | Does a popular ESP32 Bluetooth gamepad library carry over to TI, ST and C2000 boards, and on which boards does it give the same bytes? ESP32-C6-DevKitC-1, MSPM0 G3519, NUCLEO-U083RC, LAUNCHXL-F2800137, CC2340R5, 2026-10-19 | The report core of ESP32-BLE-Gamepad gives the same descriptor and report bytes on the ESP32-C6, the MSPM0 G3519, the NUCLEO-U083RC, the LAUNCHXL-F2800137 and the CC2340R5 (5 of 5 lines each); on the CC2340R5... |
Source files
Code brought from elsewhere
This project uses code that was written for other chips or tools. Each links to how to get it running.
- ESP32-BLE-Gamepad (a Bluetooth HID gamepad library) on TI, ST and C2000 boards Works 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 CC2340R5 reached a Mac as gamepad reports.
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-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
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.