From 6d48d0a10391958123145879aad43cb8d9f7e667 Mon Sep 17 00:00:00 2001 From: impressionyang Date: Tue, 11 Jul 2023 08:53:18 +0000 Subject: [PATCH] add lvgl2oled_iic.c. Signed-off-by: impressionyang --- lvgl2oled_iic.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 lvgl2oled_iic.c diff --git a/lvgl2oled_iic.c b/lvgl2oled_iic.c new file mode 100644 index 0000000..b4e4794 --- /dev/null +++ b/lvgl2oled_iic.c @@ -0,0 +1,143 @@ +#if OLED_IIC_USE_PER_PIXEL_BYTE_FOR_LVGL +static uint8_t screen_data[64][128] = {0}; +static uint8_t screen_data_line[129] = {0}; + +static void merge_lvgl_data(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, const uint8_t BMP[]) +{ + int i = 0, j = 0, bmp_pixel_idx = 0; + uint8_t temp = 0; + for (i = y0; i <= y1; i++) { + for (j = x0; j <= x1; j++) { + temp = BMP[bmp_pixel_idx]; + screen_data[i][j] = temp; + bmp_pixel_idx++; + } + } +} + +static uint8_t tranform_lvgl_line_data_to_oled_data(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) +{ +// if (x0 == x1 || y0 == y1) +// { +//// rt_kprintf("transform a empty %d %d %d %d\r\n", x0, y0, x1, y1); +//// return 0; +// } + + screen_data_line[0] = OLED_I2C_DATA; + + uint8_t data_byte = 0, i = 0, frame_index = 0, temp = 0; + frame_index = 1; + for (i = x0; i <= x1; i++) + { + data_byte = 0; + temp = screen_data[y0 + 0][i] == 0 ? 0 : 1; + data_byte |= temp << 0; + + temp = screen_data[y0 + 1][i] == 0 ? 0 : 1; + data_byte |= temp << 1; + + temp = screen_data[y0 + 2][i] == 0 ? 0 : 1; + data_byte |= temp << 2; + + temp = screen_data[y0 + 3][i] == 0 ? 0 : 1; + data_byte |= temp << 3; + + temp = screen_data[y0 + 4][i] == 0 ? 0 : 1; + data_byte |= temp << 4; + + temp = screen_data[y0 + 5][i] == 0 ? 0 : 1; + data_byte |= temp << 5; + + temp = screen_data[y0 + 6][i] == 0 ? 0 : 1; + data_byte |= temp << 6; + + temp = screen_data[y0 + 7][i] == 0 ? 0 : 1; + data_byte |= temp << 7; + + screen_data_line[frame_index++] = data_byte; + } + + return frame_index; +} + +static void flush_lvgl_data(i2c_oled_t *handle, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) +{ + uint8_t y_cut_upper = 0; + uint8_t y_cut = 0; + uint8_t y_cut_down_lines = 0; + uint8_t y_cut_down = 0; + uint8_t transform_len = 0; + uint8_t i = 0; + if (y0 == 0) { + y_cut = 0; + y_cut_upper = 0; + }else if (( (y0 + 1) % 8 ) == 0 ) { + y_cut_upper = y0; + y_cut = y0; + }else { + y_cut = ((( (y0 + 1) / 8) + 1 ) * 8); + y_cut_upper = ((y_cut / 8) - 1 ) * 8 - 1; + y_cut -= 1; + } + + if (y1 == y0 ) { + y_cut_down == y_cut; + }else if (((y1 + 1) % 8) == 0) { + y_cut_down = y1; + }else { + y_cut_down = (((y1 + 1) / 8) + 1) * 8 - 1; + } + y_cut_down_lines = (y_cut_down - y_cut) / 8; + + if (y_cut != y0) { + // flush ycut upper + transform_len = tranform_lvgl_line_data_to_oled_data(x0, y_cut_upper, x1, y_cut); + OledSetPosition(handle, x0, (y_cut_upper + 1) / 8); + handle->i2c_write_func(OLED_I2C_ADDR, screen_data_line, transform_len); + } + + for (i = 0; i < y_cut_down_lines; i++) { + transform_len = tranform_lvgl_line_data_to_oled_data(x0, y_cut + (i * 8), x1, y_cut + ((i + 1) * 8)); + OledSetPosition(handle, x0, (y_cut + (i * 8) + 1) / 8); + + handle->i2c_write_func(OLED_I2C_ADDR, screen_data_line, transform_len); + } +} + +void OledDrawLVGL(i2c_oled_t *handle, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, const uint8_t BMP[]) +{ + if (x1 > 127) + { + x1 = 127; + } + if (y1 > 63) + { + y1 = 63; + } +// rt_kprintf("finish a loop %d %d %d %d\r\n", x0, y0, x1, y1); + merge_lvgl_data(x0, y0, x1, y1, BMP); + flush_lvgl_data(handle, x0, y0, x1, y1); +} + +static int finsh_print_screen(int argc, char *argv[]) +{ + uint8_t i = 0, j = 0, temp = 0; + rt_kprintf("\r\n"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 128; j++) { + temp = screen_data[i][j]; + if (temp) { + rt_kprintf("%c", ' '); + }else{ + rt_kprintf("%c", '*'); + } + } + rt_kprintf("\n"); + } + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(finsh_print_screen, print iic screen data); + +#endif \ No newline at end of file