aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c')
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c140
1 files changed, 85 insertions, 55 deletions
diff --git a/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
index a13b82a8..d2f2a872 100644
--- a/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
+++ b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
@@ -159,7 +159,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
#if GDISP_HARDWARE_CLEARS
LLDSPEC void gdisp_lld_clear(GDisplay *g) {
- uint8_t fill = (gdispColor2Native(g->p.color) == Black) ? 0 : 0xff;
+ uint8_t fill = (gdispColor2Native(g->p.color) == gdispColor2Native(Black)) ? 0 : 0xff;
int bytes = GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT/8;
memset(RAM(g), fill, bytes);
g->flags |= GDISP_FLG_NEEDFLUSH;
@@ -168,21 +168,47 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
#if GDISP_HARDWARE_FILLS
LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
- coord_t sy = g->p.y;
- coord_t ey = sy + g->p.cy - 1;
- coord_t sx = g->p.x;
- coord_t ex = g->p.x + g->p.cx - 1;
- if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
- coord_t tmp;
- tmp = sx; sx = sy; sy = tmp;
- tmp = ex; ex = ey; ey = tmp;
+ coord_t sy, ey;
+ coord_t sx, ex;
+ coord_t col;
+ unsigned spage, zpages;
+ uint8_t * base;
+ uint8_t mask;
+
+ switch(g->g.Orientation) {
+ default:
+ case GDISP_ROTATE_0:
+ sx = g->p.x;
+ ex = g->p.x + g->p.cx - 1;
+ sy = g->p.y;
+ ey = sy + g->p.cy - 1;
+ break;
+ case GDISP_ROTATE_90:
+ sx = g->p.y;
+ ex = g->p.y + g->p.cy - 1;
+ sy = GDISP_SCREEN_HEIGHT - g->p.x - g->p.cx;
+ ey = GDISP_SCREEN_HEIGHT-1 - g->p.x;
+ break;
+ case GDISP_ROTATE_180:
+ sx = GDISP_SCREEN_WIDTH - g->p.x - g->p.cx;
+ ex = GDISP_SCREEN_WIDTH-1 - g->p.x;
+ sy = GDISP_SCREEN_HEIGHT - g->p.y - g->p.cy;
+ ey = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ break;
+ case GDISP_ROTATE_270:
+ sx = GDISP_SCREEN_WIDTH - g->p.y - g->p.cy;
+ ex = GDISP_SCREEN_WIDTH-1 - g->p.y;
+ sy = g->p.x;
+ ey = g->p.x + g->p.cx - 1;
+ break;
}
- unsigned spage = sy / 8;
- uint8_t * base = RAM(g) + GDISP_SCREEN_WIDTH * spage;
- uint8_t mask = 0xff << (sy&7);
- unsigned zpages = (ey / 8) - spage;
- coord_t col;
- if (gdispColor2Native(g->p.color)==Black) {
+
+ spage = sy / 8;
+ base = RAM(g) + GDISP_SCREEN_WIDTH * spage;
+ mask = 0xff << (sy&7);
+ zpages = (ey / 8) - spage;
+
+ if (gdispColor2Native(g->p.color) == gdispColor2Native(Black)) {
while (zpages--) {
for (col = sx; col <= ex; col++)
base[col] &= ~mask;
@@ -208,13 +234,28 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
#if GDISP_HARDWARE_DRAWPIXEL
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
- 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;
+ 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;
}
- if (gdispColor2Native(g->p.color) != Black)
+ if (gdispColor2Native(g->p.color) != gdispColor2Native(Black))
RAM(g)[xyaddr(x, y)] |= xybit(y);
else
RAM(g)[xyaddr(x, y)] &= ~xybit(y);
@@ -224,11 +265,26 @@ 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 = 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;
+ 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;
}
return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
}
@@ -262,8 +318,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
case GDISP_CONTROL_ORIENTATION:
if (g->g.Orientation == (orientation_t)g->p.ptr)
return;
- orientation_t orient = (orientation_t)g->p.ptr;
- switch(orient) {
+ switch((orientation_t)g->p.ptr) {
+ /* Rotation is handled by the drawing routines */
case GDISP_ROTATE_0:
case GDISP_ROTATE_180:
g->g.Height = GDISP_SCREEN_HEIGHT;
@@ -277,33 +333,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
default:
return;
}
- // 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;
+ g->g.Orientation = (orientation_t)g->p.ptr;
return;
case GDISP_CONTROL_CONTRAST: