Merged in ambihelical/ugfx/ssd1306 (pull request #16)
Further SSD1306 driver improvements
This commit is contained in:
commit
ecc6201c74
3 changed files with 87 additions and 49 deletions
|
@ -33,10 +33,11 @@
|
||||||
#define SSD1306_HV_PAGE_ADDRESS 0x22
|
#define SSD1306_HV_PAGE_ADDRESS 0x22
|
||||||
#define SSD1306_PAM_PAGE_START 0xB0
|
#define SSD1306_PAM_PAGE_START 0xB0
|
||||||
|
|
||||||
#define SSD1306_COMSCANINC 0xC0
|
#define SSD1306_ROWSCANINC 0xC0
|
||||||
#define SSD1306_COMSCANDEC 0xC8
|
#define SSD1306_ROWSCANDEC 0xC8
|
||||||
|
|
||||||
#define SSD1306_SEGREMAP 0xA0
|
#define SSD1306_COLSCANINC 0xA0
|
||||||
|
#define SSD1306_COLSCANDEC 0xA1
|
||||||
|
|
||||||
#define SSD1306_CHARGEPUMP 0x8D
|
#define SSD1306_CHARGEPUMP 0x8D
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
write_cmd(g, SSD1306_SETSTARTLINE | 0);
|
write_cmd(g, SSD1306_SETSTARTLINE | 0);
|
||||||
write_cmd2(g, SSD1306_ENABLE_CHARGE_PUMP, 0x14);
|
write_cmd2(g, SSD1306_ENABLE_CHARGE_PUMP, 0x14);
|
||||||
write_cmd2(g, SSD1306_MEMORYMODE, 0);
|
write_cmd2(g, SSD1306_MEMORYMODE, 0);
|
||||||
write_cmd(g, SSD1306_SEGREMAP+1);
|
write_cmd(g, SSD1306_COLSCANDEC);
|
||||||
write_cmd(g, SSD1306_COMSCANDEC);
|
write_cmd(g, SSD1306_ROWSCANDEC);
|
||||||
#if GDISP_SCREEN_HEIGHT == 64
|
#if GDISP_SCREEN_HEIGHT == 64
|
||||||
write_cmd2(g, SSD1306_SETCOMPINS, 0x12);
|
write_cmd2(g, SSD1306_SETCOMPINS, 0x12);
|
||||||
#else
|
#else
|
||||||
|
@ -159,35 +159,60 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
|
|
||||||
#if GDISP_HARDWARE_CLEARS
|
#if GDISP_HARDWARE_CLEARS
|
||||||
LLDSPEC void gdisp_lld_clear(GDisplay *g) {
|
LLDSPEC void gdisp_lld_clear(GDisplay *g) {
|
||||||
uint8_t fill = (g->p.color == Black) ? 0 : 0xff;
|
uint8_t fill = (gdispColor2Native(g->p.color) == Black) ? 0 : 0xff;
|
||||||
int bytes = GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT/8;
|
int bytes = GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT/8;
|
||||||
memset(RAM(g), fill, bytes);
|
memset(RAM(g), fill, bytes);
|
||||||
g->flags |= GDISP_FLG_NEEDFLUSH;
|
g->flags |= GDISP_FLG_NEEDFLUSH;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
while (zpages--) {
|
||||||
|
for (col = sx; col <= ex; col++)
|
||||||
|
base[col] &= ~mask;
|
||||||
|
mask = 0xff;
|
||||||
|
base += GDISP_SCREEN_WIDTH;
|
||||||
|
}
|
||||||
|
mask &= (0xff >> (7 - (ey&7)));
|
||||||
|
for (col = sx; col <= ex; col++)
|
||||||
|
base[col] &= ~mask;
|
||||||
|
} else {
|
||||||
|
while (zpages--) {
|
||||||
|
for (col = sx; col <= ex; col++)
|
||||||
|
base[col] |= mask;
|
||||||
|
mask = 0xff;
|
||||||
|
base += GDISP_SCREEN_WIDTH;
|
||||||
|
}
|
||||||
|
mask &= (0xff >> (7 - (ey&7)));
|
||||||
|
for (col = sx; col <= ex; col++)
|
||||||
|
base[col] |= mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if GDISP_HARDWARE_DRAWPIXEL
|
#if GDISP_HARDWARE_DRAWPIXEL
|
||||||
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
||||||
coord_t x, y;
|
coord_t x = g->p.x;
|
||||||
|
coord_t y = g->p.y;
|
||||||
switch(g->g.Orientation) {
|
if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
|
||||||
default:
|
coord_t tmp;
|
||||||
case GDISP_ROTATE_0:
|
tmp = x; x = y; y = tmp;
|
||||||
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) != Black)
|
||||||
RAM(g)[xyaddr(x, y)] |= xybit(y);
|
RAM(g)[xyaddr(x, y)] |= xybit(y);
|
||||||
|
@ -199,26 +224,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
|
|
||||||
#if GDISP_HARDWARE_PIXELREAD
|
#if GDISP_HARDWARE_PIXELREAD
|
||||||
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
|
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
|
||||||
coord_t x, y;
|
coord_t x = g->p.x;
|
||||||
|
coord_t y = g->p.y;
|
||||||
switch(g->g.Orientation) {
|
if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
|
||||||
default:
|
coord_t tmp;
|
||||||
case GDISP_ROTATE_0:
|
tmp = x; x = y; y = tmp;
|
||||||
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;
|
return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
|
||||||
}
|
}
|
||||||
|
@ -252,8 +262,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
case GDISP_CONTROL_ORIENTATION:
|
case GDISP_CONTROL_ORIENTATION:
|
||||||
if (g->g.Orientation == (orientation_t)g->p.ptr)
|
if (g->g.Orientation == (orientation_t)g->p.ptr)
|
||||||
return;
|
return;
|
||||||
switch((orientation_t)g->p.ptr) {
|
orientation_t orient = (orientation_t)g->p.ptr;
|
||||||
/* Rotation is handled by the drawing routines */
|
switch(orient) {
|
||||||
case GDISP_ROTATE_0:
|
case GDISP_ROTATE_0:
|
||||||
case GDISP_ROTATE_180:
|
case GDISP_ROTATE_180:
|
||||||
g->g.Height = GDISP_SCREEN_HEIGHT;
|
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||||
|
@ -267,7 +277,33 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
default:
|
default:
|
||||||
return;
|
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;
|
return;
|
||||||
|
|
||||||
case GDISP_CONTROL_CONTRAST:
|
case GDISP_CONTROL_CONTRAST:
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define GDISP_HARDWARE_PIXELREAD TRUE
|
#define GDISP_HARDWARE_PIXELREAD TRUE
|
||||||
#define GDISP_HARDWARE_CONTROL TRUE
|
#define GDISP_HARDWARE_CONTROL TRUE
|
||||||
#define GDISP_HARDWARE_CLEARS TRUE
|
#define GDISP_HARDWARE_CLEARS TRUE
|
||||||
|
#define GDISP_HARDWARE_FILLS TRUE
|
||||||
|
|
||||||
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
|
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue