Multiple fixes, SPI driver, lcd implementation, etc.
This commit is contained in:
parent
0bc7fb31fa
commit
b33ca6120e
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10)
|
|||
|
||||
project(SystemAgent)
|
||||
|
||||
set(ST7789_LCD_DEFINES "ST7789_PANEL_ZJY_240")
|
||||
set(ST7789_LCD_DEFINES "ST7789_PANEL_ZJY_320")
|
||||
set(LVGL_DEFINES "LV_CONF_INCLUDE_SIMPLE")
|
||||
|
||||
set(C_SOURCES
|
||||
|
@ -13,6 +13,7 @@ set(C_SOURCES
|
|||
"src/impl/user_st7789_impl.c"
|
||||
"src/impl/user_lvgl_impl.c"
|
||||
"src/tasks/user_lvgl_task.c"
|
||||
"src/tasks/user_clock_task.c"
|
||||
"src/utils/user_log_util.c"
|
||||
)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ typedef struct {
|
|||
int user_config_init(user_config_t *config, char *config_file);
|
||||
char *user_config_lookup_string(user_config_t *config, char *path);
|
||||
int user_config_lookup_int(user_config_t *config, char *path, int *value);
|
||||
int user_config_lookup_float(user_config_t *config, char *path, float *value);
|
||||
int user_config_lookup_double(user_config_t *config, char *path, double *value);
|
||||
int user_config_deinit(user_config_t *config);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#ifndef __USER_LVGL_IMPL_H
|
||||
#define __USER_LVGL_IMPL_H
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
void user_lvgl_impl_init(void);
|
||||
void user_lvgl_impl_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void user_lvgl_impl_deinit(void);
|
||||
|
||||
#endif
|
|
@ -20,7 +20,7 @@
|
|||
*====================*/
|
||||
|
||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||
#define LV_HOR_RES_MAX (240)
|
||||
#define LV_HOR_RES_MAX (320)
|
||||
#define LV_VER_RES_MAX (240)
|
||||
|
||||
/* Color depth:
|
||||
|
@ -44,7 +44,7 @@
|
|||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
#define LV_ANTIALIAS 0
|
||||
|
||||
/* Default display refresh period.
|
||||
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||
|
@ -53,7 +53,7 @@
|
|||
/* Dot Per Inch: used to initialize default sizes.
|
||||
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI 130 /*[px]*/
|
||||
#define LV_DPI 200 /*[px]*/
|
||||
|
||||
/* The the real width of the display changes some default values:
|
||||
* default object sizes, layout of examples, etc.
|
||||
|
@ -386,7 +386,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
|||
#define LV_FONT_MONTSERRAT_18 0
|
||||
#define LV_FONT_MONTSERRAT_20 0
|
||||
#define LV_FONT_MONTSERRAT_22 0
|
||||
#define LV_FONT_MONTSERRAT_24 0
|
||||
#define LV_FONT_MONTSERRAT_24 1
|
||||
#define LV_FONT_MONTSERRAT_26 0
|
||||
#define LV_FONT_MONTSERRAT_28 0
|
||||
#define LV_FONT_MONTSERRAT_30 0
|
||||
|
@ -409,7 +409,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
|||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
#define LV_FONT_UNSCII_16 0
|
||||
#define LV_FONT_UNSCII_16 1
|
||||
|
||||
/* Optionally declare your custom fonts here.
|
||||
* You can use these fonts as default font too
|
||||
|
@ -477,10 +477,10 @@ typedef void * lv_font_user_data_t;
|
|||
#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1)
|
||||
#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6)
|
||||
#define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_LIGHT
|
||||
#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_14
|
||||
#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_14
|
||||
#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_14
|
||||
#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_14
|
||||
#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_24
|
||||
#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_24
|
||||
#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_24
|
||||
#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_24
|
||||
|
||||
/*=================
|
||||
* Text settings
|
||||
|
|
|
@ -4,4 +4,7 @@
|
|||
int user_lvgl_task_init(void);
|
||||
int user_lvgl_task_deinit(void);
|
||||
|
||||
int user_clock_task_init(void);
|
||||
int user_clock_task_deinit(void);
|
||||
|
||||
#endif
|
|
@ -1 +1 @@
|
|||
Subproject commit 4df50bb6769fc2113eebd9c2ba4f6ad048e7998b
|
||||
Subproject commit b0be98b771d6c2bd3452f16998a3897a047c4f30
|
|
@ -22,6 +22,10 @@ agent: {
|
|||
path = "/dev/gpiochip1";
|
||||
line = 230;
|
||||
};
|
||||
blk_pin: {
|
||||
path = "/dev/gpiochip1";
|
||||
line = 231;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -37,7 +37,7 @@ int user_config_lookup_int(user_config_t *config, char *path, int *value) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int user_config_lookup_float(user_config_t *config, char *path, float *value) {
|
||||
int user_config_lookup_double(user_config_t *config, char *path, double *value) {
|
||||
if(config_lookup_float(config->libconfig_cfg, path, value) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ int user_spi_driver_init(user_spi_driver_t *spi, char *path,
|
|||
spi->speed_hz = speed_hz;
|
||||
|
||||
uint32_t mode = SPI_MODE_0;
|
||||
if(ioctl(spi->spidev_fd, SPI_IOC_WR_MODE32, &mode) == -1) {
|
||||
if(ioctl(spi->spidev_fd, SPI_IOC_WR_MODE, &mode) == -1) {
|
||||
USER_LOG(USER_LOG_ERROR, "Failed to set SPI mode.");
|
||||
return -1;
|
||||
}
|
||||
|
@ -55,31 +55,21 @@ int user_spi_driver_xfer(user_spi_driver_t *spi, uint8_t *tx_buf,
|
|||
.tx_buf = (unsigned long)tx_buf,
|
||||
.rx_buf = (unsigned long)rx_buf,
|
||||
.len = len,
|
||||
.cs_change = 0,
|
||||
.speed_hz = spi->speed_hz,
|
||||
.bits_per_word = 8,
|
||||
.tx_nbits = 1,
|
||||
.rx_nbits = 1,
|
||||
};
|
||||
|
||||
USER_LOG(USER_LOG_DEBUG, "SPI 1st byte: 0x%02x.", tx_buf[0]);
|
||||
|
||||
while(len > SPIDEV_MAX_TRANSFER_SIZE) {
|
||||
txn.len = SPIDEV_MAX_TRANSFER_SIZE;
|
||||
len -= SPIDEV_MAX_TRANSFER_SIZE;
|
||||
|
||||
USER_LOG(USER_LOG_DEBUG, "SPI Tx len: %d.", txn.len);
|
||||
|
||||
if(ioctl(spi->spidev_fd, SPI_IOC_MESSAGE(1), &txn) < 0) {
|
||||
USER_LOG(USER_LOG_ERROR, "SPI transaction error.");
|
||||
return -1;
|
||||
uint32_t xfer_count = (len / SPIDEV_MAX_TRANSFER_SIZE) + ((len % SPIDEV_MAX_TRANSFER_SIZE) ? 1 : 0);
|
||||
for(uint32_t i = 0; i < xfer_count; i++) {
|
||||
if(txn.tx_buf != 0) txn.tx_buf = (unsigned long)&tx_buf[i * SPIDEV_MAX_TRANSFER_SIZE];
|
||||
if(txn.rx_buf != 0) txn.rx_buf = (unsigned long)&rx_buf[i * SPIDEV_MAX_TRANSFER_SIZE];
|
||||
if(i == xfer_count - 1) {
|
||||
txn.len = len % SPIDEV_MAX_TRANSFER_SIZE;
|
||||
} else {
|
||||
txn.len = SPIDEV_MAX_TRANSFER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if(len > 0) {
|
||||
txn.len = len;
|
||||
|
||||
USER_LOG(USER_LOG_DEBUG, "SPI Tx len: %d.", txn.len);
|
||||
|
||||
if(ioctl(spi->spidev_fd, SPI_IOC_MESSAGE(1), &txn) < 0) {
|
||||
USER_LOG(USER_LOG_ERROR, "SPI transaction error.");
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#include "lvgl.h"
|
||||
|
||||
#include "impl/user_st7789_impl.h"
|
||||
|
||||
#include "impl/user_lvgl_impl.h"
|
||||
|
||||
#include "utils/user_log_util.h"
|
||||
|
||||
user_st7789_impl_t g_lcd_impl;
|
||||
st7789_lcd_t g_lcd = {
|
||||
.cb =
|
||||
|
@ -14,8 +13,8 @@ st7789_lcd_t g_lcd = {
|
|||
},
|
||||
.config =
|
||||
{
|
||||
.direction = ST7789_DIR_0,
|
||||
.pix_fmt = ST7789_RGB888,
|
||||
.direction = ST7789_DIR_270,
|
||||
.pix_fmt = ST7789_RGB565,
|
||||
},
|
||||
.user_data = &g_lcd_impl,
|
||||
};
|
||||
|
@ -25,6 +24,11 @@ void user_lvgl_impl_init(void) {
|
|||
st7789_lcd_init(&g_lcd);
|
||||
}
|
||||
|
||||
void user_lvgl_impl_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
|
||||
st7789_lcd_load(&g_lcd, (uint8_t *)color_p, area->x1, area->x2, area->y1, area->y2);
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
void user_lvgl_impl_deinit(void) {
|
||||
user_st7789_impl_deinit(&g_lcd_impl);
|
||||
}
|
|
@ -66,13 +66,18 @@ void user_st7789_impl_deinit(void *handle) {
|
|||
|
||||
user_st7789_impl_t *impl = handle;
|
||||
|
||||
user_gpio_deinit(impl->cs_gpio);
|
||||
user_gpio_deinit(impl->dc_gpio);
|
||||
user_gpio_deinit(impl->reset_gpio);
|
||||
|
||||
if(impl->cs_gpio) free(impl->cs_gpio);
|
||||
if(impl->dc_gpio) free(impl->dc_gpio);
|
||||
if(impl->reset_gpio) free(impl->reset_gpio);
|
||||
if(impl->cs_gpio) {
|
||||
user_gpio_deinit(impl->cs_gpio);
|
||||
free(impl->cs_gpio);
|
||||
}
|
||||
if(impl->dc_gpio) {
|
||||
user_gpio_deinit(impl->dc_gpio);
|
||||
free(impl->dc_gpio);
|
||||
}
|
||||
if(impl->reset_gpio) {
|
||||
user_gpio_deinit(impl->reset_gpio);
|
||||
free(impl->reset_gpio);
|
||||
}
|
||||
}
|
||||
|
||||
st7789_ret_t user_st7789_impl_write_cmd(void *handle, uint8_t *cmd,
|
||||
|
@ -83,11 +88,19 @@ st7789_ret_t user_st7789_impl_write_cmd(void *handle, uint8_t *cmd,
|
|||
if(impl->dc_gpio && (user_gpio_set(impl->dc_gpio, 0) != 0)) return ST7789_ERROR;
|
||||
if(impl->cs_gpio && (user_gpio_set(impl->cs_gpio, 0) != 0)) return ST7789_ERROR;
|
||||
|
||||
// ST7789VW requires parameters to be sent with DC=0.
|
||||
if(user_spi_driver_xfer(impl->spi_driver, cmd, NULL, len) != 0) {
|
||||
if(user_spi_driver_xfer(impl->spi_driver, cmd, NULL, 0x01) != 0) {
|
||||
if(impl->cs_gpio) user_gpio_set(impl->cs_gpio, 1);
|
||||
return ST7789_ERROR;
|
||||
}
|
||||
|
||||
// ST7789VW requires parameters to be sent with DC=1.
|
||||
if(len > 1) {
|
||||
if(impl->dc_gpio && (user_gpio_set(impl->dc_gpio, 1) != 0)) return ST7789_ERROR;
|
||||
if(user_spi_driver_xfer(impl->spi_driver, &cmd[1], NULL, len - 1) != 0) {
|
||||
if(impl->cs_gpio) user_gpio_set(impl->cs_gpio, 1);
|
||||
return ST7789_ERROR;
|
||||
}
|
||||
}
|
||||
if(impl->cs_gpio && (user_gpio_set(impl->cs_gpio, 1) != 0)) return ST7789_ERROR;
|
||||
|
||||
return ST7789_OK;
|
||||
|
@ -112,9 +125,14 @@ st7789_ret_t user_st7789_impl_reset(void *handle) {
|
|||
|
||||
user_st7789_impl_t *impl = handle;
|
||||
|
||||
if(&impl->reset_gpio == NULL) return ST7789_OK;
|
||||
if(impl->reset_gpio == NULL) return ST7789_OK;
|
||||
|
||||
if(user_gpio_set(impl->reset_gpio, 0) != 0) return ST7789_ERROR;
|
||||
usleep(10 * 1000); // Sleep 10ms
|
||||
usleep(1 * 1000); // Sleep 1ms
|
||||
if(user_gpio_set(impl->reset_gpio, 1) != 0) return ST7789_ERROR;
|
||||
|
||||
if(impl->cs_gpio == NULL) return ST7789_OK;
|
||||
if(user_gpio_set(impl->cs_gpio, 1) != 0) return ST7789_ERROR;
|
||||
|
||||
return ST7789_OK;
|
||||
}
|
||||
|
|
|
@ -53,12 +53,14 @@ int main(int argc, const char *argv[]) {
|
|||
}
|
||||
|
||||
user_lvgl_task_init();
|
||||
user_clock_task_init();
|
||||
|
||||
USER_LOG(USER_LOG_INFO, "Initialized, main thread sleeping.");
|
||||
while(g_running) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
user_clock_task_deinit();
|
||||
user_lvgl_task_deinit();
|
||||
|
||||
user_spi_driver_deinit(&g_spi);
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#include "utils/user_log_util.h"
|
||||
|
||||
extern uint8_t g_running;
|
||||
extern uint8_t g_lvgl_ready;
|
||||
|
||||
pthread_t user_clock_task_thread;
|
||||
|
||||
void *user_clock_task(void *arguments);
|
||||
|
||||
int user_clock_task_init(void) {
|
||||
int ret;
|
||||
|
||||
ret = pthread_create(&user_clock_task_thread, NULL, user_clock_task, NULL);
|
||||
if(ret) return ret;
|
||||
|
||||
pthread_setname_np(user_clock_task_thread, "CLOCK");
|
||||
|
||||
USER_LOG(USER_LOG_INFO, "Clock thread created.");
|
||||
}
|
||||
|
||||
int user_clock_task_deinit(void) {
|
||||
USER_LOG(USER_LOG_INFO, "CLOCK task_deinit() called.");
|
||||
|
||||
pthread_join(user_clock_task_thread, NULL);
|
||||
|
||||
USER_LOG(USER_LOG_INFO, "CLOCK tasks joined.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *user_clock_task(void *arguments) {
|
||||
while(g_running && !g_lvgl_ready) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK); /*Break the long lines*/
|
||||
lv_label_set_recolor(label1, true); /*Enable re-coloring by commands in the text*/
|
||||
lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER); /*Center aligned lines*/
|
||||
lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label "
|
||||
"and wrap long text automatically.");
|
||||
lv_obj_set_width(label1, 320);
|
||||
lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);
|
||||
|
||||
lv_obj_t * label2 = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_long_mode(label2, LV_LABEL_LONG_SROLL_CIRC); /*Circular scroll*/
|
||||
lv_obj_set_width(label2, 320);
|
||||
lv_label_set_text(label2, "It is a circularly scrolling text. ");
|
||||
lv_obj_align(label2, NULL, LV_ALIGN_CENTER, 0, 30);
|
||||
|
||||
while(g_running) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
|
@ -9,11 +9,18 @@
|
|||
#include "tasks/user_tasks.h"
|
||||
#include "impl/user_lvgl_impl.h"
|
||||
|
||||
#define PIXBUF_SIZE 320 * 10
|
||||
|
||||
extern uint8_t g_running;
|
||||
|
||||
uint8_t g_lvgl_ready = 0;
|
||||
|
||||
pthread_t user_lv_task_thread;
|
||||
pthread_t user_lv_tick_thread;
|
||||
|
||||
static lv_disp_buf_t s_disp_buf;
|
||||
static lv_color_t s_pix_buf[2][PIXBUF_SIZE];
|
||||
|
||||
void *user_lv_task(void *arguments);
|
||||
void *user_lv_tick(void *arguments);
|
||||
|
||||
|
@ -26,6 +33,14 @@ int user_lvgl_task_init(void) {
|
|||
|
||||
lv_init();
|
||||
|
||||
lv_disp_buf_init(&s_disp_buf, s_pix_buf[0], s_pix_buf[1], PIXBUF_SIZE);
|
||||
|
||||
lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.buffer = &s_disp_buf;
|
||||
disp_drv.flush_cb = user_lvgl_impl_flush_cb;
|
||||
lv_disp_t *disp = lv_disp_drv_register(&disp_drv);
|
||||
|
||||
ret = pthread_create(&user_lv_task_thread, NULL, user_lv_task, NULL);
|
||||
if(ret) return ret;
|
||||
ret = pthread_create(&user_lv_tick_thread, NULL, user_lv_tick, NULL);
|
||||
|
@ -35,6 +50,8 @@ int user_lvgl_task_init(void) {
|
|||
|
||||
pthread_setname_np(user_lv_task_thread, "LV_TASK");
|
||||
pthread_setname_np(user_lv_tick_thread, "LV_TICK");
|
||||
|
||||
g_lvgl_ready = 1;
|
||||
}
|
||||
|
||||
int user_lvgl_task_deinit(void) {
|
||||
|
|
Loading…
Reference in New Issue