nrf5/drivers: Updating a working version of ili9341 module and driver. About 10 times faster than python implementation to update a full screen.
This commit is contained in:
parent
f92e581e13
commit
67683722c8
@ -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
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user