diff --git a/doc/img/pm5/board-10p-header.png b/doc/img/pm5/board-10p-header.png new file mode 100644 index 000000000..4a5dede7f Binary files /dev/null and b/doc/img/pm5/board-10p-header.png differ diff --git a/doc/img/pm5/buzzer-circuit.png b/doc/img/pm5/buzzer-circuit.png new file mode 100644 index 000000000..9075f9342 Binary files /dev/null and b/doc/img/pm5/buzzer-circuit.png differ diff --git a/doc/img/pm5/cep-interface.png b/doc/img/pm5/cep-interface.png new file mode 100644 index 000000000..9b1f7d72f Binary files /dev/null and b/doc/img/pm5/cep-interface.png differ diff --git a/doc/img/pm5/cep-signal-routing.png b/doc/img/pm5/cep-signal-routing.png new file mode 100644 index 000000000..51be9ccbb Binary files /dev/null and b/doc/img/pm5/cep-signal-routing.png differ diff --git a/doc/img/pm5/fpga-clock-circuit.png b/doc/img/pm5/fpga-clock-circuit.png new file mode 100644 index 000000000..a6fe2876c Binary files /dev/null and b/doc/img/pm5/fpga-clock-circuit.png differ diff --git a/doc/img/pm5/fpga-debug-port.png b/doc/img/pm5/fpga-debug-port.png new file mode 100644 index 000000000..00f15d6f9 Binary files /dev/null and b/doc/img/pm5/fpga-debug-port.png differ diff --git a/doc/img/pm5/mcu-interface.png b/doc/img/pm5/mcu-interface.png new file mode 100644 index 000000000..1a1cb20cc Binary files /dev/null and b/doc/img/pm5/mcu-interface.png differ diff --git a/doc/img/pm5/power-architecture.png b/doc/img/pm5/power-architecture.png new file mode 100644 index 000000000..42bed5ac2 Binary files /dev/null and b/doc/img/pm5/power-architecture.png differ diff --git a/doc/img/pm5/power-on-control.png b/doc/img/pm5/power-on-control.png new file mode 100644 index 000000000..09123c05a Binary files /dev/null and b/doc/img/pm5/power-on-control.png differ diff --git a/doc/md/Development/PM5_VERE_Hardware_RM.md b/doc/md/Development/PM5_VERE_Hardware_RM.md new file mode 100644 index 000000000..31eb0824b --- /dev/null +++ b/doc/md/Development/PM5_VERE_Hardware_RM.md @@ -0,0 +1,420 @@ +# PM5 VERE Technical Manual + +> This document is intended for firmware developers and community maintainers. It systematically describes the hardware features, power control, peripheral interfaces, and design rationale of **PM5** (the upgraded hardware system of the PROXMARK3 project). +> This document is a **hardware overview manual**; for the registers and communication protocols of specific peripherals, refer to the individual manuals in the same directory (given as links). + +- Author: DXL & KOMBI +- Document version: v1.0 +- Date: 2026-08-25 + +--- + +## Table of Contents + +1. [Overview](#1-overview) +2. [Core Processor and FPGA Architecture](#2-core-processor-and-fpga-architecture) +3. [System Power Architecture](#3-system-power-architecture) +4. [Internal Peripherals](#4-internal-peripherals) +5. [External Interfaces](#5-external-interfaces) +6. [Storage and Clock](#6-storage-and-clock) +7. [Debug Interfaces](#7-debug-interfaces) +8. [Standard Antenna](#8-standard-antenna) +9. [system I2C bus Peripheral Address Table](#9-system-i2c-bus-peripheral-address-table) +10. [Appendix: Terms and Abbreviations](#10-appendix-terms-and-abbreviations) + +--- + +## 1. Overview + +PM5 is the upgraded hardware system developed by the PROXMARK3 project. Compared with PROXMARK3 RDV4 and PROXMARK3 EASY, its hardware design has multiple adjustments and modifications. To facilitate community software maintenance and iterative development, this manual aims to systematically explain PM5's hardware features and design rationale. + +Overview of PM5's core hardware features: + +| Category | Content | +|------|------| +| Main processor | AT32F435 (ARM Cortex-M4F, 288 MHz) | +| FPGA | GOWIN GW1N-UV4 (4608 LUTs, built-in flash) | +| Power control | No dedicated SOC; relies on the main MCU to maintain power | +| Communication bus | `system I2C bus` (connecting multiple peripherals) | +| External interfaces | Main board 10P Connect header, dual TYPEC (USB / CEP), FPGA debug port | +| Antenna | Dual-band (HF / LF) antenna, supporting I2C parameter configuration | + +--- + +## 2. Core Processor and FPGA Architecture + +### 2.1 Key Processor Changes + +The PM5 project almost completely restructured the PM3 system framework, replacing the aging AT91 processor `AT91SAM7S512` (ARM7-based, 55 MHz) and the SPARTAN FPGA `XC2S30` (972 LUTs) with more modern ones: + +- **Main processor**: `AT32F435` (ARM Cortex-M4F, 288 MHz) +- **FPGA**: `GOWIN GW1N-UV4` (4608 LUTs) + +This replacement provides a higher ceiling for hardware performance and leaves more capacity and headroom for future software development. + +### 2.2 FPGA Firmware Framework Changes + +Because the new GOWIN FPGA has more than 4 times the logic capacity of the original SPARTAN FPGA, PM5 now **no longer needs to distinguish** the three firmwares `HF.BIT`, `LF.BIT`, and `HF_15.BIT` — as of release, all current functional code occupies less than half of the FPGA's resources. + +At the same time, the new GOWIN FPGA has **internal flash** and can boot directly from internal flash (which is much faster than having the ARM "load" it at boot), so PM5's boot and flashing flow can be greatly simplified. + +**Recommended firmware development / flashing method:** + +| Scenario | Approach | +|------|------| +| During development and debugging | Use the ARM to load SRAM data into the FPGA via **emulated JTAG**, for debugging and testing | +| Releasing firmware (for non-developer users) | Use the ARM to write firmware to the FPGA's flash via **emulated JTAG** | + +This way there is no longer a 2–4 s FPGA programming wait at each boot; and since high/low-frequency firmware no longer needs to be distinguished, we no longer need to wait for FPGA programming while switching high/low-frequency card commands. + +--- + +## 3. System Power Architecture + +PM5's power system is fairly complex. This section explains it step by step, from the overall block diagram and the on/off control circuit to each control point. + +### 3.1 Power System Overview + +The overall architecture of PM5's power system is shown below: + +![PM5 power system block diagram](../../img/pm5/power-architecture.png) + +### 3.2 Power On/Off Control Circuit + +The figure below is a **simplified functional description** of PM5's power on/off control circuit; a high level on each signal can effectively trigger system power-on. + +> Note: this figure has been simplified and is intended only to describe the signal relationships. + +![PM5 power on/off control circuit](../../img/pm5/power-on-control.png) + +### 3.3 Power Control Points + +**① Power-on hold (`POWER_ON_IO`)** + +In normal applications, the power on/off control circuit is controlled jointly by the external button and the MCU: after a button press powers on the system, the MCU must pull `POWER_ON_IO` (`PB0`) high at the appropriate moment to keep the system powered on and running. + +**② Charger and coulomb counter** + +A charger and a coulomb counter are designed on the external battery wireless module. Communication with these two chips is carried out over the `system I2C bus` (addresses in [Section 9](#9-system-i2c-bus-peripheral-address-table)). + +**③ Controllable antenna drive voltage (BOOST)** + +PM5 adds a controllable antenna drive voltage mechanism. This voltage is controlled by a **BOOST** circuit with an adjustable boost ratio: + +- The FPGA's `PWMOUT` (`38`) is used to set this voltage; +- A high level on the FPGA's `PDP_EN` (`42`) is used to start the BOOST. + +**④ Low-power design (`PAN_EN`)** + +PM5 implements basic low-power design. Because the ADC consumes a lot of power while running, on PM5 a low level on the FPGA's `PAN_EN` (`24`) can be used to turn off the analog unit's power. + +**⑤ Forced restart and ISP mode (button controller)** + +PM5 has an additional hardware circuit (the button controller) used to forcibly restart the entire system by button when the host MCU is out of control or has no firmware (long-press the button for 6 s); and if USB is inserted when the restart is triggered, this hardware circuit pulls the AT32's `BOOT0` high (this signal is also used to maintain system power, see the on/off control circuit above), placing the system in **ISP mode**. + +In ISP mode: + +- The **hardware UART** (on the 10P Connect header, see [Section 5.1](#51-main-board-10p-header-interface)) or the **USB interface** (either TYPEC port) can be used with the **Artery ISP** tool to flash and update the MCU firmware; +- Long-pressing the button again for 3 s triggers a forced restart (system power-cycle restart); +- If ISP mode lasts more than 300 s, a forced restart is also triggered. + +> For the button controller's complete button logic and timing parameters, refer to [Button Controller Technical Manual](../PM5_Controllers/PM5_Button_Controller_RM.md). + +**⑥ USB insertion wake-up** + +PM5 has an additional hardware circuit that, after a USB insertion (with or without a battery present), powers the system on for a short period (untested, about several tens of ms), intended to allow the USB insertion event to wake the device. + +**⑦ Reset precautions (avoid accidental shutdown)** + +Because the power circuit does not use a dedicated SOC, PM5 relies on the main MCU to keep the power on. Therefore, PM5 does **not recommend** that the main MCU perform any behavior that causes the GPIO registers to reset (such an operation would cause the I/O that controls the main power switch to float, which would then cause the intended RESET to power down the system, manifesting as an accidental shutdown), for example: + +- `NVIC_RESET` +- `WDT` triggering, etc. + +If a software RESET is needed, use an **interrupt vector table jump** behavior instead; for WDT behavior, it may be kept if it is acceptable that a WDT event directly causes a shutdown. + +### 3.4 Power-on and On/Off Flow + +```mermaid +flowchart TD + A([System powered off]) --> B{Power-on trigger source present?
system power switch is logical OR} + B -->|Button pressed| C[Main power switch closes
system powers on] + B -->|USB inserted| C + B -->|DBG_PWR_ON high| C + C --> D[Host MCU starts] + D --> E{MCU pulls POWER_ON_IO PB0\nhigh in time?} + E -->|Yes| F[Maintain system power
enter normal operation] + E -->|No| G[Power down after trigger source released] + F --> H([System stays on]) +``` + +### 3.5 Forced Restart and ISP Mode Entry Flow + +```mermaid +flowchart TD + A([Host MCU out of control or no firmware]) --> B[Long-press button 6 seconds] + B --> C[Button controller triggers forced restart] + C --> D{USB inserted?} + D -->|Yes| E[Pull BOOT0 high
enter ISP mode] + D -->|No| F[Restart directly] + E --> G[Flash with Artery ISP tool
via hardware UART or USB interface] + G --> H{Long-press 3s again
or more than 300s elapsed?} + H -->|Yes| I[System power-cycle restart] + F --> I + I --> J([Restart]) +``` + +--- + +## 4. Internal Peripherals + +### 4.1 RGB LED + +PM5's hardware adds an RGB LED. This LED has an independent RGB controller, and communication with the RGB controller is carried out over the `system I2C bus`. + +> For details on the RGB controller, refer to [RGB Controller Technical Manual](../PM5_Controllers/PM5_RGB_Controller_RM.md). + +### 4.2 Buzzer + +PM5's hardware adds a buzzer. This buzzer is controlled by two signals: + +| Signal | Description | +|------|------| +| `BEEPER_EN` (`PB13`) | Enable signal; GPIO configured as OUTPP, pulled high to enable the buzzer | +| `BEEPER` (`PC9_TIM3_CH4`) | Waveform output, driving the buzzer to sound | + +How it works: + +- `BEEPER` can produce outputs such as SPWM using the internal timer / DMA; +- After `BEEPER_EN` is pulled low, the hardware RC produces a roughly 100 ms **sustain**, used to create a fading audio effect. + +**Recommended implementation:** + +- If the sustain is **not needed**: pull `BEEPER` low to turn it off directly for a clean cutoff effect; +- If the sustain is **needed**: keep sending the `BEEPER` signal during the sustain period, using the hardware's fade to obtain a soft tail. + +The buzzer-related circuit is shown below (simplified schematic): + +![Buzzer circuit simplified schematic](../../img/pm5/buzzer-circuit.png) + +--- + +## 5. External Interfaces + +### 5.1 Main Board 10P Connect Header + +On PM5's **main board** there is a **2x5P 2.54 mm Connect header** as a communication interface. This interface provides multiple breakout functions (used by peripherals such as the antenna), and its interface definition is as follows. + +> The picture's orientation is the order as seen "directly viewing the 10P connector with the machine's decorative side facing up" (with the antenna's yellow ICX301 connector on the right side of the visible area). + +![Main board 10P Connect header interface definition](../../img/pm5/board-10p-header.png) + +Signal definitions: + +| Signal | Internal connection | Description | +|------|----------|------| +| UART TX / RX | MCU `PA2` / `PA3` | Usable for UART or other I/O functions, not shared with other circuits; there is an ESD bleed circuit on the line, recommended level 3.3 V | +| I2C SDA / SCL | MCU `PC7` / `PC6` | I.e., the `system I2C bus`, used to communicate with various peripherals; not recommended for functions other than connecting to I2C slaves (on the multi-frequency antenna board shipped with the host, this port is used to communicate with the antenna controller), recommended level 3.3 V | +| SWDIO / SWCLK | MCU `PA13` / `PA14` | Usable for SWD debugging or other I/O functions, not shared with other circuits; there is an ESD bleed circuit on the line, recommended level 3.3 V; this interface can directly flash or debug the MCU | +| MCU_RST | Main MCU RESET | Built-in 3.3 V pull-up resistor; pull low to reset the MCU; this port is internally connected to the power control's restart circuit and cannot be used for other functions | +| DBG_PWR_ON | — | Debug-only power control signal; input high level (2.0–15 V) to turn on the system's internal main power switch (VMIX–VSYS path); note that the system power switch is a "logical OR" relationship, and this signal overrides all other on/off signals (but does not affect the MCU and reset circuit reading the button signal) | +| VCC5V4 | — | Output voltage of the internal DCDC circuit; for output only, must not be used to input any power; voltage about 5.4 V, and it is a BOOST-boosted output, so an external LDO is required if ripple requirements apply; output capability is less than 300 mA, and since fault isolation is not implemented, drawing excessive current is not recommended, otherwise the internal operating state of the PM5 may become unstable | + +### 5.2 TYPE-C Ports + +PM5 has two TYPE-C ports located in different positions: + +| Port | Tongue color | Position | Function | USB connection | +|------|----------|------|------|----------| +| USB port | Orange | Same side as the button | The familiar USB port on the traditional PM3, powering (charging) the whole device | MCU USB2 (`PB14` / `PB15`) | +| CEP interface | Black | Side | Can power (charge) the whole device, and can also output power externally | MCU USB1 (`PA11` / `PA12`) | + +> For more information on the CEP interface, see [Section 5.3](#53-cep-interface-typec_external_port). + +### 5.3 CEP Interface (TYPEC_EXTERNAL_PORT) + +On PM5, we introduced a **"dual-device interconnect"** capability for interconnecting two PM5s, for example to implement behaviors such as man-in-the-middle sniffing. To achieve **high bandwidth + high real-time + high compatibility** interconnect, we added an additional USB TYPE-C port to PM5. Its basic structure is identical to a standard 24-pin USB TYPEC port, and its interface definition is shown below: + +![CEP interface definition](../../img/pm5/cep-interface.png) + +**Signal symmetry:** the signal connections of the CEP interface (except the CC signals) are vertically reversed (centrosymmetric), which allows the cable to be inserted in either orientation. + +**CC handshake:** the CEP uses the CC lines for the handshake. PM5 has a built-in Type-C configuration channel chip `TUSB320`; this chip handles the CC handshake information of the CEP interface and communicates with the main MCU over the `system I2C bus`. + +**SIG signal assignment:** due to the requirements of dual-device interconnect and reversible cable insertion, as well as circuit layout constraints, the five signals `SIG1`–`SIG5` in the CEP port definition are used in the following connection scheme: + +![CEP SIG1-SIG5 signal connection scheme](../../img/pm5/cep-signal-routing.png) + +In this connection scheme: + +| Signal | Purpose | Connection | +|------|------|------| +| SIG1 / SIG2 / SIG4 / SIG5 | SPI signals interconnecting the internal MCUs of two PM5s | Uses GPIO `A4` / `A5` / `A6` / `A7` | +| Switch control | Swap the cable order | Controlled by the MCU's `InterCon_SPI_SWITCH` (`PB2`) | +| SIG3 | Single-wire UART or ordinary I/O communication | Connected to the MCU's `InterCon_UART` (`PA9`) | +| DP / DM | USB 2.0 portion | Directly interconnected | + +> Since `PB2` is also the MCU's `BOOT1`, this signal has an external pull-down resistor. + +**Identity handling for dual-device interconnect:** + +Since both PM5s may both be DRP when interconnected, the handshake result is random. When using the dual-device interconnect feature, we recommend adapting the CC handshake identity handling in software, for example: + +- Manually designate one device as the host; or +- Automatically switch when the handshake result is affected by the running function, etc. + +We recommend that **the CC handshake result be used to switch `InterCon_SPI_SWITCH`**; only two PM5s with different `InterCon_SPI_SWITCH` levels can correctly use SPI communication. + +**Compatibility specification and safety:** + +- Because compatibility with the standard TYPEC specification is required, before confirming that the peer is a usable PM5 device, it is recommended to set these five IOs to **floating state**; identity confirmation can be performed using USB 2.0 or single-wire UART handshaking. +- Because the single-wire UART is floating (floating input) while the peer's identity is unconfirmed, the MCU can receive external signals through the single-wire UART without causing non-compliant electrical effects on the interface. Therefore, when the CEP port is used to communicate with Flipper 0, it also uses single-wire UART handshaking first and then enables the SPI slave function. + +**External power supply capability:** + +The CEP port has the ability to supply power externally, and the on/off of this capability is controlled by the CC handshake result: if the current identity is MASTER (DFP), the output power is enabled. This power supply provides about 5.1 V, but its supply capability is limited — due to the capacity of the internal lithium battery and system power consumption, the effective external output capability does not exceed 500 mA over the long term. This port has overcurrent and short-circuit protection. + +> **Recommendation**: in dual-device interconnect scenarios, install the "BWM module" on both devices and, in software, disable the lithium battery charger charging function (if present) or reduce the charging current, to prevent (when only one PM5 is connected to external power) drawing excessive current from the external power source and causing a fault; and we do not recommend operating PM5 in scenarios that require a stable output power source, such as a power bank. + +**CEP dual-device interconnect handshake flow:** + +```mermaid +flowchart TD + A([Two PM5s connected via CEP cable]) --> B[CC handshake
handled by TUSB320] + B --> C{Role determination} + C -->|Master DFP| D[Enable external power 5.1V] + C -->|Sink UFP| E[Do not supply external power] + C -->|Both DRP| F[Handshake result random
recommend software manually designate host] + D --> G{Peer is a PM5 device?} + E --> G + F --> G + G -->|Yes| H[Toggle InterCon_SPI_SWITCH
swap cable order] + H --> I[Enable SPI high-speed interconnect
SIG1/2/4/5] + G -->|Unknown| J[Float the five IOs
USB2.0 / single-wire UART handshake confirmation] + J --> K{Confirmed usable device?} + K -->|Yes| I + K -->|No| L[Keep floating
do not enable SPI] +``` + +--- + +## 6. Storage and Clock + +### 6.1 Memory + +In PM5's system structure, in addition to the traditional `25Q flash`, we added a **read-only** `24C02 EEPROM`, which stores some factory and production information. + +- The hardware pulls the **WP** signal high to prevent accidental writes; +- The hardware reserves a jumper (soldering required) to enable writes — **if you do not know what you are doing, please do not enable it lightly**. + +This EEPROM is connected to the `system I2C bus`. + +### 6.2 Drive Clock Bypass + +Because the FPGA's internal processing introduces significant phase noise to the clock (especially the 13.56 MHz clock), this can manifest as frequency-to-amplitude conversion interference on PM3's high-Q antenna system. For this reason, we added an additional **external clock bypass circuit**: + +- This circuit can pass the 13.56 MHz crystal signal, after gating, directly to the RF circuit's driver, **bypassing the FPGA's internal complex processing**; +- The gating signal is `FE_GATE_EN` (`29`). + +The clock signal path is shown below: + +```mermaid +flowchart LR + X[13.56 MHz crystal] -->|Bypass path| G{FE_GATE_EN 29
gating} + X -->|Normal path| FPGA[FPGA internal processing
introduces phase noise] + G -->|Gating enabled| D[RF driver] + FPGA --> D + D --> RF[RF circuit] +``` + +--- + +## 7. Debug Interfaces + +### 7.1 FPGA Debug Port + +We reserved an FPGA debug port on the PCB, defined as shown below (this information is also printed on the PCB surface): + +![FPGA debug port definition](../../img/pm5/fpga-debug-port.png) + +Signal descriptions: + +| Signal | Description | +|------|------| +| ADC | The raw input of the ADC in the acquisition circuit, unrelated to the FPGA | +| DBG1 / DBG2 | Debug signal pins broken out from the FPGA, dedicated circuits; this port can withstand 3.3 V levels | +| JTAG (TDO / TDI / TMS / TCK) | The FPGA's JTAG pins | + +**Notes:** + +- The JTAG signals are shared with the ARM–FPGA communication **SPI (not SSP)** used during normal system operation; +- For the GOWIN FPGA, restoring JTAG requires **pulling the `JTAGSEL` signal low**; +- If an external debugger is connected here, the main MCU firmware must **float these five signals** at the same time, otherwise there is a risk of I/O conflict; +- You can also monitor the ARM–FPGA communication here — we have already implemented JTAG flashing based on this port, and it is SPI while running the PM3 firmware normally. + +The four **non-plated-through test points** on the left side of the figure are the ARM–FPGA SPP signals. Note: due to the peripheral differences between the AT32 and the AT91, we changed the SSP signal to **SPI-TIMODE**; its basic principle is the same as the traditional SSP, with only a difference in timing, which will not be elaborated here. These test points can be used to measure and debug the communication. + +Additionally, a separate LED on the back of the button is also a debug I/O dedicated to the FPGA, which can be used for signal indication during development (this LED is not visible outside the enclosure). + +### 7.2 Port Definition Information + +The figure below is the external interface definition of the main MCU (`AT32F435RxTx`): + +![Main MCU (AT32F435RxTx) external interface definition](../../img/pm5/mcu-interface.png) + +The figure below shows the FPGA and clock circuit: + +![FPGA and clock circuit](../../img/pm5/fpga-clock-circuit.png) + +--- + +## 8. Standard Antenna + +### 8.1 Changes vs. RDV4 + +Changes of the standard dual-band (HF, LF) antenna relative to RDV4: + +- Added an **antenna controller chip** to provide the ability to modify antenna hardware parameters via I2C; +- Replaced with the **ICX301 interface**, which is commonly used for RC model battery connections and has very solid interface performance and a relatively high insertion/removal life (>1000 times), making it convenient for users to swap antennas; +- **Q value switching** changed from a physical button to I2C switching (antenna controller); +- Added **two blue LEDs**, expanding the antenna's operating-state indication capability, configurable via I2C (antenna controller); +- **LF supports multiple frequencies**: 125, 134, 250 (new), 375 (new), 500 (new), configurable via I2C (antenna controller); +- Longer read range, and it reduces some of the blind-zone problems relative to RDV4 (in some cases the RF drive voltage needs to be adjusted). + +> For details on the antenna controller, refer to [Antenna Controller Technical Manual](../PM5_Controllers/PM5_ANT_Controller_RM.md). + +--- + +## 9. system I2C bus Peripheral Address Table + +The peripherals connected to the `system I2C bus` and their 7-bit slave addresses are as follows: + +| Peripheral name | Peripheral address (7-bit) | +|----------|:----------------:| +| RGB controller | `0x48` | +| Antenna controller | `0x51` | +| BQ27427 | `0x55` | +| AW32001 | `0x49` | +| 24C02 | `0x50` | +| TUSB320 | `0x47` | + +> **Supplementary note**: `BQ27427` is the battery coulomb counter (fuel gauge), and `AW32001` is the battery charger; both are located on the external battery wireless module. `TUSB320` is the Type-C configuration channel (CC) chip for the CEP interface. `24C02` is the read-only EEPROM (see [Section 6.1](#61-memory)). + +--- + +## 10. Appendix: Terms and Abbreviations + +| Term / abbreviation | Meaning | +|-------------|------| +| PM5 | The PROXMARK3 upgraded hardware system, the subject of this manual | +| PM3 / RDV4 / EASY | PROXMARK3 and previous hardware versions | +| MCU | Microcontroller; here it refers to the main controller chip AT32F435 | +| FPGA | Field-Programmable Gate Array; here it refers to the GOWIN GW1N-UV4 | +| system I2C bus | The system's internal I2C bus, used to connect various peripherals | +| ISP | In-System Programming | +| CEP | TYPEC_EXTERNAL_PORT, the extended TYPE-C port used for dual-device interconnect | +| CC | Type-C Configuration Channel | +| DRP / DFP / UFP | Type-C roles: dual-role / downstream (power source) / upstream (power sink) | +| SPWM | Sinusoidal Pulse-Width Modulation | +| OUTPP | Push-Pull Output | +| LUTs | Number of FPGA lookup tables, a measure of logic capacity | diff --git a/doc/md/Development/Proxmark5.md b/doc/md/Development/Proxmark5.md index 156fa1c0f..87ad0f518 100644 --- a/doc/md/Development/Proxmark5.md +++ b/doc/md/Development/Proxmark5.md @@ -1,5 +1,8 @@ These notes are mostly intended for developers. -Read first the [Proxmark5 Instructions](../Installation_Instructions/Proxmark5-Instructions.md). + - Read first the [Proxmark5 Instructions](../Installation_Instructions/Proxmark5-Instructions.md). IMPORTANT !!! + - Read the technical manual to develop new features for PM5: [Proxmark5 Technical Manual](./PM5_VERE_Hardware_RM.md) + +--- - Some hardware abstractions are still incomplete; all 'TODO DXL' items need to be addressed. - Certain timeout mechanisms (`timeout--`) are not cross-platform compatible. If `timeout--` is not used with additional clock conditions, please replace it with a timeout mechanism tied to a specific clock source, as the main clock frequency varies across different platforms. diff --git a/doc/md/PM5_Controllers/PM5_ANT_Controller_RM.md b/doc/md/PM5_Controllers/PM5_ANT_Controller_RM.md new file mode 100644 index 000000000..5fe7ba49a --- /dev/null +++ b/doc/md/PM5_Controllers/PM5_ANT_Controller_RM.md @@ -0,0 +1,299 @@ +# Antenna Controller Technical Manual + +> Intended audience: host-side (integration) developers who need to communicate with this antenna controller over the I2C bus. +> This document describes only the external interface and business logic, not the internal hardware or implementation details. + +- Author: DXL +- Document version: v1.0 +- Date: 2026-08-24 + +## Table of Contents + +1. [Overview](#1-overview) +2. [I2C Communication Basics](#2-i2c-communication-basics) +3. [Register Map Overview](#3-register-map-overview) +4. [Register Details](#4-register-details) +5. [Operation Methods](#5-operation-methods) +6. [Register Mutual Exclusion and Constraint Conditions](#6-register-mutual-exclusion-and-constraint-conditions) +7. [Business Logic Feature Summary](#7-communication-and-register-defaults-summary) +8. [Flowcharts](#8-flowcharts) + +## 1. Overview + +This controller's communication interface is a standard I2C **slave**, used to control the antenna's operating frequency, Q value, and LED indication. The host can perform all control and status queries by reading and writing several I2C registers. Supported capabilities are as follows: + +| Capability | Description | +|------|------| +| Operating frequency | Five levels: 125 kHz / 134 kHz / 250 kHz / 375 kHz / 500 kHz | +| LED indication | HF (high-frequency) LED and LF (low-frequency) LED, each independently controllable on/off | +| Q value | High Q / low Q switching | + +## 2. I2C Communication Basics + +### 2.1 Slave Address + +| Item | Value | +|----|----| +| 7-bit slave address | `0x51` | +| 8-bit write address | `0xA2` (`0x51 << 1 | 0`) | +| 8-bit read address | `0xA3` (`0x51 << 1 | 1`) | + +### 2.2 Communication Rate + +It is recommended to keep the I2C clock rate at **around 10 kHz**; an excessively high rate may cause communication failures. + +### 2.3 Communication Model + +Register operations follow the **"write the register address first, then read/write data"** convention: + +- Before any register operation, a **write** operation must be performed first to tell the slave which register is to be operated on subsequently; +- **Read operation**: first perform a write operation passing only 1 byte (the register address), then initiate a read transaction; +- **Write operation**: perform one write operation where byte 1 is the register address and the subsequent bytes are the register data. + +## 3. Register Map Overview + +| Address | Name | Access | Data Length | Description | +|------|------|------|:---:|------| +| `0x00` | Invalid register (default) | — | — | Power-on default address; not readable, and rejected if written as an address | +| `0x01` | IO data register | Read / Write | 1 byte | Directly reads/writes the raw levels of the antenna control lines (low-level pass-through interface) | +| `0x02` | IO mapping register | Read / Write | 1 byte | Logical control of frequency / LED / Q value (recommended) | +| `0xFE` | Device identification register | Read-only | 8 bytes | Device identity signature | +| `0xFF` | Firmware version register | Read-only | 2 bytes | Major version + minor version | + +## 4. Register Details + +### 4.1 `0x00` — Invalid Register + +- The default "current register" address after power-on; +- Before a valid register address is written, any **read** operation will be rejected (NACK); +- Writing `0x00` as a register address is also rejected. + +### 4.2 `0x01` — IO Data Register (Read / Write, 1 byte) + +- Directly reads/writes the 8-bit raw levels of the antenna control I/O group; +- **Read**: returns the real-time state of the current 8 control lines; +- **Write**: directly sets these 8 control lines, **without** going through the arbitration and constraint logic of `0x02`; +- The 8 bits logically cover the same group of control signals as `0x02` (frequency selection, Q value, HF/LF LED), but the bit ordering is a hardware implementation detail and is not publicly guaranteed; +- ⚠️ This register is a low-level "pass-through" interface; for normal control, use `0x02`. +- ⚠️ Unless for debugging purposes, do not operate this register; otherwise, if the antenna hardware is revised, writing incompatible data could cause anomalies. + +> **Relationship note**: writing `0x02` updates both the internal logical mapping and the actual control lines; writing `0x01` only directly changes the actual control lines and does **not** write back to the internal logical mapping. If the two are mixed, a subsequent read of `0x02` may return an old value inconsistent with what was written to `0x01`. + +### 4.3 `0x02` — IO Mapping Register (Read / Write, 1 byte) + +8-bit mapping: + +| Bit | Meaning | Value | +|:---:|------|------| +| 7 | 125 kHz enable | 1 = enabled / 0 = disabled | +| 6 | 134 kHz enable | 1 = enabled / 0 = disabled | +| 5 | 250 kHz enable | 1 = enabled / 0 = disabled | +| 4 | 375 kHz enable | 1 = enabled / 0 = disabled | +| 3 | 500 kHz enable | 1 = enabled / 0 = disabled | +| 2 | HF LED | 1 = on / 0 = off | +| 1 | LF LED | 1 = on / 0 = off | +| 0 | Q value | 1 = high Q / 0 = low Q | + +See Section 6 for constraint conditions. + +### 4.4 `0xFE` — Device Identification Register (Read-only, 8 bytes) + +- Returns a fixed 8-byte identity signature: `0x70 0x6D 0x35 0x5F 0x61 0x6E 0x74 0x78` +- Purpose: after reading, the host compares it with the expected value to confirm that the currently connected device is this antenna controller (rather than another I2C device); +- Circular reading: after the 8th byte is read, continued reading wraps back to the 1st byte. + +### 4.5 `0xFF` — Firmware Version Register (Read-only, 2 bytes) + +- Byte 1: major version +- Byte 2: minor version +- Current version: **v1.2** (major 1 / minor 2) +- Purpose: the host can use it for version adaptation and problem localization; after the 2nd byte is read, continued reading wraps back to the 1st byte. + +## 5. Operation Methods + +### 5.1 Write Register + +``` +START | write address 0xA2 | ACK | register address | ACK | data | ACK | STOP +``` + +1. Host sends `START`; +2. Host sends the 8-bit write address `0xA2`; +3. Slave replies `ACK`; +4. Host sends the register address (1 byte); +5. Slave replies `ACK`; +6. Host sends the data (each writable register of this controller has a 1-byte data body); +7. Slave replies `ACK`; +8. Host sends `STOP`. + +> If a read-only register (`0xFE` / `0xFF`) or an illegal address is written, the slave terminates the communication with **NACK**. + +### 5.2 Read Register + +A read operation consists of two stages: "set address" and "read". + +``` +Set address: START | write address 0xA2 | ACK | register address | ACK | STOP +Read data: START | read address 0xA3 | ACK | data0 | ACK | ... | dataN | NACK | STOP +``` + +1. Host sends `START`, then the write address `0xA2`; slave replies `ACK`; +2. Host sends the register address (1 byte); slave replies `ACK`; +3. Host sends `STOP` (or switches to a `repeated START`); +4. Host sends `START`, then the read address `0xA3`; slave replies `ACK`; +5. The slave sends data bytes in sequence; the host replies `ACK` for each intermediate byte and `NACK` for the last byte to end; +6. Host sends `STOP`. + +> In a single read transaction, the slave sends data continuously (`0xFE` up to 8 bytes, `0xFF` 2 bytes, `0x01` / `0x02` 1 byte); the host terminates it actively with `NACK`. + +### 5.3 Operation Examples + +| Operation | Byte sequence | +|------|---------| +| Set 125 kHz, HF LED on, low Q | Write `0x02` = `0x84` (0b10000100) | +| Set 250 kHz, both LEDs on, low Q | Write `0x02` = `0x26` (0b00100110) | +| Read firmware version | Write address `0xFF`, then read 2 bytes | + +## 6. Register Mutual Exclusion and Constraint Conditions + +1. **Frequency bit mutual exclusion** (`0x02` bit7~bit3): + - At most 1 bit may be 1 at a time; + - If multiple bits are set simultaneously, priority follows **frequency from low to high**: 125k → 134k → 250k → 375k → 500k; + - If all 5 bits are 0, **125 kHz** is automatically enabled as a fallback. + +2. **Q value and frequency linkage** (`0x02` bit0): + - High Q takes effect only when the frequency is **125 kHz or 134 kHz**; + - Set bit0 = 1 with frequency 125/134 → high Q; + - All other cases (other frequencies, or bit0 = 0) are forced to low Q. + +3. **Read-only register protection**: `0xFE` and `0xFF` are read-only; writing data to them is rejected (NACK and communication terminated). + +4. **Invalid address protection**: `0x00` is not a valid register; both writing and reading are rejected. + +## 7. Communication and Register Defaults Summary + +- **Power-on default**: 125 kHz + low Q + both LEDs off (`0x02` default value `0x80`). +- **Device identification**: the 8-byte signature `0x70 6D 35 5F 61 6E 74 78` identifies this device as a multi-frequency, full-featured antenna controller. +- **Firmware version**: major 1 / minor 2 (v1.2). +- **Multi-byte register wraparound**: `0xFE` (8 bytes) and `0xFF` (2 bytes) wrap back to the first byte after reaching the end. +- **Register address retained across transactions**: the register address is retained after `STOP` until the next write transaction resets it, so when reading the same register consecutively, the address only needs to be written once. +- **`0x01` and `0x02` are not synchronized**: `0x01` is the pass-through physical control lines, while `0x02` is the arbitrated logical mapping (see 4.2 for details). + +## 8. Flowcharts + +### 8.1 Power-on Initialization Flow + +```mermaid +flowchart TD + A([Power-on / reset]) --> B[Delay about 3ms to wait for power stabilization] + B --> C[Configure the 8 antenna control lines as outputs] + C --> D[Set default mapping: 125 kHz + low Q + LEDs off] + D --> E[Apply the default mapping to the control lines] + E --> F[Initialize I2C slave] + F --> G([Enter main loop: poll the I2C lines]) +``` + +### 8.2 IO Mapping Update Flow + +```mermaid +flowchart TD + Start([Write / update IO mapping register]) --> C125{125k bit = 1?} + C125 -->|Yes| F125[Select 125 kHz] + C125 -->|No| C134{134k bit = 1?} + C134 -->|Yes| F134[Select 134 kHz] + C134 -->|No| C250{250k bit = 1?} + C250 -->|Yes| F250[Select 250 kHz] + C250 -->|No| C375{375k bit = 1?} + C375 -->|Yes| F375[Select 375 kHz] + C375 -->|No| C500{500k bit = 1?} + C500 -->|Yes| F500[Select 500 kHz] + C500 -->|No| F125 + + F125 --> HF{HF LED bit = 1?} + F134 --> HF + F250 --> HF + F375 --> HF + F500 --> HF + HF -->|Yes| HFON[Turn on HF LED] + HF -->|No| HFOFF[Turn off HF LED] + + HFON --> LF{LF LED bit = 1?} + HFOFF --> LF + LF -->|Yes| LFON[Turn on LF LED] + LF -->|No| LFOFF[Turn off LF LED] + + LFON --> Q{High Q required and\nfrequency is 125/134?} + LFOFF --> Q + Q -->|Yes| QH[High Q] + Q -->|No| QL[Low Q] + QH --> Done([Done]) + QL --> Done +``` + +### 8.3 I2C Communication Handling Flow + +```mermaid +flowchart TD + Idle([Idle wait]) --> ST{START detected?} + ST -- No --> Idle + ST -- Yes --> Addr[Receive 7-bit slave address] + Addr --> Mt{Address matches 0x51?} + Mt -- No --> Idle + Mt -- Yes --> Op[Receive read/write bit] + Op --> Rdw{Read / write?} + Rdw -- Write --> Wr1[Receive 1 byte as register address] + Wr1 --> Vr{Address valid?} + Vr -- No --> Nk[Respond NACK] + Nk --> Idle + Vr -- Yes --> Wr2[Receive data byte] + Wr2 --> Vd{Target register writable?} + Vd -- No --> Nk + Vd -- Yes --> Apply[Apply data / update control lines] + Apply --> Wr2 + Rdw -- Read --> Chk{Valid address already set?} + Chk -- No --> Nk + Chk -- Yes --> Rd[Send data byte] + Rd --> Rsp{Host ACK?} + Rsp -- ACK --> Rd + Rsp -- NACK --> Idle +``` + +> Note: regardless of the current processing stage, detecting a STOP (SDA↑ while SCL is high) immediately returns to the idle state. + +### 8.4 Write Register Timing + +```mermaid +sequenceDiagram + participant M as Host (Master) + participant S as Slave + M->>S: START + M->>S: 0xA2 (write address) + S-->>M: ACK + M->>S: 0x02 (register address) + S-->>M: ACK + M->>S: 0x84 (data: 125kHz + HF LED on) + S-->>M: ACK + M->>S: STOP +``` + +### 8.5 Read Register Timing (reading the firmware version as an example) + +```mermaid +sequenceDiagram + participant M as Host (Master) + participant S as Slave + M->>S: START + M->>S: 0xA2 (write address) + S-->>M: ACK + M->>S: 0xFF (register address) + S-->>M: ACK + M->>S: STOP + M->>S: START + M->>S: 0xA3 (read address) + S-->>M: ACK + S-->>M: 0x01 (major version) + M->>S: ACK + S-->>M: 0x02 (minor version) + M->>S: NACK + M->>S: STOP +``` diff --git a/doc/md/PM5_Controllers/PM5_Button_Controller_RM.md b/doc/md/PM5_Controllers/PM5_Button_Controller_RM.md new file mode 100644 index 000000000..4cd4e2b93 --- /dev/null +++ b/doc/md/PM5_Controllers/PM5_Button_Controller_RM.md @@ -0,0 +1,266 @@ +# Button Controller Technical Manual + +> This document is intended for product users and integrators. It describes the button actions, timing parameters, and related business logic of this chip. + +- Author: DXL +- Document version: v1.0 +- Date: 2026-08-24 + +--- + +## Table of Contents + +1. [Overview](#1-overview) +2. [External Signals and Key Actions](#2-external-signals-and-key-actions) +3. [Button Actions and Timing](#3-button-actions-and-timing) +4. [Effects of Various Conditions on Button Business Logic](#4-effects-of-various-conditions-on-button-business-logic) +5. [Detailed Flowcharts](#5-detailed-flowcharts) +6. [Typical Operation Scenarios](#6-typical-operation-scenarios) +7. [FAQ and Notes](#7-faq-and-notes) +8. [Appendix](#appendix) + +--- + +## 1. Overview + +This chip is used to assist the host MCU. It is primarily responsible for: + +- **Reset control**: resetting (rebooting) the host MCU under specific conditions; +- **ISP mode management**: guiding the host MCU into or out of ISP (In-System Programming) mode through operations such as long presses, for firmware updates; +- **Factory test mode**: detecting the factory test signal at power-on and guiding the host MCU into a programming state, for production-line flashing. + +> **Terminology** +> - **Host MCU**: the target chip managed by this chip, which runs the main application firmware. +> - **ISP (In-System Programming)**: in-system programming, used to update the host MCU firmware. + +--- + +## 2. External Signals and Key Actions + +### 2.1 External Signals + +| Signal | Direction | Meaning | Active Level | +| --- | --- | --- | --- | +| `BTN_IN` | Input | Physical button | High = pressed, Low = not pressed | +| `USB_VBUS` | Input | USB connection / power detection | High = USB connected, Low = not connected | +| `MCU_RST` | Output | Host MCU reset control | Low = reset, High = normal operation | +| `MCU_BOOT0` | Output | Host MCU boot mode selection | High = programming (ISP) mode, Low = normal operation | + +### 2.2 Key Actions + +| Action | Behavior | +| --- | --- | +| Reset host MCU | Pull `MCU_RST` low, hold for about 5ms, then release (pull high), causing the host MCU to restart | +| Exit ISP | Stop the auto-exit timer → end the ISP state → pull `MCU_BOOT0` low → reset the host MCU | + +--- + +## 3. Button Actions and Timing + +### 3.1 Three Core Actions + +| Scenario | Trigger Condition | Result | +| --- | --- | --- | +| ① Long press to enter ISP / reset (non-ISP mode) | Long press exceeding **6 seconds** | See the "USB connected?" branch below | +| ② Long press to exit ISP (ISP mode) | Long press exceeding **3 seconds** | Exit ISP, host MCU resets back to normal operation | +| ③ Idle auto-exit ISP (ISP mode) | No button operation for more than **5 minutes** | Automatically exit ISP, host MCU resets | + +> The business logic of this chip currently only handles **long-press events**, not short-press events. +> The timing may have **errors** and is not entirely accurate; this is caused by the precision of this chip's internal oscillator. + +### 3.2 USB Branch of Action ① + +When a long press exceeds 6 seconds in non-ISP mode: + +- **USB connected** (`USB_VBUS` high): first pull `MCU_BOOT0` high, then reset the host MCU → the host MCU enters **ISP (programming) mode**; +- **USB not connected** (`USB_VBUS` low): only reset the host MCU (equivalent to a **restart**), without entering ISP. + +### 3.3 Timing Parameter Summary + +| Parameter | Value | Meaning | +| --- | --- | --- | +| Button debounce | 10ms | Duration for stable button-state determination | +| Timing base | 100ms | Minimum timing unit for long-press / idle duration | +| Non-ISP long-press threshold | 6 seconds | Long-press threshold in non-ISP mode | +| ISP long-press exit threshold | 3 seconds | Long-press exit threshold in ISP mode | +| ISP idle timeout | 5 minutes | Idle auto-exit duration in ISP mode | + +--- + +## 4. Effects of Various Conditions on Button Business Logic + +### 4.1 Key Conditions Affecting Button Behavior + +The final behavior of the button is jointly determined by the following three conditions: + +1. **Whether the device is currently in ISP mode**; +2. **Whether USB is connected** (`USB_VBUS`); +3. **Which processing stage the button is currently in**. + +### 4.2 Decision Table + +**Non-ISP mode:** + +| Button State | Duration | USB | Action | +| --- | --- | --- | --- | +| Long-pressing | Released before reaching 6 seconds | — | Cancelled, no action | +| Long-pressing | Exceeds 6 seconds | Connected | Enter ISP mode (pull `MCU_BOOT0` high, then reset) | +| Long-pressing | Exceeds 6 seconds | Not connected | Only reset the host MCU | + +**ISP mode:** + +| Button State | Duration | Action | +| --- | --- | --- | +| Long-pressing | Exceeds 3 seconds | Exit ISP (pull `MCU_BOOT0` low, then reset) | +| No press | Idle for more than 5 minutes | Automatically exit ISP | +| Holding | Any | ISP idle timing paused (not counted toward timeout) | + +### 4.3 Button Processing Stage State Machine + +```mermaid +stateDiagram-v2 + [*] --> Released + Released --> Pressed : stable press (debounce passed) + Pressed --> LongPressTriggered : threshold reached (6s or 3s) + Pressed --> Released : released (before threshold, cancelled) + LongPressTriggered --> Released : released +``` + +### 4.4 Two Important Details + +1. **After entering ISP, you must "release and then long-press again" to exit**: the long press used to enter ISP has already been marked as "processed" for that press. Therefore, to exit ISP via long press, you must **first release the button**, and then **long-press again for 3 seconds**. + +2. **Starting point of the 5-minute idle timeout**: when entering ISP, the idle timing is cleared, but it only accumulates while the button is in the "released" state. Therefore, the 5-minute timeout actually begins counting **from the moment the button is released after entering ISP**; while the button is held, the timeout timing is paused. + +--- + +## 5. Detailed Flowcharts + +### 5.1 Overall Power-on Flow + +```mermaid +flowchart TD + A([Power-on startup]) --> B[Power-on initialization] + B --> C{Factory test mode detection} + C -->|Reset signal pulled low within 10ms after power-on, and held for more than 100ms| D[Enter factory ISP mode] + D --> E{USB disconnected?} + E -->|No| E + E -->|Yes| F[Exit ISP, reset host MCU] + F --> G[Enter operating-mode main loop] + C -->|No| G +``` + +### 5.2 Factory Test Mode Detection Flow + +```mermaid +flowchart TD + S([Start detection]) --> A[Begin monitoring the reset signal] + A --> B{Within 10ms of power-on
was the reset signal pulled low?} + B -->|No, held high within 10ms| R1[Do not enter factory mode, return] + B -->|Yes| C{Reset signal held low
for more than 100ms?} + C -->|No, recovered high early| R2[Do not enter factory mode, return] + C -->|Yes| D[Wait for reset signal to release high] + D --> E[Wait another 100ms] + E --> F[Pull boot mode signal high, reset host MCU
enter ISP programming mode] + F --> G{USB disconnected?} + G -->|No| G + G -->|Yes| H[Pull boot mode signal low, reset host MCU] + H --> I([Return, enter operating mode]) +``` + +### 5.3 Operating-mode Main Loop Flow + +```mermaid +flowchart TD + L([Loop start]) --> RD[Read button level] + RD --> DB[Delay 10ms debounce] + DB --> P{Button stably pressed?} + P -->|Yes| S0{First press
and long-press timing not started?} + S0 -->|Yes| S1[Enter long-press detection
clear button timing and start timing] + S0 -->|No| REL + S1 --> REL + P -->|No| REL{Button stably released?} + REL -->|Yes, and a prior button processing exists| RA[Stop timing when not in ISP
clear button timing
reset button processing stage] + RA --> L1 + REL -->|No| L1 + L1{Not in ISP and long-press timing exceeds 6 seconds?} + L1 -->|Yes| S2[Mark this long press as processed
stop timing] + S2 --> USB{USB connected?} + USB -->|Yes| EI[Pull boot mode signal high
enter ISP mode] + EI --> RST[Reset host MCU] + USB -->|No| RST + RST --> RT{Entered ISP mode?} + RT -->|Yes| TO[Clear idle timing
start idle timeout timing] + RT -->|No| L2 + TO --> L2 + L1 -->|No| L2 + L2{In ISP and long-press timing exceeds 3 seconds?} + L2 -->|Yes| X[Mark this long press as processed
exit ISP] + X --> L3 + L2 -->|No| L3 + L3{In ISP and no button press
and idle timing exceeds 5 minutes?} + L3 -->|Yes| X2[Exit ISP] + X2 --> L + L3 -->|No| L +``` + +--- + +## 6. Typical Operation Scenarios + +### 6.1 Enter ISP to Flash Firmware + +1. Confirm that USB is connected (`USB_VBUS` high); +2. Long-press the button for **more than 6 seconds**; +3. The host MCU is reset and enters ISP (programming) mode, at which point firmware can be flashed via the host PC. + +### 6.2 Exit ISP and Return to Normal Operation + +- **Manual exit**: first release the button, then long-press again for **more than 3 seconds**; +- **Automatic exit**: keep 5 minutes without button operation, and ISP is exited automatically. + +### 6.3 Manually Restart the Host MCU + +- Without USB connected, long-press the button for **more than 6 seconds**; the host MCU will be reset (restarted) without entering ISP. + +### 6.4 Production-line Flashing (Factory Test Mode) + +- Within **10ms** after power-on, pull the host MCU reset line low and hold it for **more than 100ms**; +- This chip and the host MCU enter factory ISP mode and remain there until **USB is disconnected**, after which the host MCU is automatically reset back to normal operation mode. + +--- + +## 7. FAQ and Notes + +| Question | Explanation | +| --- | --- | +| No ISP entry after a long press? | Confirm whether USB is connected; without a connection, a long press only restarts the host MCU. | +| Once in ISP, a continuous long press cannot exit? | You must first release the button, then long-press again for 3 seconds (the long press that entered ISP does not re-trigger the exit). | +| How is the long-press time calculated? | Timing starts from when the button is stably recognized as pressed, and is cleared if released midway. | +| Does ISP exit automatically? | Yes. If there is no button operation within 5 minutes after entering ISP, it exits and resets automatically. | +| The timing seems inaccurate? | That is expected, because this chip's internal oscillator is not highly precise and may have errors. | + +--- + +## Appendix + +### Appendix A: Timing Parameter Summary + +| Parameter | Value | Description | +| --- | --- | --- | +| Debounce time | 10ms | Stable determination of button state | +| Non-ISP long-press threshold | 6 seconds | Triggers reset or ISP entry when exceeded | +| ISP long-press exit threshold | 3 seconds | Exits ISP when exceeded | +| ISP idle timeout | 5 minutes | Auto-exit ISP with no button operation | +| Reset pulse width | About 5ms | Low-level time required to reset the host MCU | + +> Note: the times described above are not highly precise. + +### Appendix B: Glossary + +| Term | Meaning | +| --- | --- | +| This chip | The button controller chip, the subject of this manual | +| Host MCU | The target chip managed by this chip, which runs the main application firmware | +| ISP | In-System Programming, used to update the host firmware | +| Long press | A button held down continuously beyond the configured threshold | diff --git a/doc/md/PM5_Controllers/PM5_RGB_Controller_RM.md b/doc/md/PM5_Controllers/PM5_RGB_Controller_RM.md new file mode 100644 index 000000000..1bc9ee22b --- /dev/null +++ b/doc/md/PM5_Controllers/PM5_RGB_Controller_RM.md @@ -0,0 +1,350 @@ +# RGB Controller Technical Manual + +> This document is intended for host-side (Host) development and integration personnel. It describes the I2C communication interface, register model, and business behavior provided by this chip. +> This document describes only the **externally visible interface and business logic**. + +- Author: DXL +- Document version: v1.0 +- Date: 2026-08-25 + +--- + +## 1. Overview + +This chip acts as an **I2C slave** and drives a chain of single-wire, daisy-chained RGB LEDs. The host sends LED color data and configuration commands to the chip over the I2C bus; the chip maintains a color buffer internally and automatically, continuously refreshes the data onto the LED strip. + +Core capabilities: + +| Capability | Description | +|------|------| +| Color setting | Set the RGB888 color value of each LED individually | +| Index management | Supports setting a start index, automatic index increment, and index locking | +| One-command lights off | Turn off all LEDs with a single command | +| Controllable blink | Hardware-timed on/off flashing, freeing the host CPU | +| Firmware version | Reads the firmware major/minor version for compatibility adaptation | + +--- + +## 2. I2C Communication Interface + +### 2.1 Slave Address + +The chip supports selecting the slave address via the level state of an **address-select pin**: + +| Address-select pin state | 7-bit slave address | Remarks | +|----------------|--------------|------| +| High level (tied to VCC) | `0x48` | Currently available | +| Low level (tied to GND) | `0x49` | Currently available | +| Tied to SCL | `0x68` | Reserved, not yet enabled | +| Tied to SDA | `0x69` | Reserved, not yet enabled | + +> Note: the address-select pin performs a level detection with debounce during the **power-on initialization phase**; a high level uses `0x48`, a low level uses `0x49`. +> The two dynamic-detection schemes "tied to SCL / tied to SDA" in the table are currently reserved designs that are not yet enabled in the actual firmware — do not rely on them. + +### 2.2 Register Addressing Method (Register Pointer) + +The chip uses the "register pointer" addressing method: **before every operation, one byte of register address must be written first**. Once the chip remembers this address, subsequent reads and writes target that register. + +- **Write operation**: when writing the data body, byte 1 is the register address, and the subsequent bytes are that register's data. +- **Read operation**: you must **first perform a write operation** (writing only 1 byte of register address) to set the target register, then initiate the read operation. + +> Key point: the register address is **retained across transactions**. The register address set by the previous write operation remains valid in subsequent read transactions until the next write operation writes a new register address. + +### 2.3 Read/Write Operation Timing + +**Write register:** + +``` +START → 7-bit address + W(0) → ACK → [register address] → [data bytes…] → STOP +``` + +**Read register:** + +``` +Step 1 (set pointer): START → 7-bit address + W(0) → ACK → [register address] → STOP +Step 2 (read data) : START → 7-bit address + R(1) → ACK → [data bytes…] → host NACK → STOP +``` + +### 2.4 Recommended Communication Rate + +It is recommended to use a communication clock rate of **around 10K**; an excessively high rate may cause communication failures. + +### 2.5 Abnormal Acknowledge (NACK) Behavior + +The chip replies NACK and terminates the current communication in the following cases: + +| Case | Description | +|------|------| +| Address mismatch | The received 7-bit address differs from the configured slave address | +| Reading an invalid address | A read operation is initiated when no register address has been set (default `0x00`) | +| Reading a write-only register | Reading the lights-off register (`0x04`) | +| Writing a read-only register | Writing the firmware version register (`0xFF`) | +| Writing an invalid address | The register address is `0x00` | +| Index out of range | The written index value ≥ the current valid LED count | + +--- + +## 3. Register Map + +### 3.1 Register Overview Table + +| Address | Name | Access | Data Length | Description | +|------|------|------|----------|------| +| `0x00` | Invalid address | — | — | Power-on default address; not readable or writable | +| `0x01` | Count register | Read / Write | 1 byte | Number of LEDs actually mounted on the hardware | +| `0x02` | Index register | Read / Write | 1 byte | Index of the LED currently being operated on | +| `0x03` | Data register | Read / Write | 3×N bytes | LED color value (RGB888) | +| `0x04` | Lights-off register | Write-only | No data body | Turn off all LEDs | +| `0x05` | Index lock register | Read / Write | 1 byte | Whether to lock the operation index | +| `0x06` | Blink enable register | Read / Write | 1 byte | Whether to enable controllable blink | +| `0x07` | Blink duration register | Read / Write | 2 bytes | On duration + off duration | +| `0xFF` | Firmware version register | Read-only | 2 bytes | Major version + minor version | + +### 3.2 Register Detailed Descriptions + +#### 0x00 — Invalid Address (Reserved) + +Power-on default value. No read operation can be performed at this address; writing this address causes NACK and terminates the communication. + +#### 0x01 — Count Register (Read/Write) + +Indicates the number of LEDs actually mounted on the current hardware. + +- **Write**: writes 1 byte. If multiple bytes are written, the **last byte** takes effect. If the written value exceeds the chip's supported upper limit, it is **clamped** to the upper limit. +- **Read**: returns the current valid LED count. +- **Default**: the chip's supported upper-limit count after power-on. + +#### 0x02 — Index Register (Read/Write) + +Indicates the LED index to be operated on (starting from 0). + +- **Write**: writes 1 byte. If multiple bytes are written, the last byte takes effect. If the written value ≥ the current valid LED count, it is an illegal operation; the chip replies NACK and terminates the communication. +- **Read**: returns the current operation index. +- **Side effect**: writing **triggers blink disable**. +- **Constraint**: the legal index range is `0 ~ (valid count - 1)`. + +#### 0x03 — Data Register (Read/Write) + +LED color data. **Every 3 bytes is the RGB888 color value of one LED**, in the byte order **R, G, B**. + +- **Write**: writes a multiple of 3 bytes consecutively. Each time 3 bytes (one complete LED) are written, the index auto-increments by 1 (unless locked, see `0x05`). +- **Read**: reads consecutively; every 3 bytes returns one LED's R, G, B, and the index auto-increments by 1. +- **Index wraparound**: when the index increments to the valid count, it resets to zero, enabling circular read/write of the buffer. +- **Persistence**: the index does **not** reset to zero after communication ends; the next operation continues from the current index. +- **Side effect**: both read and write **trigger blink disable**. + +> Example: after setting count = 8 and index = 0, writing 24 bytes (8 LEDs) each time covers the entire LED strip. + +#### 0x04 — Lights-off Register (Write-only) + +Turns off all LEDs (all colors set to R0-G0-B0). + +- **Write**: no data body required; writing triggers it. +- **Read**: not supported; reading causes NACK. +- **Deferred effect**: the lights-off action actually executes after the current I2C communication **ends (STOP)**. +- **Side effect**: also disables blink. +- **Note**: after writing, allow about **10ms** to ensure the lights-off completes; if the data or index register is written again during this period, the lights-off may fail (color disorder or some LEDs not properly turned off). + +#### 0x05 — Index Lock Register (Read/Write) + +Controls whether the index auto-increments when writing the data register. + +- **Write**: writing `0` means unlocked (index auto-increments when writing data); writing a non-`0` value means locked (index does not increment when writing data). +- **Read**: returns the current lock state (`0` / `1`). +- **Purpose**: when locked, it is suitable for repeatedly writing data commands to **refresh a single LED** (index unchanged). +- **Note**: locking affects only the index auto-increment of **write** operations; the index of **read** operations still increments. + +#### 0x06 — Blink Enable Register (Read/Write) + +Controls the controllable blink function. + +- **Write**: writing a non-`0` value enables blink (blink applies to the LED selected by the current index); writing `0` disables blink. +- **Read**: returns the current enable state (`0` / `1`). +- **Blink behavior**: once enabled, the selected LED automatically cycles through "on duration → off duration → on duration…". +- **Mutual exclusion**: see Section 4. + +#### 0x07 — Blink Duration Register (Read/Write) + +Sets the on and off durations of the blink. + +- **Write**: byte 1 is the **on duration**, byte 2 is the **off duration**. +- **Read**: returns the on duration and off duration bytes in sequence. +- **Unit**: both are 10ms; a single byte ranges from 0 to 255, i.e., up to 2.55 seconds can be set. +- **Default**: 500ms each for on and off. + +#### 0xFF — Firmware Version Register (Read-only) + +- **Read**: byte 1 is the major version, byte 2 is the minor version. +- **Write**: not supported; writing causes NACK. +- **Purpose**: it is recommended that the host read the firmware version during specific flows, so that when compatibility issues arise they can be adapted and fixed accordingly. + +--- + +## 4. Register Mutual Exclusion Conditions + +Controllable blink (after `0x06` is enabled) is **mutually exclusive** with the following operations; performing these operations **automatically disables blink**: + +| Triggering operation | Register | Disables blink? | +|----------|--------|--------------| +| Write index | `0x02` | ✅ Yes | +| Write data | `0x03` | ✅ Yes | +| Read data | `0x03` | ✅ Yes | +| Write lights-off | `0x04` | ✅ Yes (and turns off all LEDs) | +| Write blink enable (value 0) | `0x06` | ✅ Yes | + +> Design rationale: blink applies to the "LED selected by the current index", while index, data, and lights-off operations all change that LED's state, conflicting with blink. Therefore blink must be disabled first before performing these operations. + +**Other read/write restrictions (mutual exclusion / constraints)**: + +| Restriction | Description | +|------|------| +| `0x04` write-only | Reading causes NACK | +| `0xFF` read-only | Writing causes NACK | +| `0x00` invalid | Both reading and writing cause NACK | +| Index out of range | Writing an index ≥ valid count causes NACK | +| Count clamping | Writing a count above the upper limit is clamped to the upper limit | + +--- + +## 5. Business Flowcharts + +### 5.1 Power-on Initialization Flow + +```mermaid +flowchart TD + A([Power-on reset]) --> B[Controller internal initialization] + B --> C[RGB initialization
clear color buffer
turn off all LEDs by default] + C --> D[Blink timer initialization
default on/off 500ms each] + D --> E[I2C slave initialization] + E --> F{Address-select pin
level detection and debounce} + F -->|High level| G[Slave address = 0x48] + F -->|Low level| H[Slave address = 0x49] + G --> I[Enter main loop] + H --> I +``` + +### 5.2 Main Loop Overall Flow + +```mermaid +flowchart TD + A([Main loop entry]) --> B[Sample I2C bus
detect SCL / SDA transitions] + B --> C{SCL transition?} + C -->|Yes| D[I2C state machine handling] + C -->|No| E{SDA transition?} + E -->|Yes| F[START / STOP signal handling] + E -->|No| G[Cache bus state] + D --> G + F --> G + G --> H{10ms timer reached?} + H -->|Yes| I[Blink timing accumulation +1] + H -->|No| K{I2C communication in progress?} + I --> K + K -->|Yes| A + K -->|No| L{Waiting for strip reset?} + L -->|Yes| A + L -->|No| M[Blink on / off switching decision] + M --> N{Data updated?} + N -->|No| A + N -->|Yes| O[Refresh LED colors] + O --> A +``` + +### 5.3 I2C Communication State Machine + +```mermaid +stateDiagram-v2 + [*] --> IDLE + IDLE --> ADDR: START received + ADDR --> OP: 7-bit address matches + ADDR --> IDLE: address mismatch + OP --> IACK1: parse read/write bit and prepare response + IACK1 --> IACK2: SCL falling edge + IACK2 --> WRITEDATA: write operation + IACK2 --> READDATA: read operation + WRITEDATA --> WACK1: 8 bits received + WACK1 --> WACK2: SCL falling edge + WACK2 --> WRITEDATA: continue receiving + READDATA --> RACK: 8 bits sent + RACK --> READDATA: host ACK received + RACK --> IDLE: host NACK received + WRITEDATA --> IDLE: STOP received + READDATA --> IDLE: STOP received +``` + +### 5.4 Write Operation Data Flow + +```mermaid +flowchart TD + A([Host write operation]) --> B[START + address + write bit] + B --> C[Slave replies ACK] + C --> D[Receive byte 1 = register address] + D --> E{Address valid?} + E -->|Invalid 0x00| F[Reply NACK to terminate] + E -->|Valid| G[Save register address] + G --> H[Receive subsequent data bytes] + H --> I[Write by register type
count / index / data / lock / blink …] + I --> J[STOP] + J --> K[Execute deferred actions
lights off / disable blink] + K --> L([Done]) +``` + +### 5.5 Read Operation Data Flow + +```mermaid +flowchart TD + A([Read operation preamble]) --> B[First write 1 byte to set register address] + B --> C[START + address + read bit] + C --> D{Register readable?} + D -->|0x00 or 0x04| E[Reply NACK to terminate] + D -->|Readable| F[Slave ACK] + F --> G[Return data per current register
multi-byte registers auto-advance] + G --> H{Host continues reading?} + H -->|ACK| G + H -->|NACK + STOP| I([End]) +``` + +### 5.6 Blink On/Off Logic + +```mermaid +flowchart TD + A[Blink enabled
refreshed to target LED] --> B{Currently in on phase?} + B -->|Yes| C{On duration reached?} + C -->|Yes| D[Switch to off
set color to 0
restart timing] + C -->|No| E[Keep waiting] + B -->|No| F{Off duration reached?} + F -->|Yes| G[Switch to on
take color from buffer
restart timing] + F -->|No| H[Keep waiting] + D --> A + G --> A +``` + +--- + +## 6. Key Business Feature Summary + +1. **Deferred effect of changes**: actions such as lights-off and blink-disable are not executed immediately when the command arrives; instead they are processed uniformly **after the I2C communication ends (STOP)**, avoiding refresh operations interfering with bus communication stability. + +2. **Index management**: + - When writing data, the index auto-increments after every 3 bytes (lockable). + - When reading data, the index always auto-increments. + - The index wraps around to 0 after reaching the valid count. + - The index is retained across transactions and does not reset when communication ends. + +3. **Data refresh mechanism**: when data changes, a refresh-enable flag is set, and the main loop refreshes all LEDs once in a **full pass**; when there is no change, it refreshes only once, avoiding unnecessary refresh overhead. + +4. **Blink frees the host**: blink is driven by the chip's internal timer; the host only needs to set the on/off durations and enable it, without continuously sending commands, thereby freeing the host CPU. + +5. **Safety protection**: + - Out-of-range protection: a count above the upper limit is automatically clamped; an out-of-range index returns NACK. + - Communication priority: while I2C communication is in progress, LED refresh is skipped, reducing the probability of communication failure. + +--- + +## 7. Usage Notes + +1. It is recommended that the host first read the firmware version register (`0xFF`) after power-on, to adapt when compatibility issues arise. +2. After executing lights-off (`0x04`), allow about 10ms; do not write the data/index register during this period. +3. After setting the count (`0x01`), the legal range of the index (`0x02`) changes accordingly; be careful to avoid out-of-range writes. +4. Before using the blink function, confirm that the current index points to the target LED; index/data/lights-off operations disable blink. +5. It is recommended to keep the communication rate at around 10K; an excessively high rate may cause communication failures. +6. The current slave address supports only two static selections, `0x48` (high level) and `0x49` (low level); `0x68`/`0x69` are reserved.