Metadata-Version: 2.5
Name: gc9b72
Version: 0.1.0
Summary: Driver for GC9B72 round SPI TFT panels on Linux single-board computers
Project-URL: Homepage, https://github.com/guillermozuur-design/gc9b72
Project-URL: Issues, https://github.com/guillermozuur-design/gc9b72/issues
Author: Guillermo Zuur
License: MIT License
        
        Copyright (c) 2026 Guillermo Zuur
        
        The register initialisation sequence in gc9b72.py is derived from the xboot
        project (https://github.com/xboot/xstar), which is likewise MIT licensed.
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: display,gc9b72,lcd,raspberry-pi,round-display,spi,tft
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Hardware :: Hardware Drivers
Requires-Python: >=3.9
Requires-Dist: numpy
Description-Content-Type: text/markdown

# gc9b72

Python driver for GC9B72 round SPI TFT panels on Raspberry Pi and other Linux
single-board computers. Developed against a 2.1" 360x360 module.

**If your GC9B72 panel stays black or white, you are probably sending a GC9A01
init sequence.** The two controllers both drive round panels and are otherwise
unrelated, and the GC9B72 is in none of the usual libraries — not TFT_eSPI, not
Adafruit GFX. The sequence this driver sends is documented in
[INIT_SEQUENCE.md](INIT_SEQUENCE.md).

## Installing

The C and imaging libraries come from apt rather than pip:

```bash
sudo apt install -y python3-lgpio python3-spidev python3-numpy python3-pil
```

Raspberry Pi OS will not let pip write to the system Python (PEP 668, the
`externally-managed-environment` error). Install into a virtual environment
that can still see those apt packages:

```bash
python3 -m venv --system-site-packages ~/.venvs/display
~/.venvs/display/bin/pip install gc9b72
```

Run your scripts with `~/.venvs/display/bin/python`. If you would rather keep
one system-wide Python, `pip install --break-system-packages gc9b72` also
works, at the usual risk of pip and apt disagreeing later.

SPI must be enabled (`sudo raspi-config nonint do_spi 0`, then reboot). A full
frame is 253 KB and the default SPI buffer is 4 KB, so for a usable frame rate
append `spidev.bufsiz=65536` to the line in `/boot/firmware/cmdline.txt`.

If opening the device raises `PermissionError`, add yourself to the right
groups with `sudo usermod -aG spi,gpio $USER` and log back in.

## Wiring

4-wire SPI at 3.3V logic, so it connects straight to the header with no level
shifter. GPIO numbers are BCM.

| Panel | | BCM | Header pin |
|---|---|---|---|
| VCC | 3.3V power | — | 1 |
| GND | ground | — | 6 |
| SCL | SPI clock | GPIO11 | 23 |
| SDA | SPI data in | GPIO10 | 19 |
| CS | chip select | GPIO8 | 24 |
| DC | data/command | GPIO25 | 22 |
| RST | reset | GPIO24 | 18 |
| BL | backlight | GPIO18 | 12 |

BCM is the number you pass to the driver; the header pin is where the wire
physically goes. They are not the same numbering and mixing them up is how VCC
ends up on 5V.

`SDO` and `TE` are unused — leave them unconnected. **`SDA` is MOSI and `SCL`
is the clock: this is SPI, not I²C**, despite the pin names, which is the usual
way to lose an evening with these modules. VCC wants 3.3V, not 5V, unless the
module carries its own regulator.

## Using

```python
from gc9b72 import GC9B72
from PIL import Image, ImageDraw

with GC9B72(dc=25, rst=24, bl=18, speed_hz=40_000_000) as d:
    img = Image.new("RGB", (d.width, d.height), (0, 0, 0))
    ImageDraw.Draw(img).ellipse([20, 20, 340, 340], fill=(255, 100, 0))
    d.show_image(img)
```

Pin numbers are BCM. `dc`, `rst` and `bl` are the only GPIOs the driver drives;
everything else goes to the SPI bus (`/dev/spidev0.0` by default).

### Options

| Argument | Default | |
|---|---|---|
| `speed_hz` | `40_000_000` | Drop to `20_000_000` or `10_000_000` if you see noise |
| `rotation` | `0` | `0`, `90`, `180` or `270` |
| `bgr` | `False` | Set if red and blue are swapped |
| `invert` | `False` | Set if the image is a negative |
| `x_offset`, `y_offset` | `0` | Shift the visible window |
| `gpiochip` | auto | Override if the header is not detected correctly |
| `spi_bus`, `spi_device` | `0`, `0` | Which `/dev/spidev*` to open |

### Methods

`show_image(image)` draws a PIL image, `blit(array)` an `(h, w, 3)` uint8 numpy
array, and `fill(colour)` a solid colour from `rgb565(r, g, b)`. `backlight(on)`
switches the backlight and `backlight_pwm(percent)` dims it.

## Examples

The examples are not part of the installed package — clone the repository to
get them:

```bash
git clone https://github.com/guillermozuur-design/gc9b72
```

[`examples/demo.py`](examples/demo.py) draws test patterns — solid colours,
colour bars, alignment markers, a clock, and an fps benchmark:

```bash
python3 examples/demo.py           # all of them
python3 examples/demo.py bars      # left should be red, right blue
python3 examples/demo.py corners   # circle should meet the edge of the glass
python3 examples/demo.py bench
```

`bars` and `corners` are the quickest way to settle `bgr`, `rotation` and the
offsets for your particular module.

## Panels

Sold as 2.1" round TFT modules, silkscreened `Driver IC: GC9B72`. 480x480
variants exist — change `WIDTH`/`HEIGHT` at the top of `gc9b72/__init__.py`;
the init sequence is the same.

## Credits

The register init sequence is derived from `fb-gc9b72.c` in
[xboot](https://github.com/xboot/xstar). For the ESP32 there is
[Arduino_GC9B72](https://github.com/MaliosDark/Arduino_GC9B72), and for LVGL
there is [GC9B72-LVGL-Driver](https://github.com/ximon/GC9B72-LVGL-Driver).

MIT licensed — see [LICENSE](LICENSE).
