aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
diff options
context:
space:
mode:
authorergosys <ergosys@gmail.com>2014-12-13 14:34:34 -0800
committerergosys <ergosys@gmail.com>2014-12-13 15:09:37 -0800
commit9618d7917bea1cb9f753569f0ddef91714aae49f (patch)
treec18938c8249b4d8fd66319b14fd7f6630422dd9a /drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
parent7285477f1329612f9087a3bfe392f875f3517683 (diff)
downloaduGFX-9618d7917bea1cb9f753569f0ddef91714aae49f.tar.gz
uGFX-9618d7917bea1cb9f753569f0ddef91714aae49f.tar.bz2
uGFX-9618d7917bea1cb9f753569f0ddef91714aae49f.zip
Partially handle screen rotation using remapping
Use row and column remapping to change either row or column addressing for each orientation. This removes the need to reverse the drawing direction of either x or y in the drawing routines. However in the 90 and 270 case x and y must still be swapped. Also, rename the SSD1306 remapping command names so they are more descriptive.
Diffstat (limited to 'drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c')
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c86
1 files changed, 41 insertions, 45 deletions
diff --git a/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
index 2386c2d4..713c52bb 100644
--- a/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
+++ b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
@@ -105,8 +105,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
write_cmd(g, SSD1306_SETSTARTLINE | 0);
write_cmd2(g, SSD1306_ENABLE_CHARGE_PUMP, 0x14);
write_cmd2(g, SSD1306_MEMORYMODE, 0);
- write_cmd(g, SSD1306_SEGREMAP+1);
- write_cmd(g, SSD1306_COMSCANDEC);
+ write_cmd(g, SSD1306_COLSCANDEC);
+ write_cmd(g, SSD1306_ROWSCANDEC);
#if GDISP_SCREEN_HEIGHT == 64
write_cmd2(g, SSD1306_SETCOMPINS, 0x12);
#else
@@ -168,26 +168,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
#if GDISP_HARDWARE_DRAWPIXEL
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
- coord_t x, y;
-
- switch(g->g.Orientation) {
- default:
- case GDISP_ROTATE_0:
- x = g->p.x;
- y = g->p.y;
- break;
- case GDISP_ROTATE_90:
- x = g->p.y;
- y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
- break;
- case GDISP_ROTATE_180:
- x = GDISP_SCREEN_WIDTH-1 - g->p.x;
- y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
- break;
- case GDISP_ROTATE_270:
- x = GDISP_SCREEN_WIDTH-1 - g->p.y;
- y = g->p.x;
- break;
+ coord_t x = g->p.x;
+ coord_t y = g->p.y;
+ if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
+ coord_t tmp;
+ tmp = x; x = y; y = tmp;
}
if (gdispColor2Native(g->p.color) != Black)
RAM(g)[xyaddr(x, y)] |= xybit(y);
@@ -199,26 +184,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
#if GDISP_HARDWARE_PIXELREAD
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
- coord_t x, y;
-
- switch(g->g.Orientation) {
- default:
- case GDISP_ROTATE_0:
- x = g->p.x;
- y = g->p.y;
- break;
- case GDISP_ROTATE_90:
- x = g->p.y;
- y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
- break;
- case GDISP_ROTATE_180:
- x = GDISP_SCREEN_WIDTH-1 - g->p.x;
- y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
- break;
- case GDISP_ROTATE_270:
- x = GDISP_SCREEN_WIDTH-1 - g->p.y;
- y = g->p.x;
- break;
+ coord_t x = g->p.x;
+ coord_t y = g->p.y;
+ if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
+ coord_t tmp;
+ tmp = x; x = y; y = tmp;
}
return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
}
@@ -252,8 +222,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
case GDISP_CONTROL_ORIENTATION:
if (g->g.Orientation == (orientation_t)g->p.ptr)
return;
- switch((orientation_t)g->p.ptr) {
- /* Rotation is handled by the drawing routines */
+ orientation_t orient = (orientation_t)g->p.ptr;
+ switch(orient) {
case GDISP_ROTATE_0:
case GDISP_ROTATE_180:
g->g.Height = GDISP_SCREEN_HEIGHT;
@@ -267,7 +237,33 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
default:
return;
}
- g->g.Orientation = (orientation_t)g->p.ptr;
+ // Remap the rows and columns according to orientation. This just
+ // eliminates the need to reverse x or y directions in the drawing
+ // routines. There is still the need to swap x and y for 90 and 270.
+ // However, without these, the hardware fill routine would be much
+ // more complicated.
+ acquire_bus(g);
+ switch(orient) {
+ default:
+ case GDISP_ROTATE_0:
+ write_cmd(g, SSD1306_COLSCANDEC);
+ write_cmd(g, SSD1306_ROWSCANDEC);
+ break;
+ case GDISP_ROTATE_180:
+ write_cmd(g, SSD1306_COLSCANINC);
+ write_cmd(g, SSD1306_ROWSCANINC);
+ break;
+ case GDISP_ROTATE_90:
+ write_cmd(g, SSD1306_COLSCANDEC);
+ write_cmd(g, SSD1306_ROWSCANINC);
+ break;
+ case GDISP_ROTATE_270:
+ write_cmd(g, SSD1306_COLSCANINC);
+ write_cmd(g, SSD1306_ROWSCANDEC);
+ break;
+ }
+ release_bus(g);
+ g->g.Orientation = orient;
return;
case GDISP_CONTROL_CONTRAST: