2626
2727#include <stdio.h>
2828#include <string.h>
29-
29+ #include <dfs_posix.h>
3030#include "py/mphal.h"
3131#include "py/runtime.h"
32+ #include "py/mperrno.h"
3233
3334#if MICROPY_PY_MACHINE_LCD
3435
@@ -213,6 +214,105 @@ STATIC mp_obj_t machine_lcd_show_image(size_t n_args, const mp_obj_t *args) {
213214}
214215STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (machine_lcd_show_image_obj , 6 , 6 , machine_lcd_show_image );
215216
217+ STATIC rt_uint16_t rgb888to565 (rt_uint32_t RGB )
218+ {
219+ int R , G , B ;
220+ R = (RGB >> 19 ) & 0x1F ;
221+ G = (RGB >> 10 ) & 0x3F ;
222+ B = (RGB >> 3 ) & 0x1F ;
223+ return (R << 11 ) | (G << 5 ) | B ;
224+ }
225+
226+ /// \method show_image array
227+ ///
228+ /// display the image on the lcd.
229+ /// @param x x position
230+ /// @param y y position
231+ /// @param file bmp file pathname
232+ STATIC mp_obj_t machine_lcd_show_bmp (size_t n_args , const mp_obj_t * args ) {
233+ #define BMP_INFO_SIZE 54
234+ rt_uint16_t x = mp_obj_get_int (args [1 ]);
235+ rt_uint16_t y = mp_obj_get_int (args [2 ]);
236+ const char * pathname = mp_obj_str_get_str (args [3 ]);
237+
238+ int fd , len ;
239+ fd = open (pathname , O_RDONLY , 0 );
240+ if (fd < 0 )
241+ {
242+ mp_raise_OSError (MP_EINVAL );
243+ }
244+
245+ void * bmp_info = rt_malloc (BMP_INFO_SIZE );
246+ if (bmp_info == RT_NULL )
247+ {
248+ mp_raise_OSError (MP_ENOMEM );
249+ }
250+
251+ len = read (fd , bmp_info , BMP_INFO_SIZE );
252+ if (len < 0 )
253+ {
254+ close (fd );
255+ mp_raise_OSError (MP_EINVAL );
256+ }
257+
258+ rt_uint32_t width = * (rt_uint32_t * )(bmp_info + 18 );
259+ rt_uint32_t heigth = * (rt_uint32_t * )(bmp_info + 22 );
260+ rt_uint16_t bit_count = * (rt_uint16_t * )(bmp_info + 28 );
261+
262+ if (bit_count != 32 )
263+ {
264+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError ,
265+ "bit count : %d, only support 32-bit bmp picture" , bit_count ));
266+ }
267+
268+ void * image_buf = rt_malloc (2 * width );
269+ if (image_buf == RT_NULL )
270+ {
271+ mp_raise_OSError (MP_ENOMEM );
272+ }
273+
274+ void * row_buf = rt_malloc (4 * width );
275+ if (row_buf == RT_NULL )
276+ {
277+ mp_raise_OSError (MP_ENOMEM );
278+ }
279+
280+ int image_index , row_index ;
281+ rt_uint16_t rgb565_temp ;
282+
283+ for (int i = 0 ; i < heigth ; i ++ )
284+ {
285+ image_index = 0 ;
286+ row_index = 0 ;
287+
288+ len = read (fd , row_buf , 4 * width );
289+ if (len < 0 )
290+ {
291+ close (fd );
292+ mp_raise_OSError (MP_EINVAL );
293+ }
294+
295+ while (row_index < (4 * width ))
296+ {
297+ rgb565_temp = rgb888to565 (* (rt_uint32_t * )(row_buf + row_index ));
298+ * (rt_uint8_t * )(image_buf + image_index ) = (rgb565_temp >> 8 );
299+ * (rt_uint8_t * )(image_buf + image_index + 1 ) = rgb565_temp & 0xff ;
300+
301+ row_index += 4 ;
302+ image_index += 2 ;
303+ }
304+
305+ lcd_show_image ( x , y -- , width , 1 , (const rt_uint8_t * )image_buf );
306+ }
307+
308+ close (fd );
309+ rt_free (bmp_info );
310+ rt_free (image_buf );
311+ rt_free (row_buf );
312+ return mp_const_none ;
313+ }
314+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (machine_lcd_show_bmp_obj , 4 , 4 , machine_lcd_show_bmp );
315+
216316STATIC const mp_rom_map_elem_t machine_lcd_locals_dict_table [] = {
217317 // instance methods
218318 { MP_ROM_QSTR (MP_QSTR_light ), MP_ROM_PTR (& machine_lcd_light_obj ) },
@@ -224,6 +324,7 @@ STATIC const mp_rom_map_elem_t machine_lcd_locals_dict_table[] = {
224324 { MP_ROM_QSTR (MP_QSTR_circle ), MP_ROM_PTR (& machine_lcd_circle_obj ) },
225325 { MP_ROM_QSTR (MP_QSTR_set_color ), MP_ROM_PTR (& machine_lcd_set_color_obj ) },
226326 { MP_ROM_QSTR (MP_QSTR_show_image ), MP_ROM_PTR (& machine_lcd_show_image_obj ) },
327+ { MP_ROM_QSTR (MP_QSTR_show_bmp ), MP_ROM_PTR (& machine_lcd_show_bmp_obj ) },
227328 // color
228329 { MP_ROM_QSTR (MP_QSTR_WHITE ), MP_ROM_INT (WHITE ) },
229330 { MP_ROM_QSTR (MP_QSTR_BLACK ), MP_ROM_INT (BLACK ) },
0 commit comments