From 92ed93affbfc14160aeb287c011522c41f811a90 Mon Sep 17 00:00:00 2001 From: Ilya Kurdyukov <59548320+ilyakurdyukov@users.noreply.github.com> Date: Mon, 2 Sep 2024 17:11:47 +0700 Subject: [PATCH] support for Olmio A25 --- README.md | 3 +- fpdoom/entry.c | 11 +++---- fpdoom/lcd_config.h | 63 ++++++++++++++++++++++++++++++++++++++++ fpdoom/syscode.c | 70 ++++++++++++++++++++++++++------------------- fpdoom/syscode.h | 8 +++--- 5 files changed, 115 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index d1a2b24..80b47c0 100644 --- a/README.md +++ b/README.md @@ -87,10 +87,11 @@ All feature phone LCDs I've seen are vertical, if you have a phone with a horizo | 33 | Texet TM-D324 | SC6531E | NT35310 320x480 | 0 | | 34 | Texet TM-302 | SC6531DA | ST7789 240x320 | 0 | | 35 | Strike A13 | SC6531DA | GC9106 128x160 | left soft | +| 36 | Olmio A25 | SC6531E | ILI9328 240x320 | dial | * Vertex M115, Nokia TA-1174, BQ 3586, Energizer E12, Sunwind C2401, DEXP SD2810, YX Q5 Kids Camera, Nomi i184, Sigma IO67, -F+ F197, Texet TM-302, Strike A13: +F+ F197, Texet TM-302, Strike A13, Olmio A25: need keymap file * Nobby 170B: use `--spi 1 --mac 0xa8` without `--rotate` * Smart Watch DZ09: use `--spi 0 --lcd 0x80009307`, no controls - you can only watch replays, no boot key - use boot cable diff --git a/fpdoom/entry.c b/fpdoom/entry.c index a010c1f..ab640d2 100644 --- a/fpdoom/entry.c +++ b/fpdoom/entry.c @@ -322,15 +322,16 @@ void entry_main(char *image_addr, uint32_t image_size, uint32_t bss_size) { FILE *f = fopen(argv[1], "rb"); if (f) { unsigned i, n, nrow; + uint8_t *p = sys_data.keytrn; printf("keymap loaded from file\n"); - sys_data.keymap_addr = (short*)sys_data.keytrn; - memset(sys_data.keytrn, -1, 64 * 2); - n = fread(sys_data.keytrn, 1, 64 * 2, f); + sys_data.keymap_addr = (short*)p; + memset(p, -1, 64 * 2); + n = fread(p, 1, 64 * 2, f); fclose(f); nrow = 8; if (_chip == 1) - for (i = 0; i < n; i += 8) - if (*(int32_t*)&sys_data.keytrn[i + 6] != -1) { + for (i = 12; i < n; i += 16) + if (*(int32_t*)&p[i] != -1) { nrow = 5; break; } sys_data.keyrows = nrow; diff --git a/fpdoom/lcd_config.h b/fpdoom/lcd_config.h index 190d0a7..e449f90 100644 --- a/fpdoom/lcd_config.h +++ b/fpdoom/lcd_config.h @@ -630,6 +630,64 @@ static const uint8_t cmd5310_init[] = { LCM_CMD(0x29, 0), // Display ON LCM_END }; + +static const uint8_t cmd9328_init[] = { + LCM_DELAY(120), +#define X(a, b) LCM_CMD(0x00, 0), LCM_CMD(a, b) + X(0x01, 2), 0x01,0x00, // Driver Output Control 1 + X(0x02, 2), 0x07,0x00, // LCD Driving Control + //X(0x03, 2), 0x10,0x30, // Entry Mode + X(0x04, 2), 0x00,0x00, // Resize Control + X(0x08, 2), 0x02,0x07, // Display Control 2 + X(0x09, 2), 0x00,0x00, // Display Control 3 + X(0x0a, 2), 0x00,0x00, // Display Control 4 + X(0x0c, 2), 0x00,0x00, // RGB Display Interface Control 1 + X(0x0d, 2), 0x00,0x00, // Frame Maker Position + X(0x0f, 2), 0x00,0x00, // RGB Display Interface Control 2 + X(0x10, 2), 0x00,0x00, // Power Control 1 + X(0x11, 2), 0x00,0x07, // Power Control 2 + X(0x12, 2), 0x00,0x00, // Power Control 3 + X(0x13, 2), 0x00,0x00, // Power Control 4 + X(0x07, 2), 0x00,0x01, // Display Control 1 + X(0x10, 2), 0x12,0x90, // Power Control 1 + X(0x11, 2), 0x02,0x27, // Power Control 2 + X(0x12, 2), 0x00,0x9d, // Power Control 3 + X(0x13, 2), 0x1a,0x00, // Power Control 4 + X(0x29, 2), 0x00,0x1d, // Power Control 7 + X(0x2b, 2), 0x00,0x0d, // Frame Rate and Color Control + //X(0x20, 2), 0x00,0x00, // Horizontal GRAM Address Set + //X(0x21, 2), 0x00,0x00, // Vertical GRAM Address Set + X(0x30, 2), 0x00,0x00, // Gamma Control 1 + X(0x31, 2), 0x02,0x01, // Gamma Control 2 + X(0x32, 2), 0x00,0x03, // Gamma Control 3 + X(0x35, 2), 0x03,0x05, // Gamma Control 4 + X(0x36, 2), 0x00,0x04, // Gamma Control 5 + X(0x37, 2), 0x04,0x07, // Gamma Control 6 + X(0x38, 2), 0x06,0x05, // Gamma Control 7 + X(0x39, 2), 0x07,0x07, // Gamma Control 8 + X(0x3c, 2), 0x05,0x03, // Gamma Control 9 + X(0x3d, 2), 0x00,0x04, // Gamma Control 10 + //X(0x50, 2), 0x00,0x00, // Horizontal Address Start Position + //X(0x51, 2), 0x00,0xef, // Horizontal Address End Position + //X(0x52, 2), 0x00,0x00, // Vertical Address Start Position + //X(0x53, 2), 0x01,0x3f, // Vertical Address End Position + X(0x60, 2), 0xa7,0x00, // Driver Output Control 2 + X(0x61, 2), 0x00,0x01, // Base Image Display Control + X(0x6a, 2), 0x00,0x00, // Vertical Scroll Control + X(0x80, 2), 0x00,0x00, // Partial Image 1 Display Position + X(0x81, 2), 0x00,0x00, // Partial Image 1 Area (Start Line) + X(0x82, 2), 0x00,0x00, // Partial Image 1 Area (End Line) + X(0x83, 2), 0x00,0x00, // Partial Image 2 Display Position + X(0x84, 2), 0x00,0x00, // Partial Image 2 Area (Start Line) + X(0x85, 2), 0x00,0x00, // Partial Image 2 Area (End Line) + X(0x90, 2), 0x00,0x10, // Panel Interface Control 1 + X(0x92, 2), 0x06,0x00, // Panel Interface Control 2 + X(0x07, 2), 0x01,0x33, // Display Control 1 + //X(0x22, 0), // Write Data to GRAM +#undef X + LCM_END +}; + #endif #if CHIP == 2 || CHIP == 3 @@ -1119,6 +1177,11 @@ static const lcd_config_t lcd_config[] = { // NovaTek NT35310 { 0x01015310, 0xffffffff, 0, 0, 1, 320, 480, 1, 0, 0, { 5, 150, 150, 10, 20, 20 }, { 0 }, 0x00, cmd5310_init }, + +/* Olmio A25 */ + + // Ilitek ILI9328 + { 0x289328, 0x00ffffff, 0, 0, 1, 240, 320, 1, 0, 0, { 5, 150, 150, 10, 50, 50 }, { 0 }, 0xc0, cmd9328_init }, #endif #if CHIP == 2 || CHIP == 3 diff --git a/fpdoom/syscode.c b/fpdoom/syscode.c index d0e7c01..eca1f7f 100644 --- a/fpdoom/syscode.c +++ b/fpdoom/syscode.c @@ -541,20 +541,6 @@ static unsigned lcd_getid2(void) { } #if 0 -static void lcd_set_rect(int x0, int y0, int x1, int y1) { - lcm_send_cmd(0x2a); // Column Address Set - lcm_send_data(x0 >> 8); - lcm_send_data(x0 & 0xff); - lcm_send_data(x1 >> 8); - lcm_send_data(x1 & 0xff); - lcm_send_cmd(0x2b); // Page Address Set - lcm_send_data(y0 >> 8); - lcm_send_data(y0 & 0xff); - lcm_send_data(y1 >> 8); - lcm_send_data(y1 & 0xff); - lcm_send_cmd(0x2c); // Memory Write -} - void lcm_send_rgb16(uint16_t *ptr, uint32_t size) { uint32_t addr, tmp; //lcm_set_mode(1); @@ -666,22 +652,46 @@ static void lcd_init(void) { sys_data.display.h1 = h; lcm_exec(lcd->cmd_init); -#if 1 - cmd_init2[2] = mac_arg; - cmd_init2[3 + 2] = x2 >> 8; - cmd_init2[3 + 3] = x2; - cmd_init2[3 + 4] = w2 >> 8; - cmd_init2[3 + 5] = w2; - cmd_init2[3 + 6 + 2] = y2 >> 8; - cmd_init2[3 + 6 + 3] = y2; - cmd_init2[3 + 6 + 4] = h2 >> 8; - cmd_init2[3 + 6 + 5] = h2; - lcm_exec(cmd_init2); -#else - lcm_send_cmd(0x36); // Memory Access Control - lcm_send_data(mac_arg); - lcd_set_rect(x2, y2, w2, h2); -#endif + if (lcd->id == 0x289328) { + /* Why can't people use standardized commands? */ + static uint8_t cmd_init2_ili9328[] = { +#define X(a, b) LCM_CMD(0x00, 0), LCM_CMD(a, b) + // ORG, 0, I/D1, I/D0, AM, 0, 0, 0 + X(0x03, 2), 0x10,0, // Entry Mode + X(0x50, 2), 0,0, // Horizontal Address Start Position + X(0x51, 2), 0,0, // Horizontal Address End Position + X(0x52, 2), 0,0, // Vertical Address Start Position + X(0x53, 2), 0,0, // Vertical Address End Position + X(0x20, 2), 0,0, // Horizontal GRAM Address Set + X(0x21, 2), 0,0, // Vertical GRAM Address Set + X(0x22, 0), // Write Data to GRAM +#undef X + LCM_END + }; + uint8_t *p = cmd_init2_ili9328; + p[5] = mac_arg >> 2; p += 6; + if (mac_arg & 0x20) { + unsigned t; + t = w2; w2 = h2; h2 = t; + t = x2; x2 = y2; x2 = t; + } + p[4] = x2 >> 8; p[5] = x2; p += 6; + p[4] = w2 >> 8; p[5] = w2; p += 6; + p[4] = y2 >> 8; p[5] = y2; p += 6; + p[4] = h2 >> 8; p[5] = h2; p += 6; + if (!(mac_arg & 0x40)) p[4] = w2 >> 8, p[5] = w2; + p += 6; + if (!(mac_arg & 0x80)) p[4] = h2 >> 8, p[5] = h2; + lcm_exec(cmd_init2_ili9328); + } else { + uint8_t *p = cmd_init2; + p[2] = mac_arg; p += 3; + p[2] = x2 >> 8; p[3] = x2; + p[4] = w2 >> 8; p[5] = w2; p += 6; + p[2] = y2 >> 8; p[3] = y2; + p[4] = h2 >> 8; p[5] = h2; + lcm_exec(cmd_init2); + } } static void lcdc_init(void) { diff --git a/fpdoom/syscode.h b/fpdoom/syscode.h index 087822a..2dab5d4 100644 --- a/fpdoom/syscode.h +++ b/fpdoom/syscode.h @@ -113,10 +113,10 @@ extern void (*app_scr_update)(uint8_t *src, void *dest); #define KEYPAD_ENUM(M) \ M(0x01, DIAL) \ M(0x04, UP) M(0x05, DOWN) M(0x06, LEFT) M(0x07, RIGHT) \ - M(0x08, LSOFT) M(0x09, RSOFT) \ - M(0x0d, CENTER) \ - M(0x23, HASH) M(0x24, VOLUP) M(0x25, VOLDOWN) \ - M(0x29, EXTRA) M(0x2a, STAR) M(0x2b, PLUS) M(0x2d, MINUS) \ + M(0x08, LSOFT) M(0x09, RSOFT) M(0x0d, CENTER) \ + M(0x0e, CAMERA) M(0x1d, EXT_1D) M(0x1f, EXT_1F) \ + M(0x21, EXT_21) M(0x23, HASH) M(0x24, VOLUP) M(0x25, VOLDOWN) \ + M(0x29, EXT_29) M(0x2a, STAR) M(0x2b, PLUS) M(0x2d, MINUS) \ M(0x30, 0) M(0x31, 1) M(0x32, 2) M(0x33, 3) M(0x34, 4) \ M(0x35, 5) M(0x36, 6) M(0x37, 7) M(0x38, 8) M(0x39, 9)