# LILYGO / TTGO T-Display (Classic ESP32)

## Platform-independent hardware reference for firmware agents

> **Target:** the original/classic LILYGO / TTGO T-Display with the original ESP32 and a 1.14-inch ST7789V display.
>
> **Not covered:** T-Display-S3 and other later T-Display variants.
>
> **Purpose:** provide enough board-specific information for a firmware agent to configure, validate, and allocate hardware resources without depending on Arduino, PlatformIO, ESP-IDF, or any particular library API.

---

## 1. Scope and interpretation

This document describes hardware facts, electrical constraints, fixed onboard connections, peripheral capabilities, and safe allocation policies.

It intentionally does not prescribe:

- a specific IDE, build system, framework, or language;
- framework-specific API calls;
- a particular display or peripheral library;
- toolchain-specific board identifiers;
- dependency versions or project directory structure.

Those choices belong to the firmware project. The hardware constraints in this document apply regardless of the selected software environment.

### 1.1 Requirement words

- **MUST / MUST NOT**: required to avoid an electrical conflict, boot failure, or unsupported configuration.
- **SHOULD / SHOULD NOT**: safe default; deviation is allowed when the consequences are understood.
- **MAY**: optional capability.

### 1.2 Pin-allocation classes

| Class | Meaning |
|---|---|
| **Board-connected** | Physically connected to onboard hardware. Do not repurpose without intentionally accepting the conflict. A shared bus may still be possible where explicitly stated. |
| **SoC-reserved** | Required by the ESP32 itself, normally for flash or boot/programming. Not available to application wiring. |
| **Soft default** | Recommended convention, not a fixed electrical connection. It may be remapped if the project requires it. |
| **Available with caveat** | Exposed and usable, but affected by boot strapping, JTAG, ADC, input-only, or another limitation. |
| **Available** | Exposed and suitable for general use, subject to normal ESP32 electrical limits. |
| **Revision-dependent** | Varies between board production versions or cannot be determined from the common board identity alone. |

---

## 2. Board identity

The target is commonly named:

- `LILYGO T-Display`;
- `TTGO T-Display`;
- `T-Display V1.x`;
- `TTGO T-Display V1.1` in some listings.

The defining properties of this profile are:

| Property | Value |
|---|---|
| SoC | **ESP32-D0WDQ6**, original ESP32 family |
| CPU | Dual-core 32-bit Xtensa LX6, up to 240 MHz |
| On-chip SRAM | 520 KB |
| PSRAM | **None** |
| External flash | 4 MB is the common/reference configuration; 16 MB variants exist |
| Wi-Fi | 2.4 GHz 802.11 b/g/n |
| Bluetooth | Bluetooth 4.2 BR/EDR and BLE |
| Display | 1.14-inch IPS, ST7789V |
| Display resolution | 135 x 240 native portrait; commonly used as 240 x 135 landscape |
| Display interface | 4-wire SPI |
| USB connector | USB-C |
| Host connection | USB-to-UART bridge, revision-dependent |
| Buttons | Two onboard programmable buttons |
| Battery | 1-cell Li-Po support with onboard charging |

The board uses the original ESP32, not ESP32-S3. Firmware MUST NOT use T-Display-S3 pin definitions, USB assumptions, display configuration, memory configuration, or board profiles.

### 2.1 Identification confidence and limits

The display, header layout, and GPIO mapping in this document describe the established classic T-Display profile. The following cannot be inferred solely from the family name:

- exact PCB production sub-revision;
- exact flash capacity;
- exact USB-to-UART bridge model;
- whether a unit is an original board or a pin-compatible clone.

Where those differences matter, firmware or deployment tooling must verify the physical unit.

---

## 3. One-screen hardware contract

```text
BOARD:     Classic LILYGO / TTGO T-Display
MCU:       Original ESP32 / ESP32-D0WDQ6
PSRAM:     None
FLASH:     Treat as 4 MB until a larger device is verified
DISPLAY:   ST7789V, 135x240 native, 4-wire SPI

DISPLAY CONNECTIONS:
  MOSI  GPIO19
  SCLK  GPIO18
  CS    GPIO5
  DC    GPIO16
  RESET GPIO23
  BL    GPIO4

BUTTONS:
  GPIO0   onboard button and boot-strapping input
  GPIO35  onboard button, input-only

BATTERY MEASUREMENT:
  ADC     GPIO34, input-only
  ENABLE  GPIO14, active high in the manufacturer reference design

SOFT DEFAULT I2C:
  SDA GPIO21
  SCL GPIO22

MANUFACTURER-TESTED OPTIONAL EXTERNAL SPI MAPPING:
  SCK  GPIO25
  MOSI GPIO26
  MISO GPIO27
  CS   GPIO33

EXPOSED, FLEXIBLE GPIO:
  17, 21, 22, 25, 26, 27, 32, 33

EXPOSED INPUT-ONLY GPIO:
  36, 37, 38, 39

INPUT-ONLY ON THE ESP32:
  34, 35, 36, 37, 38, 39

NO SOFTWARE-CONTROLLED INTERNAL PULL RESISTORS:
  34, 35, 36, 37, 38, 39

BOOT-STRAPPING GPIO:
  0, 2, 5, 12, 15

JTAG GPIO:
  12, 13, 14, 15

GPIO LOGIC: 3.3 V only
```

---

## 4. Electrical and power rules

### 4.1 GPIO voltage

ESP32 GPIO uses a **3.3 V logic domain**. GPIO is not 5 V tolerant.

- A signal driven into an ESP32 GPIO MUST remain within the ESP32 electrical limits.
- A 5 V peripheral output MUST NOT be connected directly to a GPIO.
- Use a suitable level shifter, divider, buffer, or a native 3.3 V peripheral as appropriate.
- I2C pull-up resistors MUST NOT pull the bus above 3.3 V.

The header marked `5V` is a power rail, not a GPIO and not evidence of 5 V-tolerant logic.

### 4.2 Power rails

| Marking | Function |
|---|---|
| `G` / `GND` | Ground |
| `3V` / `3V3` | Regulated 3.3 V rail |
| `5V` | 5 V power rail |

USB-C or the intended battery connector is the normal power path. Multiple supplies SHOULD NOT be back-fed into the board unless the exact revision's power-path design has been checked.

### 4.3 GPIO load limits

GPIO is a logic signal, not a power output. A GPIO MUST NOT directly drive motors, relay coils, solenoids, LED strips, high-current LEDs, or similar loads.

Use an appropriate transistor, MOSFET, driver IC, current-limiting components, and flyback protection for inductive loads.

---

## 5. Canonical GPIO capability and allocation matrix

This table is the primary pin-allocation reference. Later sections explain the relevant peripherals without redefining the allocation status.

| GPIO | Header | Direction | Analog / special | Pulls | Boot/debug role | Board connection or convention | Allocation status |
|---:|---|---|---|---|---|---|---|
| 0 | No normal header | I/O | ADC2_CH1, Touch1 | Internal pulls available | **Strapping** | Onboard BOOT/button | **Board-connected** |
| 1 | No normal header | Output-capable | UART0 TX | Internal pulls available | Programming/logging UART | USB-UART bridge | **Board-connected** |
| 2 | Yes | I/O | ADC2_CH2, Touch2 | Internal pulls available | **Strapping** | None | **Available with caveat** |
| 3 | No normal header | Input-capable | UART0 RX | Internal pulls available | Programming UART | USB-UART bridge | **Board-connected** |
| 4 | No | I/O | ADC2_CH0, Touch0 | Internal pulls available | — | TFT backlight | **Board-connected** |
| 5 | No | I/O | — | Internal pulls available | **Strapping** | TFT chip select | **Board-connected** |
| 6-11 | No | Not for application use | External QSPI flash signals | — | SoC memory bus | External flash | **SoC-reserved** |
| 12 | Yes | I/O | ADC2_CH5, Touch5 | Internal pulls available | **Strapping, JTAG MTDI** | None | **Available with strong caveat** |
| 13 | Yes | I/O | ADC2_CH4, Touch4 | Internal pulls available | JTAG MTCK | None | **Available with caveat** |
| 14 | No intended header use | I/O | ADC2_CH6, Touch6 | Internal pulls available | JTAG MTMS | Battery ADC enable | **Board-connected** |
| 15 | Yes | I/O | ADC2_CH3, Touch3 | Internal pulls available | **Strapping, JTAG MTDO** | None | **Available with caveat** |
| 16 | No | I/O | — | Internal pulls available | — | TFT data/command | **Board-connected** |
| 17 | Yes | I/O | — | Internal pulls available | — | None | **Available** |
| 18 | No | I/O | — | Internal pulls available | — | TFT SPI clock | **Board-connected** |
| 19 | No | I/O | — | Internal pulls available | — | TFT SPI MOSI | **Board-connected** |
| 21 | Yes | I/O | — | Internal pulls available | — | Default I2C SDA | **Soft default** |
| 22 | Yes | I/O | — | Internal pulls available | — | Default I2C SCL | **Soft default** |
| 23 | No | I/O | — | Internal pulls available | — | TFT reset | **Board-connected** |
| 25 | Yes | I/O | ADC2_CH8, DAC1 | Internal pulls available | — | Suggested external SPI SCK | **Available / soft default** |
| 26 | Yes | I/O | ADC2_CH9, DAC2 | Internal pulls available | — | Suggested external SPI MOSI | **Available / soft default** |
| 27 | Yes | I/O | ADC2_CH7, Touch7 | Internal pulls available | — | Suggested external SPI MISO | **Available / soft default** |
| 32 | Yes | I/O | ADC1_CH4, Touch9 | Internal pulls available | RTC-capable | None | **Available** |
| 33 | Yes | I/O | ADC1_CH5, Touch8 | Internal pulls available | RTC-capable | Suggested external SPI CS | **Available / soft default** |
| 34 | No | **Input only** | ADC1_CH6 | **No internal pulls** | RTC-capable | Battery voltage sense | **Board-connected** |
| 35 | No | **Input only** | ADC1_CH7 | **No internal pulls** | RTC-capable | Onboard button | **Board-connected** |
| 36 / SVP | Yes | **Input only** | ADC1_CH0 | **No internal pulls** | RTC-capable; special interrupt caveat | None | **Available as input only** |
| 37 | Yes | **Input only** | ADC1_CH1 | **No internal pulls** | RTC-capable | None | **Available as input only** |
| 38 | Yes | **Input only** | ADC1_CH2 | **No internal pulls** | RTC-capable | None | **Available as input only** |
| 39 / SVN | Yes | **Input only** | ADC1_CH3 | **No internal pulls** | RTC-capable; special interrupt caveat | None | **Available as input only** |

