diff options
author | inmarket <andrewh@inmarket.com.au> | 2013-10-28 11:03:39 +1000 |
---|---|---|
committer | inmarket <andrewh@inmarket.com.au> | 2013-10-28 11:03:39 +1000 |
commit | b05a29f830008ab0e9a36d8384ed7cf4ea3fb18b (patch) | |
tree | 193e79f1d53638dad20ac86c1c2e18492311f6b6 /drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c | |
parent | 9e5ed28f98e7b0b3dbd46df7a62568dbaffab92a (diff) | |
download | uGFX-b05a29f830008ab0e9a36d8384ed7cf4ea3fb18b.tar.gz uGFX-b05a29f830008ab0e9a36d8384ed7cf4ea3fb18b.tar.bz2 uGFX-b05a29f830008ab0e9a36d8384ed7cf4ea3fb18b.zip |
Rename GDISP driver files to prevent problems when compiling for multiple controllers on platforms that put all generated object files into a single directory.
Diffstat (limited to 'drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c')
-rw-r--r-- | drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c b/drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c new file mode 100644 index 00000000..e0cfb997 --- /dev/null +++ b/drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c @@ -0,0 +1,559 @@ +/* + * 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/Nokia6610GE8/gdisp_lld.c + * @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE8 display. + * + * @addtogroup GDISP + * @{ + */ + +#include "gfx.h" + +#if GFX_USE_GDISP + +/** + * This is for the EPSON (GE8) controller driving a Nokia6610 color LCD display. + * Note that there is also a PHILIPS (GE12) controller for the same display that this code + * does not support. + * + * The controller drives a 132x132 display but a 1 pixel surround is not visible + * which gives a visible area of 130x130. + * + * This controller does not support reading back over the SPI interface. + * Additionally, the Olimex board doesn't even connect the pin. + * + * The hardware is capable of doing full width vertical scrolls aligned + * on a 4 line boundary however that is not sufficient to support general vertical scrolling. + * We also can't manually do read/modify scrolling because we can't read in SPI mode. + * + * The controller has some quirkyness when operating in other than rotation 0 mode. + * When any direction is decremented it starts at location 0 rather than the end of + * the area. Whilst this can be handled when we know the specific operation (pixel, fill, blit) + * it cannot be handled in a generic stream operation. So, when orientation support is turned + * on (and needed) we use complex operation specific routines instead of simple streaming + * routines. This has a (small) performance penalty and a significant code size penalty so + * don't turn on orientation support unless you really need it. + * + * Some of the more modern controllers have a broken command set. If you have one of these + * you will recognise it by the colors being off on anything drawn after an odd (as opposed to + * even) pixel count area being drawn. If so then set GDISP_GE8_BROKEN_CONTROLLER to TRUE + * on your gdisp_lld_board.h file. The price is that streaming calls that are completed + * without exactly the window size write operations and where the number of write operations + * is odd (rather than even), it will draw an extra pixel. If this is important to you, turn on + * orientation support and the streaming operations will be emulated (as described above). + */ + +#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_Nokia6610GE8 +#include "../drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h" +#include "gdisp/lld/gdisp_lld.h" + +#include "board_Nokia6610GE8.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#include "GE8.h" + +#define GDISP_SCAN_LINES 132 + +// Set parameters if they are not already set +#ifndef GDISP_GE8_BROKEN_CONTROLLER + #define GDISP_GE8_BROKEN_CONTROLLER TRUE +#endif +#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_SIZE + #define GDISP_SLEEP_SIZE 32 /* Sleep mode window lines */ +#endif +#ifndef GDISP_SLEEP_POS + #define GDISP_SLEEP_POS ((GDISP_SCAN_LINES-GDISP_SLEEP_SIZE)/2) +#endif +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 60 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +#if GDISP_HARDWARE_STREAM_WRITE + typedef struct dvrPriv { + color_t savecolor; + #if GDISP_GE8_BROKEN_CONTROLLER + color_t firstcolor; + #endif + } dvrPriv; + #define PRIV ((dvrPriv *)g->priv) +#endif + +#define GDISP_FLG_ODDBYTE (GDISP_FLG_DRIVER<<0) +#define GDISP_FLG_RUNBYTE (GDISP_FLG_DRIVER<<1) + +/*===========================================================================*/ +/* 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_data4(g, d1, d2, d3, d4) { write_data(g, d1); write_data(g, d2); write_data(g, d3); write_data(g, d4); } +#define write_cmd1(g, cmd, d1) { write_index(g, cmd); write_data(g, d1); } +#define write_cmd2(g, cmd, d1, d2) { write_index(g, cmd); write_data2(g, d1, d2); } +#define write_cmd3(g, cmd, d1, d2, d3) { write_index(g, cmd); write_data3(g, d1, d2, d3); } +#define write_cmd4(g, cmd, d1, d2, d3, d4) { write_index(g, cmd); write_data4(g, d1, d2, d3, d4); } + +static inline void set_viewport(GDisplay* g) { + #if GDISP_NOKIA_ORIENTATION && GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + write_cmd2(g, CASET, GDISP_RAM_X_OFFSET+g->p.x, GDISP_RAM_X_OFFSET+g->p.x); // Column address set + write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.y, GDISP_RAM_Y_OFFSET+g->p.y); // Page address set + break; + case GDISP_ROTATE_90: + write_cmd2(g, CASET, GDISP_RAM_X_OFFSET+g->p.y, GDISP_RAM_X_OFFSET+g->p.y); + write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET-1+g->g.Width-g->p.x, GDISP_RAM_Y_OFFSET-1+g->g.Width-g->p.x); + break; + case GDISP_ROTATE_180: + write_cmd2(g, CASET, GDISP_RAM_X_OFFSET-1+g->g.Width-g->p.x, GDISP_RAM_X_OFFSET-1+g->g.Width-g->p.x); + write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET-1+g->g.Height-g->p.y, GDISP_RAM_Y_OFFSET-1+g->g.Height-g->p.y); + break; + case GDISP_ROTATE_270: + write_cmd2(g, CASET, GDISP_RAM_X_OFFSET-1+g->g.Height-g->p.y, GDISP_RAM_X_OFFSET-1+g->g.Height-g->p.y); + write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.x, GDISP_RAM_Y_OFFSET+g->p.x); + break; + } + #else + write_cmd2(g, CASET, GDISP_RAM_X_OFFSET+g->p.x, GDISP_RAM_X_OFFSET+g->p.x+g->p.cx-1); // Column address set + write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.y, GDISP_RAM_Y_OFFSET+g->p.y+g->p.cy-1); // Page address set + #endif + write_index(g, RAMWR); +} +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + #if GDISP_HARDWARE_STREAM_WRITE + g->priv = gfxAlloc(sizeof(dvrPriv)); + #else + g->priv = 0; + #endif + + // Initialise the board interface + init_board(g); + + // Hardware reset + setpin_reset(g, TRUE); + delayms(20); + setpin_reset(g, FALSE); + delayms(20); + + // Get the bus for the following initialisation commands + acquire_bus(g); + + write_cmd4(g, DISCTL, 0x00, GDISP_SCAN_LINES/4-1, 0x0A, 0x00); // Display control - How the controller drives the LCD + // P1: 0x00 = 2 divisions, switching period=8 (default) + // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32) + // P3: 0x0A = standard inverse highlight, inversion every frame + // P4: 0x00 = dispersion on + write_cmd1(g, COMSCN, 0x01); // COM scan - How the LCD is connected to the controller + // P1: 0x01 = Scan 1->80, 160<-81 + write_index(g, OSCON); // Internal oscillator ON + write_index(g, SLPOUT); // Sleep out + write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON + write_cmd3(g, DATCTL, 0x00, 0x00, 0x02); // Data control + // P1: 0x00 = page address normal, column address normal, address scan in column direction + // P2: 0x00 = RGB sequence (default value) + // P3: 0x02 = 4 bits per colour (Type A) + write_cmd2(g, VOLCTR, 64*GDISP_INITIAL_CONTRAST/101, 0x03); // Voltage control (contrast setting) + // P1 = Contrast (0..63) + // P2 = 3 resistance ratio (only value that works) + delayms(100); // Allow power supply to stabilise + write_index(g, DISON); // Turn on the display + + // 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 to match */ + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + 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|GDISP_FLG_RUNBYTE); + } + LLDSPEC void gdisp_lld_write_color(GDisplay *g) { + #if GDISP_GE8_BROKEN_CONTROLLER + if (!(g->flags & GDISP_FLG_RUNBYTE)) { + PRIV->firstcolor = g->p.color; + g->flags |= GDISP_FLG_RUNBYTE; + } + #endif + if ((g->flags & GDISP_FLG_ODDBYTE)) { + // Write the pair of pixels to the display + write_data3(g, ((PRIV->savecolor >> 4) & 0xFF), + (((PRIV->savecolor << 4) & 0xF0)|((g->p.color >> 8) & 0x0F)), + (g->p.color & 0xFF)); + g->flags &= ~GDISP_FLG_ODDBYTE; + } else { + PRIV->savecolor = g->p.color; + g->flags |= GDISP_FLG_ODDBYTE; + } + } + LLDSPEC void gdisp_lld_write_stop(GDisplay *g) { + if ((g->flags & GDISP_FLG_ODDBYTE)) { + #if GDISP_GE8_BROKEN_CONTROLLER + /** + * We have a real problem here - we need to write a singular pixel + * Methods that are supposed to work... + * 1/ Write the pixel (2 bytes) and then send a NOP command. This doesn't work, the pixel doesn't get written + * and it is maintained in the latch where it causes problems for the next window. + * 2/ Just write a dummy extra pixel as stuff beyond the window gets discarded. This doesn't work as contrary to + * the documentation the buffer wraps and the first pixel gets overwritten. + * 3/ Put the controller in 16 bits per pixel Type B mode where each pixel is performed by writing two bytes. This + * also doesn't work as the controller refuses to enter Type B mode (it stays in Type A mode). + * + * These methods might work on some controllers - just not on the one of the broken versions. + * + * For these broken controllers: + * We know we can wrap to the first byte (just overprint it) if we are at the end of the stream area. + * If not, we need to create a one pixel by one pixel window to fix this - Uuch. Fortunately this should only happen if the + * user application uses the streaming calls and then terminates the stream early or after buffer wrap. + * Since this is such an unlikely situation we just don't handle it. + */ + write_data3(g, ((PRIV->savecolor >> 4) & 0xFF), + (((PRIV->savecolor << 4) & 0xF0)|((PRIV->firstcolor >> 8) & 0x0F)), + (PRIV->firstcolor & 0xFF)); + #else + write_data2(g, ((PRIV->savecolor >> 4) & 0xFF), ((PRIV->savecolor << 4) & 0xF0)); + write_index(g, NOP); + #endif + } + + release_bus(g); + } +#endif + +#if GDISP_HARDWARE_DRAWPIXEL + LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + acquire_bus(g); + set_viewport(g); + write_data3(g, 0, (g->p.color>>8) & 0x0F, g->p.color & 0xFF); + release_bus(g); + } +#endif + +/* ---- Optional Routines ---- */ + +#if GDISP_HARDWARE_FILLS + LLDSPEC void gdisp_lld_fill_area(GDisplay *g) { + unsigned tuples; + + tuples = (g->p.cx*g->p.cy+1)>>1; // With an odd sized area we over-print by one pixel. + // This extra pixel overwrites the first pixel (harmless as it is the same colour) + + acquire_bus(g); + set_viewport(g); + while(tuples--) + write_data3(g, ((g->p.color >> 4) & 0xFF), (((g->p.color << 4) & 0xF0)|((g->p.color >> 8) & 0x0F)), (g->p.color & 0xFF)); + release_bus(g); + } +#endif + +#if GDISP_HARDWARE_BITFILLS + LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { + coord_t lg, x, y; + color_t c1, c2; + unsigned tuples; + const pixel_t *buffer; + #if GDISP_PACKED_PIXELS + unsigned pnum, pstart; + const uint8_t *p; + #else + const pixel_t *p; + #endif + + tuples = (g->p.cx * g->p.cy + 1)>>1; + buffer = (const pixel_t *)g->p.ptr; + + /* Set up the data window to transfer */ + acquire_bus(g); + set_viewport(g); + + /* to surpress compiler warnings */ + x = 0; + y = 0; + + /* + * Due to the way the Nokia6610 handles a decrementing column or page, + * we have to make adjustments as to where it is actually drawing from in the bitmap. + * For example, for 90 degree rotation the column is decremented on each + * memory write. The controller always starts with column 0 and then decrements + * to column cx-1, cx-2 etc. We therefore have to write-out the last bitmap line first. + */ + switch(g->g.Orientation) { + case GDISP_ROTATE_0: x = 0; y = 0; break; + case GDISP_ROTATE_90: x = g->p.cx-1; y = 0; break; + case GDISP_ROTATE_180: x = g->p.cx-1; y = g->p.cy-1; break; + case GDISP_ROTATE_270: x = 0; y = g->p.cy-1; break; + } + + #if !GDISP_PACKED_PIXELS + // Although this controller uses packed pixels we support unpacked pixel + // formats in this blit by packing the data as we feed it to the controller. + + lg = g->p.x2 - g->p.cx; // The buffer gap between lines + buffer += g->p.y1 * g->p.x2 + g->p.x1; // The buffer start position + p = buffer + g->p.x2*y + x; // Adjustment for controller craziness + + while(tuples--) { + /* Get a pixel */ + c1 = *p++; + + /* Check for line or buffer wrapping */ + if (++x >= g->p.cx) { + x = 0; + p += lg; + if (++y >= g->p.cy) { + y = 0; + p = buffer; + } + } + + /* Get the next pixel */ + c2 = *p++; + + /* Check for line or buffer wrapping */ + if (++x >= g->p.cx) { + x = 0; + p += lg; + if (++y >= g->p.cy) { + y = 0; + p = buffer; + } + } + + /* Write the pair of pixels to the display */ + write_data3(g, ((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF)); + } + + #else + + // Although this controller uses packed pixels, we may have to feed it into + // the controller with different packing to the source bitmap + // There are 2 pixels per 3 bytes + + #if !GDISP_PACKED_LINES + srccx = (g->p.x2 + 1) & ~1; + #endif + pstart = g->p.y1 * g->p.x2 + g->p.x1; // The starting pixel number + buffer = (const pixel_t)(((const uint8_t *)buffer) + ((pstart>>1) * 3)); // The buffer start position + lg = ((g->p.x2-g->p.cx)>>1)*3; // The buffer gap between lines + pnum = pstart + g->p.x2*y + x; // Adjustment for controller craziness + p = ((const uint8_t *)buffer) + (((g->p.x2*y + x)>>1)*3); // Adjustment for controller craziness + + while (tuples--) { + /* Get a pixel */ + switch(pnum++ & 1) { + case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break; + case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); p += 3; break; + } + + /* Check for line or buffer wrapping */ + if (++x >= g->p.cx) { + x = 0; + p += lg; + pnum += g->p.x2 - g->p.cx; + if (++y >= g->p.cy) { + y = 0; + p = (const uint8_t *)buffer; + pnum = pstart; + } + } + + /* Get the next pixel */ + switch(pnum++ & 1) { + case 0: c2 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break; + case 1: c2 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); p += 3; break; + } + + /* Check for line or buffer wrapping */ + if (++x >= g->p.cx) { + x = 0; + p += lg; + pnum += g->p.x2 - g->p.cx; + if (++y >= g->p.cy) { + y = 0; + p = (const uint8_t *)buffer; + pnum = pstart; + } + } + + /* Write the pair of pixels to the display */ + write_data3(g, ((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF)); + } + #endif + + /* All done */ + 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; + acquire_bus(g); + switch((powermode_t)g->p.ptr) { + case powerOff: + set_backlight(g, 0); // Turn off the backlight + write_index(g, DISOFF); // Turn off the display + write_cmd1(g, PWRCTR, 0x00); // Power control - all off + write_index(g, SLPIN); // Sleep in + write_index(g, OSCOFF); // Internal oscillator off + break; + case powerOn: + write_index(g, OSCON); // Internal oscillator on + write_index(g, SLPOUT); // Sleep out + write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON + write_cmd2(g, VOLCTR, g->g.Contrast, 0x03); // Voltage control (contrast setting) + delayms(100); // Allow power supply to stabilise + write_index(g, DISON); // Turn on the display + write_index(g, PTLOUT); // Remove sleep window + set_backlight(g, g->g.Backlight); // Turn on the backlight + break; + case powerSleep: + write_index(g, OSCON); // Internal oscillator on + write_index(g, SLPOUT); // Sleep out + write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON + write_cmd2(g, VOLCTR, g->g.Contrast, 0x03); // Voltage control (contrast setting) + delayms(100); // Allow power supply to stabilise + write_index(g, DISON); // Turn on the display + write_cmd2(g, PTLIN, GDISP_SLEEP_POS/4, (GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)/4); // Sleep Window + set_backlight(g, g->g.Backlight); // Turn on the backlight + break; + case powerDeepSleep: + write_index(g, OSCON); // Internal oscillator on + write_index(g, SLPOUT); // Sleep out + write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON + write_cmd2(g, VOLCTR, g->g.Contrast, 0x03); // Voltage control (contrast setting) + delayms(100); // Allow power supply to stabilise + write_index(g, DISON); // Turn on the display + write_cmd2(g, PTLIN, GDISP_SLEEP_POS/4, (GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)/4); // Sleep Window + set_backlight(g, 0); // Turn off the backlight + break; + default: + release_bus(g); + return; + } + release_bus(g); + g->g.Powermode = (powermode_t)g->p.ptr; + return; + #if GDISP_NOKIA_ORIENTATION + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + acquire_bus(g); + switch((orientation_t)g->p.ptr) { + case GDISP_ROTATE_0: + write_cmd3(g, DATCTL, 0x00, 0x00, 0x02); // P1: page normal, column normal, scan in column direction + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_90: + write_cmd3(g, DATCTL, 0x05, 0x00, 0x02); // P1: page reverse, column normal, scan in page direction + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; + case GDISP_ROTATE_180: + write_cmd3(g, DATCTL, 0x03, 0x00, 0x02); // P1: page reverse, column reverse, scan in column direction + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_270: + write_cmd3(g, DATCTL, 0x06, 0x00, 0x02); // P1: page normal, column reverse, scan in page direction + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; + default: + release_bus(g); + return; + } + release_bus(g); + g->g.Orientation = (orientation_t)g->p.ptr; + return; + #endif + 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_cmd2(g, VOLCTR, 64*(unsigned)g->p.ptr/101, 0x03); + release_bus(g); + g->g.Contrast = (unsigned)g->p.ptr; + return; + } + } +#endif + +#endif /* GFX_USE_GDISP */ +/** @} */ |