From ece77252c8a00c809ae18fcfac4a6577e661d9e0 Mon Sep 17 00:00:00 2001 From: C47D Date: Sat, 16 Jan 2021 23:33:56 -0600 Subject: [PATCH 1/9] SSD1306: Replace hardcoded I2C port --- lvgl_tft/ssd1306.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index a1801fa..ca02eae 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -8,12 +8,13 @@ *********************/ #include "ssd1306.h" #include "driver/i2c.h" -#include "disp_spi.h" #include "driver/gpio.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "lvgl_i2c_conf.h" + /********************* * DEFINES *********************/ @@ -130,7 +131,7 @@ void ssd1306_init() i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); + ret = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); if (ret == ESP_OK) { ESP_LOGI(TAG, "OLED configured successfully"); } else { @@ -174,7 +175,7 @@ void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t i2c_master_write_byte(cmd, row1, true); i2c_master_write_byte(cmd, row2, true); i2c_master_stop(cmd); - i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); + i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); cmd = i2c_cmd_link_create(); @@ -217,7 +218,7 @@ void ssd1306_sleep_in() i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); + ret = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); if (ret != ESP_OK) { ESP_LOGE(TAG, "ssd1306_display_off configuration failed. code: 0x%.2X", ret); } @@ -235,7 +236,7 @@ void ssd1306_sleep_out() i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); + ret = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); if (ret != ESP_OK) { ESP_LOGE(TAG, "ssd1306_display_on configuration failed. code: 0x%.2X", ret); } From a100162d40bb352011ddb4f779644d3b62fa4e67 Mon Sep 17 00:00:00 2001 From: C47D Date: Sun, 17 Jan 2021 00:10:12 -0600 Subject: [PATCH 2/9] SSD1306: Add helper functions --- lvgl_tft/ssd1306.c | 103 ++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index ca02eae..0c008f3 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -80,7 +80,8 @@ /********************** * STATIC PROTOTYPES **********************/ - +static uint8_t send_bytes(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len); +static uint8_t send_colors(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len); /********************** * STATIC VARIABLES **********************/ @@ -154,56 +155,35 @@ void ssd1306_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { - uint8_t row1 = 0, row2 = 0; - i2c_cmd_handle_t cmd; + ESP_LOGI(TAG, "X1: %d, X2: %d, Y1: %d, Y2: %d", + area->x1, area->x2, area->y1, area->y2); + + /* Divide by 8 */ + uint8_t row1 = area->y1 >> 3; + uint8_t row2 = area->y2 >> 3; - // Divide by 8 - row1 = area->y1 >> 3; - row2 = area->y2 >> 3; + uint8_t conf[] = { + OLED_CONTROL_BYTE_CMD_STREAM, + OLED_CMD_SET_MEMORY_ADDR_MODE, + 0x00, + OLED_CMD_SET_COLUMN_RANGE, + (uint8_t) area->x1, + (uint8_t) area->x2, + OLED_CMD_SET_PAGE_RANGE, + row1, + row2, + }; - cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); - - i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); - i2c_master_write_byte(cmd, OLED_CMD_SET_MEMORY_ADDR_MODE, true); - i2c_master_write_byte(cmd, 0x00, true); - i2c_master_write_byte(cmd, OLED_CMD_SET_COLUMN_RANGE, true); - i2c_master_write_byte(cmd, area->x1, true); - i2c_master_write_byte(cmd, area->x2, true); - i2c_master_write_byte(cmd, OLED_CMD_SET_PAGE_RANGE, true); - i2c_master_write_byte(cmd, row1, true); - i2c_master_write_byte(cmd, row2, true); - i2c_master_stop(cmd); - i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); - i2c_cmd_link_delete(cmd); - - cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); - - i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); - i2c_master_write(cmd, (uint8_t *)color_p, OLED_COLUMNS * (1+row2-row1), true); - i2c_master_stop(cmd); - i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); - i2c_cmd_link_delete(cmd); + send_bytes(disp_drv, conf, sizeof conf); + send_colors(disp_drv, color_p, OLED_COLUMNS * (1 + row2 - row1)); lv_disp_flush_ready(disp_drv); } -// workaround: always send complete size display buffer, no partial update void ssd1306_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area) { - // area->y1 = (area->y1 & (~0x7)); - // area->y2 = (area->y2 & (~0x7)) + 7; - - uint8_t hor_max = disp_drv->hor_res; - uint8_t ver_max = disp_drv->ver_res; - - area->x1 = 0; - area->y1 = 0; - area->x2 = hor_max - 1; - area->y2 = ver_max - 1; + area->x1 = area->x1 & ~(0x07); + area->x2 = area->x2 | 0x07; } void ssd1306_sleep_in() @@ -246,4 +226,41 @@ void ssd1306_sleep_out() /********************** * STATIC FUNCTIONS **********************/ +static uint8_t send_bytes(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len) +{ + (void) disp_drv; + uint8_t *data = (uint8_t *) bytes; + + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); + + for (size_t idx = 0; idx < bytes_len; idx++) { + i2c_master_write_byte(cmd, data[idx], true); + } + + i2c_master_stop(cmd); + i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + + return 0; +} + +static uint8_t send_colors(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len) +{ + (void) disp_drv; + + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); + + i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); + i2c_master_write(cmd, (uint8_t *) color_buffer, buffer_len, true); + i2c_master_stop(cmd); + i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + + return 0; +} From 746ebfc24520e02c724a53123bd590b0d3178bc9 Mon Sep 17 00:00:00 2001 From: C47D Date: Sun, 17 Jan 2021 00:25:01 -0600 Subject: [PATCH 3/9] SSD1306: Use helper functions --- lvgl_tft/ssd1306.c | 92 +++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 58 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index 0c008f3..acf7841 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -98,47 +98,40 @@ static uint8_t send_colors(lv_disp_drv_t *disp_drv, void *color_buffer, size_t b **********************/ void ssd1306_init() { - esp_err_t ret; - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); - i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); - - i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true); - i2c_master_write_byte(cmd, 0x14, true); + uint8_t orientation_1 = 0; + uint8_t orientation_2 = 0; #if defined (CONFIG_DISPLAY_ORIENTATION_PORTRAIT) - i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true); - i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE_REMAP, true); + orientation_1 = OLED_CMD_SET_SEGMENT_REMAP; + orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_REMAP; #elif defined (CONFIG_DISPLAY_ORIENTATION_PORTRAIT_INVERTED) - i2c_master_write_byte(cmd, 0xA0, true); - i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE_NORMAL, true); + orientation_1 = 0xA0; + orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_NORMAL; #else - #error "Unsopported orientation" + #error "Unsupported orientation" #endif - i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); + uint8_t display_mode = 0; #if defined CONFIG_LV_INVERT_DISPLAY - i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_INVERTED, true); // Inverted display + display_mode = OLED_CMD_DISPLAY_INVERTED; #else - i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_NORMAL, true); // Non-inverted display -#endif + display_mode = OLED_CMD_DISPLAY_NORMAL; +#endif - - i2c_master_write_byte(cmd, 0xFF, true); - - i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); - i2c_master_stop(cmd); - - ret = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); - if (ret == ESP_OK) { - ESP_LOGI(TAG, "OLED configured successfully"); - } else { - ESP_LOGE(TAG, "OLED configuration failed. code: 0x%.2X", ret); - } - i2c_cmd_link_delete(cmd); + uint8_t conf[] = { + OLED_CONTROL_BYTE_CMD_STREAM, + OLED_CMD_SET_CHARGE_PUMP, + 0x14, + orientation_1, + orientation_2, + OLED_CMD_SET_CONTRAST, + display_mode, + 0xFF, + OLED_CMD_DISPLAY_ON + }; + + send_bytes(NULL, conf, sizeof conf); } void ssd1306_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, @@ -188,39 +181,22 @@ void ssd1306_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area) void ssd1306_sleep_in() { - esp_err_t ret; - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + uint8_t conf[] = { + OLED_CONTROL_BYTE_CMD_STREAM, + OLED_CMD_DISPLAY_OFF + }; - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); - i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); - - i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); - i2c_master_stop(cmd); - - ret = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "ssd1306_display_off configuration failed. code: 0x%.2X", ret); - } - i2c_cmd_link_delete(cmd); + send_bytes(NULL, conf, sizeof conf); } void ssd1306_sleep_out() { - esp_err_t ret; - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + uint8_t conf[] = { + OLED_CONTROL_BYTE_CMD_STREAM, + OLED_CMD_DISPLAY_ON + }; - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); - i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); - i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); - i2c_master_stop(cmd); - - ret = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10/portTICK_PERIOD_MS); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "ssd1306_display_on configuration failed. code: 0x%.2X", ret); - } - i2c_cmd_link_delete(cmd); + send_bytes(NULL, conf, sizeof conf); } /********************** From 2f3470b85ebd8f9b8ec4d8c6644846c43d0a457c Mon Sep 17 00:00:00 2001 From: C47D Date: Tue, 19 Jan 2021 23:53:34 -0600 Subject: [PATCH 4/9] Remove log --- lvgl_tft/ssd1306.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index acf7841..5f2b1da 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -148,9 +148,6 @@ void ssd1306_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { - ESP_LOGI(TAG, "X1: %d, X2: %d, Y1: %d, Y2: %d", - area->x1, area->x2, area->y1, area->y2); - /* Divide by 8 */ uint8_t row1 = area->y1 >> 3; uint8_t row2 = area->y2 >> 3; From d5048878b548de0302e86a4b5dddd8a2e6c4f1a3 Mon Sep 17 00:00:00 2001 From: C47D Date: Tue, 19 Jan 2021 23:54:14 -0600 Subject: [PATCH 5/9] SSD1306: Reduce display buffer size For monochrome displays each byte of the buffer size can store data for 8 pixels. We divide LV_VER_RES_MAX by 8 because the display vertical side is grouped in pages of 1 byte, so we need 1byte times LV_HOR_RES_MAX to represent the data of one page. --- lvgl_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lvgl_helpers.h b/lvgl_helpers.h index 05bdd2c..9c622f7 100644 --- a/lvgl_helpers.h +++ b/lvgl_helpers.h @@ -40,7 +40,7 @@ extern "C" { #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341 #define DISP_BUF_SIZE (LV_HOR_RES_MAX * 64) #elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306 -#define DISP_BUF_SIZE (LV_HOR_RES_MAX*LV_VER_RES_MAX) +#define DISP_BUF_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8)) #elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) #define DISP_BUF_LINES 40 #define DISP_BUF_SIZE (LV_HOR_RES_MAX * DISP_BUF_LINES) From a1add8530bffbba272d24460560418c13629c780 Mon Sep 17 00:00:00 2001 From: C47D Date: Thu, 21 Jan 2021 10:54:17 -0600 Subject: [PATCH 6/9] SSD1306: Remove unused headers and rename helpers --- lvgl_tft/ssd1306.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index 5f2b1da..3336f8a 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -1,31 +1,29 @@ /** * @file ssd1306.c * + * Code from https://github.com/yanbe/ssd1306-esp-idf-i2c.git is used as a starting point, + * in addition to code from https://github.com/espressif/esp-iot-solution. + * + * Definitions are borrowed from: + * http://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html + * + * For LVGL the forum has been used, in particular: https://blog.littlevgl.com/2019-05-06/oled */ /********************* * INCLUDES *********************/ -#include "ssd1306.h" #include "driver/i2c.h" -#include "driver/gpio.h" -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "lvgl_i2c_conf.h" +#include "ssd1306.h" + /********************* * DEFINES *********************/ #define TAG "SSD1306" -// Code from https://github.com/yanbe/ssd1306-esp-idf-i2c.git is used as a starting point, -// in addition to code from https://github.com/espressif/esp-iot-solution. -// Following definitions are borrowed from -// http://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html -// For LittlevGL the forum has been used, in particular: https://blog.littlevgl.com/2019-05-06/oled - // SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000) #define OLED_I2C_ADDRESS 0x3C #define OLED_WIDTH 128 @@ -80,8 +78,9 @@ /********************** * STATIC PROTOTYPES **********************/ -static uint8_t send_bytes(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len); -static uint8_t send_colors(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len); +static uint8_t send_data(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len); +static uint8_t send_pixels(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len); + /********************** * STATIC VARIABLES **********************/ @@ -131,11 +130,12 @@ void ssd1306_init() OLED_CMD_DISPLAY_ON }; - send_bytes(NULL, conf, sizeof conf); + send_data(NULL, conf, sizeof conf); } void ssd1306_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, - lv_color_t color, lv_opa_t opa) { + lv_color_t color, lv_opa_t opa) +{ uint16_t byte_index = x + (( y>>3 ) * buf_w); uint8_t bit_index = y & 0x7; @@ -164,8 +164,8 @@ void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t row2, }; - send_bytes(disp_drv, conf, sizeof conf); - send_colors(disp_drv, color_p, OLED_COLUMNS * (1 + row2 - row1)); + send_data(disp_drv, conf, sizeof conf); + send_pixels(disp_drv, color_p, OLED_COLUMNS * (1 + row2 - row1)); lv_disp_flush_ready(disp_drv); } @@ -183,7 +183,7 @@ void ssd1306_sleep_in() OLED_CMD_DISPLAY_OFF }; - send_bytes(NULL, conf, sizeof conf); + send_data(NULL, conf, sizeof conf); } void ssd1306_sleep_out() @@ -193,13 +193,13 @@ void ssd1306_sleep_out() OLED_CMD_DISPLAY_ON }; - send_bytes(NULL, conf, sizeof conf); + send_data(NULL, conf, sizeof conf); } /********************** * STATIC FUNCTIONS **********************/ -static uint8_t send_bytes(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len) +static uint8_t send_data(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len) { (void) disp_drv; @@ -221,7 +221,7 @@ static uint8_t send_bytes(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len return 0; } -static uint8_t send_colors(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len) +static uint8_t send_pixels(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len) { (void) disp_drv; From 9cdc3502a132e1d665faf18f851112cdce7fbd13 Mon Sep 17 00:00:00 2001 From: C47D Date: Thu, 21 Jan 2021 10:57:02 -0600 Subject: [PATCH 7/9] SSD1306: Add parenthesis to sizeof --- lvgl_tft/ssd1306.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index 3336f8a..141cfde 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -95,7 +95,7 @@ static uint8_t send_pixels(lv_disp_drv_t *disp_drv, void *color_buffer, size_t b /********************** * GLOBAL FUNCTIONS **********************/ -void ssd1306_init() +void ssd1306_init(void) { uint8_t orientation_1 = 0; uint8_t orientation_2 = 0; @@ -130,7 +130,7 @@ void ssd1306_init() OLED_CMD_DISPLAY_ON }; - send_data(NULL, conf, sizeof conf); + send_data(NULL, conf, sizeof(conf)); } void ssd1306_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, @@ -164,7 +164,7 @@ void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t row2, }; - send_data(disp_drv, conf, sizeof conf); + send_data(disp_drv, conf, sizeof(conf)); send_pixels(disp_drv, color_p, OLED_COLUMNS * (1 + row2 - row1)); lv_disp_flush_ready(disp_drv); @@ -176,24 +176,24 @@ void ssd1306_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area) area->x2 = area->x2 | 0x07; } -void ssd1306_sleep_in() +void ssd1306_sleep_in(void) { uint8_t conf[] = { OLED_CONTROL_BYTE_CMD_STREAM, OLED_CMD_DISPLAY_OFF }; - send_data(NULL, conf, sizeof conf); + send_data(NULL, conf, sizeof(conf)); } -void ssd1306_sleep_out() +void ssd1306_sleep_out(void) { uint8_t conf[] = { OLED_CONTROL_BYTE_CMD_STREAM, OLED_CMD_DISPLAY_ON }; - send_data(NULL, conf, sizeof conf); + send_data(NULL, conf, sizeof(conf)); } /********************** From 80fb2aedef079f63144c6ab1fac6a49dc598e8a0 Mon Sep 17 00:00:00 2001 From: C47D Date: Fri, 22 Jan 2021 10:12:30 -0600 Subject: [PATCH 8/9] SSD1306: Return commands result --- lvgl_tft/ssd1306.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index 141cfde..12c52ea 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -202,6 +202,7 @@ void ssd1306_sleep_out(void) static uint8_t send_data(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len) { (void) disp_drv; + esp_err_t err; uint8_t *data = (uint8_t *) bytes; @@ -215,15 +216,18 @@ static uint8_t send_data(lv_disp_drv_t *disp_drv, void *bytes, size_t bytes_len) } i2c_master_stop(cmd); - i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS); + + /* Send queued commands */ + err = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); - return 0; + return ESP_OK == err ? 0 : 1; } static uint8_t send_pixels(lv_disp_drv_t *disp_drv, void *color_buffer, size_t buffer_len) { (void) disp_drv; + esp_err_t err; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); @@ -232,8 +236,10 @@ static uint8_t send_pixels(lv_disp_drv_t *disp_drv, void *color_buffer, size_t b i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); i2c_master_write(cmd, (uint8_t *) color_buffer, buffer_len, true); i2c_master_stop(cmd); - i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS); + + /* Send queued commands */ + err = i2c_master_cmd_begin(DISP_I2C_PORT, cmd, 10 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); - return 0; + return ESP_OK == err ? 0 : 1; } From b4ac2f9c03786cc86930bf0e10889a701f201609 Mon Sep 17 00:00:00 2001 From: C47D Date: Fri, 22 Jan 2021 10:19:06 -0600 Subject: [PATCH 9/9] SSD1306: Assert on data transmission fails --- lvgl_tft/ssd1306.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lvgl_tft/ssd1306.c b/lvgl_tft/ssd1306.c index 12c52ea..79e5b38 100644 --- a/lvgl_tft/ssd1306.c +++ b/lvgl_tft/ssd1306.c @@ -14,6 +14,7 @@ * INCLUDES *********************/ #include "driver/i2c.h" +#include "assert.h" #include "lvgl_i2c_conf.h" @@ -130,7 +131,8 @@ void ssd1306_init(void) OLED_CMD_DISPLAY_ON }; - send_data(NULL, conf, sizeof(conf)); + uint8_t err = send_data(NULL, conf, sizeof(conf)); + assert(0 == err); } void ssd1306_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, @@ -164,8 +166,10 @@ void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t row2, }; - send_data(disp_drv, conf, sizeof(conf)); - send_pixels(disp_drv, color_p, OLED_COLUMNS * (1 + row2 - row1)); + uint8_t err = send_data(disp_drv, conf, sizeof(conf)); + assert(0 == err); + err = send_pixels(disp_drv, color_p, OLED_COLUMNS * (1 + row2 - row1)); + assert(0 == err); lv_disp_flush_ready(disp_drv); } @@ -183,7 +187,8 @@ void ssd1306_sleep_in(void) OLED_CMD_DISPLAY_OFF }; - send_data(NULL, conf, sizeof(conf)); + uint8_t err = send_data(NULL, conf, sizeof(conf)); + assert(0 == err); } void ssd1306_sleep_out(void) @@ -193,7 +198,8 @@ void ssd1306_sleep_out(void) OLED_CMD_DISPLAY_ON }; - send_data(NULL, conf, sizeof(conf)); + uint8_t err = send_data(NULL, conf, sizeof(conf)); + assert(0 == err); } /**********************