From 8f72cfaa943d969f759460efcda0075eebde6889 Mon Sep 17 00:00:00 2001 From: hiruna Date: Sat, 27 May 2023 13:00:33 +1000 Subject: [PATCH] source i2c_manager files from https://github.com/ropg/i2c_manager master --- lvgl_i2c/Kconfig | 12 +- lvgl_i2c/i2c_manager.c | 310 ++++++++++++++++++++--------------------- lvgl_i2c/i2c_manager.h | 22 +-- 3 files changed, 171 insertions(+), 173 deletions(-) diff --git a/lvgl_i2c/Kconfig b/lvgl_i2c/Kconfig index 48df924..5f0bf89 100644 --- a/lvgl_i2c/Kconfig +++ b/lvgl_i2c/Kconfig @@ -6,10 +6,8 @@ menu "I2C Port 0" if I2C_MANAGER_0_ENABLED config I2C_MANAGER_0_SDA int "SDA (GPIO pin)" - default 0 config I2C_MANAGER_0_SCL int "SCL (GPIO pin)" - default 0 config I2C_MANAGER_0_FREQ_HZ int "Frequency (Hz)" default 400000 @@ -19,7 +17,7 @@ menu "I2C Port 0" 5000000 (5 Mhz). I2C busses that involve external wires may have to be slower, and the real maximum speed the bus will support depends on the value of the pullup resistors and the - design of the overall circuit. + design of the overall circuit. config I2C_MANAGER_0_TIMEOUT int "R/W timeout (ms)" default 20 @@ -50,10 +48,10 @@ endmenu menu "I2C Port 1" - + config I2C_MANAGER_1_ENABLED bool "Enable I2C port 1" - + if I2C_MANAGER_1_ENABLED config I2C_MANAGER_1_SDA int "SDA (GPIO pin)" @@ -68,7 +66,7 @@ menu "I2C Port 1" 5000000 (5 Mhz). I2C busses that involve external wires may have to be slower, and the real maximum speed the bus will support depends on the value of the pullup resistors and the - design of the overall circuit. + design of the overall circuit. config I2C_MANAGER_1_TIMEOUT int "R/W timeout (ms)" default 20 @@ -95,4 +93,4 @@ menu "I2C Port 1" can attain. Try with these off first if you don't know. endif -endmenu +endmenu \ No newline at end of file diff --git a/lvgl_i2c/i2c_manager.c b/lvgl_i2c/i2c_manager.c index d09845b..6780d9f 100644 --- a/lvgl_i2c/i2c_manager.c +++ b/lvgl_i2c/i2c_manager.c @@ -42,7 +42,7 @@ SOFTWARE. #if defined __has_include - #if __has_include ("esp_idf_version.h") +#if __has_include ("esp_idf_version.h") #include "esp_idf_version.h" #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0) #define HAS_CLK_FLAGS @@ -58,29 +58,29 @@ static SemaphoreHandle_t* I2C_FN(_mutex) = &I2C_FN(_local_mutex)[0]; static const uint8_t ACK_CHECK_EN = 1; -#if defined (CONFIG_I2C_MANAGER_0_ENABLED) - #define I2C_ZERO I2C_NUM_0 +#if defined (I2C_NUM_0) && defined (CONFIG_I2C_MANAGER_0_ENABLED) +#define I2C_ZERO I2C_NUM_0 #if defined (CONFIG_I2C_MANAGER_0_PULLUPS) #define I2C_MANAGER_0_PULLUPS true #else #define I2C_MANAGER_0_PULLUPS false #endif - #define I2C_MANAGER_0_TIMEOUT ( CONFIG_I2C_MANAGER_0_TIMEOUT / portTICK_PERIOD_MS ) - #define I2C_MANAGER_0_LOCK_TIMEOUT ( CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT / portTICK_PERIOD_MS ) + #define I2C_MANAGER_0_TIMEOUT ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_TIMEOUT ) ) + #define I2C_MANAGER_0_LOCK_TIMEOUT ( ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT ) ) #endif -#if defined (CONFIG_I2C_MANAGER_1_ENABLED) - #define I2C_ONE I2C_NUM_1 +#if defined (I2C_NUM_1) && defined (CONFIG_I2C_MANAGER_1_ENABLED) +#define I2C_ONE I2C_NUM_1 #if defined (CONFIG_I2C_MANAGER_1_PULLUPS) #define I2C_MANAGER_1_PULLUPS true #else #define I2C_MANAGER_1_PULLUPS false #endif - #define I2C_MANAGER_1_TIMEOUT ( CONFIG_I2C_MANAGER_1_TIMEOUT / portTICK_PERIOD_MS ) - #define I2C_MANAGER_1_LOCK_TIMEOUT ( CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT / portTICK_PERIOD_MS ) + #define I2C_MANAGER_1_TIMEOUT ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_TIMEOUT ) ) + #define I2C_MANAGER_1_LOCK_TIMEOUT ( pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT ) ) #endif #define ERROR_PORT(port, fail) { \ @@ -89,198 +89,198 @@ static const uint8_t ACK_CHECK_EN = 1; } #if defined(I2C_ZERO) && defined (I2C_ONE) - #define I2C_PORT_CHECK(port, fail) \ +#define I2C_PORT_CHECK(port, fail) \ if (port != I2C_NUM_0 && port != I2C_NUM_1) ERROR_PORT(port, fail); #else - #if defined(I2C_ZERO) - #define I2C_PORT_CHECK(port, fail) \ +#if defined(I2C_ZERO) +#define I2C_PORT_CHECK(port, fail) \ if (port != I2C_NUM_0) ERROR_PORT(port, fail); - #elif defined(I2C_ONE) - #define I2C_PORT_CHECK(port, fail) \ +#elif defined(I2C_ONE) +#define I2C_PORT_CHECK(port, fail) \ if (port != I2C_NUM_1) ERROR_PORT(port, fail); - #else - #define I2C_PORT_CHECK(port, fail) \ +#else +#define I2C_PORT_CHECK(port, fail) \ ERROR_PORT(port, fail); - #endif +#endif #endif static void i2c_send_address(i2c_cmd_handle_t cmd, uint16_t addr, i2c_rw_t rw) { - if (addr & I2C_ADDR_10) { - i2c_master_write_byte(cmd, 0xF0 | ((addr & 0x3FF) >> 7) | rw, ACK_CHECK_EN); - i2c_master_write_byte(cmd, addr & 0xFF, ACK_CHECK_EN); - } else { - i2c_master_write_byte(cmd, (addr << 1) | rw, ACK_CHECK_EN); - } + if (addr & I2C_ADDR_10) { + i2c_master_write_byte(cmd, 0xF0 | ((addr & 0x3FF) >> 7) | rw, ACK_CHECK_EN); + i2c_master_write_byte(cmd, addr & 0xFF, ACK_CHECK_EN); + } else { + i2c_master_write_byte(cmd, (addr << 1) | rw, ACK_CHECK_EN); + } } static void i2c_send_register(i2c_cmd_handle_t cmd, uint32_t reg) { - if (reg & I2C_REG_16) { - i2c_master_write_byte(cmd, (reg & 0xFF00) >> 8, ACK_CHECK_EN); - } + if (reg & I2C_REG_16) { + i2c_master_write_byte(cmd, (reg & 0xFF00) >> 8, ACK_CHECK_EN); + } i2c_master_write_byte(cmd, reg & 0xFF, ACK_CHECK_EN); } esp_err_t I2C_FN(_init)(i2c_port_t port) { - I2C_PORT_CHECK(port, ESP_FAIL); + I2C_PORT_CHECK(port, ESP_FAIL); - esp_err_t ret = ESP_OK; + esp_err_t ret = ESP_OK; - if (I2C_FN(_mutex)[port] == 0) { + if (I2C_FN(_mutex)[port] == 0) { - ESP_LOGI(TAG, "Starting I2C master at port %d.", (int)port); + ESP_LOGI(TAG, "Starting I2C master at port %d.", (int)port); - I2C_FN(_mutex)[port] = xSemaphoreCreateMutex(); + I2C_FN(_mutex)[port] = xSemaphoreCreateMutex(); - i2c_config_t conf = {0}; - - #ifdef HAS_CLK_FLAGS - conf.clk_flags = 0; - #endif + i2c_config_t conf = {0}; - #if defined (I2C_ZERO) - if (port == I2C_NUM_0) { +#ifdef HAS_CLK_FLAGS + conf.clk_flags = 0; +#endif + +#if defined (I2C_ZERO) + if (port == I2C_NUM_0) { conf.sda_io_num = CONFIG_I2C_MANAGER_0_SDA; conf.scl_io_num = CONFIG_I2C_MANAGER_0_SCL; conf.sda_pullup_en = I2C_MANAGER_0_PULLUPS ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE; conf.scl_pullup_en = conf.sda_pullup_en; conf.master.clk_speed = CONFIG_I2C_MANAGER_0_FREQ_HZ; } - #endif +#endif - #if defined (I2C_ONE) - if (port == I2C_NUM_1) { +#if defined (I2C_ONE) + if (port == I2C_NUM_1) { conf.sda_io_num = CONFIG_I2C_MANAGER_1_SDA; conf.scl_io_num = CONFIG_I2C_MANAGER_1_SCL; conf.sda_pullup_en = I2C_MANAGER_1_PULLUPS ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE; conf.scl_pullup_en = conf.sda_pullup_en; conf.master.clk_speed = CONFIG_I2C_MANAGER_1_FREQ_HZ; } - #endif +#endif - conf.mode = I2C_MODE_MASTER; + conf.mode = I2C_MODE_MASTER; - ret = i2c_param_config(port, &conf); - ret |= i2c_driver_install(port, conf.mode, 0, 0, 0); + ret = i2c_param_config(port, &conf); + ret |= i2c_driver_install(port, conf.mode, 0, 0, 0); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to initialise I2C port %d.", (int)port); - ESP_LOGW(TAG, "If it was already open, we'll use it with whatever settings were used " - "to open it. See I2C Manager README for details."); - } else { - ESP_LOGI(TAG, "Initialised port %d (SDA: %d, SCL: %d, speed: %lu Hz.)", - port, conf.sda_io_num, conf.scl_io_num, conf.master.clk_speed); - } + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialise I2C port %d.", (int)port); + ESP_LOGW(TAG, "If it was already open, we'll use it with whatever settings were used " + "to open it. See I2C Manager README for details."); + } else { + ESP_LOGI(TAG, "Initialised port %d (SDA: %d, SCL: %d, speed: %d Hz.)", + port, conf.sda_io_num, conf.scl_io_num, conf.master.clk_speed); + } - } + } return ret; } esp_err_t I2C_FN(_read)(i2c_port_t port, uint16_t addr, uint32_t reg, uint8_t *buffer, uint16_t size) { - I2C_PORT_CHECK(port, ESP_FAIL); + I2C_PORT_CHECK(port, ESP_FAIL); esp_err_t result; // May seem weird, but init starts with a check if it's needed, no need for that check twice. - I2C_FN(_init)(port); + I2C_FN(_init)(port); - ESP_LOGV(TAG, "Reading port %d, addr 0x%03x, reg 0x%04lx", port, addr, reg); + ESP_LOGV(TAG, "Reading port %d, addr 0x%03x, reg 0x%04x", port, addr, reg); - TickType_t timeout = 0; - #if defined (I2C_ZERO) - if (port == I2C_NUM_0) { + TickType_t timeout = 0; +#if defined (I2C_ZERO) + if (port == I2C_NUM_0) { timeout = I2C_MANAGER_0_TIMEOUT; } - #endif - #if defined (I2C_ONE) - if (port == I2C_NUM_1) { +#endif +#if defined (I2C_ONE) + if (port == I2C_NUM_1) { timeout = I2C_MANAGER_1_TIMEOUT; } - #endif +#endif - if (I2C_FN(_lock)((int)port) == ESP_OK) { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - if (!(reg & I2C_NO_REG)) { - /* When reading specific register set the addr pointer first. */ - i2c_master_start(cmd); - i2c_send_address(cmd, addr, I2C_MASTER_WRITE); - i2c_send_register(cmd, reg); - } - /* Read size bytes from the current pointer. */ - i2c_master_start(cmd); - i2c_send_address(cmd, addr, I2C_MASTER_READ); - i2c_master_read(cmd, buffer, size, I2C_MASTER_LAST_NACK); - i2c_master_stop(cmd); - result = i2c_master_cmd_begin(port, cmd, timeout); - i2c_cmd_link_delete(cmd); - I2C_FN(_unlock)((int)port); - } else { - ESP_LOGE(TAG, "Lock could not be obtained for port %d.", (int)port); - return ESP_ERR_TIMEOUT; - } - - if (result != ESP_OK) { - ESP_LOGW(TAG, "Error: %d", result); + if (I2C_FN(_lock)((int)port) == ESP_OK) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + if (!(reg & I2C_NO_REG)) { + /* When reading specific register set the addr pointer first. */ + i2c_master_start(cmd); + i2c_send_address(cmd, addr, I2C_MASTER_WRITE); + i2c_send_register(cmd, reg); + } + /* Read size bytes from the current pointer. */ + i2c_master_start(cmd); + i2c_send_address(cmd, addr, I2C_MASTER_READ); + i2c_master_read(cmd, buffer, size, I2C_MASTER_LAST_NACK); + i2c_master_stop(cmd); + result = i2c_master_cmd_begin(port, cmd, timeout); + i2c_cmd_link_delete(cmd); + I2C_FN(_unlock)((int)port); + } else { + ESP_LOGE(TAG, "Lock could not be obtained for port %d.", (int)port); + return ESP_ERR_TIMEOUT; } - ESP_LOG_BUFFER_HEX_LEVEL(TAG, buffer, size, ESP_LOG_VERBOSE); + if (result != ESP_OK) { + ESP_LOGD(TAG, "Error: %d", result); + } + + ESP_LOG_BUFFER_HEX_LEVEL(TAG, buffer, size, ESP_LOG_VERBOSE); return result; } esp_err_t I2C_FN(_write)(i2c_port_t port, uint16_t addr, uint32_t reg, const uint8_t *buffer, uint16_t size) { - I2C_PORT_CHECK(port, ESP_FAIL); + I2C_PORT_CHECK(port, ESP_FAIL); esp_err_t result; // May seem weird, but init starts with a check if it's needed, no need for that check twice. - I2C_FN(_init)(port); + I2C_FN(_init)(port); - ESP_LOGV(TAG, "Writing port %d, addr 0x%03x, reg 0x%04lx", port, addr, reg); + ESP_LOGV(TAG, "Writing port %d, addr 0x%03x, reg 0x%04x", port, addr, reg); - TickType_t timeout = 0; - #if defined (I2C_ZERO) - if (port == I2C_NUM_0) { - timeout = (CONFIG_I2C_MANAGER_0_TIMEOUT) / portTICK_PERIOD_MS; + TickType_t timeout = 0; +#if defined (I2C_ZERO) + if (port == I2C_NUM_0) { + timeout = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_TIMEOUT ); } - #endif - #if defined (I2C_ONE) - if (port == I2C_NUM_1) { - timeout = (CONFIG_I2C_MANAGER_1_TIMEOUT) / portTICK_PERIOD_MS; +#endif +#if defined (I2C_ONE) + if (port == I2C_NUM_1) { + timeout = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_TIMEOUT ); } - #endif +#endif - if (I2C_FN(_lock)((int)port) == ESP_OK) { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_send_address(cmd, addr, I2C_MASTER_WRITE); - if (!(reg & I2C_NO_REG)) { - i2c_send_register(cmd, reg); - } - i2c_master_write(cmd, (uint8_t *)buffer, size, ACK_CHECK_EN); - i2c_master_stop(cmd); - result = i2c_master_cmd_begin( port, cmd, timeout); - i2c_cmd_link_delete(cmd); - I2C_FN(_unlock)((int)port); - } else { - ESP_LOGE(TAG, "Lock could not be obtained for port %d.", (int)port); - return ESP_ERR_TIMEOUT; - } - - if (result != ESP_OK) { - ESP_LOGW(TAG, "Error: %d", result); + if (I2C_FN(_lock)((int)port) == ESP_OK) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_send_address(cmd, addr, I2C_MASTER_WRITE); + if (!(reg & I2C_NO_REG)) { + i2c_send_register(cmd, reg); + } + i2c_master_write(cmd, (uint8_t *)buffer, size, ACK_CHECK_EN); + i2c_master_stop(cmd); + result = i2c_master_cmd_begin( port, cmd, timeout); + i2c_cmd_link_delete(cmd); + I2C_FN(_unlock)((int)port); + } else { + ESP_LOGE(TAG, "Lock could not be obtained for port %d.", (int)port); + return ESP_ERR_TIMEOUT; } - ESP_LOG_BUFFER_HEX_LEVEL(TAG, buffer, size, ESP_LOG_VERBOSE); + if (result != ESP_OK) { + ESP_LOGD(TAG, "Error: %d", result); + } + + ESP_LOG_BUFFER_HEX_LEVEL(TAG, buffer, size, ESP_LOG_VERBOSE); return result; } esp_err_t I2C_FN(_close)(i2c_port_t port) { - I2C_PORT_CHECK(port, ESP_FAIL); + I2C_PORT_CHECK(port, ESP_FAIL); vSemaphoreDelete(I2C_FN(_mutex)[port]); I2C_FN(_mutex)[port] = NULL; ESP_LOGI(TAG, "Closing I2C master at port %d", port); @@ -288,59 +288,59 @@ esp_err_t I2C_FN(_close)(i2c_port_t port) { } esp_err_t I2C_FN(_lock)(i2c_port_t port) { - I2C_PORT_CHECK(port, ESP_FAIL); - ESP_LOGV(TAG, "Mutex lock set for %d.", (int)port); + I2C_PORT_CHECK(port, ESP_FAIL); + ESP_LOGV(TAG, "Mutex lock set for %d.", (int)port); - TickType_t timeout; - #if defined (I2C_ZERO) - if (port == I2C_NUM_0) { - timeout = (CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT) / portTICK_PERIOD_MS; + TickType_t timeout; +#if defined (I2C_ZERO) + if (port == I2C_NUM_0) { + timeout = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_0_LOCK_TIMEOUT ); } - #endif - #if defined (I2C_ONE) - if (port == I2C_NUM_1) { - timeout = (CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT) / portTICK_PERIOD_MS; +#endif +#if defined (I2C_ONE) + if (port == I2C_NUM_1) { + timeout = pdMS_TO_TICKS( CONFIG_I2C_MANAGER_1_LOCK_TIMEOUT ); } - #endif +#endif - if (xSemaphoreTake(I2C_FN(_mutex)[port], timeout) == pdTRUE) { - return ESP_OK; - } else { - ESP_LOGE(TAG, "Removing stale mutex lock from port %d.", (int)port); - I2C_FN(_force_unlock)(port); - return (xSemaphoreTake(I2C_FN(_mutex)[port], timeout) == pdTRUE ? ESP_OK : ESP_FAIL); - } + if (xSemaphoreTake(I2C_FN(_mutex)[port], timeout) == pdTRUE) { + return ESP_OK; + } else { + ESP_LOGE(TAG, "Removing stale mutex lock from port %d.", (int)port); + I2C_FN(_force_unlock)(port); + return (xSemaphoreTake(I2C_FN(_mutex)[port], timeout) == pdTRUE ? ESP_OK : ESP_FAIL); + } } esp_err_t I2C_FN(_unlock)(i2c_port_t port) { - I2C_PORT_CHECK(port, ESP_FAIL); - ESP_LOGV(TAG, "Mutex lock removed for %d.", (int)port); - return (xSemaphoreGive(I2C_FN(_mutex)[port]) == pdTRUE) ? ESP_OK : ESP_FAIL; + I2C_PORT_CHECK(port, ESP_FAIL); + ESP_LOGV(TAG, "Mutex lock removed for %d.", (int)port); + return (xSemaphoreGive(I2C_FN(_mutex)[port]) == pdTRUE) ? ESP_OK : ESP_FAIL; } esp_err_t I2C_FN(_force_unlock)(i2c_port_t port) { - I2C_PORT_CHECK(port, ESP_FAIL); - if (I2C_FN(_mutex)[port]) { - vSemaphoreDelete(I2C_FN(_mutex)[port]); - } - I2C_FN(_mutex)[port] = xSemaphoreCreateMutex(); - return ESP_OK; + I2C_PORT_CHECK(port, ESP_FAIL); + if (I2C_FN(_mutex)[port]) { + vSemaphoreDelete(I2C_FN(_mutex)[port]); + } + I2C_FN(_mutex)[port] = xSemaphoreCreateMutex(); + return ESP_OK; } #ifdef I2C_OEM - void I2C_FN(_locking)(void* leader) { - if (leader) { - ESP_LOGI(TAG, "Now following I2C Manager for locking"); - I2C_FN(_mutex) = (SemaphoreHandle_t*)leader; - } +void I2C_FN(_locking)(void* leader) { + if (leader) { + ESP_LOGI(TAG, "Now following I2C Manager for locking"); + I2C_FN(_mutex) = (SemaphoreHandle_t*)leader; } +} #else - void* i2c_manager_locking() { +void* i2c_manager_locking() { return (void*)i2c_manager_mutex; } @@ -365,4 +365,4 @@ esp_err_t I2C_FN(_force_unlock)(i2c_port_t port) { return (void*)&_i2c_hal[port]; } -#endif +#endif \ No newline at end of file diff --git a/lvgl_i2c/i2c_manager.h b/lvgl_i2c/i2c_manager.h index f9ce585..ddbbd33 100644 --- a/lvgl_i2c/i2c_manager.h +++ b/lvgl_i2c/i2c_manager.h @@ -29,9 +29,9 @@ extern "C" { #define STR_QUOTE(s) STR_EXPAND(STR_EXPAND(s)) #ifdef I2C_OEM - #define I2C_NAME_PREFIX CONCAT(I2C_OEM, _i2c) +#define I2C_NAME_PREFIX CONCAT(I2C_OEM, _i2c) #else - #define I2C_NAME_PREFIX i2c_manager +#define I2C_NAME_PREFIX i2c_manager #endif #define I2C_TAG STR_EXPAND(I2C_NAME_PREFIX) @@ -53,19 +53,19 @@ esp_err_t I2C_FN(_force_unlock)(i2c_port_t port); #ifdef I2C_OEM - void I2C_FN(_locking)(void* leader); +void I2C_FN(_locking)(void* leader); #else - void* i2c_manager_locking(); +void* i2c_manager_locking(); - typedef struct { - int32_t (* read)(void *handle, uint8_t address, uint8_t reg, uint8_t *buffer, uint16_t size); - int32_t (* write)(void *handle, uint8_t address, uint8_t reg, const uint8_t *buffer, uint16_t size); - void *handle; - } i2c_hal_t; +typedef struct { + int32_t (* read)(void *handle, uint8_t address, uint8_t reg, uint8_t *buffer, uint16_t size); + int32_t (* write)(void *handle, uint8_t address, uint8_t reg, const uint8_t *buffer, uint16_t size); + void *handle; +} i2c_hal_t; - void* i2c_hal(i2c_port_t port); +void* i2c_hal(i2c_port_t port); #endif @@ -73,4 +73,4 @@ esp_err_t I2C_FN(_force_unlock)(i2c_port_t port); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file