1
1
// Copyright (c) 2024 - 2025 Kevin G. Schlosser
2
2
3
- // local includes
4
- #include "common/lcd_types.h"
5
- #include "common/modlcd_bus.h"
6
- #include "esp32/i2c_bus.h"
7
-
8
- // esp-idf includes
9
- #include "esp_lcd_panel_io.h"
10
- #include "driver/i2c.h"
11
-
12
- // micropython includes
13
- #include "mphalport.h"
14
3
#include "py/obj.h"
15
4
#include "py/runtime.h"
16
5
17
- // stdlib includes
18
- #include <string.h>
6
+ #include "esp_lcd_panel_io.h"
7
+ #include "driver/i2c.h"
19
8
20
9
10
+ #include "common/lcd_commmon_types.h"
11
+ #include "common/modlcd_bus.h"
12
+ #include "lcd_types.h"
13
+ #include "i2c_bus.h"
21
14
22
15
mp_lcd_err_t i2c_del (mp_obj_t obj );
23
16
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 );
24
- mp_lcd_err_t i2c_get_lane_count (mp_obj_t obj , uint8_t * lane_count );
25
17
26
18
27
- static uint8_t i2c_bus_count = 0 ;
28
- static mp_lcd_i2c_bus_obj_t * * i2c_bus_objs ;
19
+ static bool i2c_trans_done_cb (esp_lcd_panel_handle_t panel ,
20
+ const esp_lcd_rgb_panel_event_data_t * edata , void * user_ctx )
21
+ {
22
+ mp_lcd_i2c_bus_obj_t * self = (mp_lcd_i2c_bus_obj_t * )user_ctx ;
23
+
24
+ if (self -> trans_done == 0 ) {
25
+ if (self -> callback != mp_const_none && mp_obj_is_callable (self -> callback )) {
26
+ mp_lcd_flush_ready_cb (self -> callback );
27
+ }
28
+ self -> trans_done = 1 ;
29
+ }
30
+
31
+ return false;
32
+ }
29
33
30
34
31
- void mp_lcd_i2c_bus_deinit_all (void )
35
+ static void i2c_tx_param_cb (void * self_in , int cmd , uint8_t * params , size_t params_len )
36
+ {
37
+ esp_lcd_panel_io_tx_param (self -> panel_io_handle .panel_io , cmd , params , params_len );
38
+ }
39
+
40
+
41
+ static bool i2c_init_cb (void * self_in )
32
42
{
33
- // we need to copy the existing array to a new one so the order doesn't
34
- // get all mucked up when objects get removed.
35
- mp_lcd_i2c_bus_obj_t * objs [i2c_bus_count ];
43
+ mp_lcd_i2c_bus_obj_t * self = (mp_lcd_i2c_bus_obj_t * )self_in ;
44
+ mp_lcd_sw_rotation_init_t * init = & self -> sw_rot .init ;
45
+
46
+ init -> err = i2c_param_config (self -> host , self -> bus_config );
47
+ if (init -> err != LCD_OK ) {
48
+ init -> err_msg = MP_ERROR_TEXT ("%d(i2c_param_config)" );
49
+ return false;
50
+ }
36
51
37
- for (uint8_t i = 0 ;i < i2c_bus_count ;i ++ ) {
38
- objs [i ] = i2c_bus_objs [i ];
52
+ init -> err = i2c_driver_install (self -> host , I2C_MODE_MASTER , 0 , 0 , 0 );
53
+
54
+ if (init -> err != LCD_OK ) {
55
+ init -> err_msg = MP_ERROR_TEXT ("%d(i2c_driver_install)" );
56
+ return false;
39
57
}
40
58
41
- for (uint8_t i = 0 ;i < i2c_bus_count ;i ++ ) {
42
- i2c_del (MP_OBJ_FROM_PTR (objs [i ]));
59
+ init -> err = esp_lcd_new_panel_io_i2c (self -> bus_handle , self -> panel_io_config , & self -> panel_io_handle .panel_io );
60
+
61
+ if (init -> err != LCD_OK ) {
62
+ init -> err_msg = MP_ERROR_TEXT ("%d(esp_lcd_new_panel_io_i2c)" );
63
+ return false;
64
+ }
65
+
66
+ free (self -> panel_io_config );
67
+ free (self -> bus_config );
68
+ self -> panel_io_config = NULL ;
69
+ self -> bus_config = NULL ;
70
+
71
+ return true;
72
+ }
73
+
74
+
75
+ static void i2c_flush_cb (void * self_in , uint8_t last_update , int cmd , uint8_t * idle_fb )
76
+ {
77
+ LCD_UNUSED (last_update );
78
+ mp_lcd_i2c_bus_obj_t * self = (mp_lcd_i2c_bus_obj_t * )self_in ;
79
+ mp_lcd_sw_rotation_buffers_t * buffers = & self -> sw_rot .buffers ;
80
+
81
+
82
+ if (idle_fb == buffers -> idle ) {
83
+ buffers -> idle = buffers -> active ;
84
+ buffers -> active = idle_fb ;
85
+ }
86
+
87
+ mp_lcd_err_t ret = esp_lcd_panel_io_tx_color (self -> panel_io_handle .panel_io , cmd , idle_fb , self -> fb1 -> len );
88
+
89
+ if (ret != LCD_OK ) {
90
+ mp_printf (& mp_plat_print , "esp_lcd_panel_draw_bitmap error (%d)\n" , ret );
43
91
}
44
92
}
45
93
@@ -120,7 +168,6 @@ static mp_obj_t mp_lcd_i2c_bus_make_new(const mp_obj_type_t *type, size_t n_args
120
168
121
169
self -> panel_io_handle .del = & i2c_del ;
122
170
self -> panel_io_handle .init = & i2c_init ;
123
- self -> panel_io_handle .get_lane_count = & i2c_get_lane_count ;
124
171
125
172
return MP_OBJ_FROM_PTR (self );
126
173
}
@@ -146,86 +193,30 @@ mp_lcd_err_t i2c_del(mp_obj_t obj)
146
193
147
194
self -> panel_io_handle .panel_io = NULL ;
148
195
149
- if (self -> view1 != NULL ) {
150
- heap_caps_free (self -> view1 -> items );
151
- self -> view1 -> items = NULL ;
152
- self -> view1 -> len = 0 ;
153
- self -> view1 = NULL ;
154
- LCD_DEBUG_PRINT ("i2c_free_framebuffer(self, buf=1)\n" )
155
- }
156
-
157
- if (self -> view2 != NULL ) {
158
- heap_caps_free (self -> view2 -> items );
159
- self -> view2 -> items = NULL ;
160
- self -> view2 -> len = 0 ;
161
- self -> view2 = NULL ;
162
- LCD_DEBUG_PRINT ("i2c_free_framebuffer(self, buf=1)\n" )
163
- }
164
-
165
- uint8_t i = 0 ;
166
- for (;i < i2c_bus_count ;i ++ ) {
167
- if (i2c_bus_objs [i ] == self ) {
168
- i2c_bus_objs [i ] = NULL ;
169
- break ;
170
- }
171
- }
172
-
173
- for (uint8_t j = i + 1 ;j < i2c_bus_count ;j ++ ) {
174
- i2c_bus_objs [j - i + 1 ] = i2c_bus_objs [j ];
175
- }
176
-
177
- i2c_bus_count -- ;
178
- i2c_bus_objs = m_realloc (i2c_bus_objs , i2c_bus_count * sizeof (mp_lcd_i2c_bus_obj_t * ));
179
-
180
196
return ret ;
181
197
} else {
182
198
return LCD_FAIL ;
183
199
}
184
200
}
185
201
186
202
187
- 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 )
203
+ mp_lcd_err_t i2c_init (mp_obj_t obj , uint8_t cmd_bits , uint8_t param_bits )
188
204
{
189
205
mp_lcd_i2c_bus_obj_t * self = (mp_lcd_i2c_bus_obj_t * )obj ;
190
206
191
- if (bpp == 16 ) {
192
- self -> rgb565_byte_swap = rgb565_byte_swap ;
193
- } else {
207
+ if (self -> sw_rot .data .bytes_per_pixel == 2 ) {
194
208
self -> rgb565_byte_swap = false;
195
- }
196
-
209
+
197
210
self -> panel_io_config -> lcd_cmd_bits = (int )cmd_bits ;
198
211
self -> panel_io_config -> lcd_param_bits = (int )param_bits ;
212
+
213
+ self -> sw_rot .data .dst_width = 0 ;
214
+ self -> sw_rot .data .dst_height = 0 ;
215
+ self -> sw_rot .init .cb = & i2c_init_cb ;
216
+ self -> sw_rot .flush_cb = & i2c_flush_cb ;
217
+ self -> sw_rot .tx_params .cb = & i2c_tx_param_cb ;
199
218
200
- mp_lcd_err_t ret = i2c_param_config (self -> host , self -> bus_config );
201
- if (ret != 0 ) {
202
- mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("%d(i2c_param_config)" ), ret );
203
- return ret ;
204
- }
205
-
206
- ret = i2c_driver_install (self -> host , I2C_MODE_MASTER , 0 , 0 , 0 );
207
- if (ret != 0 ) {
208
- mp_raise_msg_varg (& mp_type_OSError , MP_ERROR_TEXT ("%d(i2c_driver_install)" ), ret );
209
- return ret ;
210
- }
211
-
212
- ret = esp_lcd_new_panel_io_i2c (self -> bus_handle , self -> panel_io_config , & self -> panel_io_handle .panel_io );
213
-
214
- if (ret != 0 ) {
215
- mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("%d(esp_lcd_new_panel_io_i2c)" ), ret );
216
- return ret ;
217
- }
218
-
219
- // add the new bus ONLY after successfull initilization of the bus
220
- i2c_bus_count ++ ;
221
- i2c_bus_objs = m_realloc (i2c_bus_objs , i2c_bus_count * sizeof (mp_lcd_i2c_bus_obj_t * ));
222
- i2c_bus_objs [i2c_bus_count - 1 ] = self ;
223
-
224
- free (self -> panel_io_config );
225
- free (self -> bus_config );
226
- self -> panel_io_config = NULL ;
227
- self -> bus_config = NULL ;
228
- return ret ;
219
+ return LCD_OK ;
229
220
}
230
221
231
222
0 commit comments