Skip to content

Commit 252e617

Browse files
committed
updates RGB bus and shuffles some of the build system around
1 parent f01fa83 commit 252e617

File tree

16 files changed

+236
-123
lines changed

16 files changed

+236
-123
lines changed

api_drivers/common_api_drivers/display/rgb_display.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,18 @@ def __init__(
5050
rgb565_byte_swap=rgb565_byte_swap
5151
)
5252

53-
self._disp_drv.set_flush_wait_cb(self.__sync_cb)
53+
self.__flushing_fb_index = None
5454

55-
def __sync_cb(self, *_):
56-
self._data_bus.wait_for_sync()
57-
self._disp_drv.flush_ready()
55+
def _flush_ready_cb(self, buf_num, yield_to_task):
56+
if (
57+
self.__flushing_fb_index is None or
58+
buf_num != self.__flushing_fb_index
59+
):
60+
self._disp_drv.flush_ready()
61+
self.__flushing_fb_index = buf_num
62+
return True
63+
64+
return False
5865

5966
def _dummy_set_memory_location(self, *_, **__):
6067
return 0x00

api_drivers/common_api_drivers/display/sdl_display.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,9 @@ def set_offset(self, x, y):
266266
self._offset_x, self._offset_y = x, y
267267
self._disp_drv.set_offset(x, y)
268268

269-
def invert_colors(self, value):
269+
def invert_colors(self):
270270
pass
271271

272-
invert_colors = property(None, invert_colors)
273-
274272
def set_rotation(self, value):
275273
self._disp_drv.set_rotation(value)
276274
self._rotation = value

builder/esp32.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def build_commands(_, extra_args, __, lv_cflags, ___):
278278
f'LV_CFLAGS="{lv_cflags}"',
279279
f'LV_PORT=esp32',
280280
f'BOARD={board}',
281-
'USER_C_MODULES=../../../../../micropython.cmake'
281+
'USER_C_MODULES=../../../../../ext_mod/micropython.cmake'
282282
])
283283

284284
esp_cmd.extend(extra_args)

builder/rp2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def parse_args(extra_args, lv_cflags, board):
4141
'-C',
4242
'lib/micropython/ports/rp2',
4343
'LV_PORT=rp2',
44-
'USER_C_MODULES=../../../../micropython.cmake',
44+
'USER_C_MODULES=../../../../ext_mod/micropython.cmake',
4545
'SECOND_BUILD=0'
4646
]
4747

display_driver_framework.pyi

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
from typing import Optional, Tuple, Union, ClassVar, Callable, List
1+
from typing import Optional, Tuple, Union, ClassVar, Callable, List, Any
22
from typing import TYPE_CHECKING
33

4-
import micropython
5-
import machine
4+
if TYPE_CHECKING:
5+
import micropython # NOQA
6+
import machine # NOQA
7+
import lvgl as lv # NOQA
8+
import array # NOQA
9+
import io_expander_framework # NOQA
610

7-
import lvgl as lv # NOQA
811
import lcd_bus
912

10-
if TYPE_CHECKING:
11-
import array
12-
import io_expander_framework
1313

1414
# Constants
1515

@@ -35,32 +35,38 @@ STATE_HIGH: int = ...
3535
STATE_LOW: int = ...
3636
STATE_PWM: int = ...
3737

38+
_BufferType = Union[bytearray, memoryview, bytes, array.array]
39+
_PinType = Union[machine.Pin, int, io_expander_framework.Pin]
40+
_DatabusType = Union[lcd_bus.I80Bus, lcd_bus.I2CBus, lcd_bus.RGBBus, lcd_bus.SPIBus, lcd_bus.SDLBus]
41+
3842

3943
class DisplayDriver:
4044
_INVON: ClassVar[int] = ...
4145
_INVOFF: ClassVar[int] = ...
4246

