diff --git a/drivers/gdisp/SSD1306/SSD1306.h b/drivers/gdisp/SSD1306/SSD1306.h index d1c59fe4..7d7010e8 100644 --- a/drivers/gdisp/SSD1306/SSD1306.h +++ b/drivers/gdisp/SSD1306/SSD1306.h @@ -33,10 +33,11 @@ #define SSD1306_HV_PAGE_ADDRESS 0x22 #define SSD1306_PAM_PAGE_START 0xB0 -#define SSD1306_COMSCANINC 0xC0 -#define SSD1306_COMSCANDEC 0xC8 +#define SSD1306_ROWSCANINC 0xC0 +#define SSD1306_ROWSCANDEC 0xC8 -#define SSD1306_SEGREMAP 0xA0 +#define SSD1306_COLSCANINC 0xA0 +#define SSD1306_COLSCANDEC 0xA1 #define SSD1306_CHARGEPUMP 0x8D 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: