diff options
Diffstat (limited to 'drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c')
-rw-r--r-- | drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c | 259 |
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 */ |