Commit b3d8a71a authored by Russ's avatar Russ

240x320 display support

parent a963bf85
......@@ -7,11 +7,16 @@ https://github.com/devbis/st7789_mpy.
I modified the original driver for one of my projects by adding support for
display rotation, scrolling and drawing text using 8 and 16 bit wide bitmap
fonts. Included are 12 bitmap fonts derived from classic pc text mode fonts
and a couple of example programs that run on the TTGO T-Display.
and a couple of example programs that run on the TTGO T-Display and pyboards.
The driver supports 135x240, 240x240 and 240x320 displays.
A firmware.bin file containing MicroPython v1.12-464-gcae77daf0 compiled
using ESP IDF v3 with the st7789 C driver and the frozen python font files is
available in the firmware directory.
The firmware/esp32 directory contains a firmware.bin file with MicroPython
v1.12-464-gcae77daf0 compiled using ESP IDF v3 with the st7789 C driver and
the frozen python font files for generic ESP32 boards.
The firmware/pybv11 directory contains a firmware.dfu file with MicroPython
v1.12-464-gcae77daf0 compiled with the st7789 C driver and
the frozen python font files for the Pyboard v1.1.
This is a work in progress.
......@@ -19,7 +24,7 @@ Thanks go out to:
- https://github.com/devbis for the original driver this is based on.
- https://github.com/hklang10 for letting me know of the new mp_raise_ValueError().
- https://github.com/aleggon for finding the correct offsets for a 240x240 display.
- https://github.com/aleggon for finding the correct offsets for a 240x240 display and discovering issues compiling for STM32 based boards.
-- Russ
......@@ -29,26 +34,27 @@ This is a driver for MicroPython to handle cheap displays
based on ST7789 chip.
<p align="center">
<img src="https://raw.githubusercontent.com/devbis/st7789_mpy/master/docs/ST7789.jpg" alt="ST7789 display photo"/>
<img src="https://raw.githubusercontent.com/russhughes/st7789_mpy/master/docs/ST7789.jpg" alt="ST7789 display photo"/>
</p>
It supports both 240x240 and 135x240 variants of displays.
It supports 240x240, 135x240 and 240x320 displays.
It is written in pure C, so you have to build
firmware by yourself.
Only ESP8266 and ESP32 are supported for now.
It is written in pure C. If you are using an ESP32 or pyboard1.1 you can use
one of the provided firmware files, otherwise you will have to build the
firmware from source. Only ESP8266, ESP32 and STM32 processors are supported
for now.
Building instruction
---------------------
Prepare build tools as described in the manual.
You should follow the instruction for building MicroPython and
ensure that you can build the firmware without this display module.
Prepare build tools as described in the manual. You should follow the
instruction for building MicroPython and ensure that you can build the
firmware without this display module.
Clone this module alongside the MPY sources:
$ git clone https://github.com/devbis/st7789_mpy.git
$ git clone https://github.com/russhughes/st7789_mpy.git
Go to MicroPython ports directory and for ESP8266 run:
......@@ -75,7 +81,7 @@ for more info)
Working examples
----------------
This module was tested on ESP32 and ESP8266 MCUs.
This module was tested on ESP32, ESP8266 and the STM32 based pyboard1.1.
You have to provide `machine.SPI` object and at least two pins for RESET and
DC pins on the screen for the display object.
......
"""
ttgo_hello.py
Writes "Hello!" in random colors at random locations on a
on a ST7789 TFT display connected to a pyboard1.1.
video: https://youtu.be/OtcERmad5ps
"""
import random, time
from pyb import SPI, Pin
import st7789
# Choose a font
# import vga1_8x8 as font
# import vga2_8x8 as font
# import vga1_8x16 as font
# import vga2_8x16 as font
# import vga1_16x16 as font
# import vga1_bold_16x16 as font
# import vga2_16x16 as font
# import vga2_bold_16x16 as font
# import vga1_16x32 as font
# import vga1_bold_16x32 as font
# import vga2_16x32 as font
import vga2_bold_16x32 as font
def main():
tft = st7789.ST7789(
SPI(1, SPI.MASTER, baudrate=30000000, polarity=1, phase=0),
240,
320,
reset=Pin('X3', Pin.OUT),
cs=Pin('X5', Pin.OUT),
dc=Pin('X4', Pin.OUT),
backlight=Pin('X2', Pin.OUT),
rotation=3)
tft.init()
while True:
for rotation in range(4):
tft.rotation(rotation)
tft.fill(0)
col_max = tft.width() - font.WIDTH*6
row_max = tft.height() - font.HEIGHT
for _ in range(250):
tft.text(
font,
"Hello!",
random.randint(0, col_max),
random.randint(0, row_max),
st7789.color565(
random.getrandbits(8),
random.getrandbits(8),
random.getrandbits(8)),
st7789.color565(
random.getrandbits(8),
random.getrandbits(8),
random.getrandbits(8))
)
main()
......@@ -57,10 +57,10 @@ typedef struct _st7789_ST7789_obj_t {
mp_obj_base_t base;
mp_obj_base_t *spi_obj;
uint8_t display_width; // physical width
uint8_t width; // logical width (after rotation)
uint8_t display_height; // physical width
uint8_t height; // logical height (after rotation)
uint16_t display_width; // physical width
uint16_t width; // logical width (after rotation)
uint16_t display_height; // physical width
uint16_t height; // logical height (after rotation)
uint8_t xstart;
uint8_t ystart;
uint8_t rotation;
......@@ -99,7 +99,7 @@ STATIC void write_cmd(st7789_ST7789_obj_t *self, uint8_t cmd, const uint8_t *dat
CS_HIGH()
}
STATIC void set_window(st7789_ST7789_obj_t *self, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
STATIC void set_window(st7789_ST7789_obj_t *self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
if (x0 > x1 || x1 >= self->width) {
return;
}
......@@ -135,7 +135,7 @@ STATIC void fill_color_buffer(mp_obj_base_t* spi_obj, uint16_t color, int length
}
STATIC void draw_pixel(st7789_ST7789_obj_t *self, uint8_t x, uint8_t y, uint16_t color) {
STATIC void draw_pixel(st7789_ST7789_obj_t *self, uint16_t x, uint16_t y, uint16_t color) {
uint8_t hi = color >> 8, lo = color;
set_window(self, x, y, x, y);
DC_HIGH();
......@@ -146,7 +146,7 @@ STATIC void draw_pixel(st7789_ST7789_obj_t *self, uint8_t x, uint8_t y, uint16_t
}
STATIC void fast_hline(st7789_ST7789_obj_t *self, uint8_t x, uint8_t y, uint8_t _w, uint16_t color) {
STATIC void fast_hline(st7789_ST7789_obj_t *self, uint16_t x, uint16_t y, uint16_t _w, uint16_t color) {
int w;
......@@ -164,7 +164,7 @@ STATIC void fast_hline(st7789_ST7789_obj_t *self, uint8_t x, uint8_t y, uint8_t
}
}
STATIC void fast_vline(st7789_ST7789_obj_t *self, uint8_t x, uint8_t y, uint16_t w, uint16_t color) {
STATIC void fast_vline(st7789_ST7789_obj_t *self, uint16_t x, uint16_t y, uint16_t w, uint16_t color) {
set_window(self, x, y, x, y + w - 1);
DC_HIGH();
CS_LOW();
......@@ -471,35 +471,35 @@ STATIC void set_rotation(st7789_ST7789_obj_t *self) {
if (self->rotation == 0) { // Portrait
self->width = self->display_width;
self->height = self->display_height;
if (self->display_width == 135) {
self->xstart = 52;
self->ystart = 40;
}
else if (self->display_width == 240) {
if (self->display_height == 320 || self->display_width == 240) {
self->xstart = 0;
self->ystart = 0;
}
else if (self->display_width == 135) {
self->xstart = 52;
self->ystart = 40;
}
}
else if (self->rotation == 1) { // Landscape
madctl_value |= ST7789_MADCTL_MX | ST7789_MADCTL_MV;
self->width = self->display_height;
self->height = self->display_width;
if (self->display_width == 135) {
self->xstart = 40;
self->ystart = 53;
}
else if (self->display_width == 240) {
if (self->display_height == 320 || self->display_width == 240) {
self->xstart = 0;
self->ystart = 0;
} else if (self->display_width == 135) {
self->xstart = 40;
self->ystart = 53;
}
}
else if (self->rotation == 2) { // Inverted Portrait
madctl_value |= ST7789_MADCTL_MX | ST7789_MADCTL_MY;
self->width = self->display_width;
self->height = self->display_height;
if (self->display_width == 135) {
if (self->display_height == 320) {
self->xstart = 0;
self->ystart = 0;
} else if (self->display_width == 135) {
self->xstart = 53;
self->ystart = 40;
}
......@@ -513,7 +513,10 @@ STATIC void set_rotation(st7789_ST7789_obj_t *self) {
madctl_value |= ST7789_MADCTL_MV | ST7789_MADCTL_MY;
self->width = self->display_height;
self->height = self->display_width;
if (self->display_width == 135) {
if (self->display_height == 320) {
self->xstart = 0;
self->ystart = 0;
} else if (self->display_width == 135) {
self->xstart = 40;
self->ystart = 52;
}
......@@ -752,8 +755,9 @@ mp_obj_t st7789_ST7789_make_new(const mp_obj_type_t *type,
self->height = args[ARG_height].u_int;
self->rotation = args[ARG_rotation].u_int % 4;
if (self->display_height != 240 || (self->display_width != 240 && self->display_width != 135)) {
mp_raise_ValueError(MP_ERROR_TEXT("Unsupported display. Only 240x240 and 135x240 are supported"));
if ((self->display_height != 240 && (self->display_width != 240 || self->display_width != 135)) &&
(self->display_height != 320 && self->display_width != 240)) {
mp_raise_ValueError(MP_ERROR_TEXT("Unsupported display. Only 240x320, 240x240 and 135x240 are supported"));
}
if (args[ARG_reset].u_obj == MP_OBJ_NULL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment