Update LVGL to v9.1.0

This commit is contained in:
jacqueline
2024-06-12 17:54:40 +10:00
parent 611176ed66
commit 64bd9053a2
2244 changed files with 278442 additions and 118864 deletions
@@ -21,7 +21,7 @@
#endif
#ifndef MY_DISP_VER_RES
#warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen height, default value 240 is used for now.
#warning Please define or replace the macro MY_DISP_VER_RES with the actual screen height, default value 240 is used for now.
#define MY_DISP_VER_RES 240
#endif
@@ -34,9 +34,7 @@
**********************/
static void disp_init(void);
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
// const lv_area_t * fill_area, lv_color_t color);
static void disp_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
/**********************
* STATIC VARIABLES
@@ -57,78 +55,31 @@ void lv_port_disp_init(void)
* -----------------------*/
disp_init();
/*-----------------------------
* Create a buffer for drawing
*----------------------------*/
/*------------------------------------
* Create a display and set a flush_cb
* -----------------------------------*/
lv_display_t * disp = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES);
lv_display_set_flush_cb(disp, disp_flush);
/**
* LVGL requires a buffer where it internally draws the widgets.
* Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
* The buffer has to be greater than 1 display row
*
* There are 3 buffering configurations:
* 1. Create ONE buffer:
* LVGL will draw the display's content here and writes it to your display
*
* 2. Create TWO buffer:
* LVGL will draw the display's content to a buffer and writes it your display.
* You should use DMA to write the buffer's content to the display.
* It will enable LVGL to draw the next part of the screen to the other buffer while
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
*
* 3. Double buffering
* Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
* This way LVGL will always provide the whole rendered screen in `flush_cb`
* and you only need to change the frame buffer's address.
*/
/* Example 1
* One buffer for partial rendering*/
static lv_color_t buf_1_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/
lv_display_set_buffers(disp, buf_1_1, NULL, sizeof(buf_1_1), LV_DISPLAY_RENDER_MODE_PARTIAL);
/* Example for 1) */
static lv_disp_draw_buf_t draw_buf_dsc_1;
static lv_color_t buf_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/
lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/
/* Example 2
* Two buffers for partial rendering
* In flush_cb DMA or similar hardware should be used to update the display in the background.*/
static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];
static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];
lv_display_set_buffers(disp, buf_2_1, buf_2_2, sizeof(buf_2_1), LV_DISPLAY_RENDER_MODE_PARTIAL);
/* Example for 2) */
static lv_disp_draw_buf_t draw_buf_dsc_2;
static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/
static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; /*An other buffer for 10 rows*/
lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/
/* Example 3
* Two buffers screen sized buffer for double buffering.
* Both LV_DISPLAY_RENDER_MODE_DIRECT and LV_DISPLAY_RENDER_MODE_FULL works, see their comments*/
static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];
static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES];
lv_display_set_buffers(disp, buf_3_1, buf_3_2, sizeof(buf_3_1), LV_DISPLAY_RENDER_MODE_DIRECT);
/* Example for 3) also set disp_drv.full_refresh = 1 below*/
static lv_disp_draw_buf_t draw_buf_dsc_3;
static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*A screen sized buffer*/
static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*Another screen sized buffer*/
lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2,
MY_DISP_VER_RES * LV_VER_RES_MAX); /*Initialize the display buffer*/
/*-----------------------------------
* Register the display in LVGL
*----------------------------------*/
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv.hor_res = MY_DISP_HOR_RES;
disp_drv.ver_res = MY_DISP_VER_RES;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
/*Set a display buffer*/
disp_drv.draw_buf = &draw_buf_dsc_1;
/*Required for Example 3)*/
//disp_drv.full_refresh = 1;
/* Fill a memory array with a color if you have GPU.
* Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
* But if you have a different GPU you can use with this callback.*/
//disp_drv.gpu_fill_cb = gpu_fill;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
/**********************
@@ -157,10 +108,11 @@ void disp_disable_update(void)
disp_flush_enabled = false;
}
/*Flush the content of the internal buffer the specific area on the display
/*Flush the content of the internal buffer the specific area on the display.
*`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display.
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
*'lv_display_flush_ready()' has to be called when it's finished.*/
static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)
{
if(disp_flush_enabled) {
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
@@ -170,36 +122,17 @@ static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_colo
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
/*Put a pixel to the display. For example:*/
/*put_px(x, y, *color_p)*/
color_p++;
/*put_px(x, y, *px_map)*/
px_map++;
}
}
}
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
lv_display_flush_ready(disp_drv);
}
/*OPTIONAL: GPU INTERFACE*/
/*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
// const lv_area_t * fill_area, lv_color_t color)
//{
// /*It's an example code which should be done by your GPU*/
// int32_t x, y;
// dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
//
// for(y = fill_area->y1; y <= fill_area->y2; y++) {
// for(x = fill_area->x1; x <= fill_area->x2; x++) {
// dest_buf[x] = color;
// }
// dest_buf+=dest_width; /*Go to the next line*/
// }
//}
#else /*Enable this file at the top*/
/*This dummy typedef exists purely to silence -Wpedantic.*/
@@ -34,7 +34,7 @@ static lv_fs_res_t fs_size(lv_fs_drv_t * drv, void * file_p, uint32_t * size_p);
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
static void * fs_dir_open(lv_fs_drv_t * drv, const char * path);
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn);
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len);
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * rddir_p);
/**********************
@@ -64,7 +64,6 @@ void lv_port_fs_init(void)
* Register the file system interface in LVGL
*--------------------------------------------------*/
/*Add a simple drive to open images*/
static lv_fs_drv_t fs_drv;
lv_fs_drv_init(&fs_drv);
@@ -195,8 +194,8 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param pos_p pointer to to store the result
* @param file_p pointer to a file_t variable
* @param pos_p pointer to store the result
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
@@ -228,9 +227,10 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
* @param fn pointer to a buffer to store the filename
* @param fn_len length of the buffer to store the filename
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
@@ -10,7 +10,6 @@
* INCLUDES
*********************/
#include "lv_port_indev_template.h"
#include "../../lvgl.h"
/*********************
* DEFINES
@@ -25,25 +24,25 @@
**********************/
static void touchpad_init(void);
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void touchpad_read(lv_indev_t * indev, lv_indev_data_t * data);
static bool touchpad_is_pressed(void);
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
static void touchpad_get_xy(int32_t * x, int32_t * y);
static void mouse_init(void);
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void mouse_read(lv_indev_t * indev, lv_indev_data_t * data);
static bool mouse_is_pressed(void);
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
static void mouse_get_xy(int32_t * x, int32_t * y);
static void keypad_init(void);
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void keypad_read(lv_indev_t * indev, lv_indev_data_t * data);
static uint32_t keypad_get_key(void);
static void encoder_init(void);
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void encoder_read(lv_indev_t * indev, lv_indev_data_t * data);
static void encoder_handler(void);
static void button_init(void);
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void button_read(lv_indev_t * indev, lv_indev_data_t * data);
static int8_t button_get_pressed_id(void);
static bool button_is_pressed(uint8_t id);
@@ -81,8 +80,6 @@ void lv_port_indev_init(void)
* You should shape them according to your hardware
*/
static lv_indev_drv_t indev_drv;
/*------------------
* Touchpad
* -----------------*/
@@ -91,10 +88,9 @@ void lv_port_indev_init(void)
touchpad_init();
/*Register a touchpad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = touchpad_read;
indev_touchpad = lv_indev_drv_register(&indev_drv);
indev_touchpad = lv_indev_create();
lv_indev_set_type(indev_touchpad, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev_touchpad, touchpad_read);
/*------------------
* Mouse
@@ -104,14 +100,13 @@ void lv_port_indev_init(void)
mouse_init();
/*Register a mouse input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = mouse_read;
indev_mouse = lv_indev_drv_register(&indev_drv);
indev_mouse = lv_indev_create();
lv_indev_set_type(indev_mouse, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev_mouse, mouse_read);
/*Set cursor. For simplicity set a HOME symbol now.*/
lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
lv_obj_t * mouse_cursor = lv_image_create(lv_screen_active());
lv_image_set_src(mouse_cursor, LV_SYMBOL_HOME);
lv_indev_set_cursor(indev_mouse, mouse_cursor);
/*------------------
@@ -122,10 +117,9 @@ void lv_port_indev_init(void)
keypad_init();
/*Register a keypad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = keypad_read;
indev_keypad = lv_indev_drv_register(&indev_drv);
indev_keypad = lv_indev_create();
lv_indev_set_type(indev_keypad, LV_INDEV_TYPE_KEYPAD);
lv_indev_set_read_cb(indev_keypad, keypad_read);
/*Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
*add objects to the group with `lv_group_add_obj(group, obj)`
@@ -140,10 +134,9 @@ void lv_port_indev_init(void)
encoder_init();
/*Register a encoder input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = encoder_read;
indev_encoder = lv_indev_drv_register(&indev_drv);
indev_encoder = lv_indev_create();
lv_indev_set_type(indev_encoder, LV_INDEV_TYPE_ENCODER);
lv_indev_set_read_cb(indev_touchpad, encoder_read);
/*Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
*add objects to the group with `lv_group_add_obj(group, obj)`
@@ -158,10 +151,9 @@ void lv_port_indev_init(void)
button_init();
/*Register a button input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_BUTTON;
indev_drv.read_cb = button_read;
indev_button = lv_indev_drv_register(&indev_drv);
indev_button = lv_indev_create();
lv_indev_set_type(indev_button, LV_INDEV_TYPE_BUTTON);
lv_indev_set_read_cb(indev_button, button_read);
/*Assign buttons to points on the screen*/
static const lv_point_t btn_points[2] = {
@@ -186,10 +178,10 @@ static void touchpad_init(void)
}
/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
static void touchpad_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
static lv_coord_t last_x = 0;
static lv_coord_t last_y = 0;
static int32_t last_x = 0;
static int32_t last_y = 0;
/*Save the pressed coordinates and the state*/
if(touchpad_is_pressed()) {
@@ -214,7 +206,7 @@ static bool touchpad_is_pressed(void)
}
/*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
static void touchpad_get_xy(int32_t * x, int32_t * y)
{
/*Your code comes here*/
@@ -233,7 +225,7 @@ static void mouse_init(void)
}
/*Will be called by the library to read the mouse*/
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
static void mouse_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
/*Get the current x and y coordinates*/
mouse_get_xy(&data->point.x, &data->point.y);
@@ -256,7 +248,7 @@ static bool mouse_is_pressed(void)
}
/*Get the x and y coordinates if the mouse is pressed*/
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
static void mouse_get_xy(int32_t * x, int32_t * y)
{
/*Your code comes here*/
@@ -275,7 +267,7 @@ static void keypad_init(void)
}
/*Will be called by the library to read the mouse*/
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
static void keypad_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
static uint32_t last_key = 0;
@@ -327,14 +319,14 @@ static uint32_t keypad_get_key(void)
* Encoder
* -----------------*/
/*Initialize your keypad*/
/*Initialize your encoder*/
static void encoder_init(void)
{
/*Your code comes here*/
}
/*Will be called by the library to read the encoder*/
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
static void encoder_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
data->enc_diff = encoder_diff;
@@ -361,7 +353,7 @@ static void button_init(void)
}
/*Will be called by the library to read the button*/
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
static void button_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
static uint8_t last_btn = 0;
@@ -17,7 +17,11 @@ extern "C" {
/*********************
* INCLUDES
*********************/
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
@@ -0,0 +1,183 @@
/**
* @file lv_port_lcd_stm32_template.c
*
* Example implementation of the LVGL LCD display drivers on the STM32 platform
*/
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 0
/*********************
* INCLUDES
*********************/
/* Include STM32Cube files here, e.g.:
#include "stm32f7xx_hal.h"
*/
#include "lv_port_disp.h"
#include "./src/drivers/display/st7789/lv_st7789.h"
/*********************
* DEFINES
*********************/
#ifndef MY_DISP_HOR_RES
#warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen width, default value 320 is used for now.
#define MY_DISP_HOR_RES 320
#endif
#ifndef MY_DISP_VER_RES
#warning Please define or replace the macro MY_DISP_VER_RES with the actual screen height, default value 240 is used for now.
#define MY_DISP_VER_RES 240
#endif
#define BUS_SPI1_POLL_TIMEOUT 0x1000U
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void lcd_color_transfer_ready_cb(SPI_HandleTypeDef * hspi);
static int32_t lcd_io_init(void);
static void lcd_send_cmd(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, const uint8_t * param,
size_t param_size);
static void lcd_send_color(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, uint8_t * param,
size_t param_size);
/**********************
* STATIC VARIABLES
**********************/
static lv_display_t * lcd_disp;
static volatile int lcd_bus_busy = 0;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_port_display_init(void)
{
/* Initialize LCD I/O */
if(lcd_io_init() != 0)
return;
/* Create the LVGL display object and the ST7789 LCD display driver */
lcd_disp = lv_st7789_create(MY_DISP_HOR_RES, MY_DISP_VER_RES, LV_LCD_FLAG_NONE, lcd_send_cmd, lcd_send_color);
lv_display_set_rotation(lcd_disp, LV_DISPLAY_ROTATION_270); /* set landscape orientation */
/* Example: two dynamically allocated buffers for partial rendering */
lv_color_t * buf1 = NULL;
lv_color_t * buf2 = NULL;
uint32_t buf_size = MY_DISP_HOR_RES * MY_DISP_VER_RES / 10 * lv_color_format_get_size(lv_display_get_color_format(
lcd_disp));
buf1 = lv_malloc(buf_size);
if(buf1 == NULL) {
LV_LOG_ERROR("display draw buffer malloc failed");
return;
}
buf2 = lv_malloc(buf_size);
if(buf2 == NULL) {
LV_LOG_ERROR("display buffer malloc failed");
lv_free(buf1);
return;
}
lv_display_set_buffers(lcd_disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
}
/**********************
* STATIC FUNCTIONS
**********************/
/* Callback is called when background transfer finished */
static void lcd_color_transfer_ready_cb(SPI_HandleTypeDef * hspi)
{
/* CS high */
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
lcd_bus_busy = 0;
lv_display_flush_ready(lcd_disp);
}
/* Initialize LCD I/O bus, reset LCD */
static int32_t lcd_io_init(void)
{
/* Register SPI Tx Complete Callback */
HAL_SPI_RegisterCallback(&hspi1, HAL_SPI_TX_COMPLETE_CB_ID, lcd_color_transfer_ready_cb);
/* reset LCD */
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
return HAL_OK;
}
/* Platform-specific implementation of the LCD send command function. In general this should use polling transfer. */
static void lcd_send_cmd(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, const uint8_t * param,
size_t param_size)
{
LV_UNUSED(disp);
while(lcd_bus_busy); /* wait until previous transfer is finished */
/* Set the SPI in 8-bit mode */
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
HAL_SPI_Init(&hspi1);
/* DCX low (command) */
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
/* CS low */
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
/* send command */
if(HAL_SPI_Transmit(&hspi1, cmd, cmd_size, BUS_SPI1_POLL_TIMEOUT) == HAL_OK) {
/* DCX high (data) */
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
/* for short data blocks we use polling transfer */
HAL_SPI_Transmit(&hspi1, (uint8_t *)param, (uint16_t)param_size, BUS_SPI1_POLL_TIMEOUT);
/* CS high */
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
}
}
/* Platform-specific implementation of the LCD send color function. For better performance this should use DMA transfer.
* In case of a DMA transfer a callback must be installed to notify LVGL about the end of the transfer.
*/
static void lcd_send_color(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, uint8_t * param,
size_t param_size)
{
LV_UNUSED(disp);
while(lcd_bus_busy); /* wait until previous transfer is finished */
/* Set the SPI in 8-bit mode */
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
HAL_SPI_Init(&hspi1);
/* DCX low (command) */
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
/* CS low */
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
/* send command */
if(HAL_SPI_Transmit(&hspi1, cmd, cmd_size, BUS_SPI1_POLL_TIMEOUT) == HAL_OK) {
/* DCX high (data) */
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
/* for color data use DMA transfer */
/* Set the SPI in 16-bit mode to match endianess */
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
HAL_SPI_Init(&hspi1);
lcd_bus_busy = 1;
HAL_SPI_Transmit_DMA(&hspi1, param, (uint16_t)param_size / 2);
/* NOTE: CS will be reset in the transfer ready callback */
}
}
#else /*Enable this file at the top*/
/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif
@@ -0,0 +1,49 @@
/**
* @file lv_port_lcd_stm32_template.h
*
*/
/*Copy this file as "lv_port_disp.h" and set this value to "1" to enable content*/
#if 0
#ifndef LV_PORT_LCD_STM32_TEMPL_H
#define LV_PORT_LCD_STM32_TEMPL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/* Initialize low level display driver */
void lv_port_disp_init(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_PORT_LCD_STM32_TEMPL_H*/
#endif /*Disable/Enable content*/