aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c')
-rw-r--r--drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c b/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c
new file mode 100644
index 00000000..d1086c46
--- /dev/null
+++ b/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c
@@ -0,0 +1,259 @@
+/*
+ * 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/Nokia6610GE12/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE12 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 GDISP_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_Nokia6610GE12
+#include "../drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_Nokia6610GE12.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#include "GE12.h"
+
+#define GDISP_SCAN_LINES 132
+#define GDISP_SLEEP_SIZE 32 /* Sleep mode window lines - this must be 32 on this controller */
+
+// Set parameters if they are not already set
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 130
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 130
+#endif
+#ifndef GDISP_RAM_X_OFFSET
+ #define GDISP_RAM_X_OFFSET 0 /* Offset in RAM of visible area */
+#endif
+#ifndef GDISP_RAM_Y_OFFSET
+ #define GDISP_RAM_Y_OFFSET 2 /* Offset in RAM of visible area */
+#endif
+#ifndef GDISP_SLEEP_POS
+ #define GDISP_SLEEP_POS ((GDISP_SCAN_LINES-GDISP_SLEEP_SIZE)/2 & ~3)
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+// Use the priv pointer itself to save our color. This save allocating ram for it
+// and works provided sizeof(color_t) <= sizeof(void *)
+#define savecolor(g) (*(color_t *)&g->priv)
+
+#define GDISP_FLG_ODDBYTE (GDISP_FLG_DRIVER<<0)
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some macros just to make reading the code easier
+#define delayms(ms) gfxSleepMilliseconds(ms)
+#define write_data2(g, d1, d2) { write_data(g, d1); write_data(g, d2); }
+#define write_data3(g, d1, d2, d3) { write_data(g, d1); write_data(g, d2); write_data(g, d3); }
+#define write_reg(g, cmd, d1) { write_index(g, cmd); write_data(g, d1); }
+#define write_reg2(g, cmd, d1, d2) { write_index(g, cmd); write_data2(g, d1, d2); }
+#define write_reg3(g, cmd, d1, d2, d3) { write_index(g, cmd); write_data3(g, d1, d2, d3); }
+
+static inline void set_viewport(GDisplay* g) {
+ write_reg2(g, CASET, GDISP_RAM_X_OFFSET+g->p.x, GDISP_RAM_X_OFFSET+g->p.x+g->p.cx-1); // Column address set
+ write_reg2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.y, GDISP_RAM_Y_OFFSET+g->p.y+g->p.cy-1); // Page address set
+ write_index(g, RAMWR);
+}
+
+/*===========================================================================*/
+/* 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);
+ delayms(20);
+ setpin_reset(g, FALSE);
+ delayms(20);
+
+ acquire_bus(g);
+
+ write_index(g, SLEEPOUT); // Sleep out
+ write_reg(g, COLMOD, 0x03); // Color Interface Pixel Format - 0x03 = 12 bits-per-pixel
+ write_reg(g, MADCTL, 0x00); // Memory access controller
+ write_reg(g, SETCON, 128*GDISP_INITIAL_CONTRAST/101-64); // Write contrast
+ delayms(20);
+
+ // Finish Init
+ post_init_board(g);
+
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure to match */
+ 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);
+ g->flags &= ~GDISP_FLG_ODDBYTE;
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ if ((g->flags & GDISP_FLG_ODDBYTE)) {
+ // Write the pair of pixels to the display
+ write_data3(g, ((savecolor(g) >> 4) & 0xFF),
+ (((savecolor(g) << 4) & 0xF0)|((g->p.color >> 8) & 0x0F)),
+ (g->p.color & 0xFF));
+ g->flags &= ~GDISP_FLG_ODDBYTE;
+ } else {
+ savecolor(g) = g->p.color;
+ g->flags |= GDISP_FLG_ODDBYTE;
+ }
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ if ((g->flags & GDISP_FLG_ODDBYTE)) {
+ write_data2(g, ((savecolor(g) >> 4) & 0xFF), ((savecolor(g) << 4) & 0xF0));
+ write_index(g, NOP);
+ }
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ /* The hardware is capable of supporting...
+ * GDISP_CONTROL_POWER - supported
+ * GDISP_CONTROL_ORIENTATION - supported
+ * GDISP_CONTROL_BACKLIGHT - supported
+ * GDISP_CONTROL_CONTRAST - supported
+ */
+ 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_index(g, SLEEPIN);
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_index(g, SLEEPOUT);
+ delayms(20);
+ write_index(g, NORON); // Set Normal mode (my)
+ release_bus(g);
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ write_index(g, SLEEPOUT);
+ delayms(20);
+ write_reg2(g, PTLAR, GDISP_SLEEP_POS, GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)
+ write_index(g, PTLON);
+ 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, MADCTL, 0x00);
+ 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, MADCTL, 0xA0); // MY, MX, V, LAO, RGB, X, X, X
+ 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, MADCTL, 0xC0);
+ 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, MADCTL, 0x60);
+ 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:
+ if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+ case GDISP_CONTROL_CONTRAST:
+ if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
+ acquire_bus(g);
+ write_reg(g, SETCON,(unsigned)128*(unsigned)g->p.ptr/101-64);
+ release_bus(g);
+ g->g.Contrast = (unsigned)g->p.ptr;
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */