aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c')
-rw-r--r--drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c b/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c
new file mode 100644
index 00000000..2b2f0917
--- /dev/null
+++ b/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c
@@ -0,0 +1,328 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9481/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for
+ * the ILI9481 and compatible HVGA display
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_ILI9481
+#include "../drivers/gdisp/ILI9481/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_ILI9481.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 480
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 320
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+#define write_reg2x16(g, reg, data1, data2) { write_index(g, reg); write_data(g, (data1)>>8); write_data(g, (uint8_t)(data1)); write_data(g, (data2)>>8); write_data(g, (uint8_t)(data2));}
+
+static void set_viewport(GDisplay* g) {
+ write_reg2x16(g, 0x2A, g->p.x, g->p.x + g->p.cx - 1);
+ write_reg2x16(g, 0x2B, g->p.y, g->p.y + g->p.cy - 1);
+ write_index(g, 0x2C);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ /* Hardware reset */
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ /* Get the bus for the following initialisation commands */
+ acquire_bus(g);
+
+ /* Enable Access to all Manufacturer commands (0xB0 and higher opcodes) */
+ write_reg(g, 0xB0, 0x00);
+
+ /* Frame Memory Access and Interface Setting */
+ write_index(g, 0xB3);
+ write_data(g, 0x02);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x10);
+
+ /* Display Mode and Frame Memory Write Mode Setting (B4h) */
+ /* Use internal clock for synchronization */
+ /* Use DBI interface (only DB0-17, no HSYNC, VSYNC or CLK) */
+ write_reg(g, 0xB4, 0x00);
+
+ /* Internal Backlight Control */
+/* write_index(g, 0xB9); // PWM Settings for Brightness Control
+ write_data(g, 0x01); // Disabled by default.
+ write_data(g, 0xFF); // 0xFF = Max brightness
+ write_data(g, 0xFF);
+ write_data(g, 0x18); */
+
+ /* Panel Driving settings */
+ write_index(g, 0xC0);
+ write_data(g, 0x03);
+ write_data(g, 0x3B);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x01);
+ write_data(g, 0x00); /* NW */
+ write_data(g, 0x43);
+
+ /* Display timings in Operating Mode */
+ write_index(g, 0xC1);
+ write_data(g, 0x08);
+ write_data(g, 0x15); /* CLOCK */
+ write_data(g, 0x08);
+ write_data(g, 0x08);
+
+ /* S/VCOM/Gate Driving timing setting */
+ write_index(g, 0xC4);
+ write_data(g, 0x15);
+ write_data(g, 0x03);
+ write_data(g, 0x03);
+ write_data(g, 0x01);
+
+ /* Interface Setting */
+ write_reg(g, 0xC6, 0x02);
+
+ /* Gamma Setting - should be changed if using a different panel */
+ write_index(g, 0xC8);
+ write_data(g, 0x0C);
+ write_data(g, 0x05);
+ write_data(g, 0x0A); /*0X12 */
+ write_data(g, 0x6B); /*0x7D */
+ write_data(g, 0x04);
+ write_data(g, 0x06); /*0x08 */
+ write_data(g, 0x15); /*0x0A */
+ write_data(g, 0x10);
+ write_data(g, 0x00);
+ write_data(g, 0x60); /*0x23 */
+
+ /* Address Mode setting */
+ write_reg(g, 0x36, 0x00);
+
+ /* Set Pixel Format = 16 bits per pixel */
+ /* The driver supports upto 24 bits per pixel, with dither */
+ write_reg(g, 0x3A, 0x55);
+
+ /* Exit Idle Mode */
+ write_index(g, 0x38);
+
+ /* Power Setting */
+ write_index(g, 0xD0);
+ write_data(g, 0x07);
+ write_data(g, 0x07); /* VCI = VCI1 */
+ write_data(g, 0x14); /* VRH 0x1D */
+ write_data(g, 0xA2); /* BT 0x06 */
+
+ /* VCOM Setting */
+ write_index(g, 0xD1);
+ write_data(g, 0x03);
+ write_data(g, 0x5A); /* VCM 0x5A */
+ write_data(g, 0x10); /* VDV */
+
+ /* Power Setting for Normal Mode */
+ write_index(g, 0xD2);
+ write_data(g, 0x03);
+ write_data(g, 0x04); /* 0x24 */
+ write_data(g, 0x04);
+
+ /* Exit Sleep Mode */
+ write_index(g, 0x11);
+ gfxSleepMilliseconds(150);
+
+ /* Display ON */
+ write_index(g, 0x29);
+ gfxSleepMilliseconds(30);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0001); /* enter sleep mode */
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0000); /* leave sleep mode */
+ release_bus(g);
+ if (g->g.Powermode != powerSleep)
+ gdisp_lld_init();
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0001); /* enter sleep mode */
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x03);
+ write_reg(g, 0x36, 0x00); /* X and Y axes non-inverted */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x02);
+ write_reg(g, 0x36, 0x20); /* Invert X and Y axes */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x06);
+ write_reg(g, 0x36, 0x00); /* X and Y axes non-inverted */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x07);
+ write_reg(g, 0x36, 0x20); /* Invert X and Y axes */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+ //case GDISP_CONTROL_BACKLIGHT:
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
+/** @} */