diff options
Diffstat (limited to 'drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c')
| -rw-r--r-- | drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c | 76 |
1 files changed, 29 insertions, 47 deletions
diff --git a/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c b/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c index fde320981..f586f97e3 100644 --- a/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c +++ b/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c | |||
| @@ -49,31 +49,15 @@ | |||
| 49 | # define ST7565_COM_SCAN ST7565_COM_SCAN_INC | 49 | # define ST7565_COM_SCAN ST7565_COM_SCAN_INC |
| 50 | # endif | 50 | # endif |
| 51 | # ifndef ST7565_PAGE_ORDER | 51 | # ifndef ST7565_PAGE_ORDER |
| 52 | # define ST7565_PAGE_ORDER 0, 1, 2, 3 | 52 | # define ST7565_PAGE_ORDER 0, 1, 2, 3, 4, 5, 6, 7 |
| 53 | # endif | 53 | # endif |
| 54 | 54 | ||
| 55 | /*===========================================================================*/ | 55 | /*===========================================================================*/ |
| 56 | /* Driver local functions. */ | 56 | /* Driver local functions. */ |
| 57 | /*===========================================================================*/ | 57 | /*===========================================================================*/ |
| 58 | 58 | ||
| 59 | typedef struct { | ||
| 60 | bool_t buffer2; | ||
| 61 | uint8_t data_pos; | ||
| 62 | uint8_t data[16]; | ||
| 63 | uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; | ||
| 64 | } PrivData; | ||
| 65 | |||
| 66 | // Some common routines and macros | 59 | // Some common routines and macros |
| 67 | # define PRIV(g) ((PrivData *)g->priv) | 60 | # define RAM(g) ((gU8 *)g->priv) |
| 68 | # define RAM(g) (PRIV(g)->ram) | ||
| 69 | |||
| 70 | static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) { PRIV(g)->data[PRIV(g)->data_pos++] = cmd; } | ||
| 71 | |||
| 72 | static GFXINLINE void flush_cmd(GDisplay *g) { | ||
| 73 | write_data(g, PRIV(g)->data, PRIV(g)->data_pos); | ||
| 74 | PRIV(g)->data_pos = 0; | ||
| 75 | } | ||
| 76 | |||
| 77 | # define write_cmd2(g, cmd1, cmd2) \ | 61 | # define write_cmd2(g, cmd1, cmd2) \ |
| 78 | { \ | 62 | { \ |
| 79 | write_cmd(g, cmd1); \ | 63 | write_cmd(g, cmd1); \ |
| @@ -106,9 +90,10 @@ static GFXINLINE void flush_cmd(GDisplay *g) { | |||
| 106 | 90 | ||
| 107 | LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | 91 | LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { |
| 108 | // The private area is the display surface. | 92 | // The private area is the display surface. |
| 109 | g->priv = gfxAlloc(sizeof(PrivData)); | 93 | g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8); |
| 110 | PRIV(g)->buffer2 = false; | 94 | if (!g->priv) { |
| 111 | PRIV(g)->data_pos = 0; | 95 | return gFalse; |
| 96 | } | ||
| 112 | 97 | ||
| 113 | // Initialise the board interface | 98 | // Initialise the board interface |
| 114 | init_board(g); | 99 | init_board(g); |
| @@ -119,25 +104,33 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||
| 119 | setpin_reset(g, FALSE); | 104 | setpin_reset(g, FALSE); |
| 120 | gfxSleepMilliseconds(20); | 105 | gfxSleepMilliseconds(20); |
| 121 | acquire_bus(g); | 106 | acquire_bus(g); |
| 122 | enter_cmd_mode(g); | ||
| 123 | 107 | ||
| 124 | write_cmd(g, ST7565_RESET); | ||
| 125 | write_cmd(g, ST7565_LCD_BIAS); | 108 | write_cmd(g, ST7565_LCD_BIAS); |
| 126 | write_cmd(g, ST7565_ADC); | 109 | write_cmd(g, ST7565_ADC); |
| 127 | write_cmd(g, ST7565_COM_SCAN); | 110 | write_cmd(g, ST7565_COM_SCAN); |
| 128 | 111 | ||
| 112 | write_cmd(g, ST7565_START_LINE | 0); | ||
| 113 | |||
| 114 | write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST * 64 / 101); | ||
| 129 | write_cmd(g, ST7565_RESISTOR_RATIO | 0x1); | 115 | write_cmd(g, ST7565_RESISTOR_RATIO | 0x1); |
| 130 | write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST); | ||
| 131 | 116 | ||
| 132 | // turn on internal power supply (VC=1, VR=1, VF=1) | 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) | ||
| 133 | write_cmd(g, ST7565_POWER_CONTROL | 0x07); | 126 | write_cmd(g, ST7565_POWER_CONTROL | 0x07); |
| 127 | delay_ms(50); | ||
| 134 | 128 | ||
| 135 | write_cmd(g, ST7565_INVERT_DISPLAY); | 129 | write_cmd(g, ST7565_DISPLAY_ON); |
| 136 | write_cmd(g, ST7565_ALLON_NORMAL); | 130 | write_cmd(g, ST7565_ALLON_NORMAL); |
| 131 | write_cmd(g, ST7565_INVERT_DISPLAY); // Disable Inversion of display. | ||
| 137 | 132 | ||
| 138 | write_cmd(g, ST7565_START_LINE | 0); | ||
| 139 | write_cmd(g, ST7565_RMW); | 133 | write_cmd(g, ST7565_RMW); |
| 140 | flush_cmd(g); | ||
| 141 | 134 | ||
| 142 | // Finish Init | 135 | // Finish Init |
| 143 | post_init_board(g); | 136 | post_init_board(g); |
| @@ -163,22 +156,14 @@ LLDSPEC void gdisp_lld_flush(GDisplay *g) { | |||
| 163 | if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; | 156 | if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; |
| 164 | 157 | ||
| 165 | acquire_bus(g); | 158 | acquire_bus(g); |
| 166 | enter_cmd_mode(g); | 159 | gU8 pagemap[] = {ST7565_PAGE_ORDER}; |
| 167 | unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); | 160 | for (p = 0; p < sizeof(pagemap); p++) { |
| 168 | for (p = 0; p < 4; p++) { | 161 | write_cmd(g, ST7565_PAGE | pagemap[p]); |
| 169 | write_cmd(g, ST7565_PAGE | (p + dstOffset)); | ||
| 170 | write_cmd(g, ST7565_COLUMN_MSB | 0); | 162 | write_cmd(g, ST7565_COLUMN_MSB | 0); |
| 171 | write_cmd(g, ST7565_COLUMN_LSB | 0); | 163 | write_cmd(g, ST7565_COLUMN_LSB | 0); |
| 172 | write_cmd(g, ST7565_RMW); | 164 | write_cmd(g, ST7565_RMW); |
| 173 | flush_cmd(g); | ||
| 174 | enter_data_mode(g); | ||
| 175 | write_data(g, RAM(g) + (p * GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); | 165 | write_data(g, RAM(g) + (p * GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); |
| 176 | enter_cmd_mode(g); | ||
| 177 | } | 166 | } |
| 178 | unsigned line = (PRIV(g)->buffer2 ? 32 : 0); | ||
| 179 | write_cmd(g, ST7565_START_LINE | line); | ||
| 180 | flush_cmd(g); | ||
| 181 | PRIV(g)->buffer2 = !PRIV(g)->buffer2; | ||
| 182 | release_bus(g); | 167 | release_bus(g); |
| 183 | 168 | ||
| 184 | g->flags &= ~GDISP_FLG_NEEDFLUSH; | 169 | g->flags &= ~GDISP_FLG_NEEDFLUSH; |
| @@ -243,6 +228,7 @@ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { | |||
| 243 | } | 228 | } |
| 244 | # endif | 229 | # endif |
| 245 | 230 | ||
| 231 | # if GDISP_HARDWARE_BITFILLS | ||
| 246 | LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { | 232 | LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { |
| 247 | uint8_t *buffer = (uint8_t *)g->p.ptr; | 233 | uint8_t *buffer = (uint8_t *)g->p.ptr; |
| 248 | int linelength = g->p.cx; | 234 | int linelength = g->p.cx; |
| @@ -268,6 +254,7 @@ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { | |||
| 268 | } | 254 | } |
| 269 | g->flags |= GDISP_FLG_NEEDFLUSH; | 255 | g->flags |= GDISP_FLG_NEEDFLUSH; |
| 270 | } | 256 | } |
| 257 | # endif | ||
| 271 | 258 | ||
| 272 | # if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | 259 | # if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL |
| 273 | LLDSPEC void gdisp_lld_control(GDisplay *g) { | 260 | LLDSPEC void gdisp_lld_control(GDisplay *g) { |
| @@ -279,16 +266,12 @@ LLDSPEC void gdisp_lld_control(GDisplay *g) { | |||
| 279 | case powerSleep: | 266 | case powerSleep: |
| 280 | case powerDeepSleep: | 267 | case powerDeepSleep: |
| 281 | acquire_bus(g); | 268 | acquire_bus(g); |
| 282 | enter_cmd_mode(g); | ||
| 283 | write_cmd(g, ST7565_DISPLAY_OFF); | 269 | write_cmd(g, ST7565_DISPLAY_OFF); |
| 284 | flush_cmd(g); | ||
| 285 | release_bus(g); | 270 | release_bus(g); |
| 286 | break; | 271 | break; |
| 287 | case powerOn: | 272 | case powerOn: |
| 288 | acquire_bus(g); | 273 | acquire_bus(g); |
| 289 | enter_cmd_mode(g); | ||
| 290 | write_cmd(g, ST7565_DISPLAY_ON); | 274 | write_cmd(g, ST7565_DISPLAY_ON); |
| 291 | flush_cmd(g); | ||
| 292 | release_bus(g); | 275 | release_bus(g); |
| 293 | break; | 276 | break; |
| 294 | default: | 277 | default: |
| @@ -318,12 +301,11 @@ LLDSPEC void gdisp_lld_control(GDisplay *g) { | |||
| 318 | return; | 301 | return; |
| 319 | 302 | ||
| 320 | case GDISP_CONTROL_CONTRAST: | 303 | case GDISP_CONTROL_CONTRAST: |
| 321 | g->g.Contrast = (unsigned)g->p.ptr & 63; | 304 | if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; |
| 322 | acquire_bus(g); | 305 | acquire_bus(g); |
| 323 | enter_cmd_mode(g); | 306 | write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr) << 6) / 101) & 0x3F); |
| 324 | write_cmd2(g, ST7565_CONTRAST, g->g.Contrast); | ||
| 325 | flush_cmd(g); | ||
| 326 | release_bus(g); | 307 | release_bus(g); |
| 308 | g->g.Contrast = (unsigned)g->p.ptr; | ||
| 327 | return; | 309 | return; |
| 328 | } | 310 | } |
| 329 | } | 311 | } |
