You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
7.8 KiB
C
207 lines
7.8 KiB
C
/**
|
|
* @file UC1610.c
|
|
*
|
|
*/
|
|
|
|
/*********************
|
|
* INCLUDES
|
|
*********************/
|
|
#include "UC1610.h"
|
|
|
|
#if USE_UC1610
|
|
|
|
#include <stdbool.h>
|
|
#include LV_DRV_DISP_INCLUDE
|
|
#include LV_DRV_DELAY_INCLUDE
|
|
|
|
/*********************
|
|
* DEFINES
|
|
*********************/
|
|
#define UC1610_CMD_MODE 0
|
|
#define UC1610_DATA_MODE 1
|
|
#define UC1610_RESET_MODE 0
|
|
#define UC1610_SET_MODE 1
|
|
|
|
/* hardware control commands */
|
|
#define UC1610_SYSTEM_RESET 0xE2 /* software reset */
|
|
#define UC1610_NOP 0xE3
|
|
#define UC1610_SET_TEMP_COMP 0x24 /* set temperature compensation, default -0.05%/°C */
|
|
#define UC1610_SET_PANEL_LOADING 0x29 /* set panel loading, default 16~21 nF */
|
|
#define UC1610_SET_PUMP_CONTROL 0x2F /* default internal Vlcd (8x pump) */
|
|
#define UC1610_SET_LCD_BIAS_RATIO 0xEB /* default 11 */
|
|
#define UC1610_SET_VBIAS_POT 0x81 /* 1 byte (0~255) to follow setting the contrast, default 0x81 */
|
|
#define UC1610_SET_LINE_RATE 0xA0 /* default 12,1 Klps */
|
|
#define UC1610_SET_DISPLAY_ENABLE 0xAE /* + 1 / 0 : exit sleep mode / entering sleep mode */
|
|
#define UC1610_SET_LCD_GRAY_SHADE 0xD0 /* default 24% between the two gray shade levels */
|
|
#define UC1610_SET_COM_END 0xF1 /* set the number of used com electrodes (lines number -1) */
|
|
|
|
/* ram address control */
|
|
#define UC1610_SET_AC 0x88 /* set ram address control */
|
|
#define UC1610_AC_WA_FLAG 1 /* automatic column/page increment wrap around (1 : cycle increment) */
|
|
#define UC1610_AC_AIO_FLAG (1 << 1) /* auto increment order (0/1 : column/page increment first) */
|
|
#define UC1610_AC_PID_FLAG (1 << 2) /* page address auto increment order (0/1 : +1/-1) */
|
|
|
|
/* set cursor ram address */
|
|
#define UC1610_SET_CA_LSB 0x00 /* + 4 LSB bits */
|
|
#define UC1610_SET_CA_MSB 0x10 /* + 4 MSB bits // MSB + LSB values range : 0~159 */
|
|
#define UC1610_SET_PA 0x60 /* + 5 bits // values range : 0~26 */
|
|
|
|
/* display control commands */
|
|
#define UC1610_SET_FIXED_LINES 0x90 /* + 4 bits = 2xFL */
|
|
#define UC1610_SET_SCROLL_LINES_LSB 0x40 /* + 4 LSB bits scroll up display by N (7 bits) lines */
|
|
#define UC1610_SET_SCROLL_LINES_MSB 0x50 /* + 3 MSB bits */
|
|
#define UC1610_SET_ALL_PIXEL_ON 0xA4 /* + 1 / 0 : set all pixel on, reverse */
|
|
#define UC1610_SET_INVERSE_DISPLAY 0xA6 /* + 1 / 0 : inverse all data stored in ram, reverse */
|
|
#define UC1610_SET_MAPPING_CONTROL 0xC0 /* control mirroring */
|
|
#define UC1610_SET_MAPPING_CONTROL_LC_FLAG 1
|
|
#define UC1610_SET_MAPPING_CONTROL_MX_FLAG (1 << 1)
|
|
#define UC1610_SET_MAPPING_CONTROL_MY_FLAG (1 << 2)
|
|
|
|
/* window program mode */
|
|
#define UC1610_SET_WINDOW_PROGRAM_ENABLE 0xF8 /* + 1 / 0 : enable / disable window programming mode, */
|
|
/* reset before changing boundaries */
|
|
#define UC1610_SET_WP_STARTING_CA 0xF4 /* 1 byte to follow for column address */
|
|
#define UC1610_SET_WP_ENDING_CA 0xF6 /* 1 byte to follow for column address */
|
|
#define UC1610_SET_WP_STARTING_PA 0xF5 /* 1 byte to follow for page address */
|
|
#define UC1610_SET_WP_ENDING_PA 0xF7 /* 1 byte to follow for page address */
|
|
|
|
/**********************
|
|
* TYPEDEFS
|
|
**********************/
|
|
|
|
/**********************
|
|
* STATIC PROTOTYPES
|
|
**********************/
|
|
|
|
/**********************
|
|
* STATIC VARIABLES
|
|
**********************/
|
|
static uint8_t cmd_buf[12];
|
|
|
|
/**********************
|
|
* MACROS
|
|
**********************/
|
|
|
|
/* Return the byte bitmask of a pixel color corresponding to draw_buf arrangement */
|
|
#define PIXIDX(y, c) ((c) << (((y) & 3) << 1))
|
|
|
|
/**********************
|
|
* GLOBAL FUNCTIONS
|
|
**********************/
|
|
|
|
void uc1610_init(void) {
|
|
LV_DRV_DELAY_MS(12);
|
|
|
|
/* initialization sequence */
|
|
#if UC1610_INIT_HARD_RST
|
|
LV_DRV_DISP_RST(UC1610_RESET_MODE); /* hardware reset */
|
|
LV_DRV_DELAY_MS(1);
|
|
LV_DRV_DISP_RST(UC1610_SET_MODE);
|
|
#else
|
|
cmd_buf[0] = UC1610_SYSTEM_RESET; /* software reset */
|
|
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
|
|
LV_DRV_DISP_SPI_CS(0);
|
|
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 1);
|
|
LV_DRV_DISP_SPI_CS(1);
|
|
#endif
|
|
|
|
LV_DRV_DELAY_MS(2);
|
|
cmd_buf[0] = UC1610_SET_COM_END; /* set com end value */
|
|
cmd_buf[1] = UC1610_VER_RES - 1;
|
|
cmd_buf[2] = UC1610_SET_PANEL_LOADING;
|
|
cmd_buf[3] = UC1610_SET_LCD_BIAS_RATIO;
|
|
cmd_buf[4] = UC1610_SET_VBIAS_POT; /* set contrast */
|
|
cmd_buf[5] = (UC1610_INIT_CONTRAST * 255) / 100;
|
|
#if UC1610_TOP_VIEW
|
|
cmd_buf[6] = UC1610_SET_MAPPING_CONTROL | /* top view */
|
|
UC1610_SET_MAPPING_CONTROL_MY_FLAG |
|
|
UC1610_SET_MAPPING_CONTROL_MX_FLAG;
|
|
#else
|
|
cmd_buf[6] = UC1610_SET_MAPPING_CONTROL; /* bottom view */
|
|
#endif
|
|
cmd_buf[7] = UC1610_SET_SCROLL_LINES_LSB | 0; /* set scroll line on line 0 */
|
|
cmd_buf[8] = UC1610_SET_SCROLL_LINES_MSB | 0;
|
|
cmd_buf[9] = UC1610_SET_AC | UC1610_AC_WA_FLAG; /* set auto increment wrap around */
|
|
cmd_buf[10] = UC1610_SET_INVERSE_DISPLAY | 1; /* invert colors to complies lv color system */
|
|
cmd_buf[11] = UC1610_SET_DISPLAY_ENABLE | 1; /* turn display on */
|
|
|
|
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
|
|
LV_DRV_DISP_SPI_CS(0);
|
|
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 12);
|
|
LV_DRV_DISP_SPI_CS(1);
|
|
}
|
|
|
|
|
|
void uc1610_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
|
|
/*Return if the area is out the screen*/
|
|
if(area->x2 < 0) return;
|
|
if(area->y2 < 0) return;
|
|
if(area->x1 > UC1610_HOR_RES - 1) return;
|
|
if(area->y1 > UC1610_VER_RES - 1) return;
|
|
|
|
/*Truncate the area to the screen*/
|
|
uint8_t act_x1 = area->x1 < 0 ? 0 : area->x1;
|
|
uint8_t act_y1 = area->y1 < 0 ? 0 : area->y1;
|
|
uint8_t act_x2 = area->x2 > UC1610_HOR_RES - 1 ? UC1610_HOR_RES - 1 : area->x2;
|
|
uint8_t act_y2 = area->y2 > UC1610_VER_RES - 1 ? UC1610_VER_RES - 1 : area->y2;
|
|
|
|
uint8_t * buf = (uint8_t *) color_p;
|
|
uint16_t buf_size = (act_x2 - act_x1 + 1) * (((act_y2 - act_y1) >> 2) + 1);
|
|
|
|
/*Set display window to fill*/
|
|
cmd_buf[0] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 0; /* before changing boundaries */
|
|
cmd_buf[1] = UC1610_SET_WP_STARTING_CA;
|
|
cmd_buf[2] = act_x1;
|
|
cmd_buf[3] = UC1610_SET_WP_ENDING_CA;
|
|
cmd_buf[4] = act_x2;
|
|
cmd_buf[5] = UC1610_SET_WP_STARTING_PA;
|
|
cmd_buf[6] = act_y1 >> 2;
|
|
cmd_buf[7] = UC1610_SET_WP_ENDING_PA;
|
|
cmd_buf[8] = act_y2 >> 2;
|
|
cmd_buf[9] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 1; /* entering window programming */
|
|
|
|
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
|
|
LV_DRV_DISP_SPI_CS(0);
|
|
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 10);
|
|
LV_DRV_DISP_SPI_CS(1);
|
|
|
|
/*Flush draw_buf on display memory*/
|
|
LV_DRV_DISP_CMD_DATA(UC1610_DATA_MODE);
|
|
LV_DRV_DISP_SPI_CS(0);
|
|
LV_DRV_DISP_SPI_WR_ARRAY(buf, buf_size);
|
|
LV_DRV_DISP_SPI_CS(1);
|
|
|
|
lv_disp_flush_ready(disp_drv);
|
|
}
|
|
|
|
void uc1610_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa) {
|
|
(void) disp_drv;
|
|
(void) opa;
|
|
|
|
uint16_t idx = x + buf_w * (y >> 2);
|
|
|
|
/* Convert color to depth 2 */
|
|
#if LV_COLOR_DEPTH == 1
|
|
uint8_t color2 = color.full * 3;
|
|
#else
|
|
uint8_t color2 = color.full >> (LV_COLOR_DEPTH - 2);
|
|
#endif
|
|
|
|
buf[idx] &= ~PIXIDX(y, 3); /* reset pixel color */
|
|
buf[idx] |= PIXIDX(y, color2); /* write new color */
|
|
}
|
|
|
|
void uc1610_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area) {
|
|
(void) disp_drv;
|
|
|
|
/* Round y window to display memory page size */
|
|
area->y1 = (area->y1 & (~3));
|
|
area->y2 = (area->y2 & (~3)) + 3;
|
|
}
|
|
|
|
/**********************
|
|
* STATIC FUNCTIONS
|
|
**********************/
|
|
|
|
#endif
|