diff --git a/nrf5/drivers/display/lcd_ili9341_driver.c b/nrf5/drivers/display/lcd_ili9341_driver.c index bd232a34a2..5201b5d3a0 100644 --- a/nrf5/drivers/display/lcd_ili9341_driver.c +++ b/nrf5/drivers/display/lcd_ili9341_driver.c @@ -39,7 +39,7 @@ static NRF_SPI_Type * mp_instance; static void raw_write(uint8_t value) { - hal_spi_master_tx_rx(mp_instance, 1, &value, NULL); + hal_spi_master_tx_rx(mp_instance, 1, &value, NULL); } static void cmd_write(uint8_t value) @@ -64,165 +64,193 @@ static void data_write(uint8_t value) void driver_ili9341_init(NRF_SPI_Type * p_instance, pin_obj_t * p_cs_pin, pin_obj_t * p_dc_pin) { - mp_instance = p_instance; - mp_cs_pin = p_cs_pin; - mp_dc_pin = p_dc_pin; + mp_instance = p_instance; + mp_cs_pin = p_cs_pin; + mp_dc_pin = p_dc_pin; +#if 0 + mp_hal_pin_high(enable_pin); + mp_hal_pin_high(backlight_pin); +#endif - // mp_hal_pin_high(enable_pin); - // mp_hal_pin_high(backlight_pin); - mp_hal_pin_high(mp_cs_pin); - mp_hal_pin_high(mp_dc_pin); + mp_hal_pin_high(mp_cs_pin); + mp_hal_pin_high(mp_dc_pin); - // Read driver id + // Read driver id - mp_hal_delay_ms(500); + mp_hal_delay_ms(500); - cmd_write(0x01); + cmd_write(0x01); - mp_hal_delay_ms(200); + mp_hal_delay_ms(200); - cmd_write(0xCF); - data_write(0x00); - data_write(0x8B); - data_write(0X30); + cmd_write(0xCF); + data_write(0x00); + data_write(0x8B); + data_write(0X30); - cmd_write(0xED); - data_write(0x67); - data_write(0x03); - data_write(0X12); - data_write(0X81); + cmd_write(0xED); + data_write(0x67); + data_write(0x03); + data_write(0X12); + data_write(0X81); - cmd_write(0xE8); - data_write(0x85); - data_write(0x10); - data_write(0x7A); + cmd_write(0xE8); + data_write(0x85); + data_write(0x10); + data_write(0x7A); - cmd_write(0xCB); - data_write(0x39); - data_write(0x2C); - data_write(0x00); - data_write(0x34); - data_write(0x02); + cmd_write(0xCB); + data_write(0x39); + data_write(0x2C); + data_write(0x00); + data_write(0x34); + data_write(0x02); - cmd_write(0xF7); - data_write(0x20); + cmd_write(0xF7); + data_write(0x20); - cmd_write(0xEA); - data_write(0x00); - data_write(0x00); + cmd_write(0xEA); + data_write(0x00); + data_write(0x00); - cmd_write(0xC0); /* Power control */ - data_write(0x1B); /* VRH[5:0] */ + cmd_write(0xC0); /* Power control */ + data_write(0x1B); /* VRH[5:0] */ - cmd_write(0xC1); /* Power control */ - data_write(0x10); /* SAP[2:0];BT[3:0] */ + cmd_write(0xC1); /* Power control */ + data_write(0x10); /* SAP[2:0];BT[3:0] */ - cmd_write(0xC5); /* VCM control */ - data_write(0x3F); - data_write(0x3C); + cmd_write(0xC5); /* VCM control */ + data_write(0x3F); + data_write(0x3C); - cmd_write(0xC7); /* VCM control2 */ - data_write(0XB7); + cmd_write(0xC7); /* VCM control2 */ + data_write(0XB7); - cmd_write(0x36); /* Memory Access Control */ - data_write(0x08); + cmd_write(0x36); /* Memory Access Control */ + data_write(0x08); - cmd_write(0x3A); - data_write(0x55); + cmd_write(0x3A); + data_write(0x55); - cmd_write(0xB1); - data_write(0x00); - data_write(0x1B); + cmd_write(0xB1); + data_write(0x00); + data_write(0x1B); - cmd_write(0xB6); /* Display Function Control */ - data_write(0x0A); - data_write(0xA2); + cmd_write(0xB6); /* Display Function Control */ + data_write(0x0A); + data_write(0xA2); - cmd_write(0xF2); /* 3Gamma Function Disable */ - data_write(0x00); + cmd_write(0xF2); /* 3Gamma Function Disable */ + data_write(0x00); - cmd_write(0x26); /* Gamma curve selected */ - data_write(0x01); + cmd_write(0x26); /* Gamma curve selected */ + data_write(0x01); - cmd_write(0xE0); /* Set Gamma */ - data_write(0x0F); - data_write(0x2A); - data_write(0x28); - data_write(0x08); - data_write(0x0E); - data_write(0x08); - data_write(0x54); - data_write(0XA9); - data_write(0x43); - data_write(0x0A); - data_write(0x0F); - data_write(0x00); - data_write(0x00); - data_write(0x00); - data_write(0x00); + cmd_write(0xE0); /* Set Gamma */ + data_write(0x0F); + data_write(0x2A); + data_write(0x28); + data_write(0x08); + data_write(0x0E); + data_write(0x08); + data_write(0x54); + data_write(0XA9); + data_write(0x43); + data_write(0x0A); + data_write(0x0F); + data_write(0x00); + data_write(0x00); + data_write(0x00); + data_write(0x00); - cmd_write(0XE1); /* Set Gamma */ - data_write(0x00); - data_write(0x15); - data_write(0x17); - data_write(0x07); - data_write(0x11); - data_write(0x06); - data_write(0x2B); - data_write(0x56); - data_write(0x3C); - data_write(0x05); - data_write(0x10); - data_write(0x0F); - data_write(0x3F); - data_write(0x3F); - data_write(0x0F); + cmd_write(0XE1); /* Set Gamma */ + data_write(0x00); + data_write(0x15); + data_write(0x17); + data_write(0x07); + data_write(0x11); + data_write(0x06); + data_write(0x2B); + data_write(0x56); + data_write(0x3C); + data_write(0x05); + data_write(0x10); + data_write(0x0F); + data_write(0x3F); + data_write(0x3F); + data_write(0x0F); - cmd_write(0x11); /* Exit Sleep */ + cmd_write(0x11); /* Exit Sleep */ - mp_hal_delay_ms(120); + mp_hal_delay_ms(120); - cmd_write(0x29); /* Display on */ + cmd_write(0x29); /* Display on */ } static void set_col(uint16_t start_col, uint16_t end_col) { - cmd_write(0x2A); /* Column Command address */ - data_write(start_col >> 8); - data_write(start_col & 0xFF ); - data_write(end_col >> 8); - data_write(end_col & 0xFF); + cmd_write(0x2A); /* Column Command address */ + data_write(start_col >> 8); + data_write(start_col & 0xFF ); + data_write(end_col >> 8); + data_write(end_col & 0xFF); } static void set_page(uint16_t start_page, uint16_t end_page) { - cmd_write(0x2B); /* Column Command address */ - data_write(start_page >> 8); - data_write(start_page & 0xFF); - data_write(end_page >> 8); - data_write(end_page & 0xFF); + cmd_write(0x2B); /* Column Command address */ + data_write(start_page >> 8); + data_write(start_page & 0xFF); + data_write(end_page >> 8); + data_write(end_page & 0xFF); } void driver_ili9341_clear(uint16_t color) { - set_col(0, 239); - set_page(0, 319); + set_col(0, 239); + set_page(0, 319); - cmd_write(0x2c); // start writing to the display ram + cmd_write(0x2c); // start writing to the display ram mp_hal_pin_high(mp_dc_pin); mp_hal_pin_low(mp_cs_pin); - for(uint16_t i = 0; i < 38400; i++) - { - raw_write(color >> 10); - raw_write((color >> 6) & 0xFF ); - raw_write(color & 0xFF); - raw_write(0); - } + for(uint16_t i = 0; i < 38400; i++) + { + raw_write(color >> 8); + raw_write(color & 0xFF); + raw_write(color >> 8); + raw_write(color & 0xFF); + } - mp_hal_pin_high(mp_cs_pin); + mp_hal_pin_high(mp_cs_pin); +} +void driver_ili9341_update_line(uint16_t line, fb_byte_t * p_bytes, uint16_t len, bool compressed) { + set_col(0, 239); + set_page(line, line); + + cmd_write(0x2c); + + mp_hal_pin_high(mp_dc_pin); + mp_hal_pin_low(mp_cs_pin); + + if (compressed == true) { + for (uint16_t i = 0; i < len; i++) { + for (uint8_t pixel_pos = 0; pixel_pos < 8; pixel_pos++) { + uint8_t byte = (uint8_t)((uint8_t * )p_bytes)[i]; + if (((byte >> pixel_pos) & 0x1) == 0x0) { + data_write(0x00); + data_write(0x00); + } else { + data_write(0xFF); + data_write(0xFF); + } + } + } + } + + mp_hal_pin_high(mp_cs_pin); } #endif diff --git a/nrf5/drivers/display/lcd_ili9341_driver.h b/nrf5/drivers/display/lcd_ili9341_driver.h index c81592daa6..b420ae97ab 100644 --- a/nrf5/drivers/display/lcd_ili9341_driver.h +++ b/nrf5/drivers/display/lcd_ili9341_driver.h @@ -27,10 +27,15 @@ #ifndef LCD_ILI9341_DRIVER_H__ #define LCD_ILI9341_DRIVER_H__ +#include "py/mphal.h" + #include "hal_spi.h" +#include "lcd_mono_fb.h" void driver_ili9341_init(NRF_SPI_Type * p_instance, pin_obj_t * cs_pin, pin_obj_t * dc_pin); void driver_ili9341_clear(uint16_t color); +void driver_ili9341_update_line(uint16_t line, fb_byte_t * p_bytes, uint16_t len, bool compressed); + #endif // LCD_ILI9341_DRIVER_H__ diff --git a/nrf5/drivers/display/lcd_ili9341_obj.c b/nrf5/drivers/display/lcd_ili9341_obj.c index 222442d17b..0453d72096 100644 --- a/nrf5/drivers/display/lcd_ili9341_obj.c +++ b/nrf5/drivers/display/lcd_ili9341_obj.c @@ -50,6 +50,16 @@ typedef struct _lcd_ili9341_obj_t { mp_obj_framebuf_t * framebuffer; } lcd_ili9341_obj_t; +static void dirty_line_update_cb(mp_obj_framebuf_t * p_framebuffer, + uint16_t line, + fb_byte_t * p_new, + fb_byte_t * p_old) { + // the lcd does not have double buffer needs, skip it. + (void)p_old; + + driver_ili9341_update_line(line, p_new, p_framebuffer->bytes_stride, true); +} + /// \method __str__() /// Return a string describing the ILI9341 object. STATIC void lcd_ili9341_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { @@ -85,8 +95,10 @@ from machine import Pin, SPI from display import ILI9341 cs = Pin("A16", mode=Pin.OUT, pull=Pin.PULL_UP) dc = Pin("A17", mode=Pin.OUT, pull=Pin.PULL_UP) -spi = SPI(0) -d = ILI9341(320, 240, spi, cs, dc) +spi = SPI(0, baudrate=8000000) +d = ILI9341(240, 320, spi, cs, dc) +d.text("Hello World!", 32, 32) +d.show() */ STATIC mp_obj_t lcd_ili9341_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { static const mp_arg_t allowed_args[] = { @@ -144,9 +156,14 @@ STATIC mp_obj_t lcd_ili9341_make_new(const mp_obj_type_t *type, size_t n_args, s // direction arg not yet configurable mp_int_t vertical = true; - printf("Initializing framebuffer\n"); s->framebuffer = lcd_mono_fb_helper_make_new(width, height, vertical); - printf("DONE: Initializing framebuffer\n"); + + driver_ili9341_init(s->spi->pyb->spi->instance, s->pin_cs, s->pin_dc); + // Default to white background + driver_ili9341_clear(0xFFFF); + + display_clear_screen(s->framebuffer, 0x1); + return MP_OBJ_FROM_PTR(s); } @@ -156,34 +173,19 @@ STATIC mp_obj_t lcd_ili9341_make_new(const mp_obj_type_t *type, size_t n_args, s /// Fill framebuffer with the color defined as argument. STATIC mp_obj_t lcd_ili9341_fill(mp_obj_t self_in, mp_obj_t color) { lcd_ili9341_obj_t *self = MP_OBJ_TO_PTR(self_in); - (void)self; - driver_ili9341_clear(mp_obj_get_int(color)); + display_clear_screen(self->framebuffer, (uint8_t)mp_obj_get_int(color)); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(lcd_ili9341_fill_obj, lcd_ili9341_fill); -/// \method show([num_of_refresh]) +/// \method show() /// Display content in framebuffer. -/// -/// - With no argument, no refresh is done. -/// - With `num_of_refresh` given, the lines touched by previous update -/// will be refreshed the given number of times. If no lines have been -/// touched, no update will be performed. To force a refresh, call the -/// refresh() method explicitly. STATIC mp_obj_t lcd_ili9341_show(size_t n_args, const mp_obj_t *args) { lcd_ili9341_obj_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t num_of_refresh = 0; - if (n_args > 1) { - num_of_refresh = mp_obj_get_int(args[1]); - } - - driver_ili9341_init(self->spi->pyb->spi->instance, self->pin_cs, self->pin_dc); - - (void)num_of_refresh; - (void)self; + display_update(self->framebuffer, false, dirty_line_update_cb); return mp_const_none; } @@ -240,10 +242,9 @@ STATIC mp_obj_t lcd_ili9341_text(size_t n_args, const mp_obj_t *args) { if (n_args >= 4) { color = mp_obj_get_int(args[3]); } - (void)self; - (void)str; - (void)x; - (void)y; + + display_print_string(self->framebuffer, x, y, str); + (void)color; return mp_const_none;