Added ZJY 480x320 LCD.
This commit is contained in:
parent
cdd4834ea6
commit
6fe4c748bd
|
@ -8,6 +8,7 @@ set(EPD_SOURCES
|
|||
"src/panel/epd_wfh0420cz35.c"
|
||||
"src/panel/epd_gdew042t2.c"
|
||||
"src/panel/lcd_jlx256128g_920.c"
|
||||
"src/panel/lcd_zjy350c4001.c"
|
||||
"src/panel/oled_elw1501aa.c"
|
||||
"src/panel/oled_zjy150s700.c"
|
||||
)
|
||||
|
|
|
@ -13,6 +13,7 @@ typedef struct {
|
|||
epd_ret_t (*reset_cb)(void *handle);
|
||||
epd_ret_t (*poll_busy_cb)(void *handle);
|
||||
epd_ret_t (*delay_cb)(void *handle, uint32_t msec);
|
||||
epd_ret_t (*backlight_cb)(void *handle, uint8_t on);
|
||||
} epd_cb_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef LCD_ZJY350C4001_H
|
||||
#define LCD_ZJY350C4001_H
|
||||
|
||||
#include "epd-spi/epd_common.h"
|
||||
|
||||
typedef enum {
|
||||
LCD_ZJY350C4001_DIR_0 = 0x08U,
|
||||
LCD_ZJY350C4001_DIR_90 = 0x68U,
|
||||
LCD_ZJY350C4001_DIR_180 = 0xC8U,
|
||||
LCD_ZJY350C4001_DIR_270 = 0xA8U,
|
||||
} LCD_ZJY350C4001_direction_t;
|
||||
|
||||
typedef enum {
|
||||
LCD_ZJY350C4001_RGB444 = 3,
|
||||
LCD_ZJY350C4001_RGB565 = 5,
|
||||
LCD_ZJY350C4001_RGB666 = 6,
|
||||
LCD_ZJY350C4001_RGB888 = 7,
|
||||
} LCD_ZJY350C4001_pixfmt_t;
|
||||
|
||||
typedef struct {
|
||||
LCD_ZJY350C4001_direction_t direction;
|
||||
LCD_ZJY350C4001_pixfmt_t pix_fmt;
|
||||
uint8_t inversion;
|
||||
uint8_t bgr_mode;
|
||||
} LCD_ZJY350C4001_config_t;
|
||||
|
||||
typedef struct {
|
||||
epd_cb_t cb;
|
||||
void *user_data;
|
||||
LCD_ZJY350C4001_config_t config;
|
||||
} lcd_zjy350c4001_t;
|
||||
|
||||
epd_ret_t lcd_zjy350c4001_init(lcd_zjy350c4001_t *lcd);
|
||||
epd_ret_t lcd_zjy350c4001_upload(lcd_zjy350c4001_t *lcd, uint8_t *data, uint16_t x_start, uint16_t x_end,
|
||||
uint16_t y_start, uint16_t y_end);
|
||||
epd_ret_t lcd_zjy350c4001_sleep(lcd_zjy350c4001_t *lcd, uint8_t sleep_mode);
|
||||
epd_ret_t lcd_zjy350c4001_display(lcd_zjy350c4001_t *lcd, uint8_t display_on);
|
||||
epd_ret_t lcd_zjy350c4001_config(lcd_zjy350c4001_t *lcd, LCD_ZJY350C4001_config_t *config);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,179 @@
|
|||
#include "panel/lcd_zjy350c4001.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "epd_private.h"
|
||||
|
||||
static uint8_t LCD_ZJY350C4001_init_seq_zjy_480_320[] = {
|
||||
0x01, 0xF0, 0xC3, // Enable command part 1
|
||||
0x01, 0xF0, 0x96, // Enable command part 2
|
||||
0x08, 0xE8, 0x40, 0x82, 0x07, 0x18, 0x27, 0x0A, 0xB6, 0x33, // DOCA
|
||||
0x01, 0xC5, 0x27, // VCOM control
|
||||
0x01, 0xC2, 0xA7, // Power control 3
|
||||
0x0E, 0xE0, 0xF0, 0x01, 0x06, 0x0F, 0x12, 0x1D, 0x36, 0x54, 0x44, 0x0C, 0x18, 0x16, 0x13, 0x15, // PGC
|
||||
0x0E, 0xE1, 0xF0, 0x01, 0x05, 0x0A, 0x0B, 0x07, 0x32, 0x44, 0x44, 0x0C, 0x18, 0x17, 0x13, 0x16, // NGC
|
||||
0x01, 0xF0, 0x3C, // Disable command part 1
|
||||
0x01, 0xF0, 0x69, // Disable command part 2
|
||||
};
|
||||
|
||||
epd_ret_t _LCD_ZJY350C4001_init_seq(lcd_zjy350c4001_t *lcd) {
|
||||
uint16_t i = 0;
|
||||
|
||||
while (i < sizeof(LCD_ZJY350C4001_init_seq_zjy_480_320)) {
|
||||
if (lcd->cb.write_command_cb(lcd->user_data, &LCD_ZJY350C4001_init_seq_zjy_480_320[i + 1],
|
||||
LCD_ZJY350C4001_init_seq_zjy_480_320[i] + 1) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
};
|
||||
i += LCD_ZJY350C4001_init_seq_zjy_480_320[i] + 2;
|
||||
}
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
epd_ret_t _LCD_ZJY350C4001_window(lcd_zjy350c4001_t *lcd, uint16_t x_start, uint16_t x_end, uint16_t y_start, uint16_t y_end) {
|
||||
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 LCD_ZJY350C4001_DIR_0:
|
||||
x_offset = 0;
|
||||
y_offset = 0;
|
||||
break;
|
||||
case LCD_ZJY350C4001_DIR_90:
|
||||
x_offset = 0;
|
||||
y_offset = 0;
|
||||
break;
|
||||
case LCD_ZJY350C4001_DIR_180:
|
||||
x_offset = 320;
|
||||
y_offset = 480;
|
||||
break;
|
||||
case LCD_ZJY350C4001_DIR_270:
|
||||
x_offset = 480;
|
||||
y_offset = 320;
|
||||
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_command_cb(lcd->user_data, tx_buf, 0x05) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
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_command_cb(lcd->user_data, tx_buf, 0x05) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
epd_ret_t _LCD_ZJY350C4001_reset(lcd_zjy350c4001_t *lcd) { return lcd->cb.reset_cb(lcd->user_data); }
|
||||
|
||||
epd_ret_t lcd_zjy350c4001_init(lcd_zjy350c4001_t *lcd) {
|
||||
if (_LCD_ZJY350C4001_reset(lcd) != EPD_OK) return EPD_FAIL;
|
||||
if (_LCD_ZJY350C4001_init_seq(lcd) != EPD_OK) return EPD_FAIL;
|
||||
if (lcd_zjy350c4001_config(lcd, &lcd->config) != EPD_OK) return EPD_FAIL;
|
||||
if (lcd_zjy350c4001_sleep(lcd, 0) != EPD_OK) return EPD_FAIL;
|
||||
if (lcd_zjy350c4001_display(lcd, 1) != EPD_OK) return EPD_FAIL;
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
epd_ret_t lcd_zjy350c4001_upload(lcd_zjy350c4001_t *lcd, uint8_t *data, uint16_t x_start, uint16_t x_end,
|
||||
uint16_t y_start, uint16_t y_end) {
|
||||
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 LCD_ZJY350C4001_RGB444:
|
||||
data_len = pixel_count * 3 / 2;
|
||||
break;
|
||||
case LCD_ZJY350C4001_RGB565:
|
||||
data_len = pixel_count * 2;
|
||||
break;
|
||||
case LCD_ZJY350C4001_RGB666:
|
||||
case LCD_ZJY350C4001_RGB888:
|
||||
data_len = pixel_count * 3;
|
||||
break;
|
||||
default:
|
||||
data_len = pixel_count;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set cursor
|
||||
if (_LCD_ZJY350C4001_window(lcd, x_start, x_end, y_start, y_end) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
uint8_t command = 0x2C; // Memory Write
|
||||
if (lcd->cb.write_command_cb(lcd->user_data, &command, 0x01) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
// Write pixel data
|
||||
if (lcd->cb.write_data_cb(lcd->user_data, data, data_len) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
epd_ret_t lcd_zjy350c4001_sleep(lcd_zjy350c4001_t *lcd, uint8_t sleep_mode) {
|
||||
// Write SLPIN or SLPOUT command.
|
||||
uint8_t command = sleep_mode ? 0x10 : 0x11;
|
||||
return lcd->cb.write_command_cb(lcd->user_data, &command, 0x01);
|
||||
}
|
||||
|
||||
epd_ret_t lcd_zjy350c4001_display(lcd_zjy350c4001_t *lcd, uint8_t display_on) {
|
||||
// write display_on command;
|
||||
uint8_t command = display_on ? 0x29 : 0x28;
|
||||
if (lcd->cb.write_command_cb(lcd->user_data, &command, 0x01) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
if ((lcd->cb.backlight_cb != NULL) && (lcd->cb.backlight_cb(lcd->user_data, display_on) != EPD_OK)) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
epd_ret_t lcd_zjy350c4001_config(lcd_zjy350c4001_t *lcd, LCD_ZJY350C4001_config_t *config) {
|
||||
lcd->config.direction = config->direction;
|
||||
|
||||
// Write inversion command.
|
||||
uint8_t command[2] = {config->inversion ? 0x20 : 0x21, 0x00};
|
||||
if (lcd->cb.write_command_cb(lcd->user_data, command, 0x01) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
lcd->config.inversion = config->inversion;
|
||||
|
||||
command[0] = 0x3A;
|
||||
command[1] = config->pix_fmt;
|
||||
if (lcd->cb.write_command_cb(lcd->user_data, command, 0x02) != EPD_OK) {
|
||||
return EPD_FAIL;
|
||||
}
|
||||
lcd->config.pix_fmt = config->pix_fmt;
|
||||
|
||||
command[0] = 0x36;
|
||||
command[1] = config->direction;
|
||||
if (!config->bgr_mode) {
|
||||
command[1] &= ~0x08U;
|
||||
}
|
||||
return lcd->cb.write_command_cb(lcd->user_data, command, 0x02);
|
||||
}
|
Loading…
Reference in New Issue