Updated driver.
This commit is contained in:
parent
c685c2a4a8
commit
2d90485d67
122
st7789_lcd.c
122
st7789_lcd.c
|
@ -1,6 +1,6 @@
|
|||
#include "st7789_lcd.h"
|
||||
|
||||
uint8_t ST7789_PANEL_ZJY_240_240[] = {
|
||||
uint8_t st7789_init_seq_zjy_240_240[] = {
|
||||
0x05, 0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33, // Porch Setting
|
||||
0x01, 0xB7, 0x35, // Gate Control
|
||||
0x01, 0xBB, 0x19, // VCOM Setting // Factory 0x19 -> 0.725V
|
||||
|
@ -19,6 +19,25 @@ uint8_t ST7789_PANEL_ZJY_240_240[] = {
|
|||
0x00, 0x21, // Inversion On
|
||||
};
|
||||
|
||||
uint8_t st7789_init_seq_zjy_240_135[] = {
|
||||
0x05, 0xB2, 0x05, 0x05, 0x00, 0x33, 0x33, // Porch Setting
|
||||
0x01, 0xB7, 0x23, // Gate Control
|
||||
0x01, 0xBB, 0x22, // VCOM Setting // Factory 0x19 -> 0.725V
|
||||
0x01, 0xC0, 0x2C, // LCM Control
|
||||
0x01, 0xC2, 0x01, // VDV and VRH Command Enable
|
||||
0x01, 0xC3, 0x13, // VRH Set // Factory 12H
|
||||
0x01, 0xC4, 0x20, // VDV Set
|
||||
0x01, 0xC6, 0x0F, // Frame Rate Control in Normal Mode
|
||||
0x02, 0xD0, 0xA4, 0xA1, // Power Control 1
|
||||
0x0E, 0xE0, 0x70, 0x06, 0x0C, 0x08, 0x09, 0x27,
|
||||
0x2E, 0x34, 0x46, 0x37, 0x13, 0x13, 0x25,
|
||||
0x2A, // Positive Voltage Gamma Control
|
||||
0x0E, 0xE1, 0x70, 0x04, 0x08, 0x09, 0x07, 0x03,
|
||||
0x2C, 0x42, 0x42, 0x38, 0x14, 0x14, 0x27,
|
||||
0x2C, // Negative Voltage Gamma Control
|
||||
0x00, 0x21, // Inversion On
|
||||
};
|
||||
|
||||
st7789_ret_t _st7789_init_seq(st7789_lcd_t *lcd) {
|
||||
uint16_t i = 0;
|
||||
|
||||
|
@ -29,25 +48,118 @@ st7789_ret_t _st7789_init_seq(st7789_lcd_t *lcd) {
|
|||
};
|
||||
i += ST7789_PANEL_SELECTION[i] + 2;
|
||||
}
|
||||
|
||||
return ST7789_OK;
|
||||
}
|
||||
|
||||
st7789_ret_t _st7789_window(st7789_lcd_t *lcd, uint16_t x_start, uint16_t x_end,
|
||||
uint16_t y_start, uint16_t y_end) {
|
||||
// Cursor
|
||||
uint16_t real_x_start, real_x_end, real_y_start, real_y_end;
|
||||
|
||||
uint16_t x_offset, y_offset;
|
||||
switch(lcd->config.direction) {
|
||||
case ST7789_DIR_0:
|
||||
x_offset = PANEL_X_OFFSET;
|
||||
y_offset = PANEL_Y_OFFSET;
|
||||
break;
|
||||
case ST7789_DIR_90:
|
||||
x_offset = PANEL_Y_OFFSET;
|
||||
y_offset = PANEL_X_OFFSET;
|
||||
break;
|
||||
case ST7789_DIR_180:
|
||||
x_offset = 0;
|
||||
y_offset = 80;
|
||||
break;
|
||||
case ST7789_DIR_270:
|
||||
x_offset = 80;
|
||||
y_offset = 0;
|
||||
break;
|
||||
default:
|
||||
x_offset = 0;
|
||||
y_offset = 0;
|
||||
}
|
||||
|
||||
real_x_start = x_start + x_offset;
|
||||
real_x_end = x_end + x_offset;
|
||||
real_y_start = y_start + y_offset;
|
||||
real_y_end = y_end + y_offset;
|
||||
|
||||
uint8_t tx_buf[5] = {0x2A, ((uint8_t)(real_x_start >> 0x08U) & 0xFFU),
|
||||
(real_x_start & 0xFFU),
|
||||
((uint8_t)(real_x_end >> 0x08U) & 0xFFU),
|
||||
(real_x_end & 0xFFU)};
|
||||
|
||||
if(lcd->cb.write_cmd_cb(lcd->user_data, tx_buf, 0x05) != ST7789_OK) {
|
||||
return ST7789_ERROR;
|
||||
}
|
||||
|
||||
tx_buf[0] = 0x2B;
|
||||
tx_buf[1] = ((uint8_t)(real_y_start >> 0x08U) & 0xFFU);
|
||||
tx_buf[2] = (real_y_start & 0xFFU);
|
||||
tx_buf[3] = ((uint8_t)(real_y_end >> 0x08U) & 0xFFU);
|
||||
tx_buf[4] = (real_y_end & 0xFFU);
|
||||
|
||||
if(lcd->cb.write_cmd_cb(lcd->user_data, tx_buf, 0x05) != ST7789_OK) {
|
||||
return ST7789_ERROR;
|
||||
}
|
||||
|
||||
return ST7789_OK;
|
||||
}
|
||||
|
||||
st7789_ret_t _st7789_reset(st7789_lcd_t *lcd) {
|
||||
return lcd->cb.reset_cb(lcd->user_data);
|
||||
}
|
||||
|
||||
st7789_ret_t st7789_lcd_init(st7789_lcd_t *lcd) {
|
||||
if(_st7789_init_seq(lcd) != ST7789_OK) return ST7789_ERROR;
|
||||
if(st7789_lcd_sleep(lcd, 0) != ST7789_OK) return ST7789_ERROR;
|
||||
if(st7789_lcd_display(lcd, 1) != ST7789_OK) return ST7789_ERROR;
|
||||
}
|
||||
|
||||
st7789_ret_t st7789_lcd_load(st7789_lcd_t *lcd, uint8_t *data, uint16_t x_start,
|
||||
uint16_t x_end, uint16_t y_start, uint16_t y_end) {
|
||||
uint32_t data_len = (y_end - y_start + 1) * (x_end - x_start + 1);
|
||||
|
||||
if(_st7789_window(lcd, x_start, x_end, y_start, y_end) != ST7789_OK)
|
||||
uint32_t pixel_count = (y_end - y_start + 1) * (x_end - x_start + 1);
|
||||
|
||||
uint32_t data_len = 0;
|
||||
|
||||
switch(lcd->config.pix_fmt) {
|
||||
case ST7789_RGB444:
|
||||
data_len = pixel_count * 3 / 2;
|
||||
break;
|
||||
case ST7789_RGB565:
|
||||
data_len = pixel_count * 2;
|
||||
break;
|
||||
case ST7789_RGB666:
|
||||
case ST7789_RGB888:
|
||||
data_len = pixel_count * 3;
|
||||
break;
|
||||
default:
|
||||
data_len = pixel_count;
|
||||
break;
|
||||
}
|
||||
|
||||
if(_st7789_window(lcd, x_start, x_end, y_start, y_end) != ST7789_OK) {
|
||||
return ST7789_ERROR;
|
||||
if(lcd->cb.write_data_cb(lcd->user_data, data, data_len) != ST7789_OK)
|
||||
}
|
||||
|
||||
if(lcd->cb.write_data_cb(lcd->user_data, data, data_len) != ST7789_OK) {
|
||||
return ST7789_ERROR;
|
||||
}
|
||||
|
||||
return ST7789_OK;
|
||||
}
|
||||
|
||||
st7789_ret_t st7789_lcd_sleep(st7789_lcd_t *lcd, uint8_t sleep_mode) {
|
||||
uint8_t command = 0x11;
|
||||
if(sleep_mode) command = 0x10;
|
||||
|
||||
return lcd->cb.write_cmd_cb(lcd->user_data, &command, 0x01);
|
||||
}
|
||||
|
||||
st7789_ret_t st7789_lcd_display(st7789_lcd_t *lcd, uint8_t display_on) {
|
||||
uint8_t command = 0x28;
|
||||
if(display_on) command = 0x29;
|
||||
|
||||
return lcd->cb.write_cmd_cb(lcd->user_data, &command, 0x01);
|
||||
}
|
48
st7789_lcd.h
48
st7789_lcd.h
|
@ -3,7 +3,24 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum { ST7789_OK, ST7789_ERROR } st7789_ret_t;
|
||||
typedef enum {
|
||||
ST7789_OK,
|
||||
ST7789_ERROR,
|
||||
} st7789_ret_t;
|
||||
|
||||
typedef enum {
|
||||
ST7789_DIR_0,
|
||||
ST7789_DIR_90,
|
||||
ST7789_DIR_180,
|
||||
ST7789_DIR_270,
|
||||
} st7789_direction_t;
|
||||
|
||||
typedef enum {
|
||||
ST7789_RGB444 = 3,
|
||||
ST7789_RGB565 = 5,
|
||||
ST7789_RGB666 = 6,
|
||||
ST7789_RGB888 = 7
|
||||
} st7789_pixfmt_t;
|
||||
|
||||
typedef struct {
|
||||
st7789_ret_t (*reset_cb)(void *handle);
|
||||
|
@ -11,17 +28,42 @@ typedef struct {
|
|||
st7789_ret_t (*write_data_cb)(void *handle, uint8_t *data, uint8_t len);
|
||||
} st7789_cb_t;
|
||||
|
||||
typedef struct {
|
||||
st7789_direction_t direction;
|
||||
st7789_pixfmt_t pix_fmt;
|
||||
} st7789_config_t;
|
||||
|
||||
typedef struct {
|
||||
void *user_data;
|
||||
st7789_cb_t cb;
|
||||
st7789_config_t config;
|
||||
} st7789_lcd_t;
|
||||
|
||||
#ifndef ST7789_PANEL_SELECTION
|
||||
#define ST7789_PANEL_SELECTION ST7789_PANEL_ZJY_240_240
|
||||
#ifdef ST7789_PANEL_ZJY_240
|
||||
|
||||
#define ST7789_PANEL_SELECTION st7789_init_seq_zjy_240_240
|
||||
#define PANEL_X_OFFSET 0
|
||||
#define PANEL_Y_OFFSET 0
|
||||
|
||||
#elif ST7789_PANEL_ZJY_135
|
||||
|
||||
#define ST7789_PANEL_SELECTION st7789_init_seq_zjy_240_135
|
||||
#define PANEL_X_OFFSET 53
|
||||
#define PANEL_Y_OFFSET 40
|
||||
|
||||
#else
|
||||
|
||||
#warning "Panel not defined, using default."
|
||||
#define ST7789_PANEL_SELECTION st7789_init_seq_zjy_240_240
|
||||
#define PANEL_X_OFFSET 0
|
||||
#define PANEL_Y_OFFSET 0
|
||||
|
||||
#endif
|
||||
|
||||
st7789_ret_t st7789_lcd_init(st7789_lcd_t *lcd);
|
||||
st7789_ret_t st7789_lcd_load(st7789_lcd_t *lcd, uint8_t *data, uint16_t x_start,
|
||||
uint16_t x_end, uint16_t y_start, uint16_t y_end);
|
||||
st7789_ret_t st7789_lcd_sleep(st7789_lcd_t *lcd, uint8_t sleep_mode);
|
||||
st7789_ret_t st7789_lcd_display(st7789_lcd_t *lcd, uint8_t display_on);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue