Back to portfolio

Multi-Speaker USB Audio Host

Bare-metal firmware on NXP i.MX RT1021 (Cortex-M7 @ 500 MHz) that streams audio to up to 4 USB speakers simultaneously — the audio co-processor in createq's BRIQX and Cove dual-MCU retail products, controlled by ESP32-S3 over LPUART and updatable via XMODEM OTA without physical access.

NXP embedded audio system

Project Overview

This firmware is the real-time audio engine behind createq's BRIQX retail speaker experiences. While the ESP32-S3 handles WiFi, MQTT, and cloud connectivity, the NXP RT1021 manages the hard real-time work: USB host isochronous audio streaming, SD card WAV playback, BM83 Bluetooth I2S input, speaker enumeration, and per-port hub power control — all in a cooperative single-threaded main loop on bare metal.

I developed this firmware from the MCUXpresso SDK base, authored the speaker enumeration/binding system, built the NXP OTA module, and wrote a 1,400+ line architecture document covering data flow, GPIO maps, flash layout, and performance characteristics.

My Key Contributions

1
Multi-Speaker USB Audio Host

Implemented USB Host EHCI driver integration for 4 simultaneous USB Audio Class 1.0/2.0 isochronous OUT streams via a 4-port hub. Built unified 32 KB ring buffer (8 slots × 4080 bytes) feeding 16 × 1024-byte isochronous buffers. Dual audio source mux: SD card WAV (USDHC2) + BM83 Bluetooth I2S (SAI1 slave RX @ 48 kHz). Outcome: venue installations play synchronized audio to multiple USB speakers from one NXP chip.

2
Persistent Speaker Binding (enumeration.c)

Extracted and rewrote speaker enumeration from multi_speaker.c into a dedicated module. Serial-number-to-slot mapping stored on SD (speakers.cfg, magic SPKB, v3). Fixed critical bug where pseudo-serial arrived before real serial caused slot swaps — implemented Enumeration_ResolveSlotForRealSerial for deterministic order. Outcome: speakers keep their assigned slot across power cycles, hub port changes, and connection order — the #1 field support issue resolved.

3
Per-Port Hub Power Control

Implemented GPIO VBUS switching per speaker hub port for installation mode (power-cycle one port at a time), speaker recovery during active playback, and maintenance enumeration. Coordinated with ESP32 speaker install wizard (SPK_START / SPK_BIND / SPK_DONE). Outcome: technicians install speakers one-by-one without unplugging the entire hub.

4
NXP OTA Module (nxp_ota.c)

Built MCUBoot-compatible OTA receiver: RAM-resident FlexSPI flash driver (required — can't execute from flash while writing flash), XMODEM-CRC 1K receiver over LPUART1, image trailer management on 8 MB QSPI NOR (2 MB dual application slots), RSA-2048 signed images via sign_nxp_firmware.sh. OTA path: Cloud → ESP SD → XMODEM → secondary slot → MCUBoot SWAP_MOVE → auto-confirm. Outcome: remote NXP firmware updates orchestrated entirely by the ESP32 over UART.

5
ESP32 UART Command Interface

Implemented LPUART1 binary protocol handler (4,900+ LOC in uart_comm.c): volume, play/pause, track control, speaker list/query, hub power, OTA mode switch, status notifications back to ESP. Dual-UART architecture: LPUART1 = ESP protocol, LPUART3 = debug logs. Outcome: ESP32 cloud commands reach USB speaker hardware in real time.

6
Cove ACM Protocol & Hot-Swap Recovery

Built host-testable Cove protocol framing module (cove_protocol.c) for Harman CoveX1 display integration. Implemented speaker hot-swap recovery during active playback without audio drop. Outcome: venue systems survive speaker replacement mid-event.

Architecture & Main Loop

Cooperative real-time loop (single-threaded, no RTOS overhead on audio path)

  • USB_HostEhciTaskBT_Audio_Process (4–5×/loop for SAI1 FIFO) → USB_AudioTaskAudioRingBuffer_TaskUART_Comm_ProcessCommandsSD_AudioCheckCardState
  • Flash layout: MCUBoot bootloader (256 KB) + primary slot (2 MB) + secondary slot (2 MB) on 8 MB FlexSPI QSPI NOR
  • USB hub class driver manages 4 downstream ports; each speaker gets persistent slot assignment via serial number read during enumeration

Key Metrics & Outcomes

4
USB Speakers
32 KB
Ring Buffer
500 MHz
Cortex-M7
48 kHz
I2S Audio
8 MB
QSPI Flash
RSA-2048
Signed OTA

Technologies & Languages

CNXP MCUXpresso SDKi.MX RT1021 USB Host EHCIUSB Audio ClassSAI/I2S USDHC/SDFatFSLPUART MCUBootXMODEM-CRCFlexSPI QSPI GPIO Hub PowerShell (signing)