Update drivers.

This commit is contained in:
imi415 2021-03-22 00:01:12 +08:00
parent 2881542033
commit 56664d3be5
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
18 changed files with 220 additions and 101 deletions

View File

@ -141,9 +141,3 @@ StatementMacros:
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
...

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/cmake-build*
/.vscode
/*.srctrl*
/.idea

View File

@ -1,10 +1,10 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSROOT ${BUILDROOT_SDK_PATH}/aarch64-buildroot-linux-gnu/sysroot)
set(CMAKE_SYSROOT $ENV{BUILDROOT_SDK_PATH}/aarch64-buildroot-linux-gnu/sysroot)
set(CMAKE_C_COMPILER ${BUILDROOT_SDK_PATH}/bin/aarch64-buildroot-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${BUILDROOT_SDK_PATH}/bin/aarch64-buildroot-linux-gnu-g++)
set(CMAKE_C_COMPILER $ENV{BUILDROOT_SDK_PATH}/bin/aarch64-buildroot-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER $ENV{BUILDROOT_SDK_PATH}/bin/aarch64-buildroot-linux-gnu-g++)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")

View File

@ -1,10 +1,10 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSROOT ${BUILDROOT_SDK_PATH}/arm-buildroot-linux-gnueabihf/sysroot)
set(CMAKE_SYSROOT $ENV{BUILDROOT_SDK_PATH}/arm-buildroot-linux-gnueabihf/sysroot)
set(CMAKE_C_COMPILER ${BUILDROOT_SDK_PATH}/bin/arm-buildroot-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${BUILDROOT_SDK_PATH}/bin/arm-buildroot-linux-gnueabihf-g++)
set(CMAKE_C_COMPILER $ENV{BUILDROOT_SDK_PATH}/bin/arm-buildroot-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER $ENV{BUILDROOT_SDK_PATH}/bin/arm-buildroot-linux-gnueabihf-g++)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")

View File

@ -3,16 +3,14 @@
#include <libconfig.h>
typedef enum {
USER_CONFIG_OK,
USER_CONFIG_ERROR
} user_config_ret_t;
typedef struct {
config_t libconfig_cfg;
config_t *libconfig_cfg;
} user_config_t;
user_config_ret_t user_config_init(user_config_t *config, char *config_file);
user_config_ret_t user_config_deinit(user_config_t *config);
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_deinit(user_config_t *config);
#endif

View File

@ -5,19 +5,14 @@
#include <gpiod.h>
typedef enum {
USER_GPIO_OK,
USER_GPIO_ERROR,
} user_gpio_ret_t;
typedef struct {
struct gpiod_chip *chip;
struct gpiod_line *line;
} user_gpio_t;
user_gpio_ret_t user_gpio_init(user_gpio_t *gpio, char *chip, uint32_t offset);
user_gpio_ret_t user_gpio_set(user_gpio_t *gpio, uint8_t value);
user_gpio_ret_t user_gpio_get(user_gpio_t *gpio, uint8_t *value);
user_gpio_ret_t user_gpio_deinit(user_gpio_t *gpio);
int user_gpio_init(user_gpio_t *gpio, char *chip, uint32_t offset, uint8_t output_enabled);
int user_gpio_set(user_gpio_t *gpio, uint8_t value);
int user_gpio_get(user_gpio_t *gpio, uint8_t *value);
int user_gpio_deinit(user_gpio_t *gpio);
#endif

View File

@ -3,8 +3,6 @@
#include <stdint.h>
typedef enum { USER_SPI_OK, USER_SPI_ERROR } user_spi_ret_t;
typedef struct {
int spidev_fd;
uint32_t speed_hz;
@ -12,9 +10,9 @@ typedef struct {
#define SPIDEV_MAX_TRANSFER_SIZE 4096
user_spi_ret_t user_spi_driver_init(user_spi_driver_t *spi, char *path, uint32_t speed_hz);
user_spi_ret_t user_spi_driver_deinit(user_spi_driver_t *spi);
user_spi_ret_t user_spi_driver_xfer(user_spi_driver_t *spi, uint8_t *tx_buf,
int user_spi_driver_init(user_spi_driver_t *spi, char *path, uint32_t speed_hz);
int user_spi_driver_deinit(user_spi_driver_t *spi);
int user_spi_driver_xfer(user_spi_driver_t *spi, uint8_t *tx_buf,
uint8_t *rx_buf, uint32_t len);
#endif

View File

@ -0,0 +1,7 @@
#ifndef __USER_LVGL_IMPL_H
#define __USER_LVGL_IMPL_H
void user_lvgl_impl_init(void);
void user_lvgl_impl_deinit(void);
#endif

View File

@ -3,6 +3,8 @@
#include "drivers/user_gpio_driver.h"
#include "drivers/user_spi_driver.h"
#include "drivers/user_config_driver.h"
#include "st7789_lcd.h"
typedef struct {
@ -12,7 +14,8 @@ typedef struct {
user_gpio_t *reset_gpio;
} user_st7789_impl_t;
int user_st7789_impl_init(void *handle, user_spi_driver_t *spi_driver);
int user_st7789_impl_init(void *handle);
void user_st7789_impl_deinit(void *handle);
st7789_ret_t user_st7789_impl_write_cmd(void *handle, uint8_t *cmd,
uint8_t len);
st7789_ret_t user_st7789_impl_write_data(void *handle,

View File

@ -4,6 +4,7 @@ agent: {
drivers: {
spi: {
path = "/dev/spidev0.0";
clock_speed = 10000000;
};
i2c: {
@ -15,7 +16,11 @@ agent: {
lcd: {
dc_pin: {
path = "/dev/gpiochip1";
line = 20;
line = 229;
};
reset_pin: {
path = "/dev/gpiochip1";
line = 230;
};
};
};

View File

@ -1,18 +1,55 @@
#include <stdlib.h>
#include "utils/user_log_util.h"
#include "drivers/user_config_driver.h"
user_config_ret_t user_config_init(user_config_t *config, char *config_file) {
int user_config_init(user_config_t *config, char *config_file) {
USER_LOG(USER_LOG_INFO, "Config init.");
config_init(&config->libconfig_cfg);
config->libconfig_cfg = malloc(sizeof(config_t));
if(config->libconfig_cfg == NULL) return -1;
if(!config_read_file(&config->libconfig_cfg, config_file)) {
config_init(config->libconfig_cfg);
if(!config_read_file(config->libconfig_cfg, config_file)) {
USER_LOG(USER_LOG_ERROR, "Failed to read config file %s.", config_file);
return USER_CONFIG_ERROR;
return -2;
}
return 0;
}
user_config_ret_t user_config_deinit(user_config_t *config) {
//
char *user_config_lookup_string(user_config_t *config, char *path) {
const char *value;
// This string is auto-freeed by libconfig.
if(config_lookup_string(config->libconfig_cfg, path, &value) == 0) {
return NULL;
}
return (char *)value;
}
int user_config_lookup_int(user_config_t *config, char *path, int *value) {
if(config_lookup_int(config->libconfig_cfg, path, value) == 0) {
return -1;
}
return 0;
}
int user_config_lookup_float(user_config_t *config, char *path, float *value) {
if(config_lookup_float(config->libconfig_cfg, path, value) == 0) {
return -1;
}
return 0;
}
int user_config_deinit(user_config_t *config) {
config_destroy(config->libconfig_cfg);
if(config->libconfig_cfg) {
free(config->libconfig_cfg);
}
return 0;
}

View File

@ -3,58 +3,58 @@
#include "drivers/user_gpio_driver.h"
user_gpio_ret_t user_gpio_init(user_gpio_t *gpio, char *chip, uint32_t offset) {
int user_gpio_init(user_gpio_t *gpio, char *chip, uint32_t offset, uint8_t output_enabled) {
gpio->chip = gpiod_chip_open(chip);
if(gpio->chip == NULL) {
USER_LOG(USER_LOG_ERROR, "Failed to open chip %s.", chip);
return USER_GPIO_ERROR;
return -1;
}
gpio->line = gpiod_chip_get_line(gpio->chip, offset);
if(gpio->line == NULL) {
USER_LOG(USER_LOG_ERROR, "Failed to get GPIO line %d.", offset);
gpiod_chip_close(gpio->chip);
return USER_GPIO_ERROR;
return -1;
}
return USER_GPIO_OK;
}
int ret;
user_gpio_ret_t user_gpio_set(user_gpio_t *gpio, uint8_t value) {
if(output_enabled) {
ret = gpiod_line_request_output(gpio->line, "SA", 1);
} else {
gpiod_line_request_input(gpio->line, "SA");
}
int ret = gpiod_line_request_output(gpio->line, "SA", value);
if(ret != 0) {
USER_LOG(USER_LOG_ERROR, "Failed to reserve GPIO line.");
return USER_GPIO_ERROR;
return -1;
}
ret = gpiod_line_set_value(gpio->line, value);
return 0;
}
int user_gpio_set(user_gpio_t *gpio, uint8_t value) {
int ret = gpiod_line_set_value(gpio->line, value);
if(ret != 0) {
USER_LOG(USER_LOG_ERROR, "Failed to set GPIO value.");
return USER_GPIO_ERROR;
return -1;
}
return USER_GPIO_OK;
return 0;
}
user_gpio_ret_t user_gpio_get(user_gpio_t *gpio, uint8_t *value){
int ret = gpiod_line_request_input(gpio->line, "SA");
if(ret != 0) {
USER_LOG(USER_LOG_ERROR, "Failed to reserve GPIO line.");
return USER_GPIO_ERROR;
}
int user_gpio_get(user_gpio_t *gpio, uint8_t *value){
*value = gpiod_line_get_value(gpio->line);
return USER_GPIO_OK;
return 0;
}
user_gpio_ret_t user_gpio_deinit(user_gpio_t *gpio) {
int user_gpio_deinit(user_gpio_t *gpio) {
gpiod_line_release(gpio->line);
gpiod_chip_close(gpio->chip);
return USER_GPIO_OK;
return 0;
}

View File

@ -12,7 +12,7 @@
#include "drivers/user_spi_driver.h"
user_spi_ret_t user_spi_driver_init(user_spi_driver_t *spi, char *path,
int user_spi_driver_init(user_spi_driver_t *spi, char *path,
uint32_t speed_hz) {
USER_LOG(USER_LOG_INFO, "SPI driver init.");
@ -21,21 +21,35 @@ user_spi_ret_t user_spi_driver_init(user_spi_driver_t *spi, char *path,
USER_LOG(USER_LOG_ERROR, "Failed to open spidev device, %s",
strerror(errno));
return USER_SPI_ERROR;
return -1;
}
spi->speed_hz = speed_hz;
return USER_SPI_OK;
uint32_t mode = SPI_MODE_0;
if(ioctl(spi->spidev_fd, SPI_IOC_WR_MODE32, &mode) == -1) {
USER_LOG(USER_LOG_ERROR, "Failed to set SPI mode.");
return -1;
}
uint32_t bits = 8;
if(ioctl(spi->spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {
USER_LOG(USER_LOG_ERROR, "Failed to set SPI bits per word.");
return -1;
}
return 0;
}
user_spi_ret_t user_spi_driver_deinit(user_spi_driver_t *spi) {
int user_spi_driver_deinit(user_spi_driver_t *spi) {
USER_LOG(USER_LOG_INFO, "SPI driver deinit.");
close(spi->spidev_fd);
return 0;
}
user_spi_ret_t user_spi_driver_xfer(user_spi_driver_t *spi, uint8_t *tx_buf,
int user_spi_driver_xfer(user_spi_driver_t *spi, uint8_t *tx_buf,
uint8_t *rx_buf, uint32_t len) {
struct spi_ioc_transfer txn = {
.tx_buf = (unsigned long)tx_buf,
@ -44,26 +58,34 @@ user_spi_ret_t user_spi_driver_xfer(user_spi_driver_t *spi, uint8_t *tx_buf,
.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 USER_SPI_ERROR;
return -1;
}
}
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.");
return USER_SPI_ERROR;
return -1;
}
}
return USER_SPI_OK;
return 0;
}

View File

@ -2,7 +2,7 @@
#include "impl/user_st7789_impl.h"
extern user_spi_driver_t g_spi;
#include "impl/user_lvgl_impl.h"
user_st7789_impl_t g_lcd_impl;
st7789_lcd_t g_lcd = {
@ -21,5 +21,10 @@ st7789_lcd_t g_lcd = {
};
void user_lvgl_impl_init(void) {
user_st7789_impl_init(&g_lcd_impl, &g_spi);
user_st7789_impl_init(&g_lcd_impl);
st7789_lcd_init(&g_lcd);
}
void user_lvgl_impl_deinit(void) {
user_st7789_impl_deinit(&g_lcd_impl);
}

View File

@ -3,9 +3,33 @@
#include "lvgl.h"
#include "utils/user_log_util.h"
#include "impl/user_st7789_impl.h"
int user_st7789_impl_init(void *handle, user_spi_driver_t *spi_driver) {
extern user_config_t g_config;
extern user_spi_driver_t g_spi;
int _user_st7789_impl_init_pin(user_gpio_t *gpio, char *pin_name, uint8_t is_output) {
char *chip;
uint32_t offset;
char name_buffer[64];
snprintf(name_buffer, 64, "agent.devices.lcd.%s_pin.path", pin_name);
chip = user_config_lookup_string(&g_config, name_buffer);
if(chip == NULL) return -1;
snprintf(name_buffer, 64, "agent.devices.lcd.%s_pin.line", pin_name);
if(user_config_lookup_int(&g_config, name_buffer, &offset) != 0) return -2;
if(user_gpio_init(gpio, chip, offset, is_output) != 0) return -3;
return 0;
}
int user_st7789_impl_init(void *handle) {
user_st7789_impl_t *impl = handle;
@ -16,16 +40,24 @@ int user_st7789_impl_init(void *handle, user_spi_driver_t *spi_driver) {
impl->reset_gpio = malloc(sizeof(user_gpio_t));
if(!impl->reset_gpio) return -1;
if(user_gpio_init(impl->cs_gpio, "/dev/gpiochip0", 0) != USER_GPIO_OK)
return -1;
if(user_gpio_init(impl->dc_gpio, "/dev/gpiochip0", 0) != USER_GPIO_OK)
if(_user_st7789_impl_init_pin(impl->cs_gpio, "cs", 1) != 0) {
free(impl->cs_gpio);
impl->cs_gpio = NULL;
USER_LOG(USER_LOG_WARN, "No CS pin found, SPI must be correctly configured.");
}
if(_user_st7789_impl_init_pin(impl->dc_gpio, "dc", 1) != 0) {
USER_LOG(USER_LOG_ERROR, "DC pin not found.");
return -2;
if(user_gpio_init(impl->reset_gpio, "/dev/gpiochip0", 0) != USER_GPIO_OK)
return -3;
}
if(spi_driver == NULL) return -4;
if(_user_st7789_impl_init_pin(impl->reset_gpio, "reset", 1) != 0) {
free(impl->reset_gpio);
impl->reset_gpio = NULL;
USER_LOG(USER_LOG_WARN, "No Reset pin found.");
}
impl->spi_driver = spi_driver;
impl->spi_driver = &g_spi;
return 0;
}
@ -38,9 +70,9 @@ void user_st7789_impl_deinit(void *handle) {
user_gpio_deinit(impl->dc_gpio);
user_gpio_deinit(impl->reset_gpio);
free(impl->cs_gpio);
free(impl->dc_gpio);
free(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);
}
st7789_ret_t user_st7789_impl_write_cmd(void *handle, uint8_t *cmd,
@ -48,15 +80,15 @@ st7789_ret_t user_st7789_impl_write_cmd(void *handle, uint8_t *cmd,
user_st7789_impl_t *impl = handle;
if(user_gpio_set(impl->dc_gpio, 0) != USER_GPIO_OK) return ST7789_ERROR;
if(user_gpio_set(impl->cs_gpio, 0) != USER_GPIO_OK) return ST7789_ERROR;
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) != USER_SPI_OK) {
user_gpio_set(impl->cs_gpio, 1);
if(user_spi_driver_xfer(impl->spi_driver, cmd, NULL, len) != 0) {
if(impl->cs_gpio) user_gpio_set(impl->cs_gpio, 1);
return ST7789_ERROR;
}
if(user_gpio_set(impl->cs_gpio, 1) != USER_GPIO_OK) return ST7789_ERROR;
if(impl->cs_gpio && (user_gpio_set(impl->cs_gpio, 1) != 0)) return ST7789_ERROR;
return ST7789_OK;
}
@ -65,13 +97,13 @@ st7789_ret_t user_st7789_impl_write_data(void *handle, uint8_t *data,
uint32_t len) {
user_st7789_impl_t *impl = handle;
if(user_gpio_set(impl->dc_gpio, 1) != USER_GPIO_OK) return ST7789_ERROR;
if(user_gpio_set(impl->cs_gpio, 0) != USER_GPIO_OK) return ST7789_ERROR;
if(user_spi_driver_xfer(impl->spi_driver, data, NULL, len) != USER_SPI_OK) {
user_gpio_set(impl->cs_gpio, 1);
if(impl->dc_gpio && (user_gpio_set(impl->dc_gpio, 1) != 0)) return ST7789_ERROR;
if(impl->cs_gpio && (user_gpio_set(impl->cs_gpio, 0) != 0)) return ST7789_ERROR;
if(user_spi_driver_xfer(impl->spi_driver, data, NULL, len) != 0) {
if(impl->cs_gpio) user_gpio_set(impl->cs_gpio, 1);
return ST7789_ERROR;
}
if(user_gpio_set(impl->cs_gpio, 1) != USER_GPIO_OK) return ST7789_ERROR;
if(impl->cs_gpio && (user_gpio_set(impl->cs_gpio, 1) != 0)) return ST7789_ERROR;
return ST7789_OK;
}
@ -82,7 +114,7 @@ st7789_ret_t user_st7789_impl_reset(void *handle) {
if(&impl->reset_gpio == NULL) return ST7789_OK;
if(user_gpio_set(impl->reset_gpio, 0) != USER_GPIO_OK) return ST7789_ERROR;
if(user_gpio_set(impl->reset_gpio, 0) != 0) return ST7789_ERROR;
usleep(10 * 1000); // Sleep 10ms
if(user_gpio_set(impl->cs_gpio, 1) != USER_GPIO_OK) return ST7789_ERROR;
if(user_gpio_set(impl->cs_gpio, 1) != 0) return ST7789_ERROR;
}

View File

@ -30,8 +30,24 @@ int main(int argc, const char *argv[]) {
return -1;
}
user_config_init(&g_config, "config.cfg");
if(user_spi_driver_init(&g_spi, "/dev/spidev0.0", 10000000) != USER_SPI_OK) {
if(user_config_init(&g_config, "config.cfg") != 0) {
USER_LOG(USER_LOG_FATAL, "Failed to load config file.");
return -2;
}
char *spi_path = user_config_lookup_string(&g_config, "agent.drivers.spi.path");
if(spi_path == NULL) {
USER_LOG(USER_LOG_ERROR, "Failed to find SPI device from config, using default.");
spi_path = "/dev/spidev0.0";
}
int spi_speed;
if(user_config_lookup_int(&g_config, "agent.drivers.spi.clock_speed", &spi_speed) != 0) {
USER_LOG(USER_LOG_ERROR, "Failed to find SPI speed from config, using default.");
spi_speed = 10000000;
}
if(user_spi_driver_init(&g_spi, spi_path, spi_speed) != 0) {
USER_LOG(USER_LOG_FATAL, "Failed to initialize SPI driver.");
return -2;
}

View File

@ -7,6 +7,7 @@
#include "utils/user_log_util.h"
#include "tasks/user_tasks.h"
#include "impl/user_lvgl_impl.h"
extern uint8_t g_running;
@ -19,6 +20,8 @@ void *user_lv_tick(void *arguments);
int user_lvgl_task_init(void) {
int ret;
user_lvgl_impl_init();
USER_LOG(USER_LOG_INFO, "lv_init() called.");
lv_init();
@ -41,6 +44,8 @@ int user_lvgl_task_deinit(void) {
pthread_join(user_lv_tick_thread, NULL);
USER_LOG(USER_LOG_INFO, "LVGL threads joined.");
user_lvgl_impl_deinit();
return 0;
}

View File

@ -10,11 +10,12 @@ void user_log_print(user_log_level_t level, char *fmt, ...) {
switch(level) {
case USER_LOG_DEBUG:
level_str = "[DEBUG]";
break;
case USER_LOG_INFO:
level_str = "[INFO]";
level_str = "[ INFO]";
break;
case USER_LOG_WARN:
level_str = "[WARN]";
level_str = "[ WARN]";
break;
case USER_LOG_ERROR:
level_str = "[ERROR]";