LVGL 库提交
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file lv_linux_drm.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LINUX_DRM_H
|
||||
#define LV_LINUX_DRM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_LINUX_DRM
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
lv_display_t * lv_linux_drm_create(void);
|
||||
|
||||
void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t connector_id);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* LV_USE_LINUX_DRM */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_LINUX_DRM_H */
|
||||
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* @file lv_linux_fbdev.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_linux_fbdev.h"
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <time.h>
|
||||
|
||||
#if LV_LINUX_FBDEV_BSD
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/fbio.h>
|
||||
#else
|
||||
#include <linux/fb.h>
|
||||
#endif /* LV_LINUX_FBDEV_BSD */
|
||||
|
||||
#include "../../../display/lv_display_private.h"
|
||||
#include "../../../draw/sw/lv_draw_sw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct bsd_fb_var_info {
|
||||
uint32_t xoffset;
|
||||
uint32_t yoffset;
|
||||
uint32_t xres;
|
||||
uint32_t yres;
|
||||
int bits_per_pixel;
|
||||
};
|
||||
|
||||
struct bsd_fb_fix_info {
|
||||
long int line_length;
|
||||
long int smem_len;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char * devname;
|
||||
lv_color_format_t color_format;
|
||||
#if LV_LINUX_FBDEV_BSD
|
||||
struct bsd_fb_var_info vinfo;
|
||||
struct bsd_fb_fix_info finfo;
|
||||
#else
|
||||
struct fb_var_screeninfo vinfo;
|
||||
struct fb_fix_screeninfo finfo;
|
||||
#endif /* LV_LINUX_FBDEV_BSD */
|
||||
#if LV_LINUX_FBDEV_MMAP
|
||||
char * fbp;
|
||||
#endif
|
||||
uint8_t * rotated_buf;
|
||||
size_t rotated_buf_size;
|
||||
long int screensize;
|
||||
int fbfd;
|
||||
bool force_refresh;
|
||||
} lv_linux_fb_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p);
|
||||
static uint32_t tick_get_cb(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if LV_LINUX_FBDEV_BSD
|
||||
#define FBIOBLANK FBIO_BLANK
|
||||
#endif /* LV_LINUX_FBDEV_BSD */
|
||||
|
||||
#ifndef DIV_ROUND_UP
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_linux_fbdev_create(void)
|
||||
{
|
||||
lv_tick_set_cb(tick_get_cb);
|
||||
|
||||
lv_linux_fb_t * dsc = lv_malloc_zeroed(sizeof(lv_linux_fb_t));
|
||||
LV_ASSERT_MALLOC(dsc);
|
||||
if(dsc == NULL) return NULL;
|
||||
|
||||
lv_display_t * disp = lv_display_create(800, 480);
|
||||
if(disp == NULL) {
|
||||
lv_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
dsc->fbfd = -1;
|
||||
lv_display_set_driver_data(disp, dsc);
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_linux_fbdev_set_file(lv_display_t * disp, const char * file)
|
||||
{
|
||||
char * devname = lv_strdup(file);
|
||||
LV_ASSERT_MALLOC(devname);
|
||||
if(devname == NULL) return;
|
||||
|
||||
lv_linux_fb_t * dsc = lv_display_get_driver_data(disp);
|
||||
dsc->devname = devname;
|
||||
|
||||
if(dsc->fbfd > 0) close(dsc->fbfd);
|
||||
|
||||
/* Open the file for reading and writing*/
|
||||
dsc->fbfd = open(dsc->devname, O_RDWR);
|
||||
if(dsc->fbfd == -1) {
|
||||
perror("Error: cannot open framebuffer device");
|
||||
return;
|
||||
}
|
||||
LV_LOG_INFO("The framebuffer device was opened successfully");
|
||||
|
||||
/* Make sure that the display is on.*/
|
||||
if(ioctl(dsc->fbfd, FBIOBLANK, FB_BLANK_UNBLANK) != 0) {
|
||||
perror("ioctl(FBIOBLANK)");
|
||||
/* Don't return. Some framebuffer drivers like efifb or simplefb don't implement FBIOBLANK.*/
|
||||
}
|
||||
|
||||
#if LV_LINUX_FBDEV_BSD
|
||||
struct fbtype fb;
|
||||
unsigned line_length;
|
||||
|
||||
/*Get fb type*/
|
||||
if(ioctl(dsc->fbfd, FBIOGTYPE, &fb) != 0) {
|
||||
perror("ioctl(FBIOGTYPE)");
|
||||
return;
|
||||
}
|
||||
|
||||
/*Get screen width*/
|
||||
if(ioctl(dsc->fbfd, FBIO_GETLINEWIDTH, &line_length) != 0) {
|
||||
perror("ioctl(FBIO_GETLINEWIDTH)");
|
||||
return;
|
||||
}
|
||||
|
||||
dsc->vinfo.xres = (unsigned) fb.fb_width;
|
||||
dsc->vinfo.yres = (unsigned) fb.fb_height;
|
||||
dsc->vinfo.bits_per_pixel = fb.fb_depth;
|
||||
dsc->vinfo.xoffset = 0;
|
||||
dsc->vinfo.yoffset = 0;
|
||||
dsc->finfo.line_length = line_length;
|
||||
dsc->finfo.smem_len = dsc->finfo.line_length * dsc->vinfo.yres;
|
||||
#else /* LV_LINUX_FBDEV_BSD */
|
||||
|
||||
/* Get fixed screen information*/
|
||||
if(ioctl(dsc->fbfd, FBIOGET_FSCREENINFO, &dsc->finfo) == -1) {
|
||||
perror("Error reading fixed information");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get variable screen information*/
|
||||
if(ioctl(dsc->fbfd, FBIOGET_VSCREENINFO, &dsc->vinfo) == -1) {
|
||||
perror("Error reading variable information");
|
||||
return;
|
||||
}
|
||||
#endif /* LV_LINUX_FBDEV_BSD */
|
||||
|
||||
LV_LOG_INFO("%dx%d, %dbpp", dsc->vinfo.xres, dsc->vinfo.yres, dsc->vinfo.bits_per_pixel);
|
||||
|
||||
/* Figure out the size of the screen in bytes*/
|
||||
dsc->screensize = dsc->finfo.smem_len;/*finfo.line_length * vinfo.yres;*/
|
||||
|
||||
#if LV_LINUX_FBDEV_MMAP
|
||||
/* Map the device to memory*/
|
||||
dsc->fbp = (char *)mmap(0, dsc->screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dsc->fbfd, 0);
|
||||
if((intptr_t)dsc->fbp == -1) {
|
||||
perror("Error: failed to map framebuffer device to memory");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Don't initialise the memory to retain what's currently displayed / avoid clearing the screen.
|
||||
* This is important for applications that only draw to a subsection of the full framebuffer.*/
|
||||
|
||||
LV_LOG_INFO("The framebuffer device was mapped to memory successfully");
|
||||
|
||||
switch(dsc->vinfo.bits_per_pixel) {
|
||||
case 16:
|
||||
lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB565);
|
||||
break;
|
||||
case 24:
|
||||
lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB888);
|
||||
break;
|
||||
case 32:
|
||||
lv_display_set_color_format(disp, LV_COLOR_FORMAT_XRGB8888);
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("Not supported color format (%d bits)", dsc->vinfo.bits_per_pixel);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t hor_res = dsc->vinfo.xres;
|
||||
int32_t ver_res = dsc->vinfo.yres;
|
||||
int32_t width = dsc->vinfo.width;
|
||||
uint32_t draw_buf_size = hor_res * (dsc->vinfo.bits_per_pixel >> 3);
|
||||
if(LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) {
|
||||
draw_buf_size *= LV_LINUX_FBDEV_BUFFER_SIZE;
|
||||
}
|
||||
else {
|
||||
draw_buf_size *= ver_res;
|
||||
}
|
||||
|
||||
uint8_t * draw_buf = NULL;
|
||||
uint8_t * draw_buf_2 = NULL;
|
||||
draw_buf = malloc(draw_buf_size);
|
||||
|
||||
if(LV_LINUX_FBDEV_BUFFER_COUNT == 2) {
|
||||
draw_buf_2 = malloc(draw_buf_size);
|
||||
}
|
||||
|
||||
lv_display_set_resolution(disp, hor_res, ver_res);
|
||||
lv_display_set_buffers(disp, draw_buf, draw_buf_2, draw_buf_size, LV_LINUX_FBDEV_RENDER_MODE);
|
||||
|
||||
if(width > 0) {
|
||||
lv_display_set_dpi(disp, DIV_ROUND_UP(hor_res * 254, width * 10));
|
||||
}
|
||||
|
||||
LV_LOG_INFO("Resolution is set to %" LV_PRId32 "x%" LV_PRId32 " at %" LV_PRId32 "dpi",
|
||||
hor_res, ver_res, lv_display_get_dpi(disp));
|
||||
}
|
||||
|
||||
void lv_linux_fbdev_set_force_refresh(lv_display_t * disp, bool enabled)
|
||||
{
|
||||
lv_linux_fb_t * dsc = lv_display_get_driver_data(disp);
|
||||
dsc->force_refresh = enabled;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void write_to_fb(lv_linux_fb_t * dsc, uint32_t fb_pos, const void * data, size_t sz)
|
||||
{
|
||||
#if LV_LINUX_FBDEV_MMAP
|
||||
uint8_t * fbp = (uint8_t *)dsc->fbp;
|
||||
lv_memcpy(&fbp[fb_pos], data, sz);
|
||||
#else
|
||||
if(pwrite(dsc->fbfd, data, sz, fb_pos) < 0)
|
||||
LV_LOG_ERROR("write failed: %d", errno);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p)
|
||||
{
|
||||
lv_linux_fb_t * dsc = lv_display_get_driver_data(disp);
|
||||
|
||||
#if LV_LINUX_FBDEV_MMAP
|
||||
if(dsc->fbp == NULL) {
|
||||
lv_display_flush_ready(disp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t w = lv_area_get_width(area);
|
||||
int32_t h = lv_area_get_height(area);
|
||||
lv_color_format_t cf = lv_display_get_color_format(disp);
|
||||
uint32_t px_size = lv_color_format_get_size(cf);
|
||||
|
||||
lv_area_t rotated_area;
|
||||
lv_display_rotation_t rotation = lv_display_get_rotation(disp);
|
||||
|
||||
/* Not all framebuffer kernel drivers support hardware rotation, so we need to handle it in software here */
|
||||
if(rotation != LV_DISPLAY_ROTATION_0 && LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) {
|
||||
/* (Re)allocate temporary buffer if needed */
|
||||
size_t buf_size = w * h * px_size;
|
||||
if(!dsc->rotated_buf || dsc->rotated_buf_size != buf_size) {
|
||||
dsc->rotated_buf = realloc(dsc->rotated_buf, buf_size);
|
||||
dsc->rotated_buf_size = buf_size;
|
||||
}
|
||||
|
||||
/* Rotate the pixel buffer */
|
||||
uint32_t w_stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
uint32_t h_stride = lv_draw_buf_width_to_stride(h, cf);
|
||||
|
||||
switch(rotation) {
|
||||
case LV_DISPLAY_ROTATION_0:
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_90:
|
||||
lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_180:
|
||||
lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, w_stride, rotation, cf);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_270:
|
||||
lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf);
|
||||
break;
|
||||
}
|
||||
color_p = dsc->rotated_buf;
|
||||
|
||||
/* Rotate the area */
|
||||
rotated_area = *area;
|
||||
lv_display_rotate_area(disp, &rotated_area);
|
||||
area = &rotated_area;
|
||||
|
||||
if(rotation != LV_DISPLAY_ROTATION_180) {
|
||||
w = lv_area_get_width(area);
|
||||
h = lv_area_get_height(area);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that we're within the framebuffer's bounds */
|
||||
if(area->x2 < 0 || area->y2 < 0 || area->x1 > (int32_t)dsc->vinfo.xres - 1 || area->y1 > (int32_t)dsc->vinfo.yres - 1) {
|
||||
lv_display_flush_ready(disp);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t fb_pos =
|
||||
(area->x1 + dsc->vinfo.xoffset) * px_size +
|
||||
(area->y1 + dsc->vinfo.yoffset) * dsc->finfo.line_length;
|
||||
|
||||
int32_t y;
|
||||
if(LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_DIRECT) {
|
||||
uint32_t color_pos =
|
||||
area->x1 * px_size +
|
||||
area->y1 * disp->hor_res * px_size;
|
||||
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
write_to_fb(dsc, fb_pos, &color_p[color_pos], w * px_size);
|
||||
fb_pos += dsc->finfo.line_length;
|
||||
color_pos += disp->hor_res * px_size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
w = lv_area_get_width(area);
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
write_to_fb(dsc, fb_pos, color_p, w * px_size);
|
||||
fb_pos += dsc->finfo.line_length;
|
||||
color_p += w * px_size;
|
||||
}
|
||||
}
|
||||
|
||||
if(dsc->force_refresh) {
|
||||
dsc->vinfo.activate |= FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
|
||||
if(ioctl(dsc->fbfd, FBIOPUT_VSCREENINFO, &(dsc->vinfo)) == -1) {
|
||||
perror("Error setting var screen info");
|
||||
}
|
||||
}
|
||||
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
static uint32_t tick_get_cb(void)
|
||||
{
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
uint64_t time_ms = t.tv_sec * 1000 + (t.tv_nsec / 1000000);
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_LINUX_FBDEV*/
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @file lv_linux_fbdev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LINUX_FBDEV_H
|
||||
#define LV_LINUX_FBDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
lv_display_t * lv_linux_fbdev_create(void);
|
||||
|
||||
void lv_linux_fbdev_set_file(lv_display_t * disp, const char * file);
|
||||
|
||||
/**
|
||||
* Force the display to be refreshed on every change.
|
||||
* Expected to be used with LV_DISPLAY_RENDER_MODE_DIRECT or LV_DISPLAY_RENDER_MODE_FULL.
|
||||
*/
|
||||
void lv_linux_fbdev_set_force_refresh(lv_display_t * disp, bool enabled);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* LV_USE_LINUX_FBDEV */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_LINUX_FBDEV_H */
|
||||
@@ -0,0 +1,399 @@
|
||||
/**
|
||||
* @file lv_ft81x.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_ft81x.h"
|
||||
#if LV_USE_FT81X
|
||||
|
||||
#include "lv_ft81x_defines.h"
|
||||
|
||||
#include "../../../stdlib/lv_mem.h"
|
||||
#include "../../../stdlib/lv_sprintf.h"
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
#include "../../../misc/lv_types.h"
|
||||
#include "../../../misc/lv_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* Increase as functionality is added if needed. */
|
||||
#define LV_FT81X_CMD_BUF_SIZE 63
|
||||
|
||||
/* The PWM value that corresponds to the backlight being "on".
|
||||
0x80 was found to work on at least two boards but should
|
||||
be changed as needed. */
|
||||
#define PWM_DUTY_BACKLIGHT_ON 0x80
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_ft81x_spi_cb_t spi_cb;
|
||||
void * user_data;
|
||||
uint16_t cmd_offset;
|
||||
} lv_ft81x_driver_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t buf_len;
|
||||
uint8_t buf[LV_FT81X_CMD_BUF_SIZE];
|
||||
} lv_ft81x_cmd_list_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static lv_result_t initialize(lv_display_t * disp, const lv_ft81x_parameters_t * params);
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
static void delete_cb(lv_event_t * e);
|
||||
static void lv_ft81x_cmd(lv_display_t * disp, uint8_t command, uint8_t parameter);
|
||||
static uint8_t lv_ft81x_read_8(lv_display_t * disp, uint32_t address);
|
||||
static uint16_t lv_ft81x_read_16(lv_display_t * disp, uint32_t address);
|
||||
/* static uint32_t lv_ft81x_read_32(lv_display_t * disp, uint32_t address); */
|
||||
static void lv_ft81x_write_8(lv_display_t * disp, uint32_t address, uint8_t val);
|
||||
static void lv_ft81x_write_16(lv_display_t * disp, uint32_t address, uint16_t val);
|
||||
static void lv_ft81x_write_32(lv_display_t * disp, uint32_t address, uint32_t val);
|
||||
static void lv_ft81x_cmd_list_init(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list);
|
||||
static void lv_ft81x_cmd_list_add_16(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint16_t value);
|
||||
static void lv_ft81x_cmd_list_add_32(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint32_t value);
|
||||
static void lv_ft81x_cmd_list_send(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list);
|
||||
static void lv_ft81x_encode_read_address(void * dst_4_bytes, uint32_t address);
|
||||
static void lv_ft81x_encode_write_address(void * dst_3_bytes, uint32_t address);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if LV_BIG_ENDIAN_SYSTEM
|
||||
#define BE_TO_OR_FROM_NATIVE_32(x) ((uint32_t)(x))
|
||||
#define BE_TO_OR_FROM_NATIVE_16(x) ((uint16_t)(x))
|
||||
#define LE_TO_OR_FROM_NATIVE_32(x) lv_swap_bytes_32(x)
|
||||
#define LE_TO_OR_FROM_NATIVE_16(x) lv_swap_bytes_16(x)
|
||||
#else
|
||||
#define BE_TO_OR_FROM_NATIVE_32(x) lv_swap_bytes_32(x)
|
||||
#define BE_TO_OR_FROM_NATIVE_16(x) lv_swap_bytes_16(x)
|
||||
#define LE_TO_OR_FROM_NATIVE_32(x) ((uint32_t)(x))
|
||||
#define LE_TO_OR_FROM_NATIVE_16(x) ((uint16_t)(x))
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_ft81x_create(const lv_ft81x_parameters_t * params, void * partial_buf, uint32_t buf_size,
|
||||
lv_ft81x_spi_cb_t spi_cb, void * user_data)
|
||||
{
|
||||
LV_ASSERT_NULL(spi_cb);
|
||||
|
||||
lv_display_t * disp = lv_display_create(params->hor_res, params->ver_res);
|
||||
|
||||
lv_ft81x_driver_data_t * drv = lv_malloc_zeroed(sizeof(lv_ft81x_driver_data_t));
|
||||
LV_ASSERT_MALLOC(drv);
|
||||
drv->spi_cb = spi_cb;
|
||||
drv->user_data = user_data;
|
||||
drv->cmd_offset = 0;
|
||||
lv_display_set_driver_data(disp, drv);
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB565);
|
||||
lv_display_set_buffers(disp, partial_buf, NULL, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
lv_display_add_event_cb(disp, delete_cb, LV_EVENT_DELETE, NULL);
|
||||
|
||||
lv_result_t init_res = initialize(disp, params);
|
||||
if(init_res != LV_RESULT_OK) {
|
||||
lv_display_delete(disp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
void * lv_ft81x_get_user_data(lv_display_t * disp)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
return drv->user_data;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_result_t initialize(lv_display_t * disp, const lv_ft81x_parameters_t * params)
|
||||
{
|
||||
lv_ft81x_cmd(disp, params->has_crystal ? EVE_CLKEXT : EVE_CLKINT, 0);
|
||||
if(params->is_bt81x) lv_ft81x_cmd(disp, EVE_CLKSEL, 0x46);
|
||||
lv_ft81x_cmd(disp, EVE_ACTIVE, 0);
|
||||
|
||||
/* at least 40 ms is needed for EVE to become ready. */
|
||||
lv_delay_ms(40);
|
||||
|
||||
uint32_t start_millis = lv_tick_get();
|
||||
while(lv_ft81x_read_8(disp, REG_ID) != 0x7c) {
|
||||
if(lv_tick_get() - start_millis > 1000) {
|
||||
LV_LOG_ERROR("failed to read 0x7C from the ID register 1000 ms after activation.");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
lv_delay_ms(1);
|
||||
};
|
||||
|
||||
start_millis = lv_tick_get();
|
||||
while(lv_ft81x_read_8(disp, REG_CPURESET) & 0x03) {
|
||||
if(lv_tick_get() - start_millis > 1000) {
|
||||
LV_LOG_ERROR("CPURESET register coprocessor and touch engines not in \"working status\" 1000 ms after activation.");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
lv_delay_ms(1);
|
||||
};
|
||||
|
||||
if(params->is_bt81x) lv_ft81x_write_32(disp, REG_FREQUENCY, 72000000);
|
||||
|
||||
lv_ft81x_write_8(disp, REG_PWM_DUTY, PWM_DUTY_BACKLIGHT_ON);
|
||||
|
||||
lv_ft81x_write_16(disp, REG_HSIZE, params->hor_res); /* active display width */
|
||||
lv_ft81x_write_16(disp, REG_HCYCLE, params->hcycle); /* total number of clocks per line, incl front/back porch */
|
||||
lv_ft81x_write_16(disp, REG_HOFFSET, params->hoffset); /* start of active line */
|
||||
lv_ft81x_write_16(disp, REG_HSYNC0, params->hsync0); /* start of horizontal sync pulse */
|
||||
lv_ft81x_write_16(disp, REG_HSYNC1, params->hsync1); /* end of horizontal sync pulse */
|
||||
lv_ft81x_write_16(disp, REG_VSIZE, params->ver_res); /* active display height */
|
||||
lv_ft81x_write_16(disp, REG_VCYCLE, params->vcycle); /* total number of lines per screen, including pre/post */
|
||||
lv_ft81x_write_16(disp, REG_VOFFSET, params->voffset); /* start of active screen */
|
||||
lv_ft81x_write_16(disp, REG_VSYNC0, params->vsync0); /* start of vertical sync pulse */
|
||||
lv_ft81x_write_16(disp, REG_VSYNC1, params->vsync1); /* end of vertical sync pulse */
|
||||
lv_ft81x_write_8(disp, REG_SWIZZLE, params->swizzle); /* FT8xx output to LCD - pin order */
|
||||
lv_ft81x_write_8(disp, REG_PCLK_POL, params->pclkpol); /* LCD data is clocked in on this PCLK edge */
|
||||
lv_ft81x_write_8(disp, REG_CSPREAD,
|
||||
params->cspread); /* helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */
|
||||
|
||||
/* write a basic display-list to get things started */
|
||||
lv_ft81x_write_32(disp, EVE_RAM_DL, DL_CLEAR_RGB);
|
||||
lv_ft81x_write_32(disp, EVE_RAM_DL + 4, (DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG));
|
||||
lv_ft81x_write_32(disp, EVE_RAM_DL + 8, DL_DISPLAY); /* end of display list */
|
||||
lv_ft81x_write_32(disp, REG_DLSWAP, EVE_DLSWAP_FRAME);
|
||||
|
||||
/* nothing is being displayed yet... the pixel clock is still 0x00 */
|
||||
lv_ft81x_write_8(disp, REG_GPIO,
|
||||
0x80); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIO_DIR by default */
|
||||
lv_ft81x_write_8(disp, REG_PCLK, params->pclk); /* now start clocking data to the LCD panel */
|
||||
|
||||
LV_ASSERT(lv_ft81x_read_16(disp, REG_CMD_READ) != 0xfff);
|
||||
|
||||
LV_ASSERT(0 == lv_ft81x_read_16(disp, REG_CMD_WRITE));
|
||||
|
||||
|
||||
lv_ft81x_cmd_list_t cmd_list;
|
||||
lv_ft81x_cmd_list_init(disp, &cmd_list);
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_MEMSET);
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, 0); /* address */
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, 0x00); /* val */
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, 2 * params->hor_res * params->ver_res); /* count */
|
||||
lv_ft81x_cmd_list_send(disp, &cmd_list);
|
||||
|
||||
lv_ft81x_cmd_list_init(disp, &cmd_list);
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_DLSTART);
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_CLEAR_RGB | 0); /* clear to black */
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, TAG(0));
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, TAG(20));
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_SETBITMAP);
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, 0); /* address */
|
||||
lv_ft81x_cmd_list_add_16(disp, &cmd_list, EVE_RGB565);
|
||||
lv_ft81x_cmd_list_add_16(disp, &cmd_list, params->hor_res);
|
||||
lv_ft81x_cmd_list_add_16(disp, &cmd_list, params->ver_res);
|
||||
lv_ft81x_cmd_list_add_16(disp, &cmd_list, 0);
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_BEGIN | EVE_BITMAPS);
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, VERTEX2F(0, 0));
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_END);
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, TAG(0));
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_DISPLAY);
|
||||
|
||||
lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_SWAP);
|
||||
|
||||
lv_ft81x_cmd_list_send(disp, &cmd_list);
|
||||
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
|
||||
if(drv->spi_cb == NULL) {
|
||||
LV_LOG_ERROR("The SPI callback is NULL.");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t hor_res = lv_display_get_horizontal_resolution(disp);
|
||||
uint32_t disp_row_bytes = hor_res * 2;
|
||||
|
||||
uint32_t address = disp_row_bytes * area->y1 + area->x1 * 2;
|
||||
uint8_t encoded_address[3];
|
||||
|
||||
if(lv_area_get_width(area) == hor_res) {
|
||||
lv_ft81x_encode_write_address(encoded_address, address);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, encoded_address, sizeof(encoded_address));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, px_map, lv_area_get_size(area) * 2);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
}
|
||||
else {
|
||||
uint32_t area_height = lv_area_get_height(area);
|
||||
uint32_t area_row_bytes = lv_area_get_width(area) * 2;
|
||||
for(uint32_t i = 0; i < area_height; i++) {
|
||||
lv_ft81x_encode_write_address(encoded_address, address);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, encoded_address, sizeof(encoded_address));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, px_map, area_row_bytes);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
address += disp_row_bytes;
|
||||
px_map += area_row_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
static void delete_cb(lv_event_t * e)
|
||||
{
|
||||
lv_display_t * disp = lv_event_get_target(e);
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
lv_free(drv);
|
||||
}
|
||||
|
||||
static void lv_ft81x_cmd(lv_display_t * disp, uint8_t command, uint8_t parameter)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
uint8_t data[3] = {command, parameter, 0x00};
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
}
|
||||
|
||||
static uint8_t lv_ft81x_read_8(lv_display_t * disp, uint32_t address)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
lv_ft81x_encode_read_address(&address, address);
|
||||
uint8_t val;
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, &address, sizeof(address));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_RECEIVE, &val, sizeof(val));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint16_t lv_ft81x_read_16(lv_display_t * disp, uint32_t address)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
lv_ft81x_encode_read_address(&address, address);
|
||||
uint16_t val;
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, &address, sizeof(address));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_RECEIVE, &val, sizeof(val));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
val = LE_TO_OR_FROM_NATIVE_16(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void lv_ft81x_write_8(lv_display_t * disp, uint32_t address, uint8_t val)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
uint8_t data[4];
|
||||
lv_ft81x_encode_write_address(data, address);
|
||||
data[3] = val;
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
}
|
||||
|
||||
static void lv_ft81x_write_16(lv_display_t * disp, uint32_t address, uint16_t val)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
val = LE_TO_OR_FROM_NATIVE_16(val);
|
||||
uint8_t data[5];
|
||||
lv_ft81x_encode_write_address(data, address);
|
||||
lv_memcpy(data + 3, &val, 2);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
}
|
||||
|
||||
static void lv_ft81x_write_32(lv_display_t * disp, uint32_t address, uint32_t val)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
val = LE_TO_OR_FROM_NATIVE_32(val);
|
||||
uint8_t data[7];
|
||||
lv_ft81x_encode_write_address(data, address);
|
||||
lv_memcpy(data + 3, &val, 4);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data));
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
}
|
||||
|
||||
static void lv_ft81x_cmd_list_init(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
LV_ASSERT_MSG(LV_FT81X_CMD_BUF_SIZE >= 3, "increase LV_FT81X_CMD_BUF_SIZE as needed");
|
||||
lv_ft81x_encode_write_address(cmd_list->buf, EVE_RAM_CMD + drv->cmd_offset);
|
||||
cmd_list->buf_len = 3;
|
||||
}
|
||||
|
||||
static void lv_ft81x_cmd_list_add_16(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint16_t value)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
uint8_t * buf_dst = &cmd_list->buf[cmd_list->buf_len];
|
||||
cmd_list->buf_len += 2;
|
||||
LV_ASSERT_MSG(cmd_list->buf_len <= LV_FT81X_CMD_BUF_SIZE, "increase LV_FT81X_CMD_BUF_SIZE as needed");
|
||||
value = LE_TO_OR_FROM_NATIVE_16(value);
|
||||
lv_memcpy(buf_dst, &value, 2);
|
||||
drv->cmd_offset = (drv->cmd_offset + 2) & 0xfff; /* circular */
|
||||
}
|
||||
|
||||
static void lv_ft81x_cmd_list_add_32(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint32_t value)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
uint8_t * buf_dst = &cmd_list->buf[cmd_list->buf_len];
|
||||
cmd_list->buf_len += 4;
|
||||
LV_ASSERT_MSG(cmd_list->buf_len <= LV_FT81X_CMD_BUF_SIZE, "increase LV_FT81X_CMD_BUF_SIZE as needed");
|
||||
value = LE_TO_OR_FROM_NATIVE_32(value);
|
||||
lv_memcpy(buf_dst, &value, 4);
|
||||
drv->cmd_offset = (drv->cmd_offset + 4) & 0xfff; /* circular */
|
||||
}
|
||||
|
||||
static void lv_ft81x_cmd_list_send(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list)
|
||||
{
|
||||
lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, cmd_list->buf, cmd_list->buf_len);
|
||||
drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
lv_ft81x_write_16(disp, REG_CMD_WRITE, drv->cmd_offset);
|
||||
}
|
||||
|
||||
static void lv_ft81x_encode_read_address(void * dst_4_bytes, uint32_t address)
|
||||
{
|
||||
address = BE_TO_OR_FROM_NATIVE_32(address << 8);
|
||||
lv_memcpy(dst_4_bytes, &address, 4);
|
||||
}
|
||||
|
||||
static void lv_ft81x_encode_write_address(void * dst_3_bytes, uint32_t address)
|
||||
{
|
||||
address = BE_TO_OR_FROM_NATIVE_32((address | 0x800000) << 8);
|
||||
lv_memcpy(dst_3_bytes, &address, 3);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_FT81X*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file lv_ft81x.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FT81X_H
|
||||
#define LV_FT81X_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_FT81X
|
||||
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
uint16_t hor_res;
|
||||
uint16_t ver_res;
|
||||
|
||||
uint16_t hcycle;
|
||||
uint16_t hoffset;
|
||||
uint16_t hsync0;
|
||||
uint16_t hsync1;
|
||||
uint16_t vcycle;
|
||||
uint16_t voffset;
|
||||
uint16_t vsync0;
|
||||
uint16_t vsync1;
|
||||
uint8_t swizzle;
|
||||
uint8_t pclkpol;
|
||||
uint8_t cspread;
|
||||
uint8_t pclk;
|
||||
|
||||
bool has_crystal;
|
||||
bool is_bt81x;
|
||||
} lv_ft81x_parameters_t;
|
||||
|
||||
typedef enum {
|
||||
LV_FT81X_SPI_OPERATION_CS_ASSERT,
|
||||
LV_FT81X_SPI_OPERATION_CS_DEASSERT,
|
||||
LV_FT81X_SPI_OPERATION_SEND,
|
||||
LV_FT81X_SPI_OPERATION_RECEIVE
|
||||
} lv_ft81x_spi_operation;
|
||||
|
||||
typedef void (*lv_ft81x_spi_cb_t)(lv_display_t * disp, lv_ft81x_spi_operation operation, void * data, uint32_t length);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a framebuffer-based ft81x driver display.
|
||||
* @param params pointer to a struct of display panel properties. does not need to be static.
|
||||
* @param partial_buf a single partial buffer
|
||||
* @param buf_size size of the partial buffer
|
||||
* @param spi_cb a callback called by the driver to perform SPI operations
|
||||
* @param user_data use `lv_ft81x_get_user_data` to get this pointer inside the SPI callback
|
||||
* @return pointer to the display
|
||||
*/
|
||||
lv_display_t * lv_ft81x_create(const lv_ft81x_parameters_t * params, void * partial_buf, uint32_t buf_size,
|
||||
lv_ft81x_spi_cb_t spi_cb, void * user_data);
|
||||
|
||||
/**
|
||||
* Get the `user_data` parameter that was passed to `lv_ft81x_create`. Useful in the SPI callback.
|
||||
* @param disp pointer to the ft81x display
|
||||
* @return the `user_data` pointer
|
||||
*/
|
||||
void * lv_ft81x_get_user_data(lv_display_t * disp);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_FT81X*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_FT81X_H*/
|
||||
@@ -0,0 +1,846 @@
|
||||
/**
|
||||
* @file lv_ft81x_defines.h
|
||||
*
|
||||
* Copied from https://github.com/lvgl/lvgl_esp32_drivers/blob/9fed1cc47b5a45fec6bae08b55d2147d3b50260c/lvgl_tft/EVE.h
|
||||
*/
|
||||
|
||||
#ifndef LV_FT81X_DEFINES_H
|
||||
#define LV_FT81X_DEFINES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* ft81x and ft80x each define exclusive
|
||||
* definitions. Define ft81x for now.
|
||||
*
|
||||
* bt81x is a superset of ft81x and ft80x.
|
||||
* Don't define it since its special
|
||||
* definitions are not required to use it.
|
||||
*/
|
||||
#define FT81X_ENABLE
|
||||
/* #define BT81X_ENABLE */
|
||||
|
||||
|
||||
#define DL_CLEAR 0x26000000UL /* requires OR'd arguments */
|
||||
#define DL_CLEAR_RGB 0x02000000UL /* requires OR'd arguments */
|
||||
#define DL_COLOR_RGB 0x04000000UL /* requires OR'd arguments */
|
||||
#define DL_POINT_SIZE 0x0D000000UL /* requires OR'd arguments */
|
||||
#define DL_END 0x21000000UL
|
||||
#define DL_BEGIN 0x1F000000UL /* requires OR'd arguments */
|
||||
#define DL_DISPLAY 0x00000000UL
|
||||
|
||||
#define CLR_COL 0x4
|
||||
#define CLR_STN 0x2
|
||||
#define CLR_TAG 0x1
|
||||
|
||||
/* SPI SIO/DIO/QIO tranfer widths */
|
||||
#define SPI_WIDTH_SIO 0x0
|
||||
#define SPI_WIDTH_DIO 0x1
|
||||
#define SPI_WIDTH_QIO 0x2
|
||||
|
||||
|
||||
/* Host commands */
|
||||
#define EVE_ACTIVE 0x00 /* place FT8xx in active state */
|
||||
#define EVE_STANDBY 0x41 /* place FT8xx in Standby (clk running) */
|
||||
#define EVE_SLEEP 0x42 /* place FT8xx in Sleep (clk off) */
|
||||
#define EVE_PWRDOWN 0x50 /* place FT8xx in Power Down (core off) */
|
||||
#define EVE_CLKEXT 0x44 /* select external clock source */
|
||||
#define EVE_CLKINT 0x48 /* select internal clock source */
|
||||
#define EVE_CORERST 0x68 /* reset core - all registers default and processors reset */
|
||||
#define EVE_CLK48M 0x62 /* select 48MHz PLL output */
|
||||
#define EVE_CLK36M 0x61 /* select 36MHz PLL output */
|
||||
|
||||
|
||||
/* defines used for graphics commands */
|
||||
#define EVE_NEVER 0UL
|
||||
#define EVE_LESS 1UL
|
||||
#define EVE_LEQUAL 2UL
|
||||
#define EVE_GREATER 3UL
|
||||
#define EVE_GEQUAL 4UL
|
||||
#define EVE_EQUAL 5UL
|
||||
#define EVE_NOTEQUAL 6UL
|
||||
#define EVE_ALWAYS 7UL
|
||||
|
||||
|
||||
/* Bitmap formats */
|
||||
#define EVE_ARGB1555 0UL
|
||||
#define EVE_L1 1UL
|
||||
#define EVE_L4 2UL
|
||||
#define EVE_L8 3UL
|
||||
#define EVE_RGB332 4UL
|
||||
#define EVE_ARGB2 5UL
|
||||
#define EVE_ARGB4 6UL
|
||||
#define EVE_RGB565 7UL
|
||||
#define EVE_PALETTED 8UL
|
||||
#define EVE_TEXT8X8 9UL
|
||||
#define EVE_TEXTVGA 10UL
|
||||
#define EVE_BARGRAPH 11UL
|
||||
|
||||
|
||||
/* Bitmap filter types */
|
||||
#define EVE_NEAREST 0UL
|
||||
#define EVE_BILINEAR 1UL
|
||||
|
||||
|
||||
/* Bitmap wrap types */
|
||||
#define EVE_BORDER 0UL
|
||||
#define EVE_REPEAT 1UL
|
||||
|
||||
|
||||
/* Stencil defines */
|
||||
#define EVE_KEEP 1UL
|
||||
#define EVE_REPLACE 2UL
|
||||
#define EVE_INCR 3UL
|
||||
#define EVE_DECR 4UL
|
||||
#define EVE_INVERT 5UL
|
||||
|
||||
|
||||
/* Graphics display list swap defines */
|
||||
#define EVE_DLSWAP_DONE 0UL
|
||||
#define EVE_DLSWAP_LINE 1UL
|
||||
#define EVE_DLSWAP_FRAME 2UL
|
||||
|
||||
|
||||
/* Interrupt bits */
|
||||
#define EVE_INT_SWAP 0x01
|
||||
#define EVE_INT_TOUCH 0x02
|
||||
#define EVE_INT_TAG 0x04
|
||||
#define EVE_INT_SOUND 0x08
|
||||
#define EVE_INT_PLAYBACK 0x10
|
||||
#define EVE_INT_CMDEMPTY 0x20
|
||||
#define EVE_INT_CMDFLAG 0x40
|
||||
#define EVE_INT_CONVCOMPLETE 0x80
|
||||
|
||||
|
||||
/* Touch mode */
|
||||
#define EVE_TMODE_OFF 0
|
||||
#define EVE_TMODE_ONESHOT 1
|
||||
#define EVE_TMODE_FRAME 2
|
||||
#define EVE_TMODE_CONTINUOUS 3
|
||||
|
||||
|
||||
/* Alpha blending */
|
||||
#define EVE_ZERO 0UL
|
||||
#define EVE_ONE 1UL
|
||||
#define EVE_SRC_ALPHA 2UL
|
||||
#define EVE_DST_ALPHA 3UL
|
||||
#define EVE_ONE_MINUS_SRC_ALPHA 4UL
|
||||
#define EVE_ONE_MINUS_DST_ALPHA 5UL
|
||||
|
||||
|
||||
/* Graphics primitives */
|
||||
#define EVE_BITMAPS 1UL
|
||||
#define EVE_POINTS 2UL
|
||||
#define EVE_LINES 3UL
|
||||
#define EVE_LINE_STRIP 4UL
|
||||
#define EVE_EDGE_STRIP_R 5UL
|
||||
#define EVE_EDGE_STRIP_L 6UL
|
||||
#define EVE_EDGE_STRIP_A 7UL
|
||||
#define EVE_EDGE_STRIP_B 8UL
|
||||
#define EVE_RECTS 9UL
|
||||
|
||||
|
||||
/* Widget command */
|
||||
#define EVE_OPT_MONO 1
|
||||
#define EVE_OPT_NODL 2
|
||||
#define EVE_OPT_FLAT 256
|
||||
#define EVE_OPT_CENTERX 512
|
||||
#define EVE_OPT_CENTERY 1024
|
||||
#define EVE_OPT_CENTER (EVE_OPT_CENTERX | EVE_OPT_CENTERY)
|
||||
#define EVE_OPT_NOBACK 4096
|
||||
#define EVE_OPT_NOTICKS 8192
|
||||
#define EVE_OPT_NOHM 16384
|
||||
#define EVE_OPT_NOPOINTER 16384
|
||||
#define EVE_OPT_NOSECS 32768
|
||||
#define EVE_OPT_NOHANDS 49152
|
||||
#define EVE_OPT_RIGHTX 2048
|
||||
#define EVE_OPT_SIGNED 256
|
||||
|
||||
|
||||
/* Defines related to inbuilt font */
|
||||
#define EVE_NUMCHAR_PERFONT (128L) /* number of font characters per bitmap handle */
|
||||
#define EVE_FONT_TABLE_SIZE (148L) /* size of the font table - utilized for loopup by the graphics engine */
|
||||
#define EVE_FONT_TABLE_POINTER (0xFFFFCUL) /* pointer to the inbuilt font tables starting from bitmap handle 16 */
|
||||
|
||||
|
||||
/* Audio sample type defines */
|
||||
#define EVE_LINEAR_SAMPLES 0UL /* 8bit signed samples */
|
||||
#define EVE_ULAW_SAMPLES 1UL /* 8bit ulaw samples */
|
||||
#define EVE_ADPCM_SAMPLES 2UL /* 4bit ima adpcm samples */
|
||||
|
||||
|
||||
/* Synthesized sound */
|
||||
#define EVE_SILENCE 0x00
|
||||
#define EVE_SQUAREWAVE 0x01
|
||||
#define EVE_SINEWAVE 0x02
|
||||
#define EVE_SAWTOOTH 0x03
|
||||
#define EVE_TRIANGLE 0x04
|
||||
#define EVE_BEEPING 0x05
|
||||
#define EVE_ALARM 0x06
|
||||
#define EVE_WARBLE 0x07
|
||||
#define EVE_CAROUSEL 0x08
|
||||
#define EVE_PIPS(n) (0x0F + (n))
|
||||
#define EVE_HARP 0x40
|
||||
#define EVE_XYLOPHONE 0x41
|
||||
#define EVE_TUBA 0x42
|
||||
#define EVE_GLOCKENSPIEL 0x43
|
||||
#define EVE_ORGAN 0x44
|
||||
#define EVE_TRUMPET 0x45
|
||||
#define EVE_PIANO 0x46
|
||||
#define EVE_CHIMES 0x47
|
||||
#define EVE_MUSICBOX 0x48
|
||||
#define EVE_BELL 0x49
|
||||
#define EVE_CLICK 0x50
|
||||
#define EVE_SWITCH 0x51
|
||||
#define EVE_COWBELL 0x52
|
||||
#define EVE_NOTCH 0x53
|
||||
#define EVE_HIHAT 0x54
|
||||
#define EVE_KICKDRUM 0x55
|
||||
#define EVE_POP 0x56
|
||||
#define EVE_CLACK 0x57
|
||||
#define EVE_CHACK 0x58
|
||||
#define EVE_MUTE 0x60
|
||||
#define EVE_UNMUTE 0x61
|
||||
|
||||
|
||||
/* Synthesized sound frequencies, midi note */
|
||||
#define EVE_MIDI_A0 21
|
||||
#define EVE_MIDI_A_0 22
|
||||
#define EVE_MIDI_B0 23
|
||||
#define EVE_MIDI_C1 24
|
||||
#define EVE_MIDI_C_1 25
|
||||
#define EVE_MIDI_D1 26
|
||||
#define EVE_MIDI_D_1 27
|
||||
#define EVE_MIDI_E1 28
|
||||
#define EVE_MIDI_F1 29
|
||||
#define EVE_MIDI_F_1 30
|
||||
#define EVE_MIDI_G1 31
|
||||
#define EVE_MIDI_G_1 32
|
||||
#define EVE_MIDI_A1 33
|
||||
#define EVE_MIDI_A_1 34
|
||||
#define EVE_MIDI_B1 35
|
||||
#define EVE_MIDI_C2 36
|
||||
#define EVE_MIDI_C_2 37
|
||||
#define EVE_MIDI_D2 38
|
||||
#define EVE_MIDI_D_2 39
|
||||
#define EVE_MIDI_E2 40
|
||||
#define EVE_MIDI_F2 41
|
||||
#define EVE_MIDI_F_2 42
|
||||
#define EVE_MIDI_G2 43
|
||||
#define EVE_MIDI_G_2 44
|
||||
#define EVE_MIDI_A2 45
|
||||
#define EVE_MIDI_A_2 46
|
||||
#define EVE_MIDI_B2 47
|
||||
#define EVE_MIDI_C3 48
|
||||
#define EVE_MIDI_C_3 49
|
||||
#define EVE_MIDI_D3 50
|
||||
#define EVE_MIDI_D_3 51
|
||||
#define EVE_MIDI_E3 52
|
||||
#define EVE_MIDI_F3 53
|
||||
#define EVE_MIDI_F_3 54
|
||||
#define EVE_MIDI_G3 55
|
||||
#define EVE_MIDI_G_3 56
|
||||
#define EVE_MIDI_A3 57
|
||||
#define EVE_MIDI_A_3 58
|
||||
#define EVE_MIDI_B3 59
|
||||
#define EVE_MIDI_C4 60
|
||||
#define EVE_MIDI_C_4 61
|
||||
#define EVE_MIDI_D4 62
|
||||
#define EVE_MIDI_D_4 63
|
||||
#define EVE_MIDI_E4 64
|
||||
#define EVE_MIDI_F4 65
|
||||
#define EVE_MIDI_F_4 66
|
||||
#define EVE_MIDI_G4 67
|
||||
#define EVE_MIDI_G_4 68
|
||||
#define EVE_MIDI_A4 69
|
||||
#define EVE_MIDI_A_4 70
|
||||
#define EVE_MIDI_B4 71
|
||||
#define EVE_MIDI_C5 72
|
||||
#define EVE_MIDI_C_5 73
|
||||
#define EVE_MIDI_D5 74
|
||||
#define EVE_MIDI_D_5 75
|
||||
#define EVE_MIDI_E5 76
|
||||
#define EVE_MIDI_F5 77
|
||||
#define EVE_MIDI_F_5 78
|
||||
#define EVE_MIDI_G5 79
|
||||
#define EVE_MIDI_G_5 80
|
||||
#define EVE_MIDI_A5 81
|
||||
#define EVE_MIDI_A_5 82
|
||||
#define EVE_MIDI_B5 83
|
||||
#define EVE_MIDI_C6 84
|
||||
#define EVE_MIDI_C_6 85
|
||||
#define EVE_MIDI_D6 86
|
||||
#define EVE_MIDI_D_6 87
|
||||
#define EVE_MIDI_E6 88
|
||||
#define EVE_MIDI_F6 89
|
||||
#define EVE_MIDI_F_6 90
|
||||
#define EVE_MIDI_G6 91
|
||||
#define EVE_MIDI_G_6 92
|
||||
#define EVE_MIDI_A6 93
|
||||
#define EVE_MIDI_A_6 94
|
||||
#define EVE_MIDI_B6 95
|
||||
#define EVE_MIDI_C7 96
|
||||
#define EVE_MIDI_C_7 97
|
||||
#define EVE_MIDI_D7 98
|
||||
#define EVE_MIDI_D_7 99
|
||||
#define EVE_MIDI_E7 100
|
||||
#define EVE_MIDI_F7 101
|
||||
#define EVE_MIDI_F_7 102
|
||||
#define EVE_MIDI_G7 103
|
||||
#define EVE_MIDI_G_7 104
|
||||
#define EVE_MIDI_A7 105
|
||||
#define EVE_MIDI_A_7 106
|
||||
#define EVE_MIDI_B7 107
|
||||
#define EVE_MIDI_C8 108
|
||||
|
||||
|
||||
/* GPIO bits */
|
||||
#define EVE_GPIO0 0
|
||||
#define EVE_GPIO1 1 /* default gpio pin for audio shutdown, 1 - enable, 0 - disable */
|
||||
#define EVE_GPIO7 7 /* default gpio pin for display enable, 1 - enable, 0 - disable */
|
||||
|
||||
|
||||
/* Display rotation */
|
||||
#define EVE_DISPLAY_0 0 /* 0 degrees rotation */
|
||||
#define EVE_DISPLAY_180 1 /* 180 degrees rotation */
|
||||
|
||||
|
||||
/* commands common to EVE/EVE2/EVE3 */
|
||||
#define CMD_APPEND 0xFFFFFF1E
|
||||
#define CMD_BGCOLOR 0xFFFFFF09
|
||||
#define CMD_BUTTON 0xFFFFFF0D
|
||||
#define CMD_CALIBRATE 0xFFFFFF15
|
||||
#define CMD_CLOCK 0xFFFFFF14
|
||||
#define CMD_COLDSTART 0xFFFFFF32
|
||||
#define CMD_DIAL 0xFFFFFF2D
|
||||
#define CMD_DLSTART 0xFFFFFF00
|
||||
#define CMD_FGCOLOR 0xFFFFFF0A
|
||||
#define CMD_GAUGE 0xFFFFFF13
|
||||
#define CMD_GETMATRIX 0xFFFFFF33
|
||||
#define CMD_GETPROPS 0xFFFFFF25
|
||||
#define CMD_GETPTR 0xFFFFFF23
|
||||
#define CMD_GRADCOLOR 0xFFFFFF34
|
||||
#define CMD_GRADIENT 0xFFFFFF0B
|
||||
#define CMD_INFLATE 0xFFFFFF22
|
||||
#define CMD_INTERRUPT 0xFFFFFF02
|
||||
#define CMD_KEYS 0xFFFFFF0E
|
||||
#define CMD_LOADIDENTITY 0xFFFFFF26
|
||||
#define CMD_LOADIMAGE 0xFFFFFF24
|
||||
#define CMD_LOGO 0xFFFFFF31
|
||||
#define CMD_MEMCPY 0xFFFFFF1D
|
||||
#define CMD_MEMCRC 0xFFFFFF18
|
||||
#define CMD_MEMSET 0xFFFFFF1B
|
||||
#define CMD_MEMWRITE 0xFFFFFF1A
|
||||
#define CMD_MEMZERO 0xFFFFFF1C
|
||||
#define CMD_NUMBER 0xFFFFFF2E
|
||||
#define CMD_PROGRESS 0xFFFFFF0F
|
||||
#define CMD_REGREAD 0xFFFFFF19
|
||||
#define CMD_ROTATE 0xFFFFFF29
|
||||
#define CMD_SCALE 0xFFFFFF28
|
||||
#define CMD_SCREENSAVER 0xFFFFFF2F
|
||||
#define CMD_SCROLLBAR 0xFFFFFF11
|
||||
#define CMD_SETFONT 0xFFFFFF2B
|
||||
#define CMD_SETMATRIX 0xFFFFFF2A
|
||||
#define CMD_SKETCH 0xFFFFFF30
|
||||
#define CMD_SLIDER 0xFFFFFF10
|
||||
#define CMD_SNAPSHOT 0xFFFFFF1F
|
||||
#define CMD_SPINNER 0xFFFFFF16
|
||||
#define CMD_STOP 0xFFFFFF17
|
||||
#define CMD_SWAP 0xFFFFFF01
|
||||
#define CMD_TEXT 0xFFFFFF0C
|
||||
#define CMD_TOGGLE 0xFFFFFF12
|
||||
#define CMD_TRACK 0xFFFFFF2C
|
||||
#define CMD_TRANSLATE 0xFFFFFF27
|
||||
|
||||
|
||||
/* the following are undocumented commands that therefore should not be used */
|
||||
#if 0
|
||||
#define CMD_CRC 0xFFFFFF03
|
||||
#define CMD_HAMMERAUX 0xFFFFFF04
|
||||
#define CMD_MARCH 0xFFFFFF05
|
||||
#define CMD_IDCT 0xFFFFFF06
|
||||
#define CMD_EXECUTE 0xFFFFFF07
|
||||
#define CMD_GETPOINT 0xFFFFFF08
|
||||
#define CMD_TOUCH_TRANSFORM 0xFFFFFF20
|
||||
#endif
|
||||
|
||||
|
||||
/* FT8xx graphics engine specific macros useful for static display list generation */
|
||||
#define ALPHA_FUNC(func,ref) ((9UL<<24)|(((func)&7UL)<<8)|(((ref)&255UL)<<0))
|
||||
#define BEGIN(prim) ((31UL<<24)|(((prim)&15UL)<<0))
|
||||
#define BITMAP_HANDLE(handle) ((5UL<<24)|(((handle)&31UL)<<0))
|
||||
#define BITMAP_LAYOUT(format,linestride,height) ((7UL<<24)|(((format)&31UL)<<19)|(((linestride)&1023UL)<<9)|(((height)&511UL)<<0))
|
||||
#define BITMAP_SIZE(filter,wrapx,wrapy,width,height) ((8UL<<24)|(((filter)&1UL)<<20)|(((wrapx)&1UL)<<19)|(((wrapy)&1UL)<<18)|(((width)&511UL)<<9)|(((height)&511UL)<<0))
|
||||
#define BITMAP_TRANSFORM_A(a) ((21UL<<24)|(((a)&131071UL)<<0))
|
||||
#define BITMAP_TRANSFORM_B(b) ((22UL<<24)|(((b)&131071UL)<<0))
|
||||
#define BITMAP_TRANSFORM_C(c) ((23UL<<24)|(((c)&16777215UL)<<0))
|
||||
#define BITMAP_TRANSFORM_D(d) ((24UL<<24)|(((d)&131071UL)<<0))
|
||||
#define BITMAP_TRANSFORM_E(e) ((25UL<<24)|(((e)&131071UL)<<0))
|
||||
#define BITMAP_TRANSFORM_F(f) ((26UL<<24)|(((f)&16777215UL)<<0))
|
||||
#define BLEND_FUNC(src,dst) ((11UL<<24)|(((src)&7UL)<<3)|(((dst)&7UL)<<0))
|
||||
#define CALL(dest) ((29UL<<24)|(((dest)&65535UL)<<0))
|
||||
#define CELL(cell) ((6UL<<24)|(((cell)&127UL)<<0))
|
||||
#define CLEAR(c,s,t) ((38UL<<24)|(((c)&1UL)<<2)|(((s)&1UL)<<1)|(((t)&1UL)<<0))
|
||||
#define CLEAR_COLOR_A(alpha) ((15UL<<24)|(((alpha)&255UL)<<0))
|
||||
#define CLEAR_COLOR_RGB(red,green,blue) ((2UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0))
|
||||
#define CLEAR_STENCIL(s) ((17UL<<24)|(((s)&255UL)<<0))
|
||||
#define CLEAR_TAG(s) ((18UL<<24)|(((s)&255UL)<<0))
|
||||
#define COLOR_A(alpha) ((16UL<<24)|(((alpha)&255UL)<<0))
|
||||
#define COLOR_MASK(r,g,b,a) ((32UL<<24)|(((r)&1UL)<<3)|(((g)&1UL)<<2)|(((b)&1UL)<<1)|(((a)&1UL)<<0))
|
||||
#define COLOR_RGB(red,green,blue) ((4UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0))
|
||||
/* #define DISPLAY() ((0UL<<24)) */
|
||||
#define END() ((33UL<<24))
|
||||
#define JUMP(dest) ((30UL<<24)|(((dest)&65535UL)<<0))
|
||||
#define LINE_WIDTH(width) ((14UL<<24)|(((width)&4095UL)<<0))
|
||||
#define MACRO(m) ((37UL<<24)|(((m)&1UL)<<0))
|
||||
#define POINT_SIZE(size) ((13UL<<24)|(((size)&8191UL)<<0))
|
||||
#define RESTORE_CONTEXT() ((35UL<<24))
|
||||
#define RETURN() ((36UL<<24))
|
||||
#define SAVE_CONTEXT() ((34UL<<24))
|
||||
#define STENCIL_FUNC(func,ref,mask) ((10UL<<24)|(((func)&7UL)<<16)|(((ref)&255UL)<<8)|(((mask)&255UL)<<0))
|
||||
#define STENCIL_MASK(mask) ((19UL<<24)|(((mask)&255UL)<<0))
|
||||
#define STENCIL_OP(sfail,spass) ((12UL<<24)|(((sfail)&7UL)<<3)|(((spass)&7UL)<<0))
|
||||
#define TAG(s) ((3UL<<24)|(((s)&255UL)<<0))
|
||||
#define TAG_MASK(mask) ((20UL<<24)|(((mask)&1UL)<<0))
|
||||
#define VERTEX2F(x,y) ((1UL<<30)|(((x)&32767UL)<<15)|(((y)&32767UL)<<0))
|
||||
#define VERTEX2II(x,y,handle,cell) ((2UL<<30)|(((x)&511UL)<<21)|(((y)&511UL)<<12)|(((handle)&31UL)<<7)|(((cell)&127UL)<<0))
|
||||
|
||||
|
||||
/* ----------------- BT81x exclusive definitions -----------------*/
|
||||
#if defined (BT81X_ENABLE)
|
||||
|
||||
#define EVE_GLFORMAT 31UL /* used with BITMAP_LAYOUT to indicate bitmap-format is specified by BITMAP_EXT_FORMAT */
|
||||
|
||||
#define DL_BITMAP_EXT_FORMAT 0x2E000000 /* requires OR'd arguments */
|
||||
|
||||
/* extended Bitmap formats */
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_4x4_KHR 37808UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_5x4_KHR 37809UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_5x5_KHR 37810UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_6x5_KHR 37811UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_6x6_KHR 37812UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_8x5_KHR 37813UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_8x6_KHR 37814UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_8x8_KHR 37815UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_10x5_KHR 37816UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_10x6_KHR 37817UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_10x8_KHR 37818UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_10x10_KHR 37819UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_12x10_KHR 37820UL
|
||||
#define EVE_COMPRESSED_RGBA_ASTC_12x12_KHR 37821UL
|
||||
|
||||
|
||||
#define EVE_RAM_ERR_REPORT 0x309800UL /* max 128 bytes null terminated string */
|
||||
#define EVE_RAM_FLASH 0x800000UL
|
||||
#define EVE_RAM_FLASH_POSTBLOB 0x801000UL
|
||||
|
||||
#define EVE_OPT_FLASH 64UL
|
||||
#define EVE_OPT_FORMAT 4096UL
|
||||
#define EVE_OPT_FILL 8192UL
|
||||
|
||||
|
||||
/* additional commands for BT81x */
|
||||
#define CMD_BITMAP_TRANSFORM 0xFFFFFF21
|
||||
#define CMD_SYNC 0xFFFFFF42 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_SYNC) */
|
||||
#define CMD_FLASHERASE 0xFFFFFF44 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHERASE) */
|
||||
#define CMD_FLASHWRITE 0xFFFFFF45
|
||||
#define CMD_FLASHREAD 0xFFFFFF46
|
||||
#define CMD_FLASHUPDATE 0xFFFFFF47
|
||||
#define CMD_FLASHDETACH 0xFFFFFF48 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHDETACH) */
|
||||
#define CMD_FLASHATTACH 0xFFFFFF49 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHATTACH) */
|
||||
#define CMD_FLASHFAST 0xFFFFFF4A
|
||||
#define CMD_FLASHSPIDESEL 0xFFFFFF4B /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHSPIDESEL) */
|
||||
#define CMD_FLASHSPITX 0xFFFFFF4C
|
||||
#define CMD_FLASHSPIRX 0xFFFFFF4D
|
||||
#define CMD_FLASHSOURCE 0xFFFFFF4E
|
||||
#define CMD_CLEARCACHE 0xFFFFFF4F /* does not need a dedicated function, just use EVE_cmd_dl(CMD_CLEARCACHE) */
|
||||
#define CMD_INFLATE2 0xFFFFFF50
|
||||
#define CMD_ROTATEAROUND 0xFFFFFF51
|
||||
#define CMD_RESETFONTS 0xFFFFFF52 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RESETFONTS) */
|
||||
#define CMD_ANIMSTART 0xFFFFFF53
|
||||
#define CMD_ANIMSTOP 0xFFFFFF54
|
||||
#define CMD_ANIMXY 0xFFFFFF55
|
||||
#define CMD_ANIMDRAW 0xFFFFFF56
|
||||
#define CMD_GRADIENTA 0xFFFFFF57
|
||||
#define CMD_FILLWIDTH 0xFFFFFF58
|
||||
#define CMD_APPENDF 0xFFFFFF59
|
||||
#define CMD_ANIMFRAME 0xFFFFFF5A
|
||||
#define CMD_VIDEOSTARTF 0xFFFFFF5F /* does not need a dedicated function, just use EVE_cmd_dl(CMD_VIDEOSTARTF) */
|
||||
|
||||
#if 0
|
||||
/* some undocumented commands for BT81x */
|
||||
#define CMD_NOP 0xFFFFFF5B
|
||||
#define CMD_SHA1 0xFFFFFF5C
|
||||
#define CMD_HMAC 0xFFFFFF5D
|
||||
#define CMD_LAST_ 0xFFFFFF5E
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* additional registers for BT81x */
|
||||
#define REG_ADAPTIVE_FRAMERATE 0x30257cUL
|
||||
#define REG_PLAYBACK_PAUSE 0x3025ecUL
|
||||
#define REG_FLASH_STATUS 0x3025f0UL
|
||||
#define REG_FLASH_SIZE 0x309024UL
|
||||
#define REG_PLAY_CONTROL 0x30914eUL
|
||||
#define REG_COPRO_PATCH_DTR 0x309162UL
|
||||
|
||||
|
||||
/* BT81x graphics engine specific macros */
|
||||
#define BITMAP_EXT_FORMAT(format) ((46UL<<24)|(((format)&65535UL)<<0))
|
||||
#define BITMAP_SWIZZLE(r,g,b,a) ((47UL<<24)|(((r)&7UL)<<9)|(((g)&7UL)<<6)|(((b)&7UL)<<3)|(((a)&7UL)<<0))
|
||||
#define BITMAP_SOURCE2(flash_or_ram, addr) ((1UL<<24)|((flash_or_ram) << 23)|(((addr)&8388607UL)<<0))
|
||||
#define INT_FRR() ((48UL<<24))
|
||||
|
||||
#undef BITMAP_TRANSFORM_A
|
||||
#undef BITMAP_TRANSFORM_B
|
||||
#undef BITMAP_TRANSFORM_D
|
||||
#undef BITMAP_TRANSFORM_E
|
||||
|
||||
#define BITMAP_TRANSFORM_A_EXT(p,v) ((21UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0))
|
||||
#define BITMAP_TRANSFORM_B_EXT(p,v) ((22UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0))
|
||||
#define BITMAP_TRANSFORM_D_EXT(p,v) ((24UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0))
|
||||
#define BITMAP_TRANSFORM_E_EXT(p,v) ((25UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0))
|
||||
|
||||
#define BITMAP_TRANSFORM_A(a) BITMAP_TRANSFORM_A_EXT(0,a)
|
||||
#define BITMAP_TRANSFORM_B(b) BITMAP_TRANSFORM_B_EXT(0,b)
|
||||
#define BITMAP_TRANSFORM_D(d) BITMAP_TRANSFORM_D_EXT(0,d)
|
||||
#define BITMAP_TRANSFORM_E(e) BITMAP_TRANSFORM_E_EXT(0,e)
|
||||
|
||||
#endif
|
||||
|
||||
/* ----------------- FT81x / BT81x exclusive definitions -----------------*/
|
||||
#if defined (FT81X_ENABLE)
|
||||
|
||||
|
||||
/* Host commands */
|
||||
#define EVE_CLKSEL 0x61 /* configure system clock */
|
||||
#define EVE_RST_PULSE 0x68 /* reset core - all registers default and processors reset */
|
||||
#define EVE_PINDRIVE 0x70 /* setup drive strength for various pins */
|
||||
#define EVE_PIN_PD_STATE 0x71 /* setup how pins behave during power down */
|
||||
|
||||
|
||||
/* Memory definitions */
|
||||
#define EVE_RAM_G 0x000000UL
|
||||
#define EVE_ROM_CHIPID 0x0C0000UL
|
||||
#define EVE_ROM_FONT 0x1E0000UL
|
||||
#define EVE_ROM_FONT_ADDR 0x2FFFFCUL
|
||||
#define EVE_RAM_DL 0x300000UL
|
||||
#define EVE_RAM_REG 0x302000UL
|
||||
#define EVE_RAM_CMD 0x308000UL
|
||||
|
||||
|
||||
/* Memory buffer sizes */
|
||||
#define EVE_RAM_G_SIZE 1024*1024L
|
||||
#define EVE_CMDFIFO_SIZE 4*1024L
|
||||
#define EVE_RAM_DL_SIZE 8*1024L
|
||||
|
||||
|
||||
/* various additional defines for FT81x */
|
||||
#define EVE_ADC_DIFFERENTIAL 1UL
|
||||
#define EVE_ADC_SINGLE_ENDED 0UL
|
||||
|
||||
#define EVE_INT_G8 18UL
|
||||
#define EVE_INT_L8C 12UL
|
||||
#define EVE_INT_VGA 13UL
|
||||
|
||||
#define EVE_OPT_MEDIAFIFO 16UL
|
||||
#define EVE_OPT_FULLSCREEN 8UL
|
||||
#define EVE_OPT_NOTEAR 4UL
|
||||
#define EVE_OPT_SOUND 32UL
|
||||
|
||||
#define EVE_PALETTED565 14UL
|
||||
#define EVE_PALETTED4444 15UL
|
||||
#define EVE_PALETTED8 16UL
|
||||
#define EVE_L2 17UL
|
||||
|
||||
|
||||
/* additional commands for FT81x */
|
||||
#define CMD_MEDIAFIFO 0xFFFFFF39
|
||||
#define CMD_PLAYVIDEO 0xFFFFFF3A
|
||||
#define CMD_ROMFONT 0xFFFFFF3F
|
||||
#define CMD_SETBASE 0xFFFFFF38
|
||||
#define CMD_SETBITMAP 0xFFFFFF43
|
||||
#define CMD_SETFONT2 0xFFFFFF3B
|
||||
#define CMD_SETROTATE 0xFFFFFF36
|
||||
#define CMD_SETSCRATCH 0xFFFFFF3C
|
||||
#define CMD_SNAPSHOT2 0xFFFFFF37
|
||||
#define CMD_VIDEOFRAME 0xFFFFFF41
|
||||
#define CMD_VIDEOSTART 0xFFFFFF40
|
||||
|
||||
|
||||
/* the following are undocumented commands that therefore should not be used */
|
||||
#if 0
|
||||
#define CMD_CSKETCH 0xFFFFFF35
|
||||
#define CMD_INT_RAMSHARED 0xFFFFFF3D
|
||||
#define CMD_INT_SWLOADIMAGE 0xFFFFFF3E
|
||||
#endif
|
||||
|
||||
|
||||
/* Register definitions */
|
||||
#define REG_ANA_COMP 0x302184UL /* only listed in datasheet */
|
||||
#define REG_BIST_EN 0x302174UL /* only listed in datasheet */
|
||||
#define REG_CLOCK 0x302008UL
|
||||
#define REG_CMDB_SPACE 0x302574UL
|
||||
#define REG_CMDB_WRITE 0x302578UL
|
||||
#define REG_CMD_DL 0x302100UL
|
||||
#define REG_CMD_READ 0x3020f8UL
|
||||
#define REG_CMD_WRITE 0x3020fcUL
|
||||
#define REG_CPURESET 0x302020UL
|
||||
#define REG_CSPREAD 0x302068UL
|
||||
#define REG_CTOUCH_EXTENDED 0x302108UL
|
||||
#define REG_CTOUCH_TOUCH0_XY 0x302124UL /* only listed in datasheet */
|
||||
#define REG_CTOUCH_TOUCH4_X 0x30216cUL
|
||||
#define REG_CTOUCH_TOUCH4_Y 0x302120UL
|
||||
#define REG_CTOUCH_TOUCH1_XY 0x30211cUL
|
||||
#define REG_CTOUCH_TOUCH2_XY 0x30218cUL
|
||||
#define REG_CTOUCH_TOUCH3_XY 0x302190UL
|
||||
#define REG_TOUCH_CONFIG 0x302168UL
|
||||
#define REG_DATESTAMP 0x302564UL /* only listed in datasheet */
|
||||
#define REG_DITHER 0x302060UL
|
||||
#define REG_DLSWAP 0x302054UL
|
||||
#define REG_FRAMES 0x302004UL
|
||||
#define REG_FREQUENCY 0x30200cUL
|
||||
#define REG_GPIO 0x302094UL
|
||||
#define REG_GPIOX 0x30209cUL
|
||||
#define REG_GPIOX_DIR 0x302098UL
|
||||
#define REG_GPIO_DIR 0x302090UL
|
||||
#define REG_HCYCLE 0x30202cUL
|
||||
#define REG_HOFFSET 0x302030UL
|
||||
#define REG_HSIZE 0x302034UL
|
||||
#define REG_HSYNC0 0x302038UL
|
||||
#define REG_HSYNC1 0x30203cUL
|
||||
#define REG_ID 0x302000UL
|
||||
#define REG_INT_EN 0x3020acUL
|
||||
#define REG_INT_FLAGS 0x3020a8UL
|
||||
#define REG_INT_MASK 0x3020b0UL
|
||||
#define REG_MACRO_0 0x3020d8UL
|
||||
#define REG_MACRO_1 0x3020dcUL
|
||||
#define REG_MEDIAFIFO_READ 0x309014UL /* only listed in programmers guide */
|
||||
#define REG_MEDIAFIFO_WRITE 0x309018UL /* only listed in programmers guide */
|
||||
#define REG_OUTBITS 0x30205cUL
|
||||
#define REG_PCLK 0x302070UL
|
||||
#define REG_PCLK_POL 0x30206cUL
|
||||
#define REG_PLAY 0x30208cUL
|
||||
#define REG_PLAYBACK_FORMAT 0x3020c4UL
|
||||
#define REG_PLAYBACK_FREQ 0x3020c0UL
|
||||
#define REG_PLAYBACK_LENGTH 0x3020b8UL
|
||||
#define REG_PLAYBACK_LOOP 0x3020c8UL
|
||||
#define REG_PLAYBACK_PLAY 0x3020ccUL
|
||||
#define REG_PLAYBACK_READPTR 0x3020bcUL
|
||||
#define REG_PLAYBACK_START 0x3020b4UL
|
||||
#define REG_PWM_DUTY 0x3020d4UL
|
||||
#define REG_PWM_HZ 0x3020d0UL
|
||||
#define REG_RENDERMODE 0x302010UL /* only listed in datasheet */
|
||||
#define REG_ROTATE 0x302058UL
|
||||
#define REG_SNAPFORMAT 0x30201cUL /* only listed in datasheet */
|
||||
#define REG_SNAPSHOT 0x302018UL /* only listed in datasheet */
|
||||
#define REG_SNAPY 0x302014UL /* only listed in datasheet */
|
||||
#define REG_SOUND 0x302088UL
|
||||
#define REG_SPI_WIDTH 0x302188UL /* listed with false offset in programmers guide V1.1 */
|
||||
#define REG_SWIZZLE 0x302064UL
|
||||
#define REG_TAG 0x30207cUL
|
||||
#define REG_TAG_X 0x302074UL
|
||||
#define REG_TAG_Y 0x302078UL
|
||||
#define REG_TAP_CRC 0x302024UL /* only listed in datasheet */
|
||||
#define REG_TAP_MASK 0x302028UL /* only listed in datasheet */
|
||||
#define REG_TOUCH_ADC_MODE 0x302108UL
|
||||
#define REG_TOUCH_CHARGE 0x30210cUL
|
||||
#define REG_TOUCH_DIRECT_XY 0x30218cUL
|
||||
#define REG_TOUCH_DIRECT_Z1Z2 0x302190UL
|
||||
#define REG_TOUCH_MODE 0x302104UL
|
||||
#define REG_TOUCH_OVERSAMPLE 0x302114UL
|
||||
#define REG_TOUCH_RAW_XY 0x30211cUL
|
||||
#define REG_TOUCH_RZ 0x302120UL
|
||||
#define REG_TOUCH_RZTHRESH 0x302118UL
|
||||
#define REG_TOUCH_SCREEN_XY 0x302124UL
|
||||
#define REG_TOUCH_SETTLE 0x302110UL
|
||||
#define REG_TOUCH_TAG 0x30212cUL
|
||||
#define REG_TOUCH_TAG1 0x302134UL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG1_XY 0x302130UL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG2 0x30213cUL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG2_XY 0x302138UL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG3 0x302144UL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG3_XY 0x302140UL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG4 0x30214cUL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG4_XY 0x302148UL /* only listed in datasheet */
|
||||
#define REG_TOUCH_TAG_XY 0x302128UL
|
||||
#define REG_TOUCH_TRANSFORM_A 0x302150UL
|
||||
#define REG_TOUCH_TRANSFORM_B 0x302154UL
|
||||
#define REG_TOUCH_TRANSFORM_C 0x302158UL
|
||||
#define REG_TOUCH_TRANSFORM_D 0x30215cUL
|
||||
#define REG_TOUCH_TRANSFORM_E 0x302160UL
|
||||
#define REG_TOUCH_TRANSFORM_F 0x302164UL
|
||||
#define REG_TRACKER 0x309000UL /* only listed in programmers guide */
|
||||
#define REG_TRACKER_1 0x309004UL /* only listed in programmers guide */
|
||||
#define REG_TRACKER_2 0x309008UL /* only listed in programmers guide */
|
||||
#define REG_TRACKER_3 0x30900cUL /* only listed in programmers guide */
|
||||
#define REG_TRACKER_4 0x309010UL /* only listed in programmers guide */
|
||||
#define REG_TRIM 0x302180UL
|
||||
#define REG_VCYCLE 0x302040UL
|
||||
#define REG_VOFFSET 0x302044UL
|
||||
#define REG_VOL_PB 0x302080UL
|
||||
#define REG_VOL_SOUND 0x302084UL
|
||||
#define REG_VSIZE 0x302048UL
|
||||
#define REG_VSYNC0 0x30204cUL
|
||||
#define REG_VSYNC1 0x302050UL
|
||||
|
||||
#if 0
|
||||
#define REG_BUSYBITS 0x3020e8UL /* only listed as "reserved" in datasheet */
|
||||
#define REG_CRC 0x302178UL /* only listed as "reserved" in datasheet */
|
||||
#define REG_SPI_EARLY_TX 0x30217cUL /* only listed as "reserved" in datasheet */
|
||||
#define REG_ROMSUB_SEL 0x3020f0UL /* only listed as "reserved" in datasheet */
|
||||
#define REG_TOUCH_FAULT 0x302170UL /* only listed as "reserved" in datasheet */
|
||||
#endif
|
||||
|
||||
|
||||
/* FT81x graphics engine specific macros useful for static display list generation */
|
||||
|
||||
/* beware, these are different to FTDIs implementation as these take the original values as parameters and not only the upper bits */
|
||||
#define BITMAP_LAYOUT_H(linestride,height) ((40UL<<24)|((((linestride&0xC00)>>10)&3UL)<<2)|((((height&0x600)>>9)&3UL)<<0))
|
||||
#define BITMAP_SIZE_H(width,height) ((41UL<<24)|((((width&0x600)>>9)&3UL)<<2)|((((height&0x600)>>9)&3UL)<<0))
|
||||
|
||||
#define BITMAP_SOURCE(addr) ((1UL<<24)|(((addr)&4194303UL)<<0))
|
||||
//#define NOP() ((45UL<<24))
|
||||
#define PALETTE_SOURCE(addr) ((42UL<<24)|(((addr)&4194303UL)<<0))
|
||||
#define SCISSOR_SIZE(width,height) ((28UL<<24)|(((width)&4095UL)<<12)|(((height)&4095UL)<<0))
|
||||
#define SCISSOR_XY(x,y) ((27UL<<24)|(((x)&2047UL)<<11)|(((y)&2047UL)<<0))
|
||||
#define VERTEX_FORMAT(frac) ((39UL<<24)|(((frac)&7UL)<<0))
|
||||
#define VERTEX_TRANSLATE_X(x) ((43UL<<24)|(((x)&131071UL)<<0))
|
||||
#define VERTEX_TRANSLATE_Y(y) ((44UL<<24)|(((y)&131071UL)<<0))
|
||||
|
||||
|
||||
|
||||
/* ----------------- FT80x exclusive definitions -----------------*/
|
||||
#else
|
||||
|
||||
/* Memory definitions */
|
||||
#define EVE_RAM_G 0x000000UL
|
||||
#define EVE_ROM_CHIPID 0x0C0000UL
|
||||
#define EVE_ROM_FONT 0x0BB23CUL
|
||||
#define EVE_ROM_FONT_ADDR 0x0FFFFCUL
|
||||
#define EVE_RAM_DL 0x100000UL
|
||||
#define EVE_RAM_PAL 0x102000UL
|
||||
#define EVE_RAM_CMD 0x108000UL
|
||||
#define EVE_RAM_SCREENSHOT 0x1C2000UL
|
||||
|
||||
|
||||
/* Memory buffer sizes */
|
||||
#define EVE_RAM_G_SIZE 256*1024L
|
||||
#define EVE_CMDFIFO_SIZE 4*1024L
|
||||
#define EVE_RAM_DL_SIZE 8*1024L
|
||||
#define EVE_RAM_PAL_SIZE 1*1024L
|
||||
|
||||
|
||||
/* Register definitions */
|
||||
#define REG_ID 0x102400UL
|
||||
#define REG_FRAMES 0x102404UL
|
||||
#define REG_CLOCK 0x102408UL
|
||||
#define REG_FREQUENCY 0x10240CUL
|
||||
#define REG_SCREENSHOT_EN 0x102410UL
|
||||
#define REG_SCREENSHOT_Y 0x102414UL
|
||||
#define REG_SCREENSHOT_START 0x102418UL
|
||||
#define REG_CPURESET 0x10241CUL
|
||||
#define REG_TAP_CRC 0x102420UL
|
||||
#define REG_TAP_MASK 0x102424UL
|
||||
#define REG_HCYCLE 0x102428UL
|
||||
#define REG_HOFFSET 0x10242CUL
|
||||
#define REG_HSIZE 0x102430UL
|
||||
#define REG_HSYNC0 0x102434UL
|
||||
#define REG_HSYNC1 0x102438UL
|
||||
#define REG_VCYCLE 0x10243CUL
|
||||
#define REG_VOFFSET 0x102440UL
|
||||
#define REG_VSIZE 0x102444UL
|
||||
#define REG_VSYNC0 0x102448UL
|
||||
#define REG_VSYNC1 0x10244CUL
|
||||
#define REG_DLSWAP 0x102450UL
|
||||
#define REG_ROTATE 0x102454UL
|
||||
#define REG_OUTBITS 0x102458UL
|
||||
#define REG_DITHER 0x10245CUL
|
||||
#define REG_SWIZZLE 0x102460UL
|
||||
#define REG_CSPREAD 0x102464UL
|
||||
#define REG_PCLK_POL 0x102468UL
|
||||
#define REG_PCLK 0x10246CUL
|
||||
#define REG_TAG_X 0x102470UL
|
||||
#define REG_TAG_Y 0x102474UL
|
||||
#define REG_TAG 0x102478UL
|
||||
#define REG_VOL_PB 0x10247CUL
|
||||
#define REG_VOL_SOUND 0x102480UL
|
||||
#define REG_SOUND 0x102484UL
|
||||
#define REG_PLAY 0x102488UL
|
||||
#define REG_GPIO_DIR 0x10248CUL
|
||||
#define REG_GPIO 0x102490UL
|
||||
#define REG_INT_FLAGS 0x102498UL
|
||||
#define REG_INT_EN 0x10249CUL
|
||||
#define REG_INT_MASK 0x1024A0UL
|
||||
#define REG_PLAYBACK_START 0x1024A4UL
|
||||
#define REG_PLAYBACK_LENGTH 0x1024A8UL
|
||||
#define REG_PLAYBACK_READPTR 0x1024ACUL
|
||||
#define REG_PLAYBACK_FREQ 0x1024B0UL
|
||||
#define REG_PLAYBACK_FORMAT 0x1024B4UL
|
||||
#define REG_PLAYBACK_LOOP 0x1024B8UL
|
||||
#define REG_PLAYBACK_PLAY 0x1024BCUL
|
||||
#define REG_PWM_HZ 0x1024C0UL
|
||||
#define REG_PWM_DUTY 0x1024C4UL
|
||||
#define REG_MACRO_0 0x1024C8UL
|
||||
#define REG_MACRO_1 0x1024CCUL
|
||||
#define REG_SCREENSHOT_BUSY 0x1024D8UL
|
||||
#define REG_CMD_READ 0x1024E4UL
|
||||
#define REG_CMD_WRITE 0x1024E8UL
|
||||
#define REG_CMD_DL 0x1024ECUL
|
||||
#define REG_TOUCH_MODE 0x1024F0UL
|
||||
#define REG_TOUCH_ADC_MODE 0x1024F4UL
|
||||
#define REG_TOUCH_CHARGE 0x1024F8UL
|
||||
#define REG_TOUCH_SETTLE 0x1024FCUL
|
||||
#define REG_TOUCH_OVERSAMPLE 0x102500UL
|
||||
#define REG_TOUCH_RZTHRESH 0x102504UL
|
||||
#define REG_TOUCH_RAW_XY 0x102508UL
|
||||
#define REG_TOUCH_RZ 0x10250CUL
|
||||
#define REG_TOUCH_SCREEN_XY 0x102510UL
|
||||
#define REG_TOUCH_TAG_XY 0x102514UL
|
||||
#define REG_TOUCH_TAG 0x102518UL
|
||||
#define REG_TOUCH_TRANSFORM_A 0x10251CUL
|
||||
#define REG_TOUCH_TRANSFORM_B 0x102520UL
|
||||
#define REG_TOUCH_TRANSFORM_C 0x102524UL
|
||||
#define REG_TOUCH_TRANSFORM_D 0x102528UL
|
||||
#define REG_TOUCH_TRANSFORM_E 0x10252CUL
|
||||
#define REG_TOUCH_TRANSFORM_F 0x102530UL
|
||||
#define REG_SCREENSHOT_READ 0x102554UL
|
||||
#define REG_TRIM 0x10256CUL
|
||||
#define REG_TOUCH_DIRECT_XY 0x102574UL
|
||||
#define REG_TOUCH_DIRECT_Z1Z2 0x102578UL
|
||||
#define REG_TRACKER 0x109000UL
|
||||
|
||||
/* FT80x graphics engine specific macros useful for static display list generation */
|
||||
#define BITMAP_SOURCE(addr) ((1UL<<24)|(((addr)&1048575UL)<<0))
|
||||
#define SCISSOR_SIZE(width,height) ((28UL<<24)|(((width)&1023UL)<<10)|(((height)&1023UL)<<0))
|
||||
#define SCISSOR_XY(x,y) ((27UL<<24)|(((x)&511UL)<<9)|(((y)&511UL)<<0))
|
||||
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_FT81X_DEFINES_H*/
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file lv_ili9341.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ili9341.h"
|
||||
|
||||
#if LV_USE_ILI9341
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_FRMCTR1 0xB1 /* Frame Rate Control (In Normal Mode/Full Colors) */
|
||||
#define CMD_FRMCTR2 0xB2 /* Frame Rate Control (In Idle Mode/8 colors) */
|
||||
#define CMD_FRMCTR3 0xB3 /* Frame Rate control (In Partial Mode/Full Colors) */
|
||||
#define CMD_INVCTR 0xB4 /* Display Inversion Control */
|
||||
#define CMD_DFUNCTR 0xB6 /* Display Function Control */
|
||||
#define CMD_PWCTR1 0xC0 /* Power Control 1 */
|
||||
#define CMD_PWCTR2 0xC1 /* Power Control 2 */
|
||||
#define CMD_VMCTR1 0xC5 /* VCOM Control 1 */
|
||||
#define CMD_VMCTR2 0xC7 /* VCOM Control 2 */
|
||||
#define CMD_PWCTRA 0xCB /* Power Control A */
|
||||
#define CMD_PWCTRB 0xCF /* Power Control B */
|
||||
#define CMD_GMCTRP1 0xE0 /* Positive Gamma Correction */
|
||||
#define CMD_GMCTRN1 0xE1 /* Negative Gamma Correction */
|
||||
#define CMD_DTCTRA 0xE8 /* Driver timing control A */
|
||||
#define CMD_DTCTRB 0xEA /* Driver timing control B */
|
||||
#define CMD_PONSEQ 0xED /* Power On Sequence */
|
||||
#define CMD_RDINDEX 0xD9 /* ili9341 */
|
||||
#define CMD_IDXRD 0xDD /* ILI9341 only, indexed control register read */
|
||||
#define CMD_ENA3G 0xF2 /* Enable 3 Gamma control */
|
||||
#define CMD_IFCTR 0xF6 /* Interface Control */
|
||||
#define CMD_PRCTR 0xF7 /* Pump ratio control */
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands based on LovyanGFX ILI9341 driver */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
CMD_PWCTRB, 3, 0x00, 0xC1, 0x30,
|
||||
CMD_PONSEQ, 4, 0x64, 0x03, 0x12, 0x81,
|
||||
CMD_DTCTRA, 3, 0x85, 0x00, 0x78,
|
||||
CMD_PWCTRA, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
||||
CMD_PRCTR, 1, 0x20,
|
||||
CMD_DTCTRB, 2, 0x00, 0x00,
|
||||
CMD_PWCTR1, 1, 0x23,
|
||||
CMD_PWCTR2, 1, 0x10,
|
||||
CMD_VMCTR1, 2, 0x3e, 0x28,
|
||||
CMD_VMCTR2, 1, 0x86,
|
||||
CMD_FRMCTR1, 2, 0x00, 0x13,
|
||||
CMD_DFUNCTR, 2, 0x0A, 0xA2,
|
||||
CMD_IFCTR, 3, 0x09, 0x30, 0x00,
|
||||
CMD_ENA3G, 1, 0x00,
|
||||
LV_LCD_CMD_SET_GAMMA_CURVE, 1, 0x01,
|
||||
CMD_GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
|
||||
CMD_GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_ili9341_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_ili9341_send_cmd_cb_t send_cmd_cb, lv_ili9341_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_ili9341_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_ili9341_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_ili9341_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
|
||||
}
|
||||
|
||||
void lv_ili9341_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ILI9341*/
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file lv_ili9341.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ILI9341_H
|
||||
#define LV_ILI9341_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ILI9341
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_ili9341_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_ili9341_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ILI9341 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_ili9341_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_ili9341_send_cmd_cb_t send_cmd_cb, lv_ili9341_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_ili9341_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_ili9341_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_ili9341_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_ili9341_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#endif /*LV_USE_ILI9341*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_ILI9341_H*/
|
||||
@@ -0,0 +1,341 @@
|
||||
/**
|
||||
* @file lv_lcd_generic_mipi.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_GENERIC_MIPI
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void send_cmd(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size);
|
||||
static void send_color(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size);
|
||||
static void init(lv_lcd_generic_mipi_driver_t * drv, lv_lcd_flag_t flags);
|
||||
static void set_mirror(lv_lcd_generic_mipi_driver_t * drv, bool mirror_x, bool mirror_y);
|
||||
static void set_swap_xy(lv_lcd_generic_mipi_driver_t * drv, bool swap);
|
||||
static void set_rotation(lv_lcd_generic_mipi_driver_t * drv, lv_display_rotation_t rot);
|
||||
static void res_chg_event_cb(lv_event_t * e);
|
||||
static lv_lcd_generic_mipi_driver_t * get_driver(lv_display_t * disp);
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_lcd_send_cmd_cb_t send_cmd_cb, lv_lcd_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_display_create(hor_res, ver_res);
|
||||
if(disp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_lcd_generic_mipi_driver_t * drv = (lv_lcd_generic_mipi_driver_t *)lv_malloc(sizeof(lv_lcd_generic_mipi_driver_t));
|
||||
if(drv == NULL) {
|
||||
lv_display_delete(disp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* init driver struct */
|
||||
drv->disp = disp;
|
||||
drv->send_cmd = send_cmd_cb;
|
||||
drv->send_color = send_color_cb;
|
||||
lv_display_set_driver_data(disp, (void *)drv);
|
||||
|
||||
/* init controller */
|
||||
init(drv, flags);
|
||||
|
||||
/* register resolution change callback (NOTE: this handles screen rotation as well) */
|
||||
lv_display_add_event_cb(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
|
||||
|
||||
/* register flush callback */
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
drv->x_gap = x;
|
||||
drv->y_gap = y;
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
send_cmd(drv, invert ? LV_LCD_CMD_ENTER_INVERT_MODE : LV_LCD_CMD_EXIT_INVERT_MODE, NULL, 0);
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_address_mode(lv_display_t * disp, bool mirror_x, bool mirror_y, bool swap_xy, bool bgr)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
uint8_t mad = drv->madctl_reg & ~(LV_LCD_MASK_RGB_ORDER);
|
||||
if(bgr) {
|
||||
mad |= LV_LCD_BIT_RGB_ORDER__BGR;
|
||||
}
|
||||
drv->madctl_reg = mad;
|
||||
drv->mirror_x = mirror_x;
|
||||
drv->mirror_y = mirror_y;
|
||||
drv->swap_xy = swap_xy;
|
||||
set_rotation(drv, lv_display_get_rotation(disp)); /* update screen */
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_GAMMA_CURVE, (uint8_t[]) {
|
||||
gamma,
|
||||
}, 1);
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
while(1) {
|
||||
uint8_t cmd = *cmd_list++;
|
||||
uint8_t num = *cmd_list++;
|
||||
if(cmd == LV_LCD_CMD_DELAY_MS) {
|
||||
if(num == LV_LCD_CMD_EOF) /* end of list */
|
||||
break;
|
||||
else { /* delay in 10 ms units*/
|
||||
lv_delay_ms((uint32_t)(num) * 10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
drv->send_cmd(drv->disp, &cmd, 1, cmd_list, num);
|
||||
cmd_list += num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Helper function to call the user-supplied 'send_cmd' function
|
||||
* @param drv LCD driver object
|
||||
* @param cmd command byte
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
static void send_cmd(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size)
|
||||
{
|
||||
uint8_t cmdbuf = cmd; /* MIPI uses 8 bit commands */
|
||||
drv->send_cmd(drv->disp, &cmdbuf, 1, param, param_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to call the user-supplied 'send_color' function
|
||||
* @param drv LCD driver object
|
||||
* @param cmd command byte
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
static void send_color(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size)
|
||||
{
|
||||
uint8_t cmdbuf = cmd; /* MIPI uses 8 bit commands */
|
||||
drv->send_color(drv->disp, &cmdbuf, 1, param, param_size);
|
||||
/* note: LVGL waits for your callback to call `lv_display_flush_ready` to know when the transfer has finished. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize LCD driver after a hard reset
|
||||
* @param drv LCD driver object
|
||||
*/
|
||||
static void init(lv_lcd_generic_mipi_driver_t * drv, lv_lcd_flag_t flags)
|
||||
{
|
||||
drv->x_gap = 0;
|
||||
drv->y_gap = 0;
|
||||
|
||||
/* init color mode and RGB order */
|
||||
drv->madctl_reg = flags & LV_LCD_FLAG_BGR ? LV_LCD_BIT_RGB_ORDER__BGR : LV_LCD_BIT_RGB_ORDER__RGB;
|
||||
drv->colmod_reg = flags & LV_LCD_FLAG_RGB666 ? LV_LCD_PIXEL_FORMAT_RGB666 : LV_LCD_PIXEL_FORMAT_RGB565;
|
||||
|
||||
/* init orientation */
|
||||
drv->mirror_x = flags & LV_LCD_FLAG_MIRROR_X;
|
||||
drv->mirror_y = flags & LV_LCD_FLAG_MIRROR_Y;
|
||||
drv->swap_xy = false;
|
||||
/* update madctl_reg */
|
||||
set_swap_xy(drv, drv->swap_xy);
|
||||
set_mirror(drv, drv->mirror_x, drv->mirror_y);
|
||||
|
||||
/* enter sleep mode first */
|
||||
send_cmd(drv, LV_LCD_CMD_ENTER_SLEEP_MODE, NULL, 0);
|
||||
lv_delay_ms(10);
|
||||
|
||||
/* perform software reset */
|
||||
send_cmd(drv, LV_LCD_CMD_SOFT_RESET, NULL, 0);
|
||||
lv_delay_ms(200);
|
||||
|
||||
/* LCD goes into sleep mode and display will be turned off after power on reset, exit sleep mode first */
|
||||
send_cmd(drv, LV_LCD_CMD_EXIT_SLEEP_MODE, NULL, 0);
|
||||
lv_delay_ms(300);
|
||||
|
||||
send_cmd(drv, LV_LCD_CMD_ENTER_NORMAL_MODE, NULL, 0);
|
||||
|
||||
send_cmd(drv, LV_LCD_CMD_SET_ADDRESS_MODE, (uint8_t[]) {
|
||||
drv->madctl_reg,
|
||||
}, 1);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_PIXEL_FORMAT, (uint8_t[]) {
|
||||
drv->colmod_reg,
|
||||
}, 1);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_DISPLAY_ON, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set readout directions (used for rotating the display)
|
||||
* @param drv LCD driver object
|
||||
* @param mirror_x false: normal, true: mirrored
|
||||
* @param mirror_y false: normal, true: mirrored
|
||||
*/
|
||||
static void set_mirror(lv_lcd_generic_mipi_driver_t * drv, bool mirror_x, bool mirror_y)
|
||||
{
|
||||
uint8_t mad = drv->madctl_reg & ~(LV_LCD_MASK_COLUMN_ADDRESS_ORDER | LV_LCD_MASK_PAGE_ADDRESS_ORDER);
|
||||
if(mirror_x) {
|
||||
mad |= LV_LCD_BIT_COLUMN_ADDRESS_ORDER__RTOL;
|
||||
}
|
||||
if(mirror_y) {
|
||||
mad |= LV_LCD_BIT_PAGE_ADDRESS_ORDER__BTOT;
|
||||
}
|
||||
drv->madctl_reg = mad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap horizontal and vertical readout (used for rotating the display)
|
||||
* @param drv LCD driver object
|
||||
* @param swap false: normal, true: swapped
|
||||
*/
|
||||
static void set_swap_xy(lv_lcd_generic_mipi_driver_t * drv, bool swap)
|
||||
{
|
||||
uint8_t mad = drv->madctl_reg & ~(LV_LCD_MASK_PAGE_COLUMN_ORDER);
|
||||
if(swap) {
|
||||
mad |= LV_LCD_BIT_PAGE_COLUMN_ORDER__REVERSE;
|
||||
}
|
||||
drv->madctl_reg = mad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush display buffer to the LCD
|
||||
* @param disp display object
|
||||
* @param hor_res horizontal resolution
|
||||
* @param area area stored in the buffer
|
||||
* @param px_map buffer containing pixel data
|
||||
* @note transfers pixel data to the LCD controller using the callbacks 'send_cmd' and 'send_color', which were
|
||||
* passed to the 'lv_st7789_create()' function
|
||||
*/
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
|
||||
int32_t x_start = area->x1;
|
||||
int32_t x_end = area->x2 + 1;
|
||||
int32_t y_start = area->y1;
|
||||
int32_t y_end = area->y2 + 1;
|
||||
|
||||
LV_ASSERT((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position");
|
||||
|
||||
x_start += drv->x_gap;
|
||||
x_end += drv->x_gap;
|
||||
y_start += drv->y_gap;
|
||||
y_end += drv->y_gap;
|
||||
|
||||
/* define an area of frame memory where MCU can access */
|
||||
send_cmd(drv, LV_LCD_CMD_SET_COLUMN_ADDRESS, (uint8_t[]) {
|
||||
(x_start >> 8) & 0xFF,
|
||||
x_start & 0xFF,
|
||||
((x_end - 1) >> 8) & 0xFF,
|
||||
(x_end - 1) & 0xFF,
|
||||
}, 4);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_PAGE_ADDRESS, (uint8_t[]) {
|
||||
(y_start >> 8) & 0xFF,
|
||||
y_start & 0xFF,
|
||||
((y_end - 1) >> 8) & 0xFF,
|
||||
(y_end - 1) & 0xFF,
|
||||
}, 4);
|
||||
/* transfer frame buffer */
|
||||
size_t len = (x_end - x_start) * (y_end - y_start) * lv_color_format_get_size(lv_display_get_color_format(disp));
|
||||
send_color(drv, LV_LCD_CMD_WRITE_MEMORY_START, px_map, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rotation taking into account the current mirror and swap settings
|
||||
* @param drv LCD driver object
|
||||
* @param rot rotation
|
||||
*/
|
||||
static void set_rotation(lv_lcd_generic_mipi_driver_t * drv, lv_display_rotation_t rot)
|
||||
{
|
||||
switch(rot) {
|
||||
case LV_DISPLAY_ROTATION_0:
|
||||
set_swap_xy(drv, drv->swap_xy);
|
||||
set_mirror(drv, drv->mirror_x, drv->mirror_y);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_90:
|
||||
set_swap_xy(drv, !drv->swap_xy);
|
||||
set_mirror(drv, drv->mirror_x, !drv->mirror_y);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_180:
|
||||
set_swap_xy(drv, drv->swap_xy);
|
||||
set_mirror(drv, !drv->mirror_x, !drv->mirror_y);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_270:
|
||||
set_swap_xy(drv, !drv->swap_xy);
|
||||
set_mirror(drv, !drv->mirror_x, drv->mirror_y);
|
||||
break;
|
||||
}
|
||||
send_cmd(drv, LV_LCD_CMD_SET_ADDRESS_MODE, (uint8_t[]) {
|
||||
drv->madctl_reg
|
||||
}, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_RESOLUTION_CHANGED event (handles both resolution and rotation change)
|
||||
* @param e LV_EVENT_RESOLUTION_CHANGED event
|
||||
*/
|
||||
static void res_chg_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_display_t * disp = lv_event_get_current_target(e);
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
|
||||
uint16_t hor_res = lv_display_get_horizontal_resolution(disp);
|
||||
uint16_t ver_res = lv_display_get_vertical_resolution(disp);
|
||||
lv_display_rotation_t rot = lv_display_get_rotation(disp);
|
||||
|
||||
/* TODO: implement resolution change */
|
||||
LV_UNUSED(hor_res);
|
||||
LV_UNUSED(ver_res);
|
||||
|
||||
/* handle rotation */
|
||||
set_rotation(drv, rot);
|
||||
}
|
||||
|
||||
static lv_lcd_generic_mipi_driver_t * get_driver(lv_display_t * disp)
|
||||
{
|
||||
return (lv_lcd_generic_mipi_driver_t *)lv_display_get_driver_data(disp);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GENERIC_MIPI*/
|
||||
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* @file lv_lcd_generic_mipi.h
|
||||
*
|
||||
* Generic driver for controllers adhering to the MIPI DBI/DCS specification
|
||||
*
|
||||
* Works with:
|
||||
*
|
||||
* ST7735
|
||||
* ST7789
|
||||
* ST7796
|
||||
* ILI9341
|
||||
* ILI9488 (NOTE: in SPI mode ILI9488 only supports RGB666 mode, which is currently not supported)
|
||||
*
|
||||
* any probably many more
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LCD_GENERIC_MIPI_H
|
||||
#define LV_LCD_GENERIC_MIPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_GENERIC_MIPI
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* MIPI DCS (Display Command Set) v1.02.00 User Command Set */
|
||||
#define LV_LCD_CMD_NOP 0x00 /* No Operation */
|
||||
#define LV_LCD_CMD_SOFT_RESET 0x01 /* Software Reset */
|
||||
#define LV_LCD_CMD_GET_POWER_MODE 0x0A /* Get the current power mode */
|
||||
#define LV_LCD_CMD_GET_ADDRESS_MODE 0x0B /* Get the data order for transfers from the Host to the display module and from the frame memory to the display device */
|
||||
#define LV_LCD_CMD_GET_PIXEL_FORMAT 0x0C /* Get the current pixel format */
|
||||
#define LV_LCD_CMD_GET_DISPLAY_MODE 0x0D /* Get the current display mode from the peripheral */
|
||||
#define LV_LCD_CMD_GET_SIGNAL_MODE 0x0E /* Get display module signaling mode */
|
||||
#define LV_LCD_CMD_GET_DIAGNOSTIC_RESULT 0x0F /* Get Peripheral Self-Diagnostic Result */
|
||||
#define LV_LCD_CMD_ENTER_SLEEP_MODE 0x10 /* Power for the display panel is off */
|
||||
#define LV_LCD_CMD_EXIT_SLEEP_MODE 0x11 /* Power for the display panel is on */
|
||||
#define LV_LCD_CMD_ENTER_PARTIAL_MODE 0x12 /* Part of the display area is used for image display */
|
||||
#define LV_LCD_CMD_ENTER_NORMAL_MODE 0x13 /* The whole display area is used for image display */
|
||||
#define LV_LCD_CMD_EXIT_INVERT_MODE 0x20 /* Displayed image colors are not inverted */
|
||||
#define LV_LCD_CMD_ENTER_INVERT_MODE 0x21 /* Displayed image colors are inverted */
|
||||
#define LV_LCD_CMD_SET_GAMMA_CURVE 0x26 /* Selects the gamma curve used by the display device */
|
||||
#define LV_LCD_CMD_SET_DISPLAY_OFF 0x28 /* Blanks the display device */
|
||||
#define LV_LCD_CMD_SET_DISPLAY_ON 0x29 /* Show the image on the display device */
|
||||
#define LV_LCD_CMD_SET_COLUMN_ADDRESS 0x2A /* Set the column extent */
|
||||
#define LV_LCD_CMD_SET_PAGE_ADDRESS 0x2B /* Set the page extent */
|
||||
#define LV_LCD_CMD_WRITE_MEMORY_START 0x2C /* Transfer image data from the Host Processor to the peripheral starting at the location provided by set_column_address and set_page_address */
|
||||
#define LV_LCD_CMD_READ_MEMORY_START 0x2E /* Transfer image data from the peripheral to the Host Processor interface starting at the location provided by set_column_address and set_page_address */
|
||||
#define LV_LCD_CMD_SET_PARTIAL_ROWS 0x30 /* Defines the number of rows in the partial display area on the display device */
|
||||
#define LV_LCD_CMD_SET_PARTIAL_COLUMNS 0x31 /* Defines the number of columns in the partial display area on the display device */
|
||||
#define LV_LCD_CMD_SET_SCROLL_AREA 0x33 /* Defines the vertical scrolling and fixed area on display device */
|
||||
#define LV_LCD_CMD_SET_TEAR_OFF 0x34 /* Synchronization information is not sent from the display module to the host processor */
|
||||
#define LV_LCD_CMD_SET_TEAR_ON 0x35 /* Synchronization information is sent from the display module to the host processor at the start of VFP */
|
||||
#define LV_LCD_CMD_SET_ADDRESS_MODE 0x36 /* Set the data order for transfers from the Host to the display module and from the frame memory to the display device */
|
||||
#define LV_LCD_CMD_SET_SCROLL_START 0x37 /* Defines the vertical scrolling starting point */
|
||||
#define LV_LCD_CMD_EXIT_IDLE_MODE 0x38 /* Full color depth is used on the display panel */
|
||||
#define LV_LCD_CMD_ENTER_IDLE_MODE 0x39 /* Reduced color depth is used on the display panel */
|
||||
#define LV_LCD_CMD_SET_PIXEL_FORMAT 0x3A /* Defines how many bits per pixel are used in the interface */
|
||||
#define LV_LCD_CMD_WRITE_MEMORY_CONTINUE 0x3C /* Transfer image information from the Host Processor interface to the peripheral from the last written location */
|
||||
#define LV_LCD_CMD_READ_MEMORY_CONTINUE 0x3E /* Read image data from the peripheral continuing after the last read_memory_continue or read_memory_start */
|
||||
#define LV_LCD_CMD_SET_TEAR_SCANLINE 0x44 /* Synchronization information is sent from the display module to the host processor when the display device refresh reaches the provided scanline */
|
||||
#define LV_LCD_CMD_GET_SCANLINE 0x45 /* Get the current scanline */
|
||||
#define LV_LCD_CMD_READ_DDB_CONTINUE 0xA8 /* Continue reading the DDB from the last read location */
|
||||
#define LV_LCD_CMD_READ_DDB_START 0xA1 /* Read the DDB from the provided location */
|
||||
|
||||
/* address mode flag masks */
|
||||
#define LV_LCD_MASK_FLIP_VERTICAL (1 << 0) /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */
|
||||
#define LV_LCD_MASK_FLIP_HORIZONTAL (1 << 1) /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */
|
||||
#define LV_LCD_MASK_DATA_LATCH_DATA_ORDER (1 << 2) /* Display Data Latch Order */
|
||||
#define LV_LCD_MASK_RGB_ORDER (1 << 3) /* RGB/BGR Order */
|
||||
#define LV_LCD_MASK_LINE_ADDRESS_ORDER (1 << 4) /* Line Address Order */
|
||||
#define LV_LCD_MASK_PAGE_COLUMN_ORDER (1 << 5) /* Page/Column Order */
|
||||
#define LV_LCD_MASK_COLUMN_ADDRESS_ORDER (1 << 6) /* Column Address Order */
|
||||
#define LV_LCD_MASK_PAGE_ADDRESS_ORDER (1 << 7) /* Page Address Order */
|
||||
|
||||
#define LV_LCD_BIT_FLIP_VERTICAL__NOT_FLIPPED 0
|
||||
#define LV_LCD_BIT_FLIP_VERTICAL__FLIPPED LV_LCD_MASK_FLIP_VERTICAL /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */
|
||||
#define LV_LCD_BIT_FLIP_HORIZONTAL__NOT_FLIPPED 0
|
||||
#define LV_LCD_BIT_FLIP_HORIZONTAL__FLIPPED LV_LCD_MASK_FLIP_HORIZONTAL /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */
|
||||
#define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__LTOR 0 /* Display Data Latch Order: LCD Refresh Left to Right */
|
||||
#define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__RTOL LV_LCD_MASK_DATA_LATCH_DATA_ORDER /* Display Data Latch Order: LCD Refresh Right to Left */
|
||||
#define LV_LCD_BIT_RGB_ORDER__RGB 0 /* RGB/BGR Order: RGB */
|
||||
#define LV_LCD_BIT_RGB_ORDER__BGR LV_LCD_MASK_RGB_ORDER /* RGB/BGR Order: BGR */
|
||||
#define LV_LCD_BIT_LINE_ADDRESS_ORDER__TTOB 0 /* Line Address Order: LCD Refresh Top to Bottom */
|
||||
#define LV_LCD_BIT_LINE_ADDRESS_ORDER__BTOT LV_LCD_MASK_LINE_ADDRESS_ORDER /* Line Address Order: LCD Refresh Bottom to Top */
|
||||
#define LV_LCD_BIT_PAGE_COLUMN_ORDER__NORMAL 0 /* Page/Column Order: Normal Mode */
|
||||
#define LV_LCD_BIT_PAGE_COLUMN_ORDER__REVERSE LV_LCD_MASK_PAGE_COLUMN_ORDER /* Page/Column Order: Reverse Mode */
|
||||
#define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__LTOR 0 /* Column Address Order: Left to Right */
|
||||
#define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__RTOL LV_LCD_MASK_COLUMN_ADDRESS_ORDER /* Column Address Order: Right to Left */
|
||||
#define LV_LCD_BIT_PAGE_ADDRESS_ORDER__TTOB 0 /* Page Address Order: Top to Bottom */
|
||||
#define LV_LCD_BIT_PAGE_ADDRESS_ORDER__BTOT LV_LCD_MASK_PAGE_ADDRESS_ORDER /* Page Address Order: Bottom to Top */
|
||||
|
||||
/* predefined gamma curves */
|
||||
#define LV_LCD_GAMMA_2_2 0x01 /* 2.2 */
|
||||
#define LV_LCD_GAMMA_1_8 0x02 /* 1.8 */
|
||||
#define LV_LCD_GAMMA_2_5 0x04 /* 2.5 */
|
||||
#define LV_LCD_GAMMA_1_0 0x08 /* 1.0 */
|
||||
|
||||
/* common pixel formats */
|
||||
#define LV_LCD_PIXEL_FORMAT_RGB565 0x55 /* bus: 16 bits, pixel: 16 bits */
|
||||
#define LV_LCD_PIXEL_FORMAT_RGB666 0x66 /* bus: 18 bits, pixel: 18 bits */
|
||||
|
||||
/* flags for lv_lcd_xxx_create() */
|
||||
#define LV_LCD_FLAG_NONE 0x00000000UL
|
||||
#define LV_LCD_FLAG_MIRROR_X 0x00000001UL
|
||||
#define LV_LCD_FLAG_MIRROR_Y 0x00000002UL
|
||||
#define LV_LCD_FLAG_BGR 0x00000008UL
|
||||
#define LV_LCD_FLAG_RGB666 0x00000010UL
|
||||
|
||||
/* command list */
|
||||
#define LV_LCD_CMD_DELAY_MS 0xff
|
||||
#define LV_LCD_CMD_EOF 0xff
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Configuration flags for lv_lcd_xxx_create()
|
||||
*
|
||||
*/
|
||||
typedef uint32_t lv_lcd_flag_t;
|
||||
|
||||
/**
|
||||
* Prototype of a platform-dependent callback to transfer commands and data to the LCD controller.
|
||||
* @param disp display object
|
||||
* @param cmd command buffer (can handle 16 bit commands as well)
|
||||
* @param cmd_size number of bytes of the command
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
typedef void (*lv_lcd_send_cmd_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, const uint8_t * param,
|
||||
size_t param_size);
|
||||
|
||||
/**
|
||||
* Prototype of a platform-dependent callback to transfer pixel data to the LCD controller.
|
||||
* @param disp display object
|
||||
* @param cmd command buffer (can handle 16 bit commands as well)
|
||||
* @param cmd_size number of bytes of the command
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
typedef void (*lv_lcd_send_color_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, uint8_t * param,
|
||||
size_t param_size);
|
||||
|
||||
/**
|
||||
* Generic MIPI compatible LCD driver
|
||||
*/
|
||||
typedef struct {
|
||||
lv_display_t * disp; /* the associated LVGL display object */
|
||||
lv_lcd_send_cmd_cb_t send_cmd; /* platform-specific implementation to send a command to the LCD controller */
|
||||
lv_lcd_send_color_cb_t send_color; /* platform-specific implementation to send pixel data to the LCD controller */
|
||||
uint16_t x_gap; /* x offset of the (0,0) pixel in VRAM */
|
||||
uint16_t y_gap; /* y offset of the (0,0) pixel in VRAM */
|
||||
uint8_t madctl_reg; /* current value of MADCTL register */
|
||||
uint8_t colmod_reg; /* current value of COLMOD register */
|
||||
bool mirror_x;
|
||||
bool mirror_y;
|
||||
bool swap_xy;
|
||||
} lv_lcd_generic_mipi_driver_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a MIPI DCS compatible LCD display
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer).
|
||||
* `lv_display_flush_ready` must be called after the transfer has finished.
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_lcd_send_cmd_cb_t send_cmd_cb, lv_lcd_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set address mode
|
||||
* @param disp display object
|
||||
* @param mirror_x horizontal mirror (false: normal, true: mirrored)
|
||||
* @param mirror_y vertical mirror (false: normal, true: mirrored)
|
||||
* @param swap_xy swap axes (false: normal, true: swap)
|
||||
* @param bgr RGB/BGR order (false: RGB, true: BGR)
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_address_mode(lv_display_t * disp, bool mirror_x, bool mirror_y, bool swap_xy, bool bgr);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_lcd_generic_mipi_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#endif /*LV_USE_GENERIC_MIPI*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_LCD_GENERIC_MIPI_H*/
|
||||
@@ -0,0 +1,361 @@
|
||||
/**
|
||||
* @file lv_renesas_glcdc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
*PLATFORM ABSTRACTION
|
||||
*********************/
|
||||
|
||||
#ifdef _RENESAS_RA_
|
||||
#define USE_FREE_RTOS (BSP_CFG_RTOS == 2)
|
||||
#else // RX with SMC code generation
|
||||
#ifndef _RENESAS_RX_
|
||||
#define _RENESAS_RX_ 1
|
||||
#endif
|
||||
#define USE_FREE_RTOS 1
|
||||
#define DISPLAY_HSIZE_INPUT0 LCD_CH0_IN_GR2_HSIZE
|
||||
#define DISPLAY_VSIZE_INPUT0 LCD_CH0_IN_GR2_VSIZE
|
||||
#define DISPLAY_BUFFER_STRIDE_BYTES_INPUT0 LCD_CH0_IN_GR2_LINEOFFSET
|
||||
#endif /*_RENESAS_RA_*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_renesas_glcdc.h"
|
||||
|
||||
#if LV_USE_RENESAS_GLCDC
|
||||
|
||||
#ifdef _RENESAS_RA_
|
||||
#include "LVGL_thread.h"
|
||||
#else /* RX */
|
||||
#include "hal_data.h"
|
||||
#include "platform.h"
|
||||
#include "r_glcdc_rx_if.h"
|
||||
#include "r_glcdc_rx_pinset.h"
|
||||
#endif /*_RENESAS_RA_*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../../../display/lv_display_private.h"
|
||||
#include "../../../draw/sw/lv_draw_sw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define BYTES_PER_PIXEL 2
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_display_t * glcdc_create(void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode);
|
||||
static void glcdc_init(void);
|
||||
static void give_vsync_sem_and_yield(void);
|
||||
static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
|
||||
static void flush_partial(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
|
||||
static void flush_wait_direct(lv_display_t * display);
|
||||
static void flush_wait_partial(lv_display_t * display);
|
||||
|
||||
#ifdef _RENESAS_RX_
|
||||
static void enable_dave2d_drw_interrupt(void);
|
||||
#endif /*_RENESAS_RX_*/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#ifdef _RENESAS_RX_
|
||||
static uint8_t fb_background[2][LCD_CH0_IN_GR2_HSIZE * LCD_CH0_IN_GR2_VSIZE * BYTES_PER_PIXEL]__attribute__((
|
||||
section(".framebuffer"), aligned(64), used));
|
||||
static SemaphoreHandle_t _SemaphoreVsync = NULL;
|
||||
static glcdc_cfg_t g_config;
|
||||
static glcdc_runtime_cfg_t g_layer_change;
|
||||
|
||||
/* A global variable that Dave 2D driver relies on. (Being auto generated on RA platforms)*/
|
||||
display_t g_display0_cfg;
|
||||
#endif /*_RENESAS_RX_*/
|
||||
|
||||
static void * rotation_buffer = NULL;
|
||||
static uint32_t partial_buffer_size = 0;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_renesas_glcdc_direct_create(void)
|
||||
{
|
||||
return glcdc_create(&fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0]),
|
||||
LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
}
|
||||
|
||||
lv_display_t * lv_renesas_glcdc_partial_create(void * buf1, void * buf2, size_t buf_size)
|
||||
{
|
||||
partial_buffer_size = buf_size;
|
||||
return glcdc_create(buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
}
|
||||
|
||||
/*This function is declared in and being used by FSP generated code modules*/
|
||||
#ifdef _RENESAS_RA_
|
||||
void glcdc_callback(display_callback_args_t * p_args)
|
||||
{
|
||||
if(DISPLAY_EVENT_LINE_DETECTION == p_args->event) {
|
||||
give_vsync_sem_and_yield();
|
||||
}
|
||||
else if(DISPLAY_EVENT_GR1_UNDERFLOW == p_args->event) {
|
||||
__BKPT(0); /*Layer 1 Underrun*/
|
||||
}
|
||||
else if(DISPLAY_EVENT_GR2_UNDERFLOW == p_args->event) {
|
||||
__BKPT(0); /*Layer 2 Underrun*/
|
||||
}
|
||||
else { /*DISPLAY_EVENT_FRAME_END*/
|
||||
__BKPT(0);
|
||||
}
|
||||
}
|
||||
#else /* RX */
|
||||
void glcdc_callback(glcdc_callback_args_t * p_args)
|
||||
{
|
||||
if(GLCDC_EVENT_LINE_DETECTION == p_args->event) {
|
||||
give_vsync_sem_and_yield();
|
||||
}
|
||||
else if(GLCDC_EVENT_GR1_UNDERFLOW == p_args->event) {
|
||||
while(1); /*Layer 1 Underrun*/
|
||||
}
|
||||
else if(GLCDC_EVENT_GR2_UNDERFLOW == p_args->event) {
|
||||
while(1); /*Layer 2 Underrun*/
|
||||
}
|
||||
else {/*DISPLAY_EVENT_FRAME_END*/
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
#endif /*_RENESAS_RA_*/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_display_t * glcdc_create(void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode)
|
||||
{
|
||||
#ifdef _RENESAS_RA_
|
||||
glcdc_init();
|
||||
#else
|
||||
g_display0_cfg.input->format = LCD_CH0_IN_GR2_FORMAT;
|
||||
_SemaphoreVsync = xSemaphoreCreateBinary();
|
||||
|
||||
glcdc_init();
|
||||
enable_dave2d_drw_interrupt();
|
||||
#endif /*_RENESAS_RA_*/
|
||||
|
||||
lv_display_t * display = lv_display_create(DISPLAY_HSIZE_INPUT0, DISPLAY_VSIZE_INPUT0);
|
||||
|
||||
if(render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) {
|
||||
lv_display_set_flush_cb(display, flush_direct);
|
||||
lv_display_set_flush_wait_cb(display, flush_wait_direct);
|
||||
}
|
||||
else if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) {
|
||||
lv_display_set_flush_cb(display, flush_partial);
|
||||
lv_display_set_flush_wait_cb(display, flush_wait_partial);
|
||||
}
|
||||
else {
|
||||
LV_ASSERT(0);
|
||||
}
|
||||
|
||||
lv_display_set_buffers_with_stride(display, buf1, buf2, buf_size, DISPLAY_BUFFER_STRIDE_BYTES_INPUT0, render_mode);
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
static void give_vsync_sem_and_yield(void)
|
||||
{
|
||||
#if USE_FREE_RTOS
|
||||
BaseType_t context_switch;
|
||||
|
||||
/*Set Vsync semaphore*/
|
||||
xSemaphoreGiveFromISR(_SemaphoreVsync, &context_switch);
|
||||
|
||||
/*Return to the highest priority available task*/
|
||||
portYIELD_FROM_ISR(context_switch);
|
||||
#else
|
||||
#endif /*USE_FREE_RTOS*/
|
||||
}
|
||||
|
||||
static void glcdc_init(void)
|
||||
{
|
||||
/* Fill the Frame buffer with black colour (0x0000 in RGB565), for a clean start after previous runs */
|
||||
lv_memzero(fb_background, sizeof(fb_background));
|
||||
|
||||
#ifdef _RENESAS_RA_
|
||||
/* Initialize GLCDC driver */
|
||||
uint8_t * p_fb = &fb_background[1][0];
|
||||
fsp_err_t err;
|
||||
|
||||
err = R_GLCDC_Open(&g_display0_ctrl, &g_display0_cfg);
|
||||
if(FSP_SUCCESS != err) {
|
||||
__BKPT(0);
|
||||
}
|
||||
|
||||
err = R_GLCDC_Start(&g_display0_ctrl);
|
||||
if(FSP_SUCCESS != err) {
|
||||
__BKPT(0);
|
||||
}
|
||||
|
||||
do {
|
||||
err =
|
||||
R_GLCDC_BufferChange(&g_display0_ctrl,
|
||||
(uint8_t *) p_fb,
|
||||
(display_frame_layer_t) 0);
|
||||
} while(FSP_ERR_INVALID_UPDATE_TIMING == err);
|
||||
#else /* RX */
|
||||
glcdc_err_t err;
|
||||
glcdc_runtime_cfg_t layer_change;
|
||||
|
||||
R_GLCDC_PinSet();
|
||||
|
||||
err = R_GLCDC_Open(&g_config);
|
||||
if(GLCDC_SUCCESS != err) {
|
||||
while(1);
|
||||
}
|
||||
|
||||
err = R_GLCDC_Control(GLCDC_CMD_START_DISPLAY, &g_config);
|
||||
if(GLCDC_SUCCESS != err) {
|
||||
while(1);
|
||||
}
|
||||
|
||||
g_layer_change.input = g_config.input[GLCDC_FRAME_LAYER_2];
|
||||
g_layer_change.chromakey = g_config.chromakey[GLCDC_FRAME_LAYER_2];
|
||||
g_layer_change.blend = g_config.blend[GLCDC_FRAME_LAYER_2];
|
||||
|
||||
layer_change.input.p_base = (uint32_t *)&fb_background[1][0];
|
||||
|
||||
do {
|
||||
err = R_GLCDC_LayerChange(GLCDC_FRAME_LAYER_2, &g_layer_change);
|
||||
} while(GLCDC_ERR_INVALID_UPDATE_TIMING == err);
|
||||
#endif /*_RENESAS_RA_*/
|
||||
}
|
||||
|
||||
static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
FSP_PARAMETER_NOT_USED(area);
|
||||
/*Display the frame buffer pointed by px_map*/
|
||||
|
||||
if(!lv_display_flush_is_last(display)) return;
|
||||
|
||||
#if defined(RENESAS_CORTEX_M85) && (BSP_CFG_DCACHE_ENABLED)
|
||||
/* Invalidate cache - so the HW can access any data written by the CPU */
|
||||
SCB_CleanInvalidateDCache_by_Addr(px_map, sizeof(fb_background[0]));
|
||||
#endif
|
||||
|
||||
#ifdef _RENESAS_RA_
|
||||
R_GLCDC_BufferChange(&g_display0_ctrl,
|
||||
(uint8_t *) px_map,
|
||||
(display_frame_layer_t) 0);
|
||||
#else /* RX */
|
||||
glcdc_err_t err;
|
||||
|
||||
g_layer_change.input.p_base = (uint32_t *)px_map;
|
||||
|
||||
do {
|
||||
err = R_GLCDC_LayerChange(GLCDC_FRAME_LAYER_2, &g_layer_change);
|
||||
} while(GLCDC_ERR_INVALID_UPDATE_TIMING == err);
|
||||
#endif /*_RENESAS_RA_*/
|
||||
}
|
||||
|
||||
static void flush_wait_direct(lv_display_t * display)
|
||||
{
|
||||
if(!lv_display_flush_is_last(display)) return;
|
||||
|
||||
#if USE_FREE_RTOS
|
||||
/*If Vsync semaphore has already been set, clear it then wait to avoid tearing*/
|
||||
if(uxSemaphoreGetCount(_SemaphoreVsync)) {
|
||||
xSemaphoreTake(_SemaphoreVsync, 10);
|
||||
}
|
||||
|
||||
xSemaphoreTake(_SemaphoreVsync, portMAX_DELAY);
|
||||
#endif /*USE_FREE_RTOS*/
|
||||
|
||||
}
|
||||
|
||||
static void flush_partial(lv_display_t * display, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
uint16_t * img = (uint16_t *)px_map;
|
||||
|
||||
lv_area_t rotated_area;
|
||||
lv_color_format_t cf = lv_display_get_color_format(display);
|
||||
lv_display_rotation_t rotation = lv_display_get_rotation(display);
|
||||
|
||||
if(rotation != LV_DISPLAY_ROTATION_0) {
|
||||
int32_t w = lv_area_get_width(area);
|
||||
int32_t h = lv_area_get_height(area);
|
||||
uint32_t w_stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
uint32_t h_stride = lv_draw_buf_width_to_stride(h, cf);
|
||||
|
||||
// only allocate if rotation is actually being used
|
||||
if(!rotation_buffer) {
|
||||
rotation_buffer = lv_malloc(partial_buffer_size);
|
||||
LV_ASSERT_MALLOC(rotation_buffer);
|
||||
}
|
||||
|
||||
if(rotation == LV_DISPLAY_ROTATION_180)
|
||||
lv_draw_sw_rotate(img, rotation_buffer, w, h, w_stride, w_stride, rotation, cf);
|
||||
else /* 90 or 270 */
|
||||
lv_draw_sw_rotate(img, rotation_buffer, w, h, w_stride, h_stride, rotation, cf);
|
||||
|
||||
img = rotation_buffer;
|
||||
|
||||
rotated_area = *area;
|
||||
lv_display_rotate_area(display, &rotated_area);
|
||||
area = &rotated_area;
|
||||
}
|
||||
|
||||
int32_t w = lv_area_get_width(area);
|
||||
int32_t h = lv_area_get_height(area);
|
||||
|
||||
uint16_t * fb = (uint16_t *)fb_background[1];
|
||||
|
||||
fb = fb + area->y1 * DISPLAY_HSIZE_INPUT0;
|
||||
fb = fb + area->x1;
|
||||
|
||||
int32_t i;
|
||||
for(i = 0; i < h; i++) {
|
||||
lv_memcpy(fb, img, w * BYTES_PER_PIXEL);
|
||||
|
||||
#if defined(RENESAS_CORTEX_M85) && (BSP_CFG_DCACHE_ENABLED)
|
||||
SCB_CleanInvalidateDCache_by_Addr(fb, w * BYTES_PER_PIXEL);
|
||||
#endif
|
||||
fb += DISPLAY_HSIZE_INPUT0;
|
||||
img += w;
|
||||
}
|
||||
}
|
||||
|
||||
static void flush_wait_partial(lv_display_t * display)
|
||||
{
|
||||
LV_UNUSED(display);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _RENESAS_RX_
|
||||
extern void drw_int_isr(void);
|
||||
|
||||
static void enable_dave2d_drw_interrupt(void)
|
||||
{
|
||||
bsp_int_ctrl_t grpal1;
|
||||
|
||||
/* Specify the priority of the group interrupt. */
|
||||
grpal1.ipl = 5;
|
||||
|
||||
/* Use the BSP API to register the interrupt handler for DRW2D. */
|
||||
R_BSP_InterruptWrite(BSP_INT_SRC_AL1_DRW2D_DRW_IRQ, (bsp_int_cb_t)drw_int_isr);
|
||||
|
||||
/* Use the BSP API to enable the group interrupt. */
|
||||
R_BSP_InterruptControl(BSP_INT_SRC_AL1_DRW2D_DRW_IRQ, BSP_INT_CMD_GROUP_INTERRUPT_ENABLE, (void *)&grpal1);
|
||||
}
|
||||
#endif /*_RENESAS_RX_*/
|
||||
|
||||
#endif /*LV_USE_RENESAS_GLCDC*/
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file lv_renesas_glcdc.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_RENESAS_GLCDC_H
|
||||
#define LV_RENESAS_GLCDC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_RENESAS_GLCDC
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a display using Renesas' GLCDC peripheral in DIRECT render mode
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_renesas_glcdc_direct_create(void);
|
||||
|
||||
/**
|
||||
* Create a display using Renesas' GLCDC peripheral in PARTIAL render mode
|
||||
* @param buf1 first buffer
|
||||
* @param buf2 second buffer (can be `NULL`)
|
||||
* @param buf_size buffer size in byte
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_renesas_glcdc_partial_create(void * buf1, void * buf2, size_t buf_size);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* LV_USE_RENESAS_GLCDC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_RENESAS_GLCDC_H */
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @file lv_st7735.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_st7735.h"
|
||||
|
||||
#if LV_USE_ST7735
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_GAMSET 0x26
|
||||
|
||||
#define CMD_FRMCTR1 0xB1
|
||||
#define CMD_FRMCTR2 0xB2
|
||||
#define CMD_FRMCTR3 0xB3
|
||||
#define CMD_INVCTR 0xB4
|
||||
#define CMD_DISSET5 0xB6
|
||||
|
||||
#define CMD_PWCTR1 0xC0
|
||||
#define CMD_PWCTR2 0xC1
|
||||
#define CMD_PWCTR3 0xC2
|
||||
#define CMD_PWCTR4 0xC3
|
||||
#define CMD_PWCTR5 0xC4
|
||||
#define CMD_VMCTR1 0xC5
|
||||
#define CMD_VMOFCTR 0xC7
|
||||
|
||||
#define CMD_NVFCTR1 0xD9
|
||||
|
||||
#define CMD_GMCTRP1 0xE0
|
||||
#define CMD_GMCTRN1 0xE1
|
||||
|
||||
#define CMD_PWCTR6 0xFC
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands for buydisplay.com ER-TFTM018-3 */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
0xB1, 3, 0x05, 0x3C, 0x3C,
|
||||
0xB2, 3, 0x05, 0x3C, 0x3C,
|
||||
0xB3, 6, 0x05, 0x3C, 0x3C, 0x05, 0x3C, 0x3C,
|
||||
0xB4, 1, 0x03,
|
||||
0xC0, 3, 0x28, 0x08, 0x04,
|
||||
0xC1, 1, 0XC0,
|
||||
0xC2, 2, 0x0D, 0x00,
|
||||
0xC3, 2, 0x8D, 0x2A,
|
||||
0xC4, 2, 0x8D, 0xEE,
|
||||
0xC5, 1, 0x10,
|
||||
0xE0, 16, 0x04, 0x22, 0x07, 0x0A, 0x2E, 0x30, 0x25, 0x2A, 0x28, 0x26, 0x2E, 0x3A, 0x00, 0x01, 0x03, 0x13,
|
||||
0xE1, 16, 0x04, 0x16, 0x06, 0x0D, 0x2D, 0x26, 0x23, 0x27, 0x27, 0x25, 0x2D, 0x3B, 0x00, 0x01, 0x04, 0x13,
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st7735_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7735_send_cmd_cb_t send_cmd_cb, lv_st7735_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_st7735_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_st7735_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_st7735_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
|
||||
}
|
||||
|
||||
void lv_st7735_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7735*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file lv_st7735.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST7735_H
|
||||
#define LV_ST7735_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ST7735
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_st7735_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_st7735_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7735 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7735_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7735_send_cmd_cb_t send_cmd_cb, lv_st7735_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_st7735_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_st7735_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_st7735_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_st7735_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7735*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_ST7735_H*/
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @file lv_st7789.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_st7789.h"
|
||||
|
||||
#if LV_USE_ST7789
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_FRMCTR1 0xB1
|
||||
#define CMD_FRMCTR2 0xB2
|
||||
#define CMD_FRMCTR3 0xB3
|
||||
#define CMD_INVCTR 0xB4
|
||||
#define CMD_DFUNCTR 0xB6
|
||||
#define CMD_ETMOD 0xB7
|
||||
#define CMD_PWCTR1 0xC0
|
||||
#define CMD_PWCTR2 0xC1
|
||||
#define CMD_PWCTR3 0xC2
|
||||
#define CMD_PWCTR4 0xC3
|
||||
#define CMD_PWCTR5 0xC4
|
||||
#define CMD_VMCTR 0xC5
|
||||
#define CMD_GMCTRP1 0xE0
|
||||
#define CMD_GMCTRN1 0xE1
|
||||
#define CMD_DOCA 0xE8
|
||||
#define CMD_CSCON 0xF0
|
||||
|
||||
#define CMD_RAMCTRL 0xB0
|
||||
#define CMD_PORCTRL 0xB2 /* Porch control */
|
||||
#define CMD_GCTRL 0xB7 /* Gate control */
|
||||
#define CMD_VCOMS 0xBB /* VCOMS setting */
|
||||
#define CMD_LCMCTRL 0xC0 /* LCM control */
|
||||
#define CMD_VDVVRHEN 0xC2 /* VDV and VRH command enable */
|
||||
#define CMD_VRHS 0xC3 /* VRH set */
|
||||
#define CMD_VDVSET 0xC4 /* VDV setting */
|
||||
#define CMD_FRCTR2 0xC6 /* FR Control 2 */
|
||||
#define CMD_PWCTRL1 0xD0 /* Power control 1 */
|
||||
#define CMD_PVGAMCTRL 0xE0 /* Positive Gamma Correction */
|
||||
#define CMD_NVGAMCTRL 0xE1 /* Negative Gamma Correction */
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands based on LovyanGFX ST7789 driver */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
CMD_GCTRL, 1, 0x44, /* GCTRL -- panel dependent */
|
||||
CMD_VCOMS, 1, 0x24, /* VCOMS -- panel dependent */
|
||||
CMD_VRHS, 1, 0x13, /* VRHS - panel dependent */
|
||||
CMD_PWCTRL1, 2, 0xa4, 0xa1,
|
||||
CMD_RAMCTRL, 2, 0x00, 0xC0, /* controls mapping of RGB565 to RGB666 */
|
||||
CMD_PVGAMCTRL, 14, 0xd0, 0x00, 0x02, 0x07, 0x0a, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0e, 0x12, 0x14, 0x17,
|
||||
CMD_NVGAMCTRL, 14, 0xd0, 0x00, 0x02, 0x07, 0x0a, 0x28, 0x31, 0x54, 0x47, 0x0e, 0x1c, 0x17, 0x1b, 0x1e,
|
||||
LV_LCD_CMD_SET_GAMMA_CURVE, 1, 0x01,
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st7789_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7789_send_cmd_cb_t send_cmd_cb, lv_st7789_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_st7789_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_st7789_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_st7789_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
|
||||
}
|
||||
|
||||
void lv_st7789_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7789*/
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file lv_st7789.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST7789_H
|
||||
#define LV_ST7789_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ST7789
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_st7789_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_st7789_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7789 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7789_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7789_send_cmd_cb_t send_cmd_cb, lv_st7789_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_st7789_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_st7789_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_st7789_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_st7789_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#endif /*LV_USE_ST7789*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_ST7789_H*/
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @file lv_st7796.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_st7796.h"
|
||||
|
||||
#if LV_USE_ST7796
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_FRMCTR1 0xB1
|
||||
#define CMD_FRMCTR2 0xB2
|
||||
#define CMD_FRMCTR3 0xB3
|
||||
#define CMD_INVCTR 0xB4
|
||||
#define CMD_DFUNCTR 0xB6
|
||||
#define CMD_ETMOD 0xB7
|
||||
#define CMD_PWCTR1 0xC0
|
||||
#define CMD_PWCTR2 0xC1
|
||||
#define CMD_PWCTR3 0xC2
|
||||
#define CMD_PWCTR4 0xC3
|
||||
#define CMD_PWCTR5 0xC4
|
||||
#define CMD_VMCTR 0xC5
|
||||
#define CMD_GMCTRP1 0xE0
|
||||
#define CMD_GMCTRN1 0xE1
|
||||
#define CMD_DOCA 0xE8
|
||||
#define CMD_CSCON 0xF0
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands based on LovyanGFX */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
CMD_CSCON, 1, 0xC3, /* Enable extension command 2 partI */
|
||||
CMD_CSCON, 1, 0x96, /* Enable extension command 2 partII */
|
||||
CMD_INVCTR, 1, 0x01, /* 1-dot inversion */
|
||||
CMD_DFUNCTR, 3, 0x80, /* Display Function Control: Bypass */
|
||||
0x22, /* Source Output Scan from S1 to S960, Gate Output scan from G1 to G480, scan cycle = 2 */
|
||||
0x3B, /* LCD Drive Line = 8 * (59 + 1) */
|
||||
CMD_DOCA, 8, 0x40, 0x8A, 0x00, 0x00,
|
||||
0x29, /* Source equalizing period time = 22.5 us */
|
||||
0x19, /* Timing for "Gate start" = 25 (Tclk) */
|
||||
0xA5, /* Timing for "Gate End" = 37 (Tclk), Gate driver EQ function ON */
|
||||
0x33,
|
||||
CMD_PWCTR2, 1, 0x06, /* Power control2: VAP(GVDD) = 3.85 + (vcom + vcom offset), VAN(GVCL) = -3.85 + (vcom + vcom offset) */
|
||||
CMD_PWCTR3, 1, 0xA7, /* Power control 3: Source driving current level = low, Gamma driving current level = High */
|
||||
CMD_VMCTR, 1, 0x18, /* VCOM Control: VCOM = 0.9 */
|
||||
LV_LCD_CMD_DELAY_MS, 12, /* delay 120 ms */
|
||||
CMD_GMCTRP1, 14, /* Gamma */
|
||||
0xF0, 0x09, 0x0B, 0x06, 0x04, 0x15, 0x2F,
|
||||
0x54, 0x42, 0x3C, 0x17, 0x14, 0x18, 0x1B,
|
||||
CMD_GMCTRN1, 14,
|
||||
0xE0, 0x09, 0x0B, 0x06, 0x04, 0x03, 0x2B,
|
||||
0x43, 0x42, 0x3B, 0x16, 0x14, 0x17, 0x1B,
|
||||
LV_LCD_CMD_DELAY_MS, 12, /* delay 120 ms */
|
||||
CMD_CSCON, 1, 0x3C, /* Disable extension command 2 partI */
|
||||
CMD_CSCON, 1, 0x69, /* Disable extension command 2 partII */
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st7796_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7796_send_cmd_cb_t send_cmd_cb, lv_st7796_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_st7796_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_st7796_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_st7796_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
/* NOTE: the generic method is not supported on ST7796, TODO: implement gamma tables */
|
||||
LV_UNUSED(disp);
|
||||
LV_UNUSED(gamma);
|
||||
}
|
||||
|
||||
void lv_st7796_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7796*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file lv_st7796.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST7796_H
|
||||
#define LV_ST7796_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ST7796
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_st7796_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_st7796_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7796 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7796_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7796_send_cmd_cb_t send_cmd_cb, lv_st7796_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_st7796_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_st7796_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_st7796_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_st7796_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7796*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_ST7796_H*/
|
||||
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
* @file lv_st_ltdc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_ST_LTDC
|
||||
|
||||
#include "lv_st_ltdc.h"
|
||||
#include "../../../display/lv_display_private.h"
|
||||
#include "../../../draw/sw/lv_draw_sw.h"
|
||||
#include "ltdc.h"
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
#if LV_USE_DRAW_DMA2D
|
||||
#error cannot use LV_ST_LTDC_USE_DMA2D_FLUSH with LV_USE_DRAW_DMA2D
|
||||
#endif /*LV_USE_DRAW_DMA2D*/
|
||||
|
||||
#include "dma2d.h"
|
||||
#endif /*LV_ST_LTDC_USE_DMA2D_FLUSH*/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
typedef lv_thread_sync_t sync_t;
|
||||
#else
|
||||
typedef volatile bool sync_t;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static lv_display_t * create(void * buf1, void * buf2, uint32_t buf_size, uint32_t layer_idx,
|
||||
lv_display_render_mode_t mode);
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
static void flush_wait_cb(lv_display_t * disp);
|
||||
static lv_color_format_t get_lv_cf_from_layer_cf(uint32_t cf);
|
||||
static void reload_event_callback(LTDC_HandleTypeDef * hltdc);
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
static void transfer_complete_callback(DMA2D_HandleTypeDef * hdma2d);
|
||||
static uint32_t get_dma2d_output_cf_from_layer_cf(uint32_t cf);
|
||||
static uint32_t get_dma2d_input_cf_from_lv_cf(uint32_t cf);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static struct {
|
||||
bool disp_flushed_in_flush_cb[MAX_LAYER];
|
||||
sync_t sync[MAX_LAYER];
|
||||
volatile bool layer_interrupt_is_owned[MAX_LAYER];
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
volatile uint32_t dma2d_interrupt_owner; /*layer_idx + 1, or 0 for none*/
|
||||
#endif
|
||||
} g_data;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
#define SYNC_INIT(layer_idx) lv_thread_sync_init(&g_data.sync[layer_idx])
|
||||
#define SYNC_WAIT(layer_idx) lv_thread_sync_wait(&g_data.sync[layer_idx])
|
||||
#define SYNC_SIGNAL_ISR(layer_idx) lv_thread_sync_signal_isr(&g_data.sync[layer_idx])
|
||||
#else
|
||||
#define SYNC_INIT(layer_idx) do { g_data.sync[layer_idx] = false; } while(0)
|
||||
#define SYNC_WAIT(layer_idx) do { while(!g_data.sync[layer_idx]); g_data.sync[layer_idx] = false; } while(0)
|
||||
#define SYNC_SIGNAL_ISR(layer_idx) do { g_data.sync[layer_idx] = true; } while(0)
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st_ltdc_create_direct(void * fb_adr_1, void * fb_adr_2, uint32_t layer_idx)
|
||||
{
|
||||
return create(fb_adr_1, fb_adr_2, 0, layer_idx, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
}
|
||||
|
||||
lv_display_t * lv_st_ltdc_create_partial(void * render_buf_1, void * render_buf_2, uint32_t buf_size,
|
||||
uint32_t layer_idx)
|
||||
{
|
||||
return create(render_buf_1, render_buf_2, buf_size, layer_idx, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_display_t * create(void * buf1, void * buf2, uint32_t buf_size, uint32_t layer_idx,
|
||||
lv_display_render_mode_t mode)
|
||||
{
|
||||
LTDC_LayerCfgTypeDef * layer_cfg = &hltdc.LayerCfg[layer_idx];
|
||||
uint32_t layer_width = layer_cfg->ImageWidth;
|
||||
uint32_t layer_height = layer_cfg->ImageHeight;
|
||||
uint32_t layer_cf = layer_cfg->PixelFormat;
|
||||
lv_color_format_t cf = get_lv_cf_from_layer_cf(layer_cf);
|
||||
|
||||
lv_display_t * disp = lv_display_create(layer_width, layer_height);
|
||||
lv_display_set_color_format(disp, cf);
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
lv_display_set_flush_wait_cb(disp, flush_wait_cb);
|
||||
lv_display_set_driver_data(disp, (void *)(uintptr_t)layer_idx);
|
||||
|
||||
if(mode == LV_DISPLAY_RENDER_MODE_DIRECT) {
|
||||
uint32_t cf_size = lv_color_format_get_size(cf);
|
||||
lv_display_set_buffers(disp, buf1, buf2, layer_width * layer_height * cf_size, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
|
||||
if(buf1 != NULL && buf2 != NULL) {
|
||||
HAL_LTDC_RegisterCallback(&hltdc, HAL_LTDC_RELOAD_EVENT_CB_ID, reload_event_callback);
|
||||
SYNC_INIT(layer_idx);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_display_set_buffers(disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
hdma2d.XferCpltCallback = transfer_complete_callback;
|
||||
SYNC_INIT(layer_idx);
|
||||
#endif
|
||||
}
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
uint32_t layer_idx = (uint32_t)(uintptr_t)lv_display_get_driver_data(disp);
|
||||
g_data.disp_flushed_in_flush_cb[layer_idx] = false;
|
||||
|
||||
if(disp->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) {
|
||||
if(lv_display_is_double_buffered(disp) && lv_display_flush_is_last(disp)) {
|
||||
HAL_LTDC_SetAddress_NoReload(&hltdc, (uint32_t)px_map, layer_idx);
|
||||
g_data.layer_interrupt_is_owned[layer_idx] = true;
|
||||
HAL_LTDC_Reload(&hltdc, LTDC_RELOAD_VERTICAL_BLANKING);
|
||||
}
|
||||
else {
|
||||
g_data.disp_flushed_in_flush_cb[layer_idx] = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LTDC_LayerCfgTypeDef * layer_cfg = &hltdc.LayerCfg[layer_idx];
|
||||
|
||||
lv_color_format_t cf = lv_display_get_color_format(disp);
|
||||
int32_t disp_width = disp->hor_res;
|
||||
|
||||
uint8_t * fb = (uint8_t *) layer_cfg->FBStartAdress;
|
||||
uint32_t px_size = lv_color_format_get_size(cf);
|
||||
uint32_t fb_stride = px_size * disp_width;
|
||||
lv_area_t rotated_area = *area;
|
||||
lv_display_rotate_area(disp, &rotated_area);
|
||||
uint8_t * first_pixel = fb + fb_stride * rotated_area.y1 + px_size * rotated_area.x1;
|
||||
|
||||
int32_t area_width = lv_area_get_width(area);
|
||||
int32_t area_height = lv_area_get_height(area);
|
||||
|
||||
lv_display_rotation_t rotation = lv_display_get_rotation(disp);
|
||||
if(rotation == LV_DISPLAY_ROTATION_0) {
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
uint32_t dma2d_input_cf = get_dma2d_input_cf_from_lv_cf(cf);
|
||||
uint32_t dma2d_output_cf = get_dma2d_output_cf_from_layer_cf(layer_cfg->PixelFormat);
|
||||
|
||||
while(DMA2D->CR & DMA2D_CR_START);
|
||||
DMA2D->FGPFCCR = dma2d_input_cf;
|
||||
DMA2D->FGMAR = (uint32_t)px_map;
|
||||
DMA2D->FGOR = 0;
|
||||
DMA2D->OPFCCR = dma2d_output_cf;
|
||||
DMA2D->OMAR = (uint32_t)first_pixel;
|
||||
DMA2D->OOR = disp_width - area_width;
|
||||
DMA2D->NLR = (area_width << DMA2D_NLR_PL_Pos) | (area_height << DMA2D_NLR_NL_Pos);
|
||||
g_data.dma2d_interrupt_owner = layer_idx + 1;
|
||||
DMA2D->CR = DMA2D_CR_START | DMA2D_CR_TCIE | (0x1U << DMA2D_CR_MODE_Pos); /* memory-to-memory with PFC */
|
||||
#else
|
||||
uint32_t area_stride = px_size * area_width;
|
||||
uint8_t * fb_p = first_pixel;
|
||||
uint8_t * px_map_p = px_map;
|
||||
for(int i = 0; i < area_height; i++) {
|
||||
lv_memcpy(fb_p, px_map_p, area_stride);
|
||||
fb_p += fb_stride;
|
||||
px_map_p += area_stride;
|
||||
}
|
||||
g_data.disp_flushed_in_flush_cb[layer_idx] = true;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
uint32_t area_stride = px_size * area_width;
|
||||
lv_draw_sw_rotate(px_map, first_pixel, area_width, area_height, area_stride, fb_stride, rotation, cf);
|
||||
g_data.disp_flushed_in_flush_cb[layer_idx] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flush_wait_cb(lv_display_t * disp)
|
||||
{
|
||||
uint32_t layer_idx = (uint32_t)(uintptr_t)lv_display_get_driver_data(disp);
|
||||
if(!g_data.disp_flushed_in_flush_cb[layer_idx]) {
|
||||
SYNC_WAIT(layer_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static lv_color_format_t get_lv_cf_from_layer_cf(uint32_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LTDC_PIXEL_FORMAT_ARGB8888:
|
||||
return LV_COLOR_FORMAT_ARGB8888;
|
||||
case LTDC_PIXEL_FORMAT_RGB888:
|
||||
return LV_COLOR_FORMAT_RGB888;
|
||||
case LTDC_PIXEL_FORMAT_RGB565:
|
||||
return LV_COLOR_FORMAT_RGB565;
|
||||
case LTDC_PIXEL_FORMAT_L8:
|
||||
return LV_COLOR_FORMAT_L8;
|
||||
case LTDC_PIXEL_FORMAT_AL88:
|
||||
return LV_COLOR_FORMAT_AL88;
|
||||
default:
|
||||
LV_ASSERT_MSG(0, "the LTDC color format is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
static void reload_event_callback(LTDC_HandleTypeDef * hltdc)
|
||||
{
|
||||
uint32_t i;
|
||||
for(i = 0; i < MAX_LAYER; i++) {
|
||||
if(g_data.layer_interrupt_is_owned[i]) {
|
||||
g_data.layer_interrupt_is_owned[i] = false;
|
||||
SYNC_SIGNAL_ISR(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
static void transfer_complete_callback(DMA2D_HandleTypeDef * hdma2d)
|
||||
{
|
||||
DMA2D->IFCR = 0x3FU;
|
||||
uint32_t owner = g_data.dma2d_interrupt_owner;
|
||||
if(owner) {
|
||||
g_data.dma2d_interrupt_owner = 0;
|
||||
owner -= 1;
|
||||
SYNC_SIGNAL_ISR(owner);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_dma2d_output_cf_from_layer_cf(uint32_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LTDC_PIXEL_FORMAT_ARGB8888:
|
||||
return DMA2D_OUTPUT_ARGB8888;
|
||||
case LTDC_PIXEL_FORMAT_RGB888:
|
||||
return DMA2D_OUTPUT_RGB888;
|
||||
case LTDC_PIXEL_FORMAT_RGB565:
|
||||
return DMA2D_OUTPUT_RGB565;
|
||||
default:
|
||||
LV_ASSERT_MSG(0, "DMA2D cannot output to the LTDC color format");
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_dma2d_input_cf_from_lv_cf(uint32_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
return DMA2D_INPUT_ARGB8888;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
return DMA2D_INPUT_RGB888;
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
return DMA2D_INPUT_RGB565;
|
||||
case LV_COLOR_FORMAT_L8:
|
||||
return DMA2D_INPUT_L8;
|
||||
case LV_COLOR_FORMAT_AL88:
|
||||
return DMA2D_INPUT_AL88;
|
||||
case LV_COLOR_FORMAT_A8:
|
||||
return DMA2D_INPUT_A8;
|
||||
default:
|
||||
LV_ASSERT_MSG(0, "the LVGL color format is not a DMA2D input color format");
|
||||
}
|
||||
}
|
||||
#endif /*LV_ST_LTDC_USE_DMA2D_FLUSH*/
|
||||
|
||||
#endif /*LV_USE_ST_LTDC*/
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @file lv_st_ltdc.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST_LTDC_H
|
||||
#define LV_ST_LTDC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_ST_LTDC
|
||||
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a direct render mode display bound to a LTDC layer.
|
||||
* @param fb_adr_1 The LTDC layer's framebuffer memory address.
|
||||
* @param fb_adr_2 An additional framebuffer-sized buffer to use for double buffering, or `NULL`.
|
||||
* @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1.
|
||||
* @return The display.
|
||||
*/
|
||||
lv_display_t * lv_st_ltdc_create_direct(void * fb_adr_1, void * fb_adr_2, uint32_t layer_idx);
|
||||
|
||||
/**
|
||||
* Create a partial render mode display bound to a LTDC layer. The layer's framebuffer is flushed to internally.
|
||||
* Enable `LV_ST_LTDC_USE_DMA2D_FLUSH` for parallel flushing.
|
||||
* @param render_buf_1 A render buffer.
|
||||
* @param render_buf_2 An additional render buffer for double-buffering, or `NULL`.
|
||||
* @param buf_size The size of the buffer(s) in bytes.
|
||||
* @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1.
|
||||
* @return The display.
|
||||
*/
|
||||
lv_display_t * lv_st_ltdc_create_partial(void * render_buf_1, void * render_buf_2, uint32_t buf_size,
|
||||
uint32_t layer_idx);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST_LTDC*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_ST_LTDC_H*/
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @file lv_tft_espi.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_tft_espi.h"
|
||||
#if LV_USE_TFT_ESPI
|
||||
|
||||
#include <TFT_eSPI.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
TFT_eSPI * tft;
|
||||
} lv_tft_espi_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
static void resolution_changed_event_cb(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_tft_espi_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes)
|
||||
{
|
||||
lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_malloc_zeroed(sizeof(lv_tft_espi_t));
|
||||
LV_ASSERT_MALLOC(dsc);
|
||||
if(dsc == NULL) return NULL;
|
||||
|
||||
lv_display_t * disp = lv_display_create(hor_res, ver_res);
|
||||
if(disp == NULL) {
|
||||
lv_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dsc->tft = new TFT_eSPI(hor_res, ver_res);
|
||||
dsc->tft->begin(); /* TFT init */
|
||||
dsc->tft->setRotation(0);
|
||||
lv_display_set_driver_data(disp, (void *)dsc);
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
lv_display_add_event_cb(disp, resolution_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
|
||||
lv_display_set_buffers(disp, (void *)buf, NULL, buf_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
return disp;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_display_get_driver_data(disp);
|
||||
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
dsc->tft->startWrite();
|
||||
dsc->tft->setAddrWindow(area->x1, area->y1, w, h);
|
||||
dsc->tft->pushColors((uint16_t *)px_map, w * h, true);
|
||||
dsc->tft->endWrite();
|
||||
|
||||
lv_display_flush_ready(disp);
|
||||
|
||||
}
|
||||
|
||||
static void resolution_changed_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_display_t * disp = (lv_display_t *)lv_event_get_target(e);
|
||||
lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_display_get_driver_data(disp);
|
||||
int32_t hor_res = lv_display_get_horizontal_resolution(disp);
|
||||
int32_t ver_res = lv_display_get_vertical_resolution(disp);
|
||||
lv_display_rotation_t rot = lv_display_get_rotation(disp);
|
||||
|
||||
/* handle rotation */
|
||||
switch(rot) {
|
||||
case LV_DISPLAY_ROTATION_0:
|
||||
dsc->tft->setRotation(0); /* Portrait orientation */
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_90:
|
||||
dsc->tft->setRotation(1); /* Landscape orientation */
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_180:
|
||||
dsc->tft->setRotation(2); /* Portrait orientation, flipped */
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_270:
|
||||
dsc->tft->setRotation(3); /* Landscape orientation, flipped */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_TFT_ESPI*/
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file lv_tft_espi.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TFT_ESPI_H
|
||||
#define LV_TFT_ESPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_TFT_ESPI
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
lv_display_t * lv_tft_espi_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* LV_USE_TFT_ESPI */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_TFT_ESPI_H */
|
||||
Reference in New Issue
Block a user