### 5.1 Interpretation rules

- A board-connected pin is not a general-purpose free pin even if the ESP32 peripheral matrix technically supports another function on it.
- GPIO18 and GPIO19 MAY participate in a deliberately shared SPI bus, but the display remains physically connected and all devices require correct chip-select and transaction management.
- Soft-default pins are not electrically fixed. They can be remapped if the project maintains a conflict-free allocation.
- GPIO36-39 can never provide ordinary digital output, PWM, UART TX, SPI clock, SPI MOSI, or chip select.
- External circuits on GPIO34-39 require external bias resistors whenever a defined idle state is needed.

---

## 6. Exposed header pinout

### 6.1 Orientation

The physical order below assumes:

- display facing the observer;
- USB-C connector at the bottom.

### 6.2 Left header, top to bottom

| Label | Function | Key note |
|---|---|---|
| G | Ground | Power return |
| G | Ground | Power return |
| 21 | GPIO21 | Flexible I/O; default I2C SDA |
| 22 | GPIO22 | Flexible I/O; default I2C SCL |
| 17 | GPIO17 | Flexible general I/O |
| 2 | GPIO2 | Strapping, ADC2, touch |
| 15 | GPIO15 | Strapping, JTAG, ADC2, touch |
| 13 | GPIO13 | JTAG, ADC2, touch |
| 12 | GPIO12 | Strapping, JTAG, ADC2, touch; use conservatively |
| G | Ground | Power return |
| G | Ground | Power return |
| 3V | 3.3 V rail | Power, not GPIO |

### 6.3 Right header, top to bottom

| Label | Function | Key note |
|---|---|---|
| 3V | 3.3 V rail | Power, not GPIO |
| 36 / SVP | GPIO36 / SENSOR_VP | Input only, ADC1, no internal pulls |
| 37 | GPIO37 / SENSOR_CAPP | Input only, ADC1, no internal pulls |
| 38 | GPIO38 / SENSOR_CAPN | Input only, ADC1, no internal pulls |
| 39 / SVN | GPIO39 / SENSOR_VN | Input only, ADC1, no internal pulls |
| 32 | GPIO32 | Flexible I/O, ADC1, touch |
| 33 | GPIO33 | Flexible I/O, ADC1, touch |
| 25 | GPIO25 | Flexible I/O, ADC2, DAC1 |
| 26 | GPIO26 | Flexible I/O, ADC2, DAC2 |
| 27 | GPIO27 | Flexible I/O, ADC2, touch |
| G | Ground | Power return |
| 5V | 5 V rail | Power, never GPIO |

### 6.4 SVP and SVN

`SVP` and `SVN` are analog-capable ESP32 input names, not supply rails:

- SVP / SENSOR_VP = GPIO36 = ADC1_CH0;
- SVN / SENSOR_VN = GPIO39 = ADC1_CH3.

GPIO37 and GPIO38 are also named SENSOR_CAPP and SENSOR_CAPN by the original ESP32. Application firmware SHOULD normally refer to these pins by GPIO number unless a low-level analog function specifically requires the signal name.

---

## 7. Onboard hardware

### 7.1 ST7789V display

| Signal | GPIO | Status |
|---|---:|---|
| MOSI | 19 | Board-connected |
| SCLK | 18 | Board-connected |
| CS | 5 | Board-connected; GPIO5 is also a strapping pin |
| DC | 16 | Board-connected |
| RESET | 23 | Board-connected |
| Backlight | 4 | Board-connected |
| MISO | Not dedicated | Normally unnecessary for display writes |

Display characteristics:

- controller: ST7789V;
- native pixel matrix: 135 x 240;
- common landscape coordinate system: 240 x 135;
- interface: 4-wire SPI;
- a 40 MHz SPI write clock is used by the established TFT_eSPI classic T-Display profile.

Rotation, offsets, color order, inversion, and initialization sequence must match the selected ST7789V implementation. A known classic T-Display software profile SHOULD be used as the reference when a framework does not already provide a board definition.

The display backlight is controlled by GPIO4. Reference classic T-Display software treats the backlight-enable level as active high. A clone or unknown revision SHOULD be validated before relying on polarity outside a known board profile.

#### Sharing the display SPI signals

SPI clock and MOSI are electrically shareable in principle. Sharing GPIO18/GPIO19 is safe only if:

- every external device has an independent chip-select;
- inactive devices release the bus as required;
- the software uses correct per-device transaction settings;
- GPIO5, GPIO16, GPIO23, and GPIO4 remain under intentional display control;
- display operation is tested across initialization, reset, and sleep transitions.

The conservative default is to leave all display signals dedicated and use the optional external SPI mapping in section 12.2.

### 7.2 Onboard buttons

| Button signal | GPIO | Constraints |
|---|---:|---|
| BOOT/button | 0 | Strapping pin; participates in download-mode entry |
| Second button | 35 | Input-only; no software-controlled internal pull resistor |

Manufacturer materials have used inconsistent human-readable numbering for Button 1 and Button 2. Firmware, requirements, and tests MUST identify buttons by GPIO number rather than by the labels “Button 1” and “Button 2”.

The manufacturer factory reference treats the button signals as active-low and uses GPIO35 as a low-level deep-sleep wake source. The onboard circuit provides the required biasing; this does not imply that a separate external circuit on GPIO35 can use an internal pull-up.

Manual bootloader entry uses the GPIO0 button:

1. hold GPIO0/BOOT low;
2. reset the ESP32;
3. release GPIO0;
4. start or retry the firmware upload.

Exact reset-button placement and host-tool behavior may vary, but the GPIO0 strapping principle is platform-independent.

### 7.3 Battery support and voltage measurement

The board supports a 1-cell Li-Po battery through a 1.25 mm two-pin connector and includes onboard charging circuitry.

| Function | GPIO | Property |
|---|---:|---|
| Battery voltage ADC | 34 | ADC1_CH6, input-only, board-connected |
| Battery-sense enable | 14 | Output-capable, board-connected, active high in manufacturer reference |

Platform-independent measurement sequence:

```text
1. Configure GPIO14 as a digital output.
2. Drive GPIO14 to the battery-sense enabled state (HIGH in the reference design).
3. Allow the measurement network to settle as required by the implementation.
4. Sample ADC1_CH6 on GPIO34.
5. Convert the raw ADC result using the framework's calibrated ADC facilities.
6. Apply the board divider ratio; the historical factory design uses approximately x2.
7. If low-power operation requires it, return the enable circuit to the intended idle state.
```

ADC reference voltage and transfer characteristics are not ideal constants. Production firmware SHOULD use the calibration method supported by the selected ESP32 framework and SHOULD validate the divider ratio for the actual board revision when voltage accuracy matters.

GPIO34 and GPIO14 SHOULD remain reserved even if battery measurement is not immediately used. Repurposing either pin requires an intentional decision based on the schematic and physical revision.

### 7.4 USB-to-UART bridge

The exact bridge is revision-dependent:

- current product material describes a CH9102-family device;
- historical material and older boards also reference CP210x-family devices.

Firmware normally communicates with the original ESP32 ROM bootloader and UART0 and SHOULD NOT depend on the bridge model. Host driver troubleshooting must use the USB VID/PID or actual chip marking rather than assuming one bridge for every classic T-Display.

GPIO1 and GPIO3 are normally associated with UART0 and the onboard bridge. They SHOULD remain available for upload, bootloader communication, and logging unless the project deliberately changes that behavior.

---

## 8. Digital GPIO and boot constraints

### 8.1 Input-only pins

The original ESP32 GPIO34-39 are input-only. On this board:

- GPIO34 is used for battery sensing;
- GPIO35 is used by an onboard button;
- GPIO36-39 are exposed on the header.

GPIO34-39 MUST NOT be used for:

- digital output;
- PWM;
- UART TX;
- SPI SCK, MOSI, or CS;
- ordinary bidirectional I2C;
- LED, relay-driver, or enable outputs;
- any function that requires the GPIO output driver.

They MAY be used for analog input, digital input, routed peripheral input, and supported RTC-domain input functions.

### 8.2 Internal pull resistors

GPIO34-39 do not provide software-controlled internal pull-up or pull-down resistors. External circuits using these GPIOs MUST include suitable biasing whenever the signal source does not always drive a defined level.

An onboard circuit may already bias its own connected pin. That bias belongs to the board circuit and does not change the SoC capability.

### 8.3 Strapping pins

The original ESP32 samples these pins during reset:

- GPIO0;
- GPIO2;
- GPIO5;
- GPIO12 / MTDI;
- GPIO15 / MTDO.

On this board:

- GPIO0 is the onboard BOOT/button signal;
- GPIO5 is TFT chip select;
- GPIO2, GPIO12, and GPIO15 are exposed.

External hardware MUST NOT force an incompatible level on a strapping pin while the ESP32 resets or powers up. After boot, the exposed pins may be used according to their normal capabilities, but connected peripherals and pull resistors must preserve a valid reset state.

GPIO12 deserves especially conservative treatment because its reset level participates in flash-voltage-related boot configuration on the original ESP32.

### 8.4 External QSPI flash pins

GPIO6-11 are used by the ESP32 external flash interface in the standard configuration. They are not application GPIO on this board and MUST NOT be reassigned.

---

## 9. ADC

### 9.1 ADC1 and ADC2

The original ESP32 provides ADC1 and ADC2 resources. ADC channel capability does not guarantee that a pin is electrically free on the board.

#### Exposed ADC1 inputs

| GPIO | Channel | Digital output capability | Notes |
|---:|---|---|---|
| 36 | ADC1_CH0 | No | Input-only; no internal pulls |
| 37 | ADC1_CH1 | No | Input-only; no internal pulls |
| 38 | ADC1_CH2 | No | Input-only; no internal pulls |
| 39 | ADC1_CH3 | No | Input-only; no internal pulls |
| 32 | ADC1_CH4 | Yes | Flexible I/O |
| 33 | ADC1_CH5 | Yes | Flexible I/O |

#### Board-connected ADC1 inputs

| GPIO | Channel | Board use |
|---:|---|---|
| 34 | ADC1_CH6 | Battery voltage |
| 35 | ADC1_CH7 | Onboard button circuit |

#### Exposed ADC2 inputs

| GPIO | Channel | Additional caveat |
|---:|---|---|
| 2 | ADC2_CH2 | Strapping |
| 12 | ADC2_CH5 | Strapping and JTAG |
| 13 | ADC2_CH4 | JTAG |
| 15 | ADC2_CH3 | Strapping and JTAG |
| 25 | ADC2_CH8 | Also DAC1 |
| 26 | ADC2_CH9 | Also DAC2 |
| 27 | ADC2_CH7 | Also touch |

### 9.2 Wi-Fi limitation

On the original ESP32, ADC2 resources conflict with Wi-Fi operation. Firmware MUST NOT rely on ADC2 sampling while Wi-Fi is active unless the selected framework and operating mode explicitly guarantee the required behavior.

For analog sensing in Wi-Fi applications, ADC1 is the safe default:

- GPIO32 or GPIO33 when a flexible I/O pin is desired;
- GPIO36-39 when input-only operation and external biasing are acceptable.

### 9.3 Accuracy and input range

ADC conversion depends on attenuation, calibration data, source impedance, noise, and the selected software driver. Firmware MUST NOT assume that raw ADC counts map linearly to an exact 0-3.3 V range without calibration.

The signal at the GPIO MUST remain inside the ESP32 electrical limits even when an attenuation setting permits measurement of a wider nominal ADC range.

---

## 10. DAC

The original ESP32 provides two true DAC outputs:

| GPIO | DAC channel | Other capability |
|---:|---|---|
| 25 | DAC1 | Digital I/O, ADC2_CH8 |
| 26 | DAC2 | Digital I/O, ADC2_CH9 |

Both pins are exposed. DAC availability and resolution must be accessed through the selected framework's original-ESP32 DAC support.

The DAC outputs are signal sources, not high-current power outputs. Their use also consumes pins that form part of the recommended optional external SPI mapping.

---

## 11. Capacitive touch

Exposed touch-capable pins:

| GPIO | Touch channel | Caveat |
|---:|---|---|
| 2 | Touch2 | Strapping |
| 15 | Touch3 | Strapping and JTAG |
| 13 | Touch4 | JTAG |
| 12 | Touch5 | Strapping and JTAG |
| 27 | Touch7 | Optional external SPI MISO convention |
| 33 | Touch8 | Optional external SPI CS convention |
| 32 | Touch9 | None beyond project allocation |

Touch-capable pins consumed by onboard hardware:

| GPIO | Touch channel | Board use |
|---:|---|---|
| 0 | Touch1 | BOOT/button |
| 4 | Touch0 | TFT backlight |
| 14 | Touch6 | Battery-sense enable |

Touch sensing is sensitive to board layout, electrode geometry, grounding, noise, and framework calibration. A touch capability in the SoC does not make a board-connected pin available for an external electrode.

---

## 12. Communication peripherals

The original ESP32 GPIO matrix allows many peripheral signals to be routed to different GPIOs. A suggested mapping in this section is a default allocation policy, not a fixed board connection.

### 12.1 I2C

Soft-default mapping:

| Signal | GPIO | Status |
|---|---:|---|
| SDA | 21 | Soft default |
| SCL | 22 | Soft default |

GPIO21/22 are output-capable, exposed, and identified by LILYGO as the default pair. They SHOULD be the first choice unless the project has already allocated them.

I2C may be remapped. The chosen pins must be output-capable, and bus pull-ups must terminate at 3.3 V. GPIO36-39 cannot implement ordinary bidirectional I2C because they lack output drivers.

### 12.2 SPI

The onboard display uses GPIO18/19 plus control signals described in section 7.1.

The manufacturer factory test demonstrates this independent optional mapping for an SD card:

| Signal | GPIO | Status |
|---|---:|---|
| SCK | 25 | Soft default |
| MOSI | 26 | Soft default |
| MISO | 27 | Soft default |
| CS | 33 | Soft default |

This mapping is the recommended starting point for an external SPI device when the display must remain undisturbed. It is not hard-wired and may be changed.

Every SPI device requires compatible voltage levels, a controlled chip-select, and transaction settings appropriate to that device. An SD card may be a 3.3 V device while an SD breakout module still contains incompatible level shifting or pull-up circuitry; the module design must be checked.

### 12.3 UART

UART0 is normally used by the onboard USB-UART bridge through GPIO1/GPIO3 for programming and diagnostics.

External UART devices SHOULD use another hardware UART routed through the GPIO matrix. Pin selection rules:

- TX must use an output-capable free GPIO;
- RX may use an input-only GPIO if no output behavior is required;
- display, battery, BOOT, and flash pins must remain protected;
- exposed strapping pins should be avoided unless reset behavior has been analyzed;
- external voltage levels must be compatible with 3.3 V GPIO.

A possible conflict-free starting pair is TX GPIO17 and RX GPIO32. This is an allocation example, not a board-defined UART connector.

### 12.4 PWM

ESP32 LEDC/PWM output can be routed to normal output-capable GPIOs.

Suitable exposed candidates include:

- GPIO17;
- GPIO21 and GPIO22 when I2C is not allocated;
- GPIO25, GPIO26, GPIO27, and GPIO33 when the optional SPI mapping is not allocated;
- GPIO32.

GPIO36-39 MUST NOT be used for PWM. GPIO4 MAY be driven with PWM only when intentionally controlling the onboard display backlight.

---

## 13. JTAG and debugging

The original ESP32's traditional JTAG mapping overlaps:

| JTAG signal | GPIO | Board/project caveat |
|---|---:|---|
| MTDI | 12 | Exposed strapping pin |
| MTCK | 13 | Exposed |
| MTMS | 14 | Battery-sense enable circuit |
| MTDO | 15 | Exposed strapping pin |

Hardware JTAG therefore conflicts with normal board functions more than it would on a bare ESP32. Before enabling JTAG, the project must account for:

- the GPIO14 battery circuit;
- boot-safe levels on GPIO12 and GPIO15;
- any external devices already wired to GPIO12/13/15;
- the debugging adapter voltage and drive behavior;
- the exact board revision and schematic.

The presence of JTAG capability in the SoC does not mean the standard JTAG pin group is free on this board.

---

## 14. Deep sleep, RTC GPIO, and wake-up

Several ADC-capable pins belong to the RTC domain and can participate in supported low-power and wake-up modes. Exact wake-source combinations and APIs depend on the selected framework and ESP32 silicon rules.

The LILYGO factory test demonstrates GPIO35 as a low-level wake source. This is useful because GPIO35 is connected to an onboard button and is input-only.

Low-power firmware must consider:

- the active level and board bias of the selected wake pin;
- which GPIO states are retained during sleep;
- the display controller state;
- TFT backlight state on GPIO4;
- battery measurement enable state on GPIO14;
- external peripheral leakage and pull resistors;
- wake-source limitations of the selected sleep mode.

Original ESP32 documentation describes special restrictions affecting GPIO36 and GPIO39 interrupt behavior when ADC, Wi-Fi/Bluetooth, and certain sleep-related conditions interact. Sleep-heavy firmware SHOULD consult the applicable ESP32 silicon errata and framework documentation before treating GPIO36 or GPIO39 as unrestricted interrupt/wake inputs.

---

## 15. Platform-independent pin-selection policy

### 15.1 Allocation order

A firmware agent SHOULD allocate pins in this order:

1. Preserve SoC-reserved flash pins.
2. Preserve board-connected display, button, battery, and USB-UART pins.
3. Record all peripherals already allocated by the project.
4. Apply direction, voltage, ADC, wake, and timing requirements.
5. Prefer unrestricted GPIO before strapping or JTAG pins.
6. Treat I2C and optional external SPI mappings as soft defaults.
7. Validate the complete reset, boot, active, and sleep states of every shared or caveated pin.

### 15.2 General digital I/O

Preferred exposed flexible GPIO:

```text
GPIO17, GPIO21, GPIO22, GPIO25, GPIO26, GPIO27, GPIO32, GPIO33
```

GPIO21/22 SHOULD remain available if I2C is expected. GPIO25/26/27/33 SHOULD remain available as a group if an external SPI bus is expected.

### 15.3 Boot-sensitive alternatives

These exposed output-capable pins are usable only after reset behavior has been considered:

```text
GPIO2, GPIO12, GPIO15
```

GPIO13 is generally usable when JTAG is not required but still belongs to the traditional JTAG set.

### 15.4 Analog input with Wi-Fi

Prefer ADC1:

```text
GPIO32, GPIO33, GPIO36, GPIO37, GPIO38, GPIO39
```

Use GPIO36-39 only when input-only behavior and external biasing are acceptable.

### 15.5 Push-button input

For an external button, prefer a free GPIO that supports an internal pull resistor, such as GPIO17, GPIO25, GPIO26, GPIO27, GPIO32, or GPIO33, subject to current project allocation.

If GPIO36-39 is used, an external pull resistor is mandatory.

### 15.6 True analog output

Use GPIO25/DAC1 or GPIO26/DAC2. Confirm that neither is already allocated to external SPI or another device.

---

## 16. External wiring patterns

These are electrical mappings, not framework-specific code examples.

### 16.1 3.3 V I2C peripheral

```text
Peripheral VCC -> 3V3
Peripheral GND -> GND
Peripheral SDA -> GPIO21 by default
Peripheral SCL -> GPIO22 by default
```

Verify that module pull-ups connect to 3.3 V.

### 16.2 Optional independent SPI peripheral

```text
Peripheral VCC  -> compatible 3.3 V supply
Peripheral GND  -> GND
Peripheral SCK  -> GPIO25 by default
Peripheral MOSI -> GPIO26 by default
Peripheral MISO -> GPIO27 by default
Peripheral CS   -> GPIO33 by default
```

### 16.3 Analog sensor used with Wi-Fi

Prefer GPIO32 or GPIO33 for a flexible ADC1 input, or GPIO36-39 when input-only behavior is suitable. The sensor output must remain inside the GPIO electrical limits.

### 16.4 External power load

```text
GPIO -> driver input
driver -> load
external/load supply -> load power
common reference/ground -> as required by the circuit
flyback protection -> across inductive load where required
```

The GPIO must not supply load current directly.

---

## 17. Toolchain-independent firmware requirements

Regardless of IDE or framework, a project for this board SHOULD satisfy the following:

1. Target the original ESP32 architecture, not ESP32-S3.
2. Do not require PSRAM.
3. Use a 4 MB-compatible flash and partition layout until the installed flash is verified.
4. Configure the display as an ST7789V with the classic T-Display pin map.
5. Preserve board-connected and SoC-reserved pins.
6. Keep all pin definitions in one project board-profile module rather than scattering raw GPIO numbers.
7. Select ADC calibration, sleep, SPI, I2C, UART, and GPIO APIs appropriate to the chosen framework and version.
8. Treat framework board names, upload speeds, serial-port names, package versions, and library APIs as project configuration, not hardware facts.

### 17.1 Flash configuration

The safe baseline is:

- 4 MB flash-compatible layout;
- no PSRAM;
- original ESP32 target;
- QIO is used by the established reference configuration.

A 16 MB partition layout MUST NOT be selected only because a 16 MB model exists. Determine actual flash capacity using deployment tooling, flash-chip identification, runtime inspection, board markings, or another reliable method.

### 17.2 Display software

Known software sources confirming the classic pin map include:

- LILYGO's display library and examples;
- LILYGO's classic T-Display repository;
- TFT_eSPI `Setup25_TTGO_T_Display.h`.

These sources validate hardware configuration. They are not mandatory dependencies. A project may use any implementation that correctly initializes the ST7789V and observes the electrical and timing constraints.

---

## 18. Revision-dependent properties

| Property | Safe handling |
|---|---|
| Flash capacity | Assume 4 MB compatibility; verify before using a larger layout |
| USB-UART bridge | Detect actual USB device/chip when host drivers matter |
| Exact PCB revision | Use the classic pin profile but check the schematic before repurposing board-connected signals |
| Clone behavior | Validate power path, backlight polarity, battery circuit, and flash capacity |

Secondary component variation does not change the requirement to target the classic original-ESP32 T-Display pinout rather than the T-Display-S3 pinout.

---

## 19. Common failure modes

| Failure | Cause | Prevention |
|---|---|---|
| GPIO36-39 selected as output | These pins are input-only | Validate direction against the canonical matrix |
| Floating external input on GPIO34-39 | No internal pull resistors | Add an external pull-up or pull-down |
| Board stops booting after peripheral wiring | External circuit drives a strapping pin during reset | Avoid or boot-analyze GPIO0/2/5/12/15 |
| Analog reading fails when Wi-Fi starts | Sensor uses ADC2 | Use an available ADC1 pin |
| Display stops working | Display pin reused or SPI transactions conflict | Preserve display signals or implement deliberate sharing |
| Incorrect battery voltage | Sense enable, divider, attenuation, or calibration omitted | Follow the measurement sequence and calibrate |
| Upload or logging becomes unreliable | UART0 pins or bridge behavior changed | Preserve GPIO1/GPIO3 unless deliberate |
| Firmware image does not fit or boot | Unverified flash/partition assumption | Use 4 MB-compatible baseline and verify capacity |
| Wrong screen pins or USB behavior | T-Display-S3 profile selected | Target the classic original-ESP32 model |
| Button identity reversed | Human-readable numbering differs across examples | Refer to GPIO0 and GPIO35 |
| Peripheral damages or destabilizes GPIO | 5 V logic or excessive load | Use 3.3 V signaling and proper drivers |
| JTAG interferes with battery or boot | Traditional JTAG overlaps GPIO12-15 | Analyze board and reset behavior before enabling JTAG |

---

## 20. Machine-readable hardware profile

This profile is a compact representation of the normative information above. The canonical matrix and explanatory sections take precedence if a future edit creates a discrepancy.

```yaml
board:
  family: LILYGO_T_Display_classic
  aliases:
    - TTGO_T_Display
    - T_Display_V1
  excluded_families:
    - T_Display_S3
  soc: ESP32-D0WDQ6
  architecture: Xtensa_LX6_dual_core
  cpu_max_mhz: 240
  sram_kb: 520
  psram: false

flash:
  safe_baseline_mb: 4
  known_variants_mb: [4, 16]
  verify_before_large_partition: true
  soc_flash_gpio: [6, 7, 8, 9, 10, 11]

display:
  controller: ST7789V
  native_width: 135
  native_height: 240
  common_landscape_width: 240
  common_landscape_height: 135
  interface: SPI_4_wire
  reference_write_clock_mhz: 40
  pins:
    mosi: 19
    sclk: 18
    cs: 5
    dc: 16
    reset: 23
    backlight: 4
    miso: null

buttons:
  - pin: 0
    roles: [onboard_button, boot_strap]
    active_level_reference: low
  - pin: 35
    roles: [onboard_button, input_only, rtc_wakeup_reference]
    active_level_reference: low
    internal_pull: false

battery:
  chemistry: 1S_LiPo
  onboard_charging: true
  adc_pin: 34
  adc_channel: ADC1_CH6
  adc_enable_pin: 14
  adc_enable_level_reference: high
  divider_factor_reference: approximately_2
  calibration_recommended: true

usb_uart:
  uart: UART0
  tx_pin: 1
  rx_pin: 3
  bridge: revision_dependent
  known_families: [CH9102_family, CP210x_family]

allocation:
  soc_reserved:
    6: external_flash
    7: external_flash
    8: external_flash
    9: external_flash
    10: external_flash
    11: external_flash
  board_connected:
    0: onboard_button_boot
    1: usb_uart_tx
    3: usb_uart_rx
    4: tft_backlight
    5: tft_cs
    14: battery_adc_enable
    16: tft_dc
    18: tft_sclk
    19: tft_mosi
    23: tft_reset
    34: battery_adc
    35: onboard_button
  soft_defaults:
    i2c:
      sda: 21
      scl: 22
    external_spi:
      sclk: 25
      mosi: 26
      miso: 27
      cs: 33
  preferred_flexible_gpio: [17, 21, 22, 25, 26, 27, 32, 33]
  available_with_boot_caveat: [2, 12, 15]
  available_with_jtag_caveat: [12, 13, 15]

gpio_constraints:
  input_only: [34, 35, 36, 37, 38, 39]
  exposed_input_only: [36, 37, 38, 39]
  no_internal_pull: [34, 35, 36, 37, 38, 39]
  boot_strapping: [0, 2, 5, 12, 15]
  traditional_jtag: [12, 13, 14, 15]
  gpio_logic_voltage: 3.3
  gpio_5v_tolerant: false

adc:
  prefer_adc1_with_wifi: true
  exposed_adc1:
    36: ADC1_CH0
    37: ADC1_CH1
    38: ADC1_CH2
    39: ADC1_CH3
    32: ADC1_CH4
    33: ADC1_CH5
  board_connected_adc1:
    34: ADC1_CH6_battery
    35: ADC1_CH7_button
  exposed_adc2:
    2: ADC2_CH2
    12: ADC2_CH5
    13: ADC2_CH4
    15: ADC2_CH3
    25: ADC2_CH8
    26: ADC2_CH9
    27: ADC2_CH7

dac:
  25: DAC1
  26: DAC2

touch:
  exposed:
    2: Touch2
    15: Touch3
    13: Touch4
    12: Touch5
    27: Touch7
    33: Touch8
    32: Touch9
  board_connected:
    0: Touch1_button_boot
    4: Touch0_tft_backlight
    14: Touch6_battery_enable
```

---

## 21. Verification and sources

Board-specific claims were cross-checked using manufacturer documentation, manufacturer source/hardware data, Espressif documentation, and an independent established display profile.

### 21.1 Evidence summary

| Fact group | Principal evidence | Status |
|---|---|---|
| Classic ESP32, no PSRAM, display type and resolution | LILYGO documentation and repositories | Confirmed |
| TFT GPIO mapping | LILYGO documentation, factory source, TFT_eSPI Setup25 | Confirmed |
| Buttons and battery GPIO | LILYGO documentation and factory source | Confirmed |
| Header pinout | LILYGO KiCad symbol and board documentation | Confirmed for classic profile |
| Input-only pins, pulls, ADC, DAC, touch, strapping | Espressif original ESP32 documentation | Confirmed |
| ADC2/Wi-Fi restriction | Espressif ADC documentation | Confirmed |
| Optional external SPI mapping | LILYGO factory test | Confirmed as manufacturer-tested soft default |
| Flash capacity | 4 MB reference plus 16 MB product variant | Revision-dependent |
| USB-UART bridge | Current and historical LILYGO materials | Revision-dependent |

### 21.2 Manufacturer documentation

- LILYGO T-Display documentation:  
  https://wiki.lilygo.cc/products/t-display-series/t-display/
- LILYGO T-Display Quick Start:  
  https://wiki.lilygo.cc/products/t-display-series/t-display/quick-start
- LILYGO product page:  
  https://lilygo.cc/products/t-display

### 21.3 Manufacturer source and hardware data

- TTGO-T-Display repository:  
  https://github.com/Xinyuan-LilyGO/TTGO-T-Display
- Factory test source:  
  https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/TFT_eSPI/examples/FactoryTest/FactoryTest.ino
- LILYGO KiCad board symbol:  
  https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/kicad/TTGO_T_Display/symbols/TTGO_T_Display.kicad_sym
- LILYGO display library:  
  https://github.com/Xinyuan-LilyGO/LilyGo-display-library
- LILYGO ESP-IDF display examples:  
  https://github.com/Xinyuan-LilyGO/LilyGo-Display-IDF

### 21.4 Espressif documentation

- ESP32 Series Datasheet:  
  https://documentation.espressif.com/esp32_datasheet_en.html
- ESP-IDF GPIO and RTC GPIO documentation for ESP32:  
  https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/gpio.html
- ESP-IDF ADC documentation for ESP32:  
  https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/adc/index.html

### 21.5 Independent software-profile cross-check

- TFT_eSPI classic T-Display profile:  
  https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup25_TTGO_T_Display.h

---

## 22. Firmware-agent decision rules

A firmware agent using this document must:

1. Confirm that the target is the classic original-ESP32 T-Display.
2. Inspect the current project's existing pin allocation before assigning new GPIO.
3. Treat the canonical GPIO matrix as the primary allocation reference.
4. Preserve board-connected and SoC-reserved pins unless the task explicitly requires controlled sharing or repurposing.
5. Distinguish soft defaults from fixed hardware connections.
6. Never configure GPIO34-39 as outputs.
7. Add external bias resistors when an external GPIO34-39 input requires a defined idle state.
8. Protect strapping-pin levels during reset.
9. Prefer ADC1 for analog sensing when Wi-Fi may be active.
10. Keep GPIO signaling at 3.3 V and use proper drivers for loads.
11. Treat 4 MB flash as the safe baseline until capacity is verified.
12. Keep framework-specific APIs and project configuration outside this hardware reference.
13. Centralize final project pin assignments in one board-profile source file.
14. Revalidate boot, display, upload, active operation, and sleep behavior after any pin-allocation change.
