diff --git a/lv_port/lv_port_display_espressif.c b/lv_port/lv_port_display_espressif.c index 1684767..7d3bd26 100644 --- a/lv_port/lv_port_display_espressif.c +++ b/lv_port/lv_port_display_espressif.c @@ -6,6 +6,29 @@ #include "sdkconfig.h" #include "driver/gpio.h" +#include "disp_spi.h" +#include "lvgl_i2c/i2c_manager.h" + +#include +#include + +/* NOTE: Needed by the I2C Manager */ +#define OLED_I2C_PORT (CONFIG_LV_I2C_DISPLAY_PORT) +/* FIXME: Be able to get display driver I2C address from Kconfig */ +#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306) +#define OLED_I2C_ADDRESS 0x3C +#endif + +#define LV_DISPLAY_DC_CMD_MODE 0 +#define LV_DISPLAY_DC_DATA_MODE 1 + +/* Helper functions to get display communication interface kind, this can be + * implemented as users see fit, we're using the symbols created by Kconfig + * because is what we have available. + * Other ways to implement it is using the user_data poiter in lv_disp_drv_t */ +static inline bool display_interface_is_spi(lv_disp_drv_t * drv); +static inline bool display_interface_is_i2c(lv_disp_drv_t * drv); + void display_port_delay(lv_disp_drv_t *drv, uint32_t delay_ms) { (void) drv; @@ -55,3 +78,76 @@ bool display_port_gpio_is_busy(lv_disp_drv_t *drv) return device_busy; } + +void display_interface_send_cmd(lv_disp_drv_t *drv, uint32_t cmd, cmd_width_t cmd_width, void *args, size_t args_len) +{ + (void) drv; + + if (display_interface_is_spi(drv)) { + disp_wait_for_pending_transactions(); + display_port_gpio_dc(drv, LV_DISPLAY_DC_CMD_MODE); + + if (CMD_WIDTH_8BITS == cmd_width) { + disp_spi_send_data(&cmd, 1); + } + else if (CMD_WIDTH_16BITS == cmd_width) { + /* Send 16bits cmd */ + } + else { + /* Invalid cmd size */ + assert(0); + } + + if (args != CMD_WITHOUT_ARGS) { + display_port_gpio_dc(drv, LV_DISPLAY_DC_DATA_MODE); + disp_spi_send_data(args, args_len); + } + } + + if (display_interface_is_i2c(drv)) { + uint8_t *data = (uint8_t *) args; + lvgl_i2c_write(OLED_I2C_PORT, OLED_I2C_ADDRESS, cmd, data, args_len); + } +} + +void display_interface_send_data(lv_disp_drv_t *drv, void *data, size_t len) +{ + (void) drv; + + if (display_interface_is_spi(drv)) { + disp_wait_for_pending_transactions(); + display_port_gpio_dc(drv, LV_DISPLAY_DC_DATA_MODE); + disp_spi_send_colors(data, len); + /* lv_disp_flush_ready is called in the SPI xfer done callback */ + } + + if (display_interface_is_i2c(drv)) { + lvgl_i2c_write(OLED_I2C_PORT, OLED_I2C_ADDRESS, OLED_CONTROL_BYTE_DATA_STREAM, data, len); + } +} + +static inline bool display_interface_is_spi(lv_disp_drv_t * drv) +{ + (void) drv; + + bool retval = false; + +#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI) + retval = true; +#endif + + return retval; +} + +static inline bool display_interface_is_i2c(lv_disp_drv_t * drv) +{ + (void) drv; + + bool retval = false; + +#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_I2C) + retval = true; +#endif + + return retval; +} diff --git a/lvgl_tft/display_port.h b/lvgl_tft/display_port.h index f0004d6..b2cb1d4 100644 --- a/lvgl_tft/display_port.h +++ b/lvgl_tft/display_port.h @@ -15,6 +15,16 @@ extern "C" #include #include +#define CMD_WITHOUT_ARGS NULL + +enum { + CMD_WIDTH_8BITS, + CMD_WIDTH_16BITS, + CMD_WIDTH_INVALID, +}; + +typedef uint8_t cmd_width_t; + /** * Busy wait delay port * @@ -56,6 +66,28 @@ void display_port_gpio_rst(lv_disp_drv_t *drv, uint8_t state); */ bool display_port_gpio_is_busy(lv_disp_drv_t *drv); +/** + * Send cmd to display + * + * @param drv Pointer to driver + * @param cmd Command to send + * @param cmd_width Width of the command (in bits) to be sent, see @ref cmd_width_t + * @param args Pointer to arguments, use CMD_WITHOUT_ARGS to send command without arguments + * @param args_len Arguments length (in bytes) to be sent + */ +void display_interface_send_cmd(lv_disp_drv_t *drv, uint32_t cmd, cmd_width_t cmd_width, void *args, size_t args_len); + +/** + * Send (image) data to display + * + * User must call lv_disp_flush after the image is sent + * + * @param drv Pointer to driver + * @param data Pointer to data to be sent + * @param len Data length (in bytes) to be sent + */ +void display_interface_send_data(lv_disp_drv_t *drv, void *data, size_t len); + #ifdef __cplusplus } /* extern "C" */ #endif