47+
_displays: ClassVar[_DatabusType] = ...
48+
4349
display_width: int = ...
4450
display_height: int = ...
45-
_reset_pin: Optional[machine.Pin, int, io_expander_framework.Pin] = ...
51+
_reset_pin: Optional[_PinType] = ...
4652
_reset_state: int = ...
47-
_power_pin: Optional[machine.Pin, int, io_expander_framework.Pin] = ...
53+
_power_pin: Optional[_PinType] = ...
4854
_power_on_state: int = ...
49-
_backlight_pin: Optional[machine.Pin, int, io_expander_framework.Pin] = ...
55+
_backlight_pin: Optional[_PinType] = ...
5056
_backlight_on_state: int = ...
5157
_offset_x: int = ...
5258
_offset_y: int = ...
53-
_data_bus: Union[lcd_bus.I80Bus, lcd_bus.I2CBus, lcd_bus.RGBBus, lcd_bus.SPIBus, lcd_bus.SDLBus] = ...
59+
_data_bus: _DatabusType = ...
5460
_param_buf: bytearray = ...
5561
_param_mv: memoryview = ...
56-
_disp_drv: lv.display_driver_t = ...
62+
_disp_drv: lv.display_driver_t = ... # NOQA
5763
_color_byte_order: int = ...
5864
_color_space: int = ...
5965
_physical_width: int = ...
6066
_physical_height: int = ...
6167
_initilized: bool = ...
62-
_frame_buffer1: Optional[Union[bytes, bytearray, array.array, memoryview]] = ...
63-
_frame_buffer2: Optional[Union[bytes, bytearray, array.array, memoryview]] = ...
68+
_frame_buffer1: Optional[_BufferType] = ...
69+
_frame_buffer2: Optional[_BufferType] = ...
6470
_backup_set_memory_location: Optional[Callable] = ...
6571
_rotation: int = ...
6672

@@ -101,23 +107,23 @@ class DisplayDriver:
101107

102108
def __init__(
103109
self,
104-
data_bus: Union[lcd_bus.I80Bus, lcd_bus.I2CBus, lcd_bus.RGBBus, lcd_bus.SPIBus, lcd_bus.SDLBus],
110+
data_bus: _DatabusType,
105111
display_width: int,
106112
display_height: int,
107-
frame_buffer1: Optional[Union[bytes, bytearray, array.array, memoryview]] = None,
108-
frame_buffer2: Optional[Union[bytes, bytearray, array.array, memoryview]] = None,
109-
reset_pin: Optional[machine.Pin, int, io_expander_framework.Pin] = None,
113+
frame_buffer1: Optional[_BufferType] = None,
114+
frame_buffer2: Optional[_BufferType] = None,
115+
reset_pin: Optional[_PinType] = None,
110116
reset_state: int = STATE_HIGH,
111-
power_pin: Optional[machine.Pin, int, io_expander_framework.Pin] = None,
117+
power_pin: Optional[_PinType] = None,
112118
power_on_state: int = STATE_HIGH,
113-
backlight_pin: Optional[machine.Pin, int, io_expander_framework.Pin] = None,
119+
backlight_pin: Optional[_PinType] = None,
114120
backlight_on_state: int = STATE_HIGH,
115121
offset_x: int = 0,
116122
offset_y: int = 0,
117123
color_byte_order: int = BYTE_ORDER_RGB,
118-
color_space: int = lv.COLOR_FORMAT.RGB888,
124+
color_space: int = lv.COLOR_FORMAT.RGB888, # NOQA
119125
rgb565_byte_swap: bool = False
120-
):
126+
) -> object:
121127
...
122128

123129
def set_physical_resolution(self, width: int, height: int) -> None:
@@ -168,19 +174,19 @@ class DisplayDriver:
168174
def is_double_buffered(self) -> bool:
169175
...
170176

171-
def get_screen_active(self) -> lv.obj:
177+
def get_screen_active(self) -> lv.obj: # NOQA
172178
...
173179

174-
def get_screen_prev(self) -> lv.obj:
180+
def get_screen_prev(self) -> lv.obj: # NOQA
175181
...
176182

177-
def get_layer_top(self) -> lv.obj:
183+
def get_layer_top(self) -> lv.obj: # NOQA
178184
...
179185

180-
def get_layer_sys(self) -> lv.obj:
186+
def get_layer_sys(self) -> lv.obj: # NOQA
181187
...
182188

183-
def get_layer_bottom(self) -> lv.obj:
189+
def get_layer_bottom(self) -> lv.obj: # NOQA
184190
...
185191

186192
def add_event_cb(self, event_cb, filter, user_data) -> None: # NOQA
@@ -222,11 +228,9 @@ class DisplayDriver:
222228
def delete_refr_timer(self) -> None:
223229
...
224230

225-
def invert_colors(self, value: bool) -> None:
231+
def invert_colors(self) -> None:
226232
...
227233

228-
invert_colors: property = invert_colors
229-
230234
def set_default(self) -> None:
231235
...
232236

@@ -245,10 +249,10 @@ class DisplayDriver:
245249
def init(self) -> None:
246250
...
247251

248-
def set_params(self, cmd: int, params: Optional[Union[bytes, bytearray, array.array, memoryview]] = None) -> None:
252+
def set_params(self, cmd: int, params: Optional[_BufferType] = None) -> None:
249253
...
250254

251-
def get_params(self, cmd: int, params: Union[bytes, bytearray, array.array, memoryview]) -> None:
255+
def get_params(self, cmd: int, params: _BufferType) -> None:
252256
...
253257

254258
def get_power(self) -> bool:
@@ -283,7 +287,7 @@ class DisplayDriver:
283287
def _set_memory_location(self, x1: int, y1: int, x2: int, y2: int) -> int:
284288
...
285289

286-
def _flush_cb(self, disp: lv.display_driver_t, area: lv.area_t, color_p: lv.CArray) -> None:
290+
def _flush_cb(self, disp: lv.display_driver_t, area: lv.area_t, color_p: lv.CArray) -> None: # NOQA
287291
...
288292

289293
# we always register this callback no matter what. This is what tells LVGL
@@ -292,7 +296,7 @@ class DisplayDriver:
292296
# gets emptied. Everything is handeled internally in the bus driver if
293297
# using DMA and double buffer or a single buffer.
294298

295-
def _flush_ready_cb(self) -> None:
299+
def _flush_ready_cb(self, *param) -> None:
296300
...
297301

298302
def _madctl(self, colormode: int, rotations: Tuple[int, int, int, int], rotation: Optional[int] = None) -> int:

ext_mod/lcd_bus/esp32_include/rgb_bus.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
// esp-idf includes
1111
#include "esp_lcd_panel_io.h"
1212
#include "esp_lcd_panel_rgb.h"
13-
#include "freertos/FreeRTOS.h"
14-
#include "freertos/task.h"
1513

1614
// micropython includes
1715
#include "mphalport.h"
@@ -40,8 +38,6 @@
4038
uint32_t buffer_size;
4139
mp_obj_array_t *view1;
4240
mp_obj_array_t *view2;
43-
TaskHandle_t xTaskToNotify;
44-
uint8_t current_buffer_index;
4541

4642
} mp_lcd_rgb_bus_obj_t;
4743

ext_mod/lcd_bus/esp32_src/rgb_bus.c

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -49,30 +49,62 @@
4949
uint8_t bb_fb_index; // Current frame buffer index which used by bounce buffer
5050
} rgb_panel_t;
5151

52+
bool callback_from_isr(mp_obj_t cb, uint8_t buf_num)
53+
{
54+
volatile uint32_t sp = (uint32_t)esp_cpu_get_sp();
55+
bool ret = false;
56+
57+
// Calling micropython from ISR
58+
// See: https://github.com/micropython/micropython/issues/4895
59+
void *old_state = mp_thread_get_state();
60+
61+
mp_state_thread_t ts; // local thread state for the ISR
62+
mp_thread_set_state(&ts);
63+
mp_stack_set_top((void*)sp); // need to include in root-pointer scan
64+
mp_stack_set_limit(CONFIG_FREERTOS_IDLE_TASK_STACKSIZE - 1024); // tune based on ISR thread stack size
65+
mp_locals_set(mp_state_ctx.thread.dict_locals); // use main thread's locals
66+
mp_globals_set(mp_state_ctx.thread.dict_globals); // use main thread's globals
67+
68+
mp_sched_lock(); // prevent VM from switching to another MicroPython thread
69+
gc_lock(); // prevent memory allocation
70+
71+
nlr_buf_t nlr;
72+
if (nlr_push(&nlr) == 0) {
73+
mp_obj_t args[1] = { mp_obj_new_int_from_uint(buf_num) };
74+
mp_obj_t ret_val = mp_call_function_n_kw(cb, 1, 0, &args[0]);
75+
if ((ret_val != mp_const_none) && mp_obj_is_integer(ret_val) && (mp_obj_get_int_truncated(ret_val) == 1)) {
76+
ret = true;
77+
}
78+
nlr_pop();
79+
} else {
80+
ets_printf("Uncaught exception in IRQ callback handler!\n");
81+
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); // changed to &mp_plat_print to fit this context
82+
}
83+
84+
gc_unlock();
85+
mp_sched_unlock();
86+
87+
mp_thread_set_state(old_state);
88+
// mp_hal_wake_main_task_from_isr();
89+
90+
return ret;
91+
}
92+
5293

5394
IRAM_ATTR static bool rgb_bus_trans_done_cb(esp_lcd_panel_handle_t panel, const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx)
5495
{
55-
LCD_UNUSED(panel);
5696
LCD_UNUSED(edata);
97+
rgb_panel_t *rgb_panel = __containerof(panel, rgb_panel_t, base);
5798

5899
mp_lcd_rgb_bus_obj_t *self = (mp_lcd_rgb_bus_obj_t *)user_ctx;
59-
BaseType_t need_yield = pdFALSE;
60-
61-
// Notify that the current RGB frame buffer has been transmitted
62-
vTaskNotifyGiveIndexedFromISR(self->xTaskToNotify, 7, &need_yield);
63-
return (need_yield == pdTRUE);
64-
}
100+
bool ret = false;
65101

66-
mp_obj_t mp_lcd_bus_wait_for_sync(mp_obj_t obj)
67-
{
68-
mp_lcd_rgb_bus_obj_t *self = (mp_lcd_rgb_bus_obj_t *)obj;
69-
ulTaskNotifyValueClearIndexed(self->xTaskToNotify, 7, ULONG_MAX);
70-
ulTaskNotifyTakeIndexed(7, pdTRUE, portMAX_DELAY);
71-
return mp_const_none;
102+
if (self->callback != mp_const_none && mp_obj_is_callable(self->callback)) {
103+
ret = callback_from_isr(self->callback, (uint8_t)rgb_panel->cur_fb_index);
104+
}
105+
return ret;
72106
}
73107

74-
MP_DEFINE_CONST_FUN_OBJ_1(mp_lcd_bus_wait_for_sync_obj, mp_lcd_bus_wait_for_sync);
75-
76108
esp_lcd_rgb_panel_event_callbacks_t callbacks = { .on_vsync = rgb_bus_trans_done_cb };
77109

78110
mp_lcd_err_t rgb_del(mp_obj_t obj);
@@ -170,7 +202,6 @@
170202
self->base.type = &mp_lcd_rgb_bus_type;
171203

172204
self->callback = mp_const_none;
173-
self->xTaskToNotify = xTaskGetCurrentTaskHandle();
174205

175206
self->bus_config.pclk_hz = (uint32_t)args[ARG_freq].u_int;
176207
self->bus_config.hsync_pulse_width = (uint32_t)args[ARG_hsync_pulse_width].u_int;
@@ -458,12 +489,6 @@
458489
{
459490
mp_lcd_rgb_bus_obj_t *self = (mp_lcd_rgb_bus_obj_t *)obj;
460491

461-
if (self->view1->items == color) {
462-
self->current_buffer_index = 0;
463-
} else {
464-
self->current_buffer_index = 1;
465-
}
466-
467492
esp_err_t ret = esp_lcd_panel_draw_bitmap(
468493
self->panel_handle,
469494
x_start,
@@ -482,28 +507,12 @@
482507
}
483508

484509

485-
STATIC const mp_rom_map_elem_t mp_lcd_rgb_bus_locals_dict_table[] = {
486-
{ MP_ROM_QSTR(MP_QSTR_wait_for_sync), MP_ROM_PTR(&mp_lcd_bus_wait_for_sync_obj) },
487-
{ MP_ROM_QSTR(MP_QSTR_get_lane_count), MP_ROM_PTR(&mp_lcd_bus_get_lane_count_obj) },
488-
{ MP_ROM_QSTR(MP_QSTR_allocate_framebuffer), MP_ROM_PTR(&mp_lcd_bus_allocate_framebuffer_obj) },
489-
{ MP_ROM_QSTR(MP_QSTR_free_framebuffer), MP_ROM_PTR(&mp_lcd_bus_free_framebuffer_obj) },
490-
{ MP_ROM_QSTR(MP_QSTR_register_callback), MP_ROM_PTR(&mp_lcd_bus_register_callback_obj) },
491-
{ MP_ROM_QSTR(MP_QSTR_tx_param), MP_ROM_PTR(&mp_lcd_bus_tx_param_obj) },
492-
{ MP_ROM_QSTR(MP_QSTR_tx_color), MP_ROM_PTR(&mp_lcd_bus_tx_color_obj) },
493-
{ MP_ROM_QSTR(MP_QSTR_rx_param), MP_ROM_PTR(&mp_lcd_bus_rx_param_obj) },
494-
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&mp_lcd_bus_init_obj) },
495-
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mp_lcd_bus_deinit_obj) },
496-
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_lcd_bus_deinit_obj) }
497-
};
498-
499-
MP_DEFINE_CONST_DICT(mp_lcd_rgb_bus_locals_dict, mp_lcd_rgb_bus_locals_dict_table);
500-
501510
MP_DEFINE_CONST_OBJ_TYPE(
502511
mp_lcd_rgb_bus_type,
503512
MP_QSTR_RGBBus,
504513
MP_TYPE_FLAG_NONE,
505514
make_new, mp_lcd_rgb_bus_make_new,
506-
locals_dict, (mp_obj_dict_t *)&mp_lcd_rgb_bus_locals_dict
515+
locals_dict, (mp_obj_dict_t *)&mp_lcd_bus_locals_dict
507516
);
508517
#else
509518
#include "../common_src/rgb_bus.c"

0 commit comments

Comments
 (0)