diff options
Diffstat (limited to 'drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c')
| -rw-r--r-- | drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c | 314 |
1 files changed, 0 insertions, 314 deletions
diff --git a/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c b/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c deleted file mode 100644 index f586f97e3..000000000 --- a/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c +++ /dev/null | |||
| @@ -1,314 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms of the GFX License. If a copy of | ||
| 3 | * the license was not distributed with this file, you can obtain one at: | ||
| 4 | * | ||
| 5 | * http://ugfx.org/license.html | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include "gfx.h" | ||
| 9 | |||
| 10 | #if GFX_USE_GDISP | ||
| 11 | |||
| 12 | # define GDISP_DRIVER_VMT GDISPVMT_ST7565_QMK | ||
| 13 | # include "gdisp_lld_config.h" | ||
| 14 | # include "src/gdisp/gdisp_driver.h" | ||
| 15 | |||
| 16 | # include "board_st7565.h" | ||
| 17 | |||
| 18 | /*===========================================================================*/ | ||
| 19 | /* Driver local definitions. */ | ||
| 20 | /*===========================================================================*/ | ||
| 21 | |||
| 22 | # ifndef GDISP_SCREEN_HEIGHT | ||
| 23 | # define GDISP_SCREEN_HEIGHT LCD_HEIGHT | ||
| 24 | # endif | ||
| 25 | # ifndef GDISP_SCREEN_WIDTH | ||
| 26 | # define GDISP_SCREEN_WIDTH LCD_WIDTH | ||
| 27 | # endif | ||
| 28 | # ifndef GDISP_INITIAL_CONTRAST | ||
| 29 | # define GDISP_INITIAL_CONTRAST 35 | ||
| 30 | # endif | ||
| 31 | # ifndef GDISP_INITIAL_BACKLIGHT | ||
| 32 | # define GDISP_INITIAL_BACKLIGHT 100 | ||
| 33 | # endif | ||
| 34 | |||
| 35 | # define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) | ||
| 36 | |||
| 37 | # include "st7565.h" | ||
| 38 | |||
| 39 | /*===========================================================================*/ | ||
| 40 | /* Driver config defaults for backward compatibility. */ | ||
| 41 | /*===========================================================================*/ | ||
| 42 | # ifndef ST7565_LCD_BIAS | ||
| 43 | # define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 | ||
| 44 | # endif | ||
| 45 | # ifndef ST7565_ADC | ||
| 46 | # define ST7565_ADC ST7565_ADC_NORMAL | ||
| 47 | # endif | ||
| 48 | # ifndef ST7565_COM_SCAN | ||
| 49 | # define ST7565_COM_SCAN ST7565_COM_SCAN_INC | ||
| 50 | # endif | ||
| 51 | # ifndef ST7565_PAGE_ORDER | ||
| 52 | # define ST7565_PAGE_ORDER 0, 1, 2, 3, 4, 5, 6, 7 | ||
| 53 | # endif | ||
| 54 | |||
| 55 | /*===========================================================================*/ | ||
| 56 | /* Driver local functions. */ | ||
| 57 | /*===========================================================================*/ | ||
| 58 | |||
| 59 | // Some common routines and macros | ||
| 60 | # define RAM(g) ((gU8 *)g->priv) | ||
| 61 | # define write_cmd2(g, cmd1, cmd2) \ | ||
| 62 | { \ | ||
| 63 | write_cmd(g, cmd1); \ | ||
| 64 | write_cmd(g, cmd2); \ | ||
| 65 | } | ||
| 66 | # define write_cmd3(g, cmd1, cmd2, cmd3) \ | ||
| 67 | { \ | ||
| 68 | write_cmd(g, cmd1); \ | ||
| 69 | write_cmd(g, cmd2); \ | ||
| 70 | write_cmd(g, cmd3); \ | ||
| 71 | } | ||
| 72 | |||
| 73 | // Some common routines and macros | ||
| 74 | # define delay(us) gfxSleepMicroseconds(us) | ||
| 75 | # define delay_ms(ms) gfxSleepMilliseconds(ms) | ||
| 76 | |||
| 77 | # define xyaddr(x, y) ((x) + ((y) >> 3) * GDISP_SCREEN_WIDTH) | ||
| 78 | # define xybit(y) (1 << ((y)&7)) | ||
| 79 | |||
| 80 | /*===========================================================================*/ | ||
| 81 | /* Driver exported functions. */ | ||
| 82 | /*===========================================================================*/ | ||
| 83 | |||
| 84 | /* | ||
| 85 | * As this controller can't update on a pixel boundary we need to maintain the | ||
| 86 | * the entire display surface in memory so that we can do the necessary bit | ||
| 87 | * operations. Fortunately it is a small display in monochrome. | ||
| 88 | * 64 * 128 / 8 = 1024 bytes. | ||
| 89 | */ | ||
| 90 | |||
| 91 | LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | ||
| 92 | // The private area is the display surface. | ||
| 93 | g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8); | ||
| 94 | if (!g->priv) { | ||
| 95 | return gFalse; | ||
| 96 | } | ||
| 97 | |||
| 98 | // Initialise the board interface | ||
| 99 | init_board(g); | ||
| 100 | |||
| 101 | // Hardware reset | ||
| 102 | setpin_reset(g, TRUE); | ||
| 103 | gfxSleepMilliseconds(20); | ||
| 104 | setpin_reset(g, FALSE); | ||
| 105 | gfxSleepMilliseconds(20); | ||
| 106 | acquire_bus(g); | ||
| 107 | |||
| 108 | write_cmd(g, ST7565_LCD_BIAS); | ||
| 109 | write_cmd(g, ST7565_ADC); | ||
| 110 | write_cmd(g, ST7565_COM_SCAN); | ||
| 111 | |||
| 112 | write_cmd(g, ST7565_START_LINE | 0); | ||
| 113 | |||
| 114 | write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST * 64 / 101); | ||
| 115 | write_cmd(g, ST7565_RESISTOR_RATIO | 0x1); | ||
| 116 | |||
| 117 | // turn on voltage converter (VC=1, VR=0, VF=0) | ||
| 118 | write_cmd(g, ST7565_POWER_CONTROL | 0x04); | ||
| 119 | delay_ms(50); | ||
| 120 | |||
| 121 | // turn on voltage regulator (VC=1, VR=1, VF=0) | ||
| 122 | write_cmd(g, ST7565_POWER_CONTROL | 0x06); | ||
| 123 | delay_ms(50); | ||
| 124 | |||
| 125 | // turn on voltage follower (VC=1, VR=1, VF=1) | ||
| 126 | write_cmd(g, ST7565_POWER_CONTROL | 0x07); | ||
| 127 | delay_ms(50); | ||
| 128 | |||
| 129 | write_cmd(g, ST7565_DISPLAY_ON); | ||
| 130 | write_cmd(g, ST7565_ALLON_NORMAL); | ||
| 131 | write_cmd(g, ST7565_INVERT_DISPLAY); // Disable Inversion of display. | ||
| 132 | |||
| 133 | write_cmd(g, ST7565_RMW); | ||
| 134 | |||
| 135 | // Finish Init | ||
| 136 | post_init_board(g); | ||
| 137 | |||
| 138 | // Release the bus | ||
| 139 | release_bus(g); | ||
| 140 | |||
| 141 | /* Initialise the GDISP structure */ | ||
| 142 | g->g.Width = GDISP_SCREEN_WIDTH; | ||
| 143 | g->g.Height = GDISP_SCREEN_HEIGHT; | ||
| 144 | g->g.Orientation = GDISP_ROTATE_0; | ||
| 145 | g->g.Powermode = powerOff; | ||
| 146 | g->g.Backlight = GDISP_INITIAL_BACKLIGHT; | ||
| 147 | g->g.Contrast = GDISP_INITIAL_CONTRAST; | ||
| 148 | return TRUE; | ||
| 149 | } | ||
| 150 | |||
| 151 | # if GDISP_HARDWARE_FLUSH | ||
| 152 | LLDSPEC void gdisp_lld_flush(GDisplay *g) { | ||
| 153 | unsigned p; | ||
| 154 | |||
| 155 | // Don't flush if we don't need it. | ||
| 156 | if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; | ||
| 157 | |||
| 158 | acquire_bus(g); | ||
| 159 | gU8 pagemap[] = {ST7565_PAGE_ORDER}; | ||
| 160 | for (p = 0; p < sizeof(pagemap); p++) { | ||
| 161 | write_cmd(g, ST7565_PAGE | pagemap[p]); | ||
| 162 | write_cmd(g, ST7565_COLUMN_MSB | 0); | ||
| 163 | write_cmd(g, ST7565_COLUMN_LSB | 0); | ||
| 164 | write_cmd(g, ST7565_RMW); | ||
| 165 | write_data(g, RAM(g) + (p * GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); | ||
| 166 | } | ||
| 167 | release_bus(g); | ||
| 168 | |||
| 169 | g->flags &= ~GDISP_FLG_NEEDFLUSH; | ||
| 170 | } | ||
| 171 | # endif | ||
| 172 | |||
| 173 | # if GDISP_HARDWARE_DRAWPIXEL | ||
| 174 | LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { | ||
| 175 | coord_t x, y; | ||
| 176 | |||
| 177 | switch (g->g.Orientation) { | ||
| 178 | default: | ||
| 179 | case GDISP_ROTATE_0: | ||
| 180 | x = g->p.x; | ||
| 181 | y = g->p.y; | ||
| 182 | break; | ||
| 183 | case GDISP_ROTATE_90: | ||
| 184 | x = g->p.y; | ||
| 185 | y = GDISP_SCREEN_HEIGHT - 1 - g->p.x; | ||
| 186 | break; | ||
| 187 | case GDISP_ROTATE_180: | ||
| 188 | x = GDISP_SCREEN_WIDTH - 1 - g->p.x; | ||
| 189 | y = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||
| 190 | break; | ||
| 191 | case GDISP_ROTATE_270: | ||
| 192 | x = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||
| 193 | y = g->p.x; | ||
| 194 | break; | ||
| 195 | } | ||
| 196 | if (gdispColor2Native(g->p.color) != Black) | ||
| 197 | RAM(g)[xyaddr(x, y)] |= xybit(y); | ||
| 198 | else | ||
| 199 | RAM(g)[xyaddr(x, y)] &= ~xybit(y); | ||
| 200 | g->flags |= GDISP_FLG_NEEDFLUSH; | ||
| 201 | } | ||
| 202 | # endif | ||
| 203 | |||
| 204 | # if GDISP_HARDWARE_PIXELREAD | ||
| 205 | LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { | ||
| 206 | coord_t x, y; | ||
| 207 | |||
| 208 | switch (g->g.Orientation) { | ||
| 209 | default: | ||
| 210 | case GDISP_ROTATE_0: | ||
| 211 | x = g->p.x; | ||
| 212 | y = g->p.y; | ||
| 213 | break; | ||
| 214 | case GDISP_ROTATE_90: | ||
| 215 | x = g->p.y; | ||
| 216 | y = GDISP_SCREEN_HEIGHT - 1 - g->p.x; | ||
| 217 | break; | ||
| 218 | case GDISP_ROTATE_180: | ||
| 219 | x = GDISP_SCREEN_WIDTH - 1 - g->p.x; | ||
| 220 | y = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||
| 221 | break; | ||
| 222 | case GDISP_ROTATE_270: | ||
| 223 | x = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||
| 224 | y = g->p.x; | ||
| 225 | break; | ||
| 226 | } | ||
| 227 | return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; | ||
| 228 | } | ||
| 229 | # endif | ||
| 230 | |||
| 231 | # if GDISP_HARDWARE_BITFILLS | ||
| 232 | LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { | ||
| 233 | uint8_t *buffer = (uint8_t *)g->p.ptr; | ||
| 234 | int linelength = g->p.cx; | ||
| 235 | for (int i = 0; i < g->p.cy; i++) { | ||
| 236 | unsigned dstx = g->p.x; | ||
| 237 | unsigned dsty = g->p.y + i; | ||
| 238 | unsigned srcx = g->p.x1; | ||
| 239 | unsigned srcy = g->p.y1 + i; | ||
| 240 | unsigned srcbit = srcy * g->p.x2 + srcx; | ||
| 241 | for (int j = 0; j < linelength; j++) { | ||
| 242 | uint8_t src = buffer[srcbit / 8]; | ||
| 243 | uint8_t bit = 7 - (srcbit % 8); | ||
| 244 | uint8_t bitset = (src >> bit) & 1; | ||
| 245 | uint8_t *dst = &(RAM(g)[xyaddr(dstx, dsty)]); | ||
| 246 | if (bitset) { | ||
| 247 | *dst |= xybit(dsty); | ||
| 248 | } else { | ||
| 249 | *dst &= ~xybit(dsty); | ||
| 250 | } | ||
| 251 | dstx++; | ||
| 252 | srcbit++; | ||
| 253 | } | ||
| 254 | } | ||
| 255 | g->flags |= GDISP_FLG_NEEDFLUSH; | ||
| 256 | } | ||
| 257 | # endif | ||
| 258 | |||
| 259 | # if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | ||
| 260 | LLDSPEC void gdisp_lld_control(GDisplay *g) { | ||
| 261 | switch (g->p.x) { | ||
| 262 | case GDISP_CONTROL_POWER: | ||
| 263 | if (g->g.Powermode == (powermode_t)g->p.ptr) return; | ||
| 264 | switch ((powermode_t)g->p.ptr) { | ||
| 265 | case powerOff: | ||
| 266 | case powerSleep: | ||
| 267 | case powerDeepSleep: | ||
| 268 | acquire_bus(g); | ||
| 269 | write_cmd(g, ST7565_DISPLAY_OFF); | ||
| 270 | release_bus(g); | ||
| 271 | break; | ||
| 272 | case powerOn: | ||
| 273 | acquire_bus(g); | ||
| 274 | write_cmd(g, ST7565_DISPLAY_ON); | ||
| 275 | release_bus(g); | ||
| 276 | break; | ||
| 277 | default: | ||
| 278 | return; | ||
| 279 | } | ||
| 280 | g->g.Powermode = (powermode_t)g->p.ptr; | ||
| 281 | return; | ||
| 282 | |||
| 283 | case GDISP_CONTROL_ORIENTATION: | ||
| 284 | if (g->g.Orientation == (orientation_t)g->p.ptr) return; | ||
| 285 | switch ((orientation_t)g->p.ptr) { | ||
| 286 | /* Rotation is handled by the drawing routines */ | ||
| 287 | case GDISP_ROTATE_0: | ||
| 288 | case GDISP_ROTATE_180: | ||
| 289 | g->g.Height = GDISP_SCREEN_HEIGHT; | ||
| 290 | g->g.Width = GDISP_SCREEN_WIDTH; | ||
| 291 | break; | ||
| 292 | case GDISP_ROTATE_90: | ||
| 293 | case GDISP_ROTATE_270: | ||
| 294 | g->g.Height = GDISP_SCREEN_WIDTH; | ||
| 295 | g->g.Width = GDISP_SCREEN_HEIGHT; | ||
| 296 | break; | ||
| 297 | default: | ||
| 298 | return; | ||
| 299 | } | ||
| 300 | g->g.Orientation = (orientation_t)g->p.ptr; | ||
| 301 | return; | ||
| 302 | |||
| 303 | case GDISP_CONTROL_CONTRAST: | ||
| 304 | if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; | ||
| 305 | acquire_bus(g); | ||
| 306 | write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr) << 6) / 101) & 0x3F); | ||
| 307 | release_bus(g); | ||
| 308 | g->g.Contrast = (unsigned)g->p.ptr; | ||
| 309 | return; | ||
| 310 | } | ||
| 311 | } | ||
| 312 | # endif // GDISP_NEED_CONTROL | ||
| 313 | |||
| 314 | #endif // GFX_USE_GDISP | ||
