Add error-resilient firmware with diagnostic LED blink patterns (3 slow = alive, solid = I2C OK, fast burst = I2C error). Document EVM external MCU wiring: disconnect P6 EN jumper, power VDD from XIAO 5V, leave SCL/SDA jumpers in place with MSP430 unpowered. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
102 lines
4.5 KiB
Markdown
102 lines
4.5 KiB
Markdown
# LP5562EVM MSP430 Serial Protocol (Reverse-Engineered)
|
||
|
||
**Date**: 2026-03-05
|
||
**Status**: Working — I2C read/write verified, LEDs cycling
|
||
|
||
## Hardware
|
||
|
||
- **EVM**: LP5562EVM (SNVU203A) with MSP430F5510 USB-to-I2C bridge
|
||
- **USB**: CDC device, VID:PID `2047:0300`, appears as `/dev/ttyACM0`
|
||
- **Baud**: 115200, 8N1
|
||
- **EN pin**: Must be jumpered to VDD externally — MSP430 does NOT drive EN after reset
|
||
|
||
## Protocol
|
||
|
||
Commands are ASCII text, no line terminator needed. The MSP430 parses character-by-character and responds after receiving the expected number of hex digits.
|
||
|
||
### Commands
|
||
|
||
| Command | Format | Response | Description |
|
||
|---------|--------|----------|-------------|
|
||
| `?` | `?` | `TI Sep 12 2012 08:19:25\n` | Firmware version |
|
||
| `I` (read) | `I<addr2><reg2>` | `SS DD OK\n` | I2C register read |
|
||
| `O` (write) | `O<addr2><reg2><data2>` | `SS OK\n` | I2C register write |
|
||
| `R` (read) | `R<addr2><reg2>` | `OK\n` | I2C read (no data returned) |
|
||
| `A` | `A` | `OK\n` | Unknown (possibly internal) |
|
||
|
||
- `addr2`: 2-char hex I2C 7-bit address (e.g., `30` for LP5562)
|
||
- `reg2`: 2-char hex register address
|
||
- `data2`: 2-char hex data byte
|
||
- `SS`: 2-char hex status (`00` = success, `02` = I2C NAK / device not responding)
|
||
- `DD`: 2-char hex data byte read from device
|
||
|
||
### Other Command Prefixes
|
||
|
||
These accept input but are not fully understood:
|
||
|
||
| Prefix | Chars consumed | Response | Guess |
|
||
|--------|---------------|----------|-------|
|
||
| `S` | 2 hex chars | (silent) | GPIO/setting control? |
|
||
| `V` | 2 hex chars | (silent) | Voltage/value setting? |
|
||
| `C` | 6 hex chars | `OK\n` | Config/control? |
|
||
| `P` | 8 hex chars | (silent or `OK`) | Program memory? |
|
||
|
||
### Invalid Commands
|
||
|
||
Single characters not recognized as command prefixes return `?\n`. Extra characters after a complete command also return `?\n` each.
|
||
|
||
## LP5562 Register Quirks via EVM Bridge
|
||
|
||
| Register | Address | Writable | Read-back | Notes |
|
||
|----------|---------|----------|-----------|-------|
|
||
| ENABLE | 0x00 | Yes | Yes | |
|
||
| OP_MODE | 0x01 | Yes | Yes | |
|
||
| B/G/R/W_PWM | 0x02-0x05 | Yes | Yes | |
|
||
| B/G/R_CURRENT | 0x06-0x08 | Yes | Yes | |
|
||
| W_CURRENT | 0x09 | No | Always 0x00 | Write ACKs but no effect |
|
||
| CONFIG | 0x0B | Functional | Always 0x00 | Write-only: takes effect but reads 0 |
|
||
| STATUS | 0x0C | N/A | Yes | Read-only |
|
||
| LED_MAP | 0x70 | Yes | Yes | Default 0x39 (engines mapped) — must set to 0x00 for direct PWM |
|
||
|
||
## Working Init Sequence
|
||
|
||
```
|
||
O300DFF # Reset (write 0xFF to RESET register)
|
||
# Wait 500ms
|
||
O300040 # ENABLE = 0x40 (chip_en)
|
||
# Wait 1ms (>500us startup)
|
||
O300B01 # CONFIG = 0x01 (internal oscillator) — write-only
|
||
O307000 # LED_MAP = 0x00 (all channels = I2C direct)
|
||
O300632 # B_CURRENT = 0x32 (5mA)
|
||
O300732 # G_CURRENT = 0x32
|
||
O300832 # R_CURRENT = 0x32
|
||
# W_CURRENT left at default 0xAF (0x09 not writable)
|
||
O3002FF # B_PWM = 0xFF (full brightness)
|
||
```
|
||
|
||
## LED Hardware on EVM
|
||
|
||
- **D1**: LRTB_G6SF (Osram RGB LED) — driven by B/G/R channels
|
||
- **D2-D5**: LW Q38E (Osram white LEDs) — driven by W channel
|
||
- **D7**: LSL296 (red status LED) — driven by MSP430, not LP5562
|
||
- All LP5562 LED outputs pass through **P5** header (4x2 dual-row with jumpers)
|
||
|
||
## Key Discovery: EN Pin
|
||
|
||
The LP5562 EN pin is controlled by the MSP430's GPIO (EN-UC), connected through the P6 header. After USB reset, the MSP430 holds EN low. The TI Windows GUI software presumably sends a command to assert EN, but we were unable to identify which serial command does this.
|
||
|
||
**Workaround**: Jumper EN directly to VDD (3.3V) on P1 or P6 header. This is acceptable because in the final xblink design, EN is controlled by a wired-AND circuit (MCU GPIO + hall sensor), not the EVM's MSP430.
|
||
|
||
Without EN high, all I2C reads return status `02` (NAK) with data `00`.
|
||
|
||
## Using EVM with External MCU (XIAO M0)
|
||
|
||
When driving the LP5562 from an external MCU instead of the MSP430:
|
||
|
||
1. **Disconnect EVM from USB** — the MSP430 must be unpowered to avoid I2C bus contention.
|
||
2. **P6 header**: Remove the **EN jumper** to disconnect EN-UC (MSP430's EN output). Leave SCL/SDA jumpers in place — the unpowered MSP430's I/O pins go high-impedance.
|
||
3. **P4 header**: Feed external VDD (e.g., XIAO 5V pin → P4 VDD). The on-board LP2985 3.3V LDO only runs from USB power.
|
||
4. **Wiring**: XIAO A0 → P6 EN (LP5562 side), A4 → SDA, A5 → SCL, GND → GND, 5V → VDD.
|
||
|
||
The LP5562 VDD range is 2.7–5.5V. Using 5V ensures headroom for white LED forward voltage (~3.0V) plus LP5562 current sink saturation (~0.4V).
|