Skip to content

Commit 1718aa6

Browse files
committed
Finished making software rotation available to all bus types
The code compiles, I still have yet to test if it actually works. I also made some changes to the rotation code that should improve performance. Reducing the number of math operations that were being done per pixel. Decreased memory use when not using software rotation.
1 parent eb818d9 commit 1718aa6

File tree

16 files changed

+583
-704
lines changed

16 files changed

+583
-704
lines changed

ext_mod/lcd_bus/esp32_include/bus_task.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#ifndef __BUS_TASK_H__
99
#define __BUS_TASK_H__
1010

11+
#define DEFAULT_STACK_SIZE (5 * 1024)
12+
1113
typedef struct _bus_lock_t {
1214
SemaphoreHandle_t handle;
1315
StaticSemaphore_t buffer;

ext_mod/lcd_bus/esp32_include/i2c_bus.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@
2525

2626
uint32_t buffer_flags;
2727

28+
uint8_t lane_count : 5;
2829
uint8_t trans_done : 1;
2930
uint8_t rgb565_byte_swap : 1;
3031

3132
lcd_panel_io_t panel_io_handle;
32-
esp_lcd_panel_io_i2c_config_t panel_io_config;
33-
i2c_config_t bus_config;
33+
esp_lcd_panel_io_i2c_config_t *panel_io_config;
34+
i2c_config_t *bus_config;
3435
esp_lcd_i2c_bus_handle_t bus_handle;
3536

3637
int host;

ext_mod/lcd_bus/esp32_include/i80_bus.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@
2828
mp_obj_array_t *view2;
2929
uint32_t buffer_flags;
3030

31+
uint8_t lane_count : 5;
3132
uint8_t trans_done : 1;
3233
uint8_t rgb565_byte_swap : 1;
3334

3435
lcd_panel_io_t panel_io_handle;
3536

36-
esp_lcd_panel_io_i80_config_t panel_io_config;
37-
esp_lcd_i80_bus_config_t bus_config;
37+
esp_lcd_panel_io_i80_config_t *panel_io_config;
38+
esp_lcd_i80_bus_config_t *bus_config;
3839
esp_lcd_i80_bus_handle_t bus_handle;
3940
} mp_lcd_i80_bus_obj_t;
4041

ext_mod/lcd_bus/esp32_include/rgb_bus.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,13 @@
4242

4343
uint32_t buffer_flags;
4444

45+
uint8_t lane_count : 5;
4546
uint8_t trans_done : 1;
4647
uint8_t rgb565_byte_swap : 1;
4748

4849
lcd_panel_io_t panel_io_handle;
4950

50-
esp_lcd_rgb_panel_config_t panel_io_config;
51-
esp_lcd_rgb_timing_t bus_config;
52-
51+
esp_lcd_rgb_panel_config_t *panel_io_config;
5352
esp_lcd_panel_handle_t panel_handle;
5453
uint32_t buffer_size;
5554

ext_mod/lcd_bus/esp32_include/rotation.h

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#include "bus_task.h"
2-
#include "lcd_types.h"
32

4-
#include "py/misc.h"
3+
// micropy includes
4+
#include "py/obj.h"
5+
#include "py/runtime.h"
6+
#include "mphalport.h"
7+
58

69
#include "freertos/FreeRTOS.h"
710
#include "freertos/task.h"
@@ -10,16 +13,10 @@
1013
#ifndef __ROTATION_H__
1114
#define __ROTATION_H__
1215

13-
#if LCD_RGB_OPTIMUM_FB_SIZE
14-
typedef struct _rotation_optimum_t {
15-
uint16_t flush_count;
16-
uint8_t sample_count;
17-
uint8_t curr_index;
18-
uint16_t *samples;
19-
bus_lock_t lock;
20-
} rotation_optimum_t;
21-
#endif
22-
16+
#define ROTATION_0 (0)
17+
#define ROTATION_90 (1)
18+
#define ROTATION_180 (2)
19+
#define ROTATION_270 (3)
2320

2421
typedef struct _rotation_task_t {
2522
bus_lock_t lock;
@@ -41,7 +38,7 @@
4138

4239

4340
typedef struct _rotation_init_err_t {
44-
mp_lcd_err_t code;
41+
int code;
4542
mp_rom_error_text_t msg;
4643
} rotation_init_err_t;
4744

@@ -63,13 +60,13 @@
6360
int param_cmd[24];
6461
void *param[24];
6562
size_t param_size[24];
66-
bool param_last_cmd[24]
63+
bool param_last_cmd[24];
6764

6865
} rotation_data_t;
6966

7067

71-
typedef mp_lcd_err_t (*init_func_cb_t)(void *self_in);
72-
68+
typedef int (*init_func_cb_t)(void *self_in);
69+
typedef void (*last_update_cb_t)(void *self_in, void *idle_buf);
7370

7471
typedef struct _rotation_t {
7572
rotation_task_t task;
@@ -79,17 +76,11 @@
7976
int lcd_cmd;
8077

8178
init_func_cb_t init_func;
79+
last_update_cb_t last_update_func;
8280

83-
84-
#if LCD_RGB_OPTIMUM_FB_SIZE
85-
rotation_optimum_t optimum;
86-
#endif
8781
} rotation_t;
8882

8983
void rotation_task_start(void *self_in);
90-
mp_lcd_err_t rotation_set_buffers(void *self_in);
91-
92-
uint32_t rotate(void *src, void *dst, rotation_data_t *data);
93-
84+
int rotation_set_buffers(void *self_in);
9485

9586
#endif

ext_mod/lcd_bus/esp32_include/spi_bus.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929

3030
uint32_t buffer_flags;
3131

32+
uint8_t lane_count : 5;
3233
uint8_t trans_done : 1;
3334
uint8_t rgb565_byte_swap : 1;
3435

3536
lcd_panel_io_t panel_io_handle;
36-
esp_lcd_panel_io_spi_config_t panel_io_config;
37-
spi_bus_config_t bus_config;
37+
esp_lcd_panel_io_spi_config_t *panel_io_config;
3838
esp_lcd_spi_bus_handle_t bus_handle;
3939

4040
spi_host_device_t host;

ext_mod/lcd_bus/esp32_src/bus_task.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "bus_task.h"
12

23
#include "freertos/FreeRTOS.h"
34
#include "freertos/task.h"

ext_mod/lcd_bus/esp32_src/i2c_bus.c

Lines changed: 80 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,15 @@
2121

2222

2323
mp_lcd_err_t i2c_del(mp_obj_t obj);
24-
mp_lcd_err_t i2c_init(mp_obj_t obj, uint16_t width, uint16_t height, uint8_t bpp, uint32_t buffer_size, bool rgb565_byte_swap, uint8_t cmd_bits, uint8_t param_bits, bool sw_rotation);
25-
mp_lcd_err_t i2c_get_lane_count(mp_obj_t obj, uint8_t *lane_count);
24+
mp_lcd_err_t i2c_init(mp_obj_t obj, uint16_t width, uint16_t height, uint8_t bpp, uint32_t buffer_size, bool rgb565_byte_swap, uint8_t cmd_bits, uint8_t param_bits, bool sw_rotate);
2625
mp_lcd_err_t i2c_tx_param(mp_obj_t obj, int lcd_cmd, void *param, size_t param_size, bool is_flush, bool last_flush_cmd);
2726

2827

2928
static bool i2c_bus_trans_done_cb(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
3029
{
3130
LCD_UNUSED(panel_io);
3231

33-
mp_lcd_spi_bus_obj_t *self = (mp_lcd_spi_bus_obj_t *)user_ctx;
32+
mp_lcd_i2c_bus_obj_t *self = (mp_lcd_i2c_bus_obj_t *)user_ctx;
3433
bus_event_set_from_isr(&self->rotation->task.swap_bufs);
3534
return false;
3635
}
@@ -40,31 +39,34 @@ static mp_lcd_err_t i2c_rotation_init_func(void *self_in)
4039
{
4140
mp_lcd_i2c_bus_obj_t *self = (mp_lcd_i2c_bus_obj_t *)self_in;
4241

43-
self->panel_io_config.on_color_trans_done = &i2c_bus_trans_done_cb;
42+
self->panel_io_config->on_color_trans_done = &i2c_bus_trans_done_cb;
4443

45-
rotation_t *rotation = self->rotation;
46-
rotation_init_err_t *init_err = &rotation->init_err;
47-
rotation_task_t *task = &rotation->task;
44+
rotation_init_err_t *init_err = &self->rotation->init_err;
4845

46+
init_err->code = i2c_param_config(self->host, self->bus_config);
47+
if (init_err->code != LCD_OK) {
48+
init_err->msg = MP_ERROR_TEXT("%d(i2c_param_config)");
49+
return init_err->code;
50+
}
4951

50-
init_err->code = i2c_param_config(self->host, &self->bus_config);
52+
init_err->code = i2c_driver_install(self->host, I2C_MODE_MASTER, 0, 0, 0);
5153
if (init_err->code != LCD_OK) {
52-
init_err->err_msg = MP_ERROR_TEXT("%d(i2c_param_config)");
53-
bus_lock_release(&task->init_lock);
54-
} else {
55-
init_err->code = i2c_driver_install(self->host, I2C_MODE_MASTER, 0, 0, 0);
56-
if (init_err->code != LCD_OK) {
57-
init_err->err_msg = MP_ERROR_TEXT("%d(i2c_driver_install)");
58-
bus_lock_release(&task->init_lock);
59-
} else {
60-
init_err->code = esp_lcd_new_panel_io_i2c(self->bus_handle , &self->panel_io_config, &self->panel_io_handle.panel_io);
61-
if (init_err->code != LCD_OK) {
62-
init_err->err_msg = MP_ERROR_TEXT("%d(esp_lcd_new_panel_io_i2c)");
63-
bus_lock_release(&task->init_lock);
64-
}
65-
}
54+
init_err->msg = MP_ERROR_TEXT("%d(i2c_driver_install)");
55+
return init_err->code;
56+
}
57+
58+
init_err->code = esp_lcd_new_panel_io_i2c(self->bus_handle , self->panel_io_config, &self->panel_io_handle.panel_io);
59+
if (init_err->code != LCD_OK) {
60+
init_err->msg = MP_ERROR_TEXT("%d(esp_lcd_new_panel_io_i2c)");
61+
return init_err->code;
6662
}
6763

64+
free(self->bus_config);
65+
self->bus_config = NULL;
66+
67+
free(self->panel_io_config);
68+
self->panel_io_config = NULL;
69+
6870
return init_err->code;
6971
}
7072

@@ -115,28 +117,29 @@ static mp_obj_t mp_lcd_i2c_bus_make_new(const mp_obj_type_t *type, size_t n_args
115117
self->base.type = &mp_lcd_i2c_bus_type;
116118

117119
self->callback = mp_const_none;
118-
120+
self->lane_count = 1;
119121
self->host = args[ARG_host].u_int;
120122
self->bus_handle = (esp_lcd_i2c_bus_handle_t)((uint32_t)self->host);
121123

122-
self->bus_config.mode = I2C_MODE_MASTER;
123-
self->bus_config.sda_io_num = (int)args[ARG_sda].u_int;
124-
self->bus_config.scl_io_num = (int)args[ARG_scl].u_int;
125-
self->bus_config.sda_pullup_en = (bool)args[ARG_sda_pullup].u_bool;
126-
self->bus_config.scl_pullup_en = (bool)args[ARG_scl_pullup].u_bool;
127-
self->bus_config.master.clk_speed = (uint32_t)args[ARG_freq].u_int;
128-
self->bus_config.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL;
129-
130-
self->panel_io_config.dev_addr = (uint32_t)args[ARG_addr].u_int;
131-
self->panel_io_config.user_ctx = self;
132-
self->panel_io_config.control_phase_bytes = (size_t)args[ARG_control_phase_bytes].u_int;
133-
self->panel_io_config.dc_bit_offset = (unsigned int)args[ARG_dc_bit_offset].u_int;
134-
self->panel_io_config.flags.dc_low_on_data = (unsigned int)args[ARG_dc_low_on_data].u_bool;
135-
self->panel_io_config.flags.disable_control_phase = (unsigned int)args[ARG_disable_control_phase].u_bool;
124+
self->bus_config = (i2c_config_t *)malloc(sizeof(i2c_config_t));
125+
self->bus_config->mode = I2C_MODE_MASTER;
126+
self->bus_config->sda_io_num = (int)args[ARG_sda].u_int;
127+
self->bus_config->scl_io_num = (int)args[ARG_scl].u_int;
128+
self->bus_config->sda_pullup_en = (bool)args[ARG_sda_pullup].u_bool;
129+
self->bus_config->scl_pullup_en = (bool)args[ARG_scl_pullup].u_bool;
130+
self->bus_config->master.clk_speed = (uint32_t)args[ARG_freq].u_int;
131+
self->bus_config->clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL;
132+
133+
self->panel_io_config = (esp_lcd_panel_io_i2c_config_t *)malloc(sizeof(esp_lcd_panel_io_i2c_config_t));
134+
self->panel_io_config->dev_addr = (uint32_t)args[ARG_addr].u_int;
135+
self->panel_io_config->user_ctx = self;
136+
self->panel_io_config->control_phase_bytes = (size_t)args[ARG_control_phase_bytes].u_int;
137+
self->panel_io_config->dc_bit_offset = (unsigned int)args[ARG_dc_bit_offset].u_int;
138+
self->panel_io_config->flags.dc_low_on_data = (unsigned int)args[ARG_dc_low_on_data].u_bool;
139+
self->panel_io_config->flags.disable_control_phase = (unsigned int)args[ARG_disable_control_phase].u_bool;
136140

137141
self->panel_io_handle.del = &i2c_del;
138142
self->panel_io_handle.init = &i2c_init;
139-
self->panel_io_handle.get_lane_count = &i2c_get_lane_count;
140143
self->panel_io_handle.tx_param = &i2c_tx_param;
141144

142145
return MP_OBJ_FROM_PTR(self);
@@ -160,7 +163,7 @@ mp_lcd_err_t i2c_del(mp_obj_t obj)
160163
}
161164

162165

163-
mp_lcd_err_t i2c_init(mp_obj_t obj, uint16_t width, uint16_t height, uint8_t bpp, uint32_t buffer_size, bool rgb565_byte_swap, uint8_t cmd_bits, uint8_t param_bits, bool sw_rotation)
166+
mp_lcd_err_t i2c_init(mp_obj_t obj, uint16_t width, uint16_t height, uint8_t bpp, uint32_t buffer_size, bool rgb565_byte_swap, uint8_t cmd_bits, uint8_t param_bits, bool sw_rotate)
164167
{
165168
mp_lcd_i2c_bus_obj_t *self = (mp_lcd_i2c_bus_obj_t *)obj;
166169

@@ -170,55 +173,64 @@ mp_lcd_err_t i2c_init(mp_obj_t obj, uint16_t width, uint16_t height, uint8_t bpp
170173
self->rgb565_byte_swap = false;
171174
}
172175

173-
self->panel_io_config.lcd_cmd_bits = (int)cmd_bits;
174-
self->panel_io_config.lcd_param_bits = (int)param_bits;
176+
self->panel_io_config->lcd_cmd_bits = (int)cmd_bits;
177+
self->panel_io_config->lcd_param_bits = (int)param_bits;
175178

176179
esp_err_t ret;
177180

178-
if (sw_rotation) {
179-
self->rotation = (rotation_t *)malloc(sizeof(rotation_t));
180-
self->rotation->init_func = &i2c_rotation_init_func;
181+
if (sw_rotate) {
182+
self->rotation = (rotation_t *)malloc(sizeof(rotation_t));
183+
self->rotation->init_func = &i2c_rotation_init_func;
181184

182-
rotation_task_start(self);
183-
ret = self->rotation->init_err.code;
185+
ret = rotation_set_buffers(self);
186+
if (ret != LCD_OK) mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("unable to allocate sw rotate fb"));
184187

185-
if (ret != LCD_OK) {
186-
mp_raise_msg_varg(&mp_type_ValueError, self->rotation->init_err.msg, self->rotation->init_err.code);
187-
}
188+
rotation_task_start(self);
189+
ret = self->rotation->init_err.code;
188190

189-
} else {
190-
self->panel_io_config.on_color_trans_done = &bus_trans_done_cb;
191-
192-
ret = i2c_param_config(self->host, &self->bus_config);
193-
if (ret != 0) {
194-
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%d(i2c_param_config)"), ret);
195-
}
196-
197-
ret = i2c_driver_install(self->host, I2C_MODE_MASTER, 0, 0, 0);
198-
if (ret != 0) {
199-
mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("%d(i2c_driver_install)"), ret);
200-
}
201-
202-
ret = esp_lcd_new_panel_io_i2c(self->bus_handle , &self->panel_io_config, &self->panel_io_handle.panel_io);
203-
if (ret != 0) {
204-
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%d(esp_lcd_new_panel_io_i2c)"), ret);
205-
}
191+
if (ret != LCD_OK) {
192+
mp_raise_msg_varg(&mp_type_ValueError, self->rotation->init_err.msg, self->rotation->init_err.code);
193+
}
194+
} else {
195+
self->panel_io_config->on_color_trans_done = &bus_trans_done_cb;
196+
197+
ret = i2c_param_config(self->host, self->bus_config);
198+
if (ret != 0) {
199+
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%d(i2c_param_config)"), ret);
200+
}
201+
202+
ret = i2c_driver_install(self->host, I2C_MODE_MASTER, 0, 0, 0);
203+
if (ret != 0) {
204+
mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("%d(i2c_driver_install)"), ret);
206205
}
207206

207+
ret = esp_lcd_new_panel_io_i2c(self->bus_handle , self->panel_io_config, &self->panel_io_handle.panel_io);
208+
if (ret != 0) {
209+
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%d(esp_lcd_new_panel_io_i2c)"), ret);
210+
}
211+
212+
free(self->bus_config);
213+
self->bus_config = NULL;
214+
215+
free(self->panel_io_config);
216+
self->panel_io_config = NULL;
217+
}
218+
208219
return ret;
209220
}
210221

222+
211223
mp_lcd_err_t i2c_tx_param(mp_obj_t obj, int lcd_cmd, void *param, size_t param_size, bool is_flush, bool last_flush_cmd)
212224
{
213-
mp_lcd_spi_bus_obj_t *self = (mp_lcd_spi_bus_obj_t *)obj;
225+
mp_lcd_i2c_bus_obj_t *self = (mp_lcd_i2c_bus_obj_t *)obj;
214226

215227
mp_lcd_err_t ret;
216228

217229
if (self->rotation == NULL || !is_flush) {
218230
LCD_UNUSED(last_flush_cmd);
219231
ret = esp_lcd_panel_io_tx_param(self->panel_io_handle.panel_io, lcd_cmd, param, param_size);
220232
} else {
221-
bus_lock_acquire(&self->rotation->task.tx_param_lock);
233+
bus_lock_acquire(&self->rotation->task.tx_param_lock, -1);
222234

223235
if (self->rotation->data.tx_param_count == 24) {
224236
bus_lock_release(&self->rotation->task.tx_param_lock);
@@ -240,14 +252,6 @@ mp_lcd_err_t i2c_tx_param(mp_obj_t obj, int lcd_cmd, void *param, size_t param_s
240252
}
241253

242254

243-
mp_lcd_err_t i2c_get_lane_count(mp_obj_t obj, uint8_t *lane_count)
244-
{
245-
LCD_UNUSED(obj);
246-
*lane_count = 1;
247-
return LCD_OK;
248-
}
249-
250-
251255
MP_DEFINE_CONST_OBJ_TYPE(
252256
mp_lcd_i2c_bus_type,
253257
MP_QSTR_I2CBus,

0 commit comments

Comments
 (0)