123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- #include <stdio.h>
- #include <string.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "driver/gpio.h"
- #include <esp_heap_caps.h>
- #include <esp_log.h>
- #include "gds.h"
- #include "gds_private.h"
- #define PAGE_BLOCK 1024
- #define min(a,b) (((a) < (b)) ? (a) : (b))
- static char TAG[] = "ILI9341";
- #define L1_CMD_NOP 0X00
- #define L1_CMD_SOFTWARE_RESET 0X01
- #define L1_CMD_READ_DISPLAY_IDENTIFICATION_INFORMATION 0X04
- #define L1_CMD_READ_DISPLAY_STATUS 0X09
- #define L1_CMD_READ_DISPLAY_POWER_MODE 0X0A
- #define L1_CMD_READ_DISPLAY_MADCTL 0X0B
- #define L1_CMD_READ_DISPLAY_PIXEL_FORMAT 0X0C
- #define L1_CMD_READ_DISPLAY_IMAGE_FORMAT 0X0D
- #define L1_CMD_READ_DISPLAY_SIGNAL_MODE 0X0E
- #define L1_CMD_READ_DISPLAY_SELF_DIAGNOSTIC_RESULT 0X0F
- #define L1_CMD_ENTER_SLEEP_MODE 0X10
- #define L1_CMD_SLEEP_OUT 0X11
- #define L1_CMD_PARTIAL_MODE_ON 0X12
- #define L1_CMD_NORMAL_DISPLAY_MODE_ON 0X13
- #define L1_CMD_DISPLAY_INVERSION_OFF 0X20
- #define L1_CMD_DISPLAY_INVERSION_ON 0X21
- #define L1_CMD_GAMMA_SET 0X26
- #define L1_CMD_DISPLAY_OFF 0X28
- #define L1_CMD_DISPLAY_ON 0X29
- #define L1_CMD_COLUMN_ADDRESS_SET 0X2A
- #define L1_CMD_PAGE_ADDRESS_SET 0X2B
- #define L1_CMD_MEMORY_WRITE 0X2C
- #define L1_CMD_COLOR_SET 0X2D
- #define L1_CMD_MEMORY_READ 0X2E
- #define L1_CMD_PARTIAL_AREA 0X30
- #define L1_CMD_VERTICAL_SCROLLING_DEFINITION 0X33
- #define L1_CMD_TEARING_EFFECT_LINE_OFF 0X34
- #define L1_CMD_TEARING_EFFECT_LINE_ON 0X35
- #define L1_CMD_MEMORY_ACCESS_CONTROL 0X36
- #define L1_CMD_VERTICAL_SCROLLING_START_ADDRESS 0X37
- #define L1_CMD_IDLE_MODE_OFF 0X38
- #define L1_CMD_IDLE_MODE_ON 0X39
- #define L1_CMD_COLMOD_PIXEL_FORMAT_SET 0X3A
- #define L1_CMD_WRITE_MEMORY_CONTINUE 0X3C
- #define L1_CMD_READ_MEMORY_CONTINUE 0X3E
- #define L1_CMD_SET_TEAR_SCANLINE 0X44
- #define L1_CMD_GET_SCANLINE 0X45
- #define L1_CMD_WRITE_DISPLAY_BRIGHTNESS 0X51
- #define L1_CMD_READ_DISPLAY_BRIGHTNESS 0X52
- #define L1_CMD_WRITE_CTRL_DISPLAY 0X53
- #define L1_CMD_READ_CTRL_DISPLAY 0X54
- #define L1_CMD_WRITE_CONTENT_ADAPTIVE_BRIGHTNESS_CONTROL 0X55
- #define L1_CMD_READ_CONTENT_ADAPTIVE_BRIGHTNESS_CONTROL 0X56
- #define L1_CMD_WRITE_CABC_MINIMUM_BRIGHTNESS 0X5E
- #define L1_CMD_READ_CABC_MINIMUM_BRIGHTNESS 0X5F
- #define L1_CMD_READ_ID1 0XDA
- #define L1_CMD_READ_ID2 0XDB
- #define L1_CMD_READ_ID3 0XDC
- #define L2_CMD_RGB_INTERFACE_SIGNAL_CONTROL 0XB0
- #define L2_CMD_FRAME_RATE_CONTROL_IN_NORMAL_MODE_FULL_COLORS 0XB1
- #define L2_CMD_FRAME_RATE_CONTROL_IN_IDLE_MODE_8_COLORS 0XB2
- #define L2_CMD_FRAME_RATE_CONTROL_IN_PARTIAL_MODE_FULL_COLORS 0XB3
- #define L2_CMD_DISPLAY_INVERSION_CONTROL 0XB4
- #define L2_CMD_BLANKING_PORCH_CONTROL 0XB5
- #define L2_CMD_DISPLAY_FUNCTION_CONTROL 0XB6
- #define L2_CMD_ENTRY_MODE_SET 0XB7
- #define L2_CMD_BACKLIGHT_CONTROL_1 0XB8
- #define L2_CMD_BACKLIGHT_CONTROL_2 0XB9
- #define L2_CMD_BACKLIGHT_CONTROL_3 0XBA
- #define L2_CMD_BACKLIGHT_CONTROL_4 0XBB
- #define L2_CMD_BACKLIGHT_CONTROL_5 0XBC
- #define L2_CMD_BACKLIGHT_CONTROL_7 0XBE
- #define L2_CMD_BACKLIGHT_CONTROL_8 0XBF
- #define L2_CMD_POWER_CONTROL_1 0XC0
- #define L2_CMD_POWER_CONTROL_2 0XC1
- #define L2_CMD_VCOM_CONTROL_1 0XC5
- #define L2_CMD_VCOM_CONTROL_2 0XC7
- #define L2_CMD_NV_MEMORY_WRITE 0XD0
- #define L2_CMD_NV_MEMORY_PROTECTION_KEY 0XD1
- #define L2_CMD_NV_MEMORY_STATUS_READ 0XD2
- #define L2_CMD_READ_ID4 0XD3
- #define L2_CMD_POSITIVE_GAMMA_CORRECTION 0XE0
- #define L2_CMD_NEGATIVE_GAMMA_CORRECTION 0XE1
- #define L2_CMD_DIGITAL_GAMMA_CONTROL_1 0XE2
- #define L2_CMD_DIGITAL_GAMMA_CONTROL_2 0XE3
- #define L2_CMD_INTERFACE_CONTROL 0XF6
- typedef struct {
- uint8_t cmd;
- uint8_t data[16];
- uint8_t databytes;
- } lcd_init_cmd_t;
- static const lcd_init_cmd_t ili_init_cmds[]={
-
- {0xCF, {0x00, 0x83, 0X30}, 3},
-
- {0xED, {0x64, 0x03, 0X12, 0X81}, 4},
-
- {0xE8, {0x85, 0x01, 0x79}, 3},
-
- {0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5},
-
- {0xF7, {0x20}, 1},
-
- {0xEA, {0x00, 0x00}, 2},
-
- {0xC0, {0x26}, 1},
-
- {0xC1, {0x11}, 1},
-
- {0xC5, {0x35, 0x3E}, 2},
-
- {0xC7, {0xBE}, 1},
-
- {0x36, {0x28}, 1},
-
- {0x3A, {0x55}, 1},
-
- {0xB1, {0x00, 0x1B}, 2},
-
- {0xF2, {0x08}, 1},
-
- {0x26, {0x01}, 1},
-
- {0xE0, {0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0X87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00}, 15},
-
- {0XE1, {0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F}, 15},
-
- {0x2A, {0x00, 0x00, 0x00, 0xEF}, 4},
-
- {0x2B, {0x00, 0x00, 0x01, 0x3f}, 4},
-
- {0x2C, {0}, 0},
-
- {0xB7, {0x07}, 1},
-
- {0xB6, {0x0A, 0x82, 0x27, 0x00}, 4},
-
- {0x11, {0}, 0x80},
-
- {0x29, {0}, 0x80},
- {0, {0}, 0xff},
- };
- #define PARALLEL_LINES 16
- struct PrivateSpace {
- uint8_t *iRAM, *Shadowbuffer;
- uint8_t ReMap, PageSize;
- uint8_t Offset;
- };
- static void WriteDataByte( struct GDS_Device* Device, uint8_t Data ) {
- Device->WriteData( Device, &Data, 1);
- }
- static void SetColumnAddress( struct GDS_Device* Device, uint8_t Start, uint8_t End ) {
- Device->WriteCommand( Device, L1_CMD_COLUMN_ADDRESS_SET );
- Device->WriteData( Device, &Start, 1 );
- Device->WriteData( Device, &End, 1 );
- }
- static void SetRowAddress( struct GDS_Device* Device, uint8_t Start, uint8_t End ) {
- Device->WriteCommand( Device, L1_CMD_PAGE_ADDRESS_SET );
- Device->WriteData( Device, &Start, 1 );
- Device->WriteData( Device, &End, 1 );
- }
- static void Update( struct GDS_Device* Device ) {
- struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
-
-
- SetColumnAddress( Device, Private->Offset, Private->Offset + Device->Width - 1);
-
- #ifdef SHADOW_BUFFER
- uint16_t *optr = (uint16_t*) Private->Shadowbuffer, *iptr = (uint16_t*) Device->Framebuffer;
- bool dirty = false;
-
- for (int r = 0, page = 0; r < Device->Height; r++) {
-
- for (int c = Device->Width / 2 / 2; --c >= 0;) {
- if (*optr != *iptr) {
- dirty = true;
- *optr = *iptr;
- }
- iptr++; optr++;
- }
-
-
- if (++page == Private->PageSize) {
- if (dirty) {
- uint16_t *optr = (uint16_t*) Private->iRAM, *iptr = (uint16_t*) (Private->Shadowbuffer + (r - page + 1) * Device->Width / 2);
- SetRowAddress( Device, r - page + 1, r );
- for (int i = page * Device->Width / 2 / 2; --i >= 0; iptr++) *optr++ = (*iptr >> 8) | (*iptr << 8);
-
- Device->WriteCommand( Device, 0x5c );
- Device->WriteData( Device, Private->iRAM, Device->Width * page / 2 );
- dirty = false;
- }
- page = 0;
- }
- }
- #else
- for (int r = 0; r < Device->Height; r += Private->PageSize) {
- SetRowAddress( Device, r, r + Private->PageSize - 1 );
- Device->WriteCommand( Device, L1_CMD_MEMORY_WRITE );
- if (Private->iRAM) {
- uint16_t *optr = (uint16_t*) Private->iRAM, *iptr = (uint16_t*) (Device->Framebuffer + r * Device->Width / 2);
- for (int i = Private->PageSize * Device->Width / 2 / 2; --i >= 0; iptr++) *optr++ = (*iptr >> 8) | (*iptr << 8);
-
- Device->WriteData( Device, Private->iRAM, Private->PageSize * Device->Width / 2 );
- } else {
- Device->WriteData( Device, Device->Framebuffer + r * Device->Width / 2, Private->PageSize * Device->Width / 2 );
- }
- }
- #endif
- }
- typedef enum {
- MAC_BIT_MH=2,
- MAC_BIT_BGR,
- MAC_BIT_ML,
- MAC_BIT_MV,
- MAC_BIT_MX,
- MAC_BIT_MY,
- } mac_bits;
- uint16_t set_mac_bit(mac_bits bit, uint16_t val){
- return (1 << bit) | val;
- }
- uint16_t unset_mac_bit(mac_bits bit, uint16_t val){
- return ~(1 << bit) & val;
- }
- static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) {
- struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
- Private->ReMap = HFlip ? (Private->ReMap & ~(1 << MAC_BIT_MX)) : (Private->ReMap | (1 << MAC_BIT_MX));
- Private->ReMap = VFlip ? (Private->ReMap | (1 << MAC_BIT_MY)) : (Private->ReMap & ~(1 << MAC_BIT_MY));
- Device->WriteCommand( Device, L1_CMD_MEMORY_ACCESS_CONTROL );
- Device->WriteData( Device, &Private->ReMap, 1 );
- WriteDataByte(Device,0x00);
- }
- static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, L1_CMD_DISPLAY_ON ); }
- static void DisplayOff( struct GDS_Device* Device ) { Device->WriteCommand( Device, L1_CMD_DISPLAY_OFF ); }
- static void SetContrast( struct GDS_Device* Device, uint8_t Contrast ) {
- Device->WriteCommand( Device, L1_CMD_WRITE_DISPLAY_BRIGHTNESS );
- uint8_t loc_contrast = (uint8_t)((float)Contrast/5.0f* 255.0f);
- Device->WriteData( Device, &loc_contrast , 1 );
- WriteDataByte(Device,0x00);
- }
- static bool Init( struct GDS_Device* Device ) {
- struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
-
-
-
- Private->PageSize = min(8, PAGE_BLOCK / (Device->Width / 2));
- Private->PageSize = Device->Height / (Device->Height / Private->PageSize) ;
-
- #ifdef SHADOW_BUFFER
- #endif
- Private->iRAM =NULL;
-
-
- ESP_LOGI(TAG, "ILI9341 ");
-
- Device->DisplayOff( Device );
- int cmd=0;
-
- while (ili_init_cmds[cmd].databytes!=0xff) {
- Device->WriteCommand( Device, ili_init_cmds[cmd].cmd );
- Device->WriteData(Device,ili_init_cmds[cmd].data,ili_init_cmds[cmd].databytes&0x1F);
- if (ili_init_cmds[cmd].databytes&0x80) {
- vTaskDelay(100 / portTICK_RATE_MS);
- }
- cmd++;
- }
-
-
- Device->DisplayOn( Device );
- Device->Update( Device );
-
- return true;
- }
- static const struct GDS_Device ILI9341 = {
- .DisplayOn = DisplayOn, .DisplayOff = DisplayOff, .SetContrast = SetContrast,
- .SetLayout = SetLayout,
- .Update = Update, .Init = Init,
- };
- struct GDS_Device* ILI9341_Detect(char *Driver, struct GDS_Device* Device) {
- if (!strcasestr(Driver, "ILI9341")) return NULL;
-
- if (!Device) Device = calloc(1, sizeof(struct GDS_Device));
-
- *Device = ILI9341;
- Device->Depth = 4;
-
- return Device;
- }
|