NXP LPC2103F
The NXP LPC2103FBD48 sits on the same small board as the CP2104 USB-to-UART bridge, tucked behind the front panel. It is an ARM7TDMI-S core in a 48-pin LQFP package with 32 KB of on-chip flash and 8 KB of SRAM. The firmware configures the PLL to multiply the 14.7456 MHz crystal by 4, producing a core clock (CCLK) of 58.98 MHz. The peripheral clock (PCLK) runs at the default CCLK/4 ratio — 14.7456 MHz — which divides cleanly to standard baud rates with zero error.
The LPC2103F is the sole interface between the user and the audio engine. It drives the vacuum fluorescent display through a 4-bit parallel GPIO interface (HD44780 command set), reads the rotary encoder for menu navigation, decodes NEC-format IR commands arriving on the 3.5mm jack via Timer1 capture on P0.17, and monitors the 12V trigger input on P0.20 for power state changes. Every parameter the user can adjust — crossover frequency from 40 to 260 Hz, phase in 45-degree steps, six EQ presets, three sound modes, night mode, power control behavior — lives as state managed by the LPC2103F firmware. When a value changes, the MCU translates it into one or more I2C register writes and sends them to the D2-81431 at slave address 0xB2 over the 480 kHz I2C bus.
The firmware version is V1.19, hardcoded in the factory reset display string. The manual ships with V1.03.
UART0: TX-only
Section titled “UART0: TX-only”The firmware analysis confirmed that UART0 is transmit-only. The MCU sends a single boot message at 9600 baud, 8N1:
SNAPAV EPISODEEA500 AMPLIFIERAfter that, the serial port is never touched again. There is no receive interrupt (U0IER is never written), no FIFO configuration (U0FCR is never written), no command parser, and no input buffer. Cross-referencing every access to the UART0 register block found exactly 6 references — all in the putchar function and the pin init, all transmit-side. UART1 has zero references in the entire firmware.
UART0 configuration
Section titled “UART0 configuration”| Parameter | Value | Source |
|---|---|---|
| PINSEL0 | 0x55 | P0.0 = TXD0, P0.1 = RXD0, P0.2 = SCL0, P0.3 = SDA0 |
| U0LCR | 3 | 8 data bits, no parity, 1 stop bit |
| U0DLL | 97 | Baud divisor: 14,745,600 / (16 × 97) = 9600.00 baud |
The baud rate works out to exactly 9600 with zero error because 14.7456 MHz is a UART-friendly crystal frequency. The divisor of 97 is an integer — no fractional baud rate correction needed.
ISP bootloader entry
Section titled “ISP bootloader entry”The LPC2100 family includes a factory-programmed In-System Programming bootloader in a protected region of ROM (0x7FFFE000). This bootloader activates when pin P0.14 is held LOW during a reset event. On this board, jumper JP24 controls P0.14. Installing the jumper pulls P0.14 to ground, and the next power-on enters ISP mode. The rear-panel UPDATE/OPERATE switch does not control P0.14 — it controls the D2-81431’s BMS[3:0] boot mode pins. These are two independent mechanisms on two independent chips.
The ISP bootloader speaks a well-documented protocol at 115200 baud, 8N1, beginning with auto-baud synchronization. The open-source tool lpc21isp handles the complete protocol — connecting, synchronizing, erasing sectors, writing flash, and verifying. The flash dump page documents the complete extraction procedure using a patched version of lpc21isp.
JTAG pinout
Section titled “JTAG pinout”The JTAG pin assignments for the LPC2103FBD48 in the LQFP48 package, verified against the NXP datasheet and the Olimex LPC-H2103 reference design schematic:
| Signal | GPIO | LQFP48 Pin | Description |
|---|---|---|---|
| nRESET | — | 6 | Active-low reset |
| TRST | P0.27 | 8 | Test Reset |
| TMS | P0.28 | 9 | Test Mode Select |
| TCK | P0.29 | 10 | Test Clock (must be less than CCLK/6) |
| TDI | P0.30 | 15 | Test Data In |
| TDO | P0.31 | 16 | Test Data Out (output only) |
| RTCK | — | 26 | Return Test Clock |
| DBGSEL | — | 27 | Debug Select (HIGH enables EmbeddedICE) |
When DBGSEL is driven HIGH, the JTAG pins are automatically configured for debugging regardless of the pin function select register settings. The EmbeddedICE-RT module provides real-time debug: halt, step, breakpoint, watchpoint, and memory access while the core is stopped.
GPIO assignments (firmware-decoded)
Section titled “GPIO assignments (firmware-decoded)”Every GPIO pin used by the firmware has been identified by cross-referencing the IODIR0 register value (0x02CD9CF0) with every function that accesses GPIO:
| Pin | Direction | Function |
|---|---|---|
| P0.0 | Alt (TXD0) | UART0 TX to CP2104 |
| P0.1 | Alt (RXD0) | UART0 RX from CP2104 (not read by firmware) |
| P0.2 | Alt (SCL0) | I2C0 clock to D2-81431, 480 kHz |
| P0.3 | Alt (SDA0) | I2C0 data to D2-81431 |
| P0.4–P0.7 | Output | VFD data bus DB4–DB7 |
| P0.8 | Input | Encoder push button |
| P0.11 | Output | VFD Register Select |
| P0.12 | Output | Heartbeat LED |
| P0.13 | Input | D2-81431 fault/status (8-sample debounce) |
| P0.14 | Special | ISP entry via JP24 |
| P0.17 | Alt (CAP1.2) | IR receiver (Timer1 capture) |
| P0.18 | Output | VFD Enable strobe |
| P0.20 | Input | 12V trigger / audio sense |
| P0.21 | Input | Rotary encoder channel B |
| P0.23 | Output | Amplifier enable (HIGH=on, LOW=standby) |
| P0.24 | Input | Rotary encoder channel A |