Skip to content

Commit a68ce89

Browse files
authored
Merge pull request #70 from ropg/I2C_Manager
Replace all LVGL driver I2C code with I2C Manager
2 parents b3515c4 + 93a4449 commit a68ce89

24 files changed

+902
-689
lines changed

CMakeLists.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,17 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
7676

7777
if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
7878
list(APPEND SOURCES "lvgl_touch/tp_spi.c")
79-
elseif(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
80-
list(APPEND SOURCES "lvgl_touch/tp_i2c.c")
8179
endif()
8280
endif()
8381

82+
if(CONFIG_LV_I2C)
83+
list(APPEND SOURCES "lvgl_i2c/i2c_manager.c")
84+
endif()
85+
8486
idf_component_register(SRCS ${SOURCES}
8587
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
8688
REQUIRES lvgl)
87-
89+
8890
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_LVGL_H_INCLUDE_SIMPLE")
8991

9092
else()

Kconfig

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
1-
rsource "lvgl_tft/Kconfig"
2-
rsource "lvgl_touch/Kconfig"
1+
menu "LVGL ESP Drivers"
2+
3+
rsource "lvgl_tft/Kconfig"
4+
5+
rsource "lvgl_touch/Kconfig"
6+
7+
endmenu
8+
9+
menu "I2C Port Settings"
10+
depends on LV_I2C && !HAVE_I2C_MANAGER
11+
12+
rsource "lvgl_i2c/Kconfig"
13+
14+
endmenu

README.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ For a ready to use ESP32 project take look at the [lv_port_esp32](https://github
66
- [Supported display controllers](#supported-display-controllers)
77
- [Supported indev controllers](#supported-indev-controllers)
88
- [Support for predefined development kits](#support-for-predefined-development-kits)
9+
- [Thread-safe I2C with I2C Manager](#thread-safe-i2c-with-i2c-manager)
910

1011
**NOTE:** You need to set the display horizontal and vertical size, color depth and
1112
swap of RGB565 color on the LVGL configuration menuconfig (it's not handled automatically).
@@ -35,8 +36,8 @@ swap of RGB565 color on the LVGL configuration menuconfig (it's not handled auto
3536
## Supported indev controllers
3637

3738
- XPT2046
38-
- FT3236
39-
- other FT6X36 or the FT6206 controllers should work as well (not tested)
39+
- FT3236, FT6X36
40+
- FT6206 controllers should work as well (not tested)
4041
- STMPE610
4142
- FT81x (Single, Dual, and Quad SPI)
4243

@@ -52,7 +53,7 @@ and sets the gpio numbers for the interface.
5253
|---------------------------|-----------------------|-----------|-----------|-----------|
5354
| ESP Wrover Kit v4.1 | ILI9341 | SPI | 240 | 320 |
5455
| M5Stack | ILI9341 | SPI | 240 | 320 |
55-
| M5Core2 | ILI9341 | SPI | 240 | 320 |
56+
| M5Stack Core2 | ILI9341 | SPI | 240 | 320 |
5657
| M5Stick | SH1107 | SPI | - | - |
5758
| M5StickC | ST7735S | SPI | 80 | 160 |
5859
| Adafruit 3.5 Featherwing | HX8357 | SPI | 480 | 320 |
@@ -65,3 +66,16 @@ and sets the gpio numbers for the interface.
6566

6667
**NOTE:** See [Supported display controllers](#supported-display-controllers) for more information on display configuration.
6768
**NOTE:** See [Supported indev controllers](#supported-indev-controllers) for more information about indev configuration.
69+
70+
71+
## Thread-safe I2C with I2C Manager
72+
73+
LVGL can use I2C to read from a touch sensor or write to a display, possibly
74+
many times a second. Meanwhile, other tasks may also want to read from i2c
75+
devices on the same bus. I2C using the ESP-IDF is not thread-safe.
76+
77+
I2C Manager (`i2c_manager`) is a component that will let code in multiple threads
78+
talk to devices on the I2C ports without getting in each other's way. These drivers
79+
use a built-in copy of I2C Manager to talk to the I2C port, but you can also use
80+
the I2C Manager component itself and have others play nice with LVGL and vice-versa.
81+
[Click here](i2c_manager/README.md) for details.

component.mk

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# LVGL ESP32 drivers
22

33
# Define sources and include dirs
4-
COMPONENT_SRCDIRS := . lvgl_tft lvgl_touch
4+
COMPONENT_SRCDIRS := . lvgl_tft lvgl_touch lvgl_i2c
55
COMPONENT_ADD_INCLUDEDIRS := .
66

77
# LVGL is supposed to be used as a ESP-IDF component
@@ -44,4 +44,6 @@ $(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_CON
4444
$(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_CONTROLLER_RA8875)), lvgl_touch/ra8875_touch.o)
4545

4646
$(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)), lvgl_touch/tp_spi.o)
47-
$(call compile_only_if,$(and $(CONFIG_LV_TOUCH_CONTROLLER),$(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)), lvgl_touch/tp_i2c.o)
47+
48+
# I2C Manager
49+
$(call compile_only_if,$(CONFIG_LV_I2C), lvgl_i2c/i2c_manager.o)

lvgl_helpers.c

Lines changed: 12 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414
#include "lvgl_touch/tp_spi.h"
1515

1616
#include "lvgl_spi_conf.h"
17-
#include "lvgl_i2c_conf.h"
1817

19-
#include "driver/i2c.h"
18+
#include "lvgl_i2c/i2c_manager.h"
2019

2120
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
2221
#include "lvgl.h"
@@ -68,7 +67,7 @@ void lvgl_driver_init(void)
6867
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
6968
SPI_BUS_MAX_TRANSFER_SZ, 1,
7069
DISP_SPI_IO2, DISP_SPI_IO3);
71-
70+
7271
disp_spi_add_device(TFT_SPI_HOST);
7372
disp_driver_init();
7473

@@ -86,48 +85,29 @@ void lvgl_driver_init(void)
8685
TP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
8786
SPI_BUS_MAX_TRANSFER_SZ, 1,
8887
-1, -1);
89-
88+
9089
disp_spi_add_device(TFT_SPI_HOST);
9190
tp_spi_add_device(TOUCH_SPI_HOST);
92-
93-
disp_driver_init();
94-
touch_driver_init();
9591

96-
return;
97-
#endif
98-
99-
#if defined (SHARED_I2C_BUS)
100-
ESP_LOGI(TAG, "Initializing shared I2C master");
101-
102-
lvgl_i2c_driver_init(DISP_I2C_PORT,
103-
DISP_I2C_SDA, DISP_I2C_SCL,
104-
DISP_I2C_SPEED_HZ);
105-
10692
disp_driver_init();
10793
touch_driver_init();
108-
94+
10995
return;
11096
#endif
11197

11298
/* Display controller initialization */
11399
#if defined CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI
114100
ESP_LOGI(TAG, "Initializing SPI master for display");
115-
101+
116102
lvgl_spi_driver_init(TFT_SPI_HOST,
117103
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
118104
SPI_BUS_MAX_TRANSFER_SZ, 1,
119105
DISP_SPI_IO2, DISP_SPI_IO3);
120-
106+
121107
disp_spi_add_device(TFT_SPI_HOST);
122-
108+
123109
disp_driver_init();
124-
#elif defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_I2C)
125-
ESP_LOGI(TAG, "Initializing I2C master for display");
126-
/* Init the i2c master on the display driver code */
127-
lvgl_i2c_driver_init(DISP_I2C_PORT,
128-
DISP_I2C_SDA, DISP_I2C_SCL,
129-
DISP_I2C_SPEED_HZ);
130-
110+
#elif defined (CONFIG_LV_I2C_DISPLAY)
131111
disp_driver_init();
132112
#else
133113
#error "No protocol defined for display controller"
@@ -137,22 +117,16 @@ void lvgl_driver_init(void)
137117
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
138118
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
139119
ESP_LOGI(TAG, "Initializing SPI master for touch");
140-
120+
141121
lvgl_spi_driver_init(TOUCH_SPI_HOST,
142122
TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK,
143123
0 /* Defaults to 4094 */, 2,
144124
-1, -1);
145-
125+
146126
tp_spi_add_device(TOUCH_SPI_HOST);
147-
127+
148128
touch_driver_init();
149-
#elif defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
150-
ESP_LOGI(TAG, "Initializing I2C master for touch");
151-
152-
lvgl_i2c_driver_init(TOUCH_I2C_PORT,
153-
TOUCH_I2C_SDA, TOUCH_I2C_SCL,
154-
TOUCH_I2C_SPEED_HZ);
155-
129+
#elif defined (CONFIG_LV_I2C_TOUCH)
156130
touch_driver_init();
157131
#elif defined (CONFIG_LV_TOUCH_DRIVER_ADC)
158132
touch_driver_init();
@@ -165,42 +139,6 @@ void lvgl_driver_init(void)
165139
#endif
166140
}
167141

168-
/* Config the i2c master
169-
*
170-
* This should init the i2c master to be used on display and touch controllers.
171-
* So we should be able to know if the display and touch controllers shares the
172-
* same i2c master.
173-
*/
174-
bool lvgl_i2c_driver_init(int port, int sda_pin, int scl_pin, int speed_hz)
175-
{
176-
esp_err_t err;
177-
178-
ESP_LOGI(TAG, "Initializing I2C master port %d...", port);
179-
ESP_LOGI(TAG, "SDA pin: %d, SCL pin: %d, Speed: %d (Hz)",
180-
sda_pin, scl_pin, speed_hz);
181-
182-
i2c_config_t conf = {
183-
.mode = I2C_MODE_MASTER,
184-
.sda_io_num = sda_pin,
185-
.sda_pullup_en = GPIO_PULLUP_ENABLE,
186-
.scl_io_num = scl_pin,
187-
.scl_pullup_en = GPIO_PULLUP_ENABLE,
188-
.master.clk_speed = speed_hz,
189-
};
190-
191-
ESP_LOGI(TAG, "Setting I2C master configuration...");
192-
err = i2c_param_config(port, &conf);
193-
assert(ESP_OK == err);
194-
195-
ESP_LOGI(TAG, "Installing I2C master driver...");
196-
err = i2c_driver_install(port,
197-
I2C_MODE_MASTER,
198-
0, 0 /*I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE */,
199-
0 /* intr_alloc_flags */);
200-
assert(ESP_OK == err);
201-
202-
return ESP_OK != err;
203-
}
204142

205143
/* Initialize spi bus master
206144
*

lvgl_helpers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ extern "C" {
8888
* GLOBAL PROTOTYPES
8989
**********************/
9090

91+
void lvgl_i2c_locking(void* leader);
92+
9193
/* Initialize detected SPI and I2C bus and devices */
9294
void lvgl_driver_init(void);
9395

9496
/* Initialize SPI master */
9597
bool lvgl_spi_driver_init(int host, int miso_pin, int mosi_pin, int sclk_pin,
9698
int max_transfer_sz, int dma_channel, int quadwp_pin, int quadhd_pin);
97-
/* Initialize I2C master */
98-
bool lvgl_i2c_driver_init(int port, int sda_pin, int scl_pin, int speed);
9999

100100
/**********************
101101
* MACROS

lvgl_i2c/Kconfig

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
menu "I2C Port 0"
2+
3+
config I2C_MANAGER_0_ENABLED
4+
bool "Enable I2C port 0"
5+
6+
if I2C_MANAGER_0_ENABLED
7+
config I2C_MANAGER_0_SDA
8+
int "SDA (GPIO pin)"
9+
config I2C_MANAGER_0_SCL
10+
int "SCL (GPIO pin)"
11+
config I2C_MANAGER_0_FREQ_HZ
12+
int "Frequency (Hz)"
13+
default 400000
14+
range 100000 5000000
15+
help
16+
The clock speed in Hz. Ranges from 100000 (100 kHz) to
17+
5000000 (5 Mhz). I2C busses that involve external wires may
18+
have to be slower, and the real maximum speed the bus will
19+
support depends on the value of the pullup resistors and the
20+
design of the overall circuit.
21+
config I2C_MANAGER_0_TIMEOUT
22+
int "R/W timeout (ms)"
23+
default 20
24+
range 10 1000
25+
help
26+
Timeout for I2C read and write operations. This does not
27+
include the time waiting for a lock.
28+
config I2C_MANAGER_0_LOCK_TIMEOUT
29+
int "Stale lock override (ms)"
30+
default 50
31+
range 10 1000
32+
help
33+
Timeout at which point an operation waiting for its turn on
34+
the port will assume that whatever set the lock has died and
35+
overrides it. Set this somewhat larger than the previous
36+
timeout.
37+
config I2C_MANAGER_0_PULLUPS
38+
bool "Use ESP32 built-in bus pull-up resistors"
39+
help
40+
The I2C bus needs resistors to make sure it's in a defined
41+
state when nobody is talking. Many circuits have external
42+
pullup resistors already and turning these on will increase
43+
power consumption slightly and may limit the speed your bus
44+
can attain. Try with these off first if you don't know.
45+
endif
46+
47+
endmenu
48+
49+
50+
menu "I2C Port 1"
51+
52+
config I2C_MANAGER_1_ENABLED
53+
bool "Enable I2C port 1"
54+
55+
if I2C_MANAGER_1_ENABLED
56+
config I2C_MANAGER_1_SDA
57+
int "SDA (GPIO pin)"
58+
config I2C_MANAGER_1_SCL
59+
int "SCL (GPIO pin)"
60+
config I2C_MANAGER_1_FREQ_HZ
61+
int "Frequency (Hz)"
62+
default 1000000
63+
range 100000 5000000
64+
help
65+
The clock speed in Hz. Ranges from 100000 (100 kHz) to
66+
5000000 (5 Mhz). I2C busses that involve external wires may
67+
have to be slower, and the real maximum speed the bus will
68+
support depends on the value of the pullup resistors and the
69+
design of the overall circuit.
70+
config I2C_MANAGER_1_TIMEOUT
71+
int "R/W timeout (ms)"
72+
default 20
73+
range 10 1000
74+
help
75+
Timeout for I2C read and write operations. This does not
76+
include the time waiting for a lock. Default should be fine.
77+
config I2C_MANAGER_1_LOCK_TIMEOUT
78+
int "Stale lock override (ms)"
79+
default 50
80+
help
81+
Timeout at which point an operation waiting for its turn on
82+
the port will assume that whatever set the lock has died and
83+
overrides it. Set this somewhat larger than the previous
84+
timeout. Default should be fine.
85+
range 30 1000
86+
config I2C_MANAGER_1_PULLUPS
87+
bool "Use ESP32 built-in bus pull-up resistors"
88+
help
89+
The I2C bus needs resistors to make sure it's in a defined
90+
state when nobody is talking. Many circuits have external
91+
pullup resistors already and turning these on will increase
92+
power consumption slightly and may limit the speed your bus
93+
can attain. Try with these off first if you don't know.
94+
endif
95+
96+
endmenu

0 commit comments

Comments
 (0)