diff options
| author | Fred Sundvik <fsundvik@gmail.com> | 2017-03-31 23:58:10 +0300 |
|---|---|---|
| committer | Fred Sundvik <fsundvik@gmail.com> | 2017-04-09 18:34:59 +0300 |
| commit | 2b24d35846693a3365a35b6ee9bc31b70659cfcf (patch) | |
| tree | 5c40b615290e6847e24d432ab4b621fd1f5a4a09 /keyboards | |
| parent | 503565d1742ed458c992192a05f6ffe1db053135 (diff) | |
| download | qmk_firmware-2b24d35846693a3365a35b6ee9bc31b70659cfcf.tar.gz qmk_firmware-2b24d35846693a3365a35b6ee9bc31b70659cfcf.zip | |
Hopefully finally fix the corrupt LCD
The SPI bus is now selected and deselected before each set of commands.
Also speed up things by buffering many commands into a single batch.
Diffstat (limited to 'keyboards')
| -rw-r--r-- | keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h | 46 | ||||
| -rw-r--r-- | keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c | 393 |
2 files changed, 228 insertions, 211 deletions
diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h index abda0bd85..c2092b5e8 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h | |||
| @@ -37,10 +37,14 @@ | |||
| 37 | // MSB First | 37 | // MSB First |
| 38 | // CLK Low by default | 38 | // CLK Low by default |
| 39 | static const SPIConfig spi1config = { | 39 | static const SPIConfig spi1config = { |
| 40 | NULL, | 40 | // Operation complete callback or @p NULL. |
| 41 | /* HW dependent part.*/ | 41 | .end_cb = NULL, |
| 42 | ST7565_GPIOPORT, | 42 | //The chip select line port - when not using pcs. |
| 43 | ST7565_SS_PIN, | 43 | .ssport = ST7565_GPIOPORT, |
| 44 | // brief The chip select line pad number - when not using pcs. | ||
| 45 | .sspad=ST7565_SS_PIN, | ||
| 46 | // SPI initialization data. | ||
| 47 | .tar0 = | ||
| 44 | SPIx_CTARn_FMSZ(7) | 48 | SPIx_CTARn_FMSZ(7) |
| 45 | | SPIx_CTARn_ASC(7) | 49 | | SPIx_CTARn_ASC(7) |
| 46 | | SPIx_CTARn_DT(7) | 50 | | SPIx_CTARn_DT(7) |
| @@ -50,13 +54,10 @@ static const SPIConfig spi1config = { | |||
| 50 | //SPI_CR1_BR_0 | 54 | //SPI_CR1_BR_0 |
| 51 | }; | 55 | }; |
| 52 | 56 | ||
| 53 | static bool_t st7565_is_data_mode = 1; | ||
| 54 | |||
| 55 | static GFXINLINE void init_board(GDisplay *g) { | 57 | static GFXINLINE void init_board(GDisplay *g) { |
| 56 | (void) g; | 58 | (void) g; |
| 57 | palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); | 59 | palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); |
| 58 | palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); | 60 | palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); |
| 59 | st7565_is_data_mode = 1; | ||
| 60 | palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); | 61 | palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); |
| 61 | palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); | 62 | palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); |
| 62 | palSetPadModeRaw(MOSI, ST7565_SPI_MODE); | 63 | palSetPadModeRaw(MOSI, ST7565_SPI_MODE); |
| @@ -65,7 +66,6 @@ static GFXINLINE void init_board(GDisplay *g) { | |||
| 65 | 66 | ||
| 66 | spiInit(); | 67 | spiInit(); |
| 67 | spiStart(&SPID1, &spi1config); | 68 | spiStart(&SPID1, &spi1config); |
| 68 | spiSelect(&SPID1); | ||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static GFXINLINE void post_init_board(GDisplay *g) { | 71 | static GFXINLINE void post_init_board(GDisplay *g) { |
| @@ -86,39 +86,27 @@ static GFXINLINE void acquire_bus(GDisplay *g) { | |||
| 86 | (void) g; | 86 | (void) g; |
| 87 | // Only the LCD is using the SPI bus, so no need to acquire | 87 | // Only the LCD is using the SPI bus, so no need to acquire |
| 88 | // spiAcquireBus(&SPID1); | 88 | // spiAcquireBus(&SPID1); |
| 89 | spiSelect(&SPID1); | ||
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | static GFXINLINE void release_bus(GDisplay *g) { | 92 | static GFXINLINE void release_bus(GDisplay *g) { |
| 92 | (void) g; | 93 | (void) g; |
| 93 | // Only the LCD is using the SPI bus, so no need to release | 94 | // Only the LCD is using the SPI bus, so no need to release |
| 94 | //spiReleaseBus(&SPID1); | 95 | //spiReleaseBus(&SPID1); |
| 96 | spiUnselect(&SPID1); | ||
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) { | 99 | static GFXINLINE void enter_data_mode(GDisplay *g) { |
| 98 | (void) g; | 100 | palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); |
| 99 | if (st7565_is_data_mode) { | 101 | } |
| 100 | // The sleeps need to be at lest 10 vs 25 ns respectively | 102 | |
| 101 | // So let's sleep two ticks, one tick might not be enough | 103 | static GFXINLINE void enter_cmd_mode(GDisplay *g) { |
| 102 | // if we are at the end of the tick | 104 | palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); |
| 103 | chThdSleep(2); | ||
| 104 | palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||
| 105 | chThdSleep(2); | ||
| 106 | st7565_is_data_mode = 0; | ||
| 107 | } | ||
| 108 | spiSend(&SPID1, 1, &cmd); | ||
| 109 | } | 105 | } |
| 110 | 106 | ||
| 107 | |||
| 111 | static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { | 108 | static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { |
| 112 | (void) g; | 109 | (void) g; |
| 113 | if (!st7565_is_data_mode) { | ||
| 114 | // The sleeps need to be at lest 10 vs 25 ns respectively | ||
| 115 | // So let's sleep two ticks, one tick might not be enough | ||
| 116 | // if we are at the end of the tick | ||
| 117 | chThdSleep(2); | ||
| 118 | palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||
| 119 | chThdSleep(2); | ||
| 120 | st7565_is_data_mode = 1; | ||
| 121 | } | ||
| 122 | spiSend(&SPID1, length, data); | 110 | spiSend(&SPID1, length, data); |
| 123 | } | 111 | } |
| 124 | 112 | ||
diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c index c33aea81a..4547f1419 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c | |||
| @@ -20,16 +20,16 @@ | |||
| 20 | /*===========================================================================*/ | 20 | /*===========================================================================*/ |
| 21 | 21 | ||
| 22 | #ifndef GDISP_SCREEN_HEIGHT | 22 | #ifndef GDISP_SCREEN_HEIGHT |
| 23 | #define GDISP_SCREEN_HEIGHT 32 | 23 | #define GDISP_SCREEN_HEIGHT 32 |
| 24 | #endif | 24 | #endif |
| 25 | #ifndef GDISP_SCREEN_WIDTH | 25 | #ifndef GDISP_SCREEN_WIDTH |
| 26 | #define GDISP_SCREEN_WIDTH 128 | 26 | #define GDISP_SCREEN_WIDTH 128 |
| 27 | #endif | 27 | #endif |
| 28 | #ifndef GDISP_INITIAL_CONTRAST | 28 | #ifndef GDISP_INITIAL_CONTRAST |
| 29 | #define GDISP_INITIAL_CONTRAST 0 | 29 | #define GDISP_INITIAL_CONTRAST 0 |
| 30 | #endif | 30 | #endif |
| 31 | #ifndef GDISP_INITIAL_BACKLIGHT | 31 | #ifndef GDISP_INITIAL_BACKLIGHT |
| 32 | #define GDISP_INITIAL_BACKLIGHT 100 | 32 | #define GDISP_INITIAL_BACKLIGHT 100 |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | #define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) | 35 | #define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) |
| @@ -40,16 +40,16 @@ | |||
| 40 | /* Driver config defaults for backward compatibility. */ | 40 | /* Driver config defaults for backward compatibility. */ |
| 41 | /*===========================================================================*/ | 41 | /*===========================================================================*/ |
| 42 | #ifndef ST7565_LCD_BIAS | 42 | #ifndef ST7565_LCD_BIAS |
| 43 | #define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 | 43 | #define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 |
| 44 | #endif | 44 | #endif |
| 45 | #ifndef ST7565_ADC | 45 | #ifndef ST7565_ADC |
| 46 | #define ST7565_ADC ST7565_ADC_NORMAL | 46 | #define ST7565_ADC ST7565_ADC_NORMAL |
| 47 | #endif | 47 | #endif |
| 48 | #ifndef ST7565_COM_SCAN | 48 | #ifndef ST7565_COM_SCAN |
| 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 |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | /*===========================================================================*/ | 55 | /*===========================================================================*/ |
| @@ -58,12 +58,24 @@ | |||
| 58 | 58 | ||
| 59 | typedef struct{ | 59 | typedef struct{ |
| 60 | bool_t buffer2; | 60 | bool_t buffer2; |
| 61 | uint8_t data_pos; | ||
| 62 | uint8_t data[16]; | ||
| 61 | uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; | 63 | uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; |
| 62 | }PrivData; | 64 | }PrivData; |
| 63 | 65 | ||
| 64 | // Some common routines and macros | 66 | // Some common routines and macros |
| 65 | #define PRIV(g) ((PrivData*)g->priv) | 67 | #define PRIV(g) ((PrivData*)g->priv) |
| 66 | #define RAM(g) (PRIV(g)->ram) | 68 | #define RAM(g) (PRIV(g)->ram) |
| 69 | |||
| 70 | static GFXINLINE void write_cmd(GDisplay* g, uint8_t cmd) { | ||
| 71 | PRIV(g)->data[PRIV(g)->data_pos++] = cmd; | ||
| 72 | } | ||
| 73 | |||
| 74 | static GFXINLINE void flush_cmd(GDisplay* g) { | ||
| 75 | write_data(g, PRIV(g)->data, PRIV(g)->data_pos); | ||
| 76 | PRIV(g)->data_pos = 0; | ||
| 77 | } | ||
| 78 | |||
| 67 | #define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); } | 79 | #define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); } |
| 68 | #define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } | 80 | #define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } |
| 69 | 81 | ||
| @@ -86,207 +98,224 @@ typedef struct{ | |||
| 86 | */ | 98 | */ |
| 87 | 99 | ||
| 88 | LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | 100 | LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { |
| 89 | // The private area is the display surface. | 101 | // The private area is the display surface. |
| 90 | g->priv = gfxAlloc(sizeof(PrivData)); | 102 | g->priv = gfxAlloc(sizeof(PrivData)); |
| 91 | PRIV(g)->buffer2 = false; | 103 | PRIV(g)->buffer2 = false; |
| 92 | 104 | PRIV(g)->data_pos = 0; | |
| 93 | // Initialise the board interface | 105 | |
| 94 | init_board(g); | 106 | // Initialise the board interface |
| 95 | 107 | init_board(g); | |
| 96 | // Hardware reset | 108 | |
| 97 | setpin_reset(g, TRUE); | 109 | // Hardware reset |
| 98 | gfxSleepMilliseconds(20); | 110 | setpin_reset(g, TRUE); |
| 99 | setpin_reset(g, FALSE); | 111 | gfxSleepMilliseconds(20); |
| 100 | gfxSleepMilliseconds(20); | 112 | setpin_reset(g, FALSE); |
| 101 | 113 | gfxSleepMilliseconds(20); | |
| 102 | acquire_bus(g); | 114 | |
| 115 | acquire_bus(g); | ||
| 116 | enter_cmd_mode(g); | ||
| 103 | write_cmd(g, ST7565_DISPLAY_OFF); | 117 | write_cmd(g, ST7565_DISPLAY_OFF); |
| 104 | write_cmd(g, ST7565_LCD_BIAS); | 118 | write_cmd(g, ST7565_LCD_BIAS); |
| 105 | write_cmd(g, ST7565_ADC); | 119 | write_cmd(g, ST7565_ADC); |
| 106 | write_cmd(g, ST7565_COM_SCAN); | 120 | write_cmd(g, ST7565_COM_SCAN); |
| 107 | 121 | ||
| 108 | write_cmd(g, ST7565_START_LINE | 0); | 122 | write_cmd(g, ST7565_START_LINE | 0); |
| 109 | 123 | ||
| 110 | write_cmd(g, ST7565_RESISTOR_RATIO | 0x6); | 124 | write_cmd(g, ST7565_RESISTOR_RATIO | 0x6); |
| 111 | 125 | ||
| 112 | // turn on voltage converter (VC=1, VR=0, VF=0) | 126 | // turn on voltage converter (VC=1, VR=0, VF=0) |
| 113 | write_cmd(g, ST7565_POWER_CONTROL | 0x04); | 127 | write_cmd(g, ST7565_POWER_CONTROL | 0x04); |
| 114 | delay_ms(50); | 128 | flush_cmd(g); |
| 129 | delay_ms(50); | ||
| 115 | 130 | ||
| 116 | // turn on voltage regulator (VC=1, VR=1, VF=0) | 131 | // turn on voltage regulator (VC=1, VR=1, VF=0) |
| 117 | write_cmd(g, ST7565_POWER_CONTROL | 0x06); | 132 | write_cmd(g, ST7565_POWER_CONTROL | 0x06); |
| 118 | delay_ms(50); | 133 | flush_cmd(g); |
| 134 | delay_ms(50); | ||
| 119 | 135 | ||
| 120 | // turn on voltage follower (VC=1, VR=1, VF=1) | 136 | // turn on voltage follower (VC=1, VR=1, VF=1) |
| 121 | write_cmd(g, ST7565_POWER_CONTROL | 0x07); | 137 | write_cmd(g, ST7565_POWER_CONTROL | 0x07); |
| 122 | delay_ms(50); | 138 | flush_cmd(g); |
| 139 | delay_ms(50); | ||
| 123 | 140 | ||
| 124 | write_cmd(g, 0xE2); | 141 | write_cmd(g, 0xE2); |
| 125 | write_cmd(g, ST7565_COM_SCAN); | 142 | write_cmd(g, ST7565_COM_SCAN); |
| 126 | write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101); | 143 | write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101); |
| 127 | //write_cmd2(g, ST7565_CONTRAST, 0); | 144 | //write_cmd2(g, ST7565_CONTRAST, 0); |
| 128 | write_cmd(g, ST7565_DISPLAY_ON); | 145 | write_cmd(g, ST7565_DISPLAY_ON); |
| 129 | write_cmd(g, ST7565_ALLON_NORMAL); | 146 | write_cmd(g, ST7565_ALLON_NORMAL); |
| 130 | write_cmd(g, ST7565_INVERT_DISPLAY); | 147 | write_cmd(g, ST7565_INVERT_DISPLAY); |
| 131 | 148 | ||
| 132 | write_cmd(g, ST7565_RMW); | 149 | write_cmd(g, ST7565_RMW); |
| 150 | flush_cmd(g); | ||
| 133 | 151 | ||
| 134 | // Finish Init | 152 | // Finish Init |
| 135 | post_init_board(g); | 153 | post_init_board(g); |
| 136 | 154 | ||
| 137 | // Release the bus | 155 | // Release the bus |
| 138 | release_bus(g); | 156 | release_bus(g); |
| 139 | 157 | ||
| 140 | /* Initialise the GDISP structure */ | 158 | /* Initialise the GDISP structure */ |
| 141 | g->g.Width = GDISP_SCREEN_WIDTH; | 159 | g->g.Width = GDISP_SCREEN_WIDTH; |
| 142 | g->g.Height = GDISP_SCREEN_HEIGHT; | 160 | g->g.Height = GDISP_SCREEN_HEIGHT; |
| 143 | g->g.Orientation = GDISP_ROTATE_0; | 161 | g->g.Orientation = GDISP_ROTATE_0; |
| 144 | g->g.Powermode = powerOn; | 162 | g->g.Powermode = powerOn; |
| 145 | g->g.Backlight = GDISP_INITIAL_BACKLIGHT; | 163 | g->g.Backlight = GDISP_INITIAL_BACKLIGHT; |
| 146 | g->g.Contrast = GDISP_INITIAL_CONTRAST; | 164 | g->g.Contrast = GDISP_INITIAL_CONTRAST; |
| 147 | return TRUE; | 165 | return TRUE; |
| 148 | } | 166 | } |
| 149 | 167 | ||
| 150 | #if GDISP_HARDWARE_FLUSH | 168 | #if GDISP_HARDWARE_FLUSH |
| 151 | LLDSPEC void gdisp_lld_flush(GDisplay *g) { | 169 | LLDSPEC void gdisp_lld_flush(GDisplay *g) { |
| 152 | unsigned p; | 170 | unsigned p; |
| 153 | 171 | ||
| 154 | // Don't flush if we don't need it. | 172 | // Don't flush if we don't need it. |
| 155 | if (!(g->flags & GDISP_FLG_NEEDFLUSH)) | 173 | if (!(g->flags & GDISP_FLG_NEEDFLUSH)) |
| 156 | return; | 174 | return; |
| 157 | 175 | ||
| 158 | acquire_bus(g); | 176 | acquire_bus(g); |
| 159 | unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); | 177 | enter_cmd_mode(g); |
| 160 | for (p = 0; p < 4; p++) { | 178 | unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); |
| 161 | write_cmd(g, ST7565_PAGE | (p + dstOffset)); | 179 | for (p = 0; p < 4; p++) { |
| 162 | write_cmd(g, ST7565_COLUMN_MSB | 0); | 180 | write_cmd(g, ST7565_PAGE | (p + dstOffset)); |
| 163 | write_cmd(g, ST7565_COLUMN_LSB | 0); | 181 | write_cmd(g, ST7565_COLUMN_MSB | 0); |
| 164 | write_cmd(g, ST7565_RMW); | 182 | write_cmd(g, ST7565_COLUMN_LSB | 0); |
| 165 | write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); | 183 | write_cmd(g, ST7565_RMW); |
| 166 | } | 184 | flush_cmd(g); |
| 167 | unsigned line = (PRIV(g)->buffer2 ? 32 : 0); | 185 | enter_data_mode(g); |
| 168 | write_cmd(g, ST7565_START_LINE | line); | 186 | write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); |
| 169 | PRIV(g)->buffer2 = !PRIV(g)->buffer2; | 187 | enter_cmd_mode(g); |
| 170 | release_bus(g); | 188 | } |
| 171 | 189 | unsigned line = (PRIV(g)->buffer2 ? 32 : 0); | |
| 172 | g->flags &= ~GDISP_FLG_NEEDFLUSH; | 190 | write_cmd(g, ST7565_START_LINE | line); |
| 173 | } | 191 | flush_cmd(g); |
| 192 | PRIV(g)->buffer2 = !PRIV(g)->buffer2; | ||
| 193 | release_bus(g); | ||
| 194 | |||
| 195 | g->flags &= ~GDISP_FLG_NEEDFLUSH; | ||
| 196 | } | ||
| 174 | #endif | 197 | #endif |
| 175 | 198 | ||
| 176 | #if GDISP_HARDWARE_DRAWPIXEL | 199 | #if GDISP_HARDWARE_DRAWPIXEL |
| 177 | LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { | 200 | LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { |
| 178 | coord_t x, y; | 201 | coord_t x, y; |
| 179 | 202 | ||
| 180 | switch(g->g.Orientation) { | 203 | switch(g->g.Orientation) { |
| 181 | default: | 204 | default: |
| 182 | case GDISP_ROTATE_0: | 205 | case GDISP_ROTATE_0: |
| 183 | x = g->p.x; | 206 | x = g->p.x; |
| 184 | y = g->p.y; | 207 | y = g->p.y; |
| 185 | break; | 208 | break; |
| 186 | case GDISP_ROTATE_90: | 209 | case GDISP_ROTATE_90: |
| 187 | x = g->p.y; | 210 | x = g->p.y; |
| 188 | y = GDISP_SCREEN_HEIGHT-1 - g->p.x; | 211 | y = GDISP_SCREEN_HEIGHT-1 - g->p.x; |
| 189 | break; | 212 | break; |
| 190 | case GDISP_ROTATE_180: | 213 | case GDISP_ROTATE_180: |
| 191 | x = GDISP_SCREEN_WIDTH-1 - g->p.x; | 214 | x = GDISP_SCREEN_WIDTH-1 - g->p.x; |
| 192 | y = GDISP_SCREEN_HEIGHT-1 - g->p.y; | 215 | y = GDISP_SCREEN_HEIGHT-1 - g->p.y; |
| 193 | break; | 216 | break; |
| 194 | case GDISP_ROTATE_270: | 217 | case GDISP_ROTATE_270: |
| 195 | x = GDISP_SCREEN_HEIGHT-1 - g->p.y; | 218 | x = GDISP_SCREEN_HEIGHT-1 - g->p.y; |
| 196 | y = g->p.x; | 219 | y = g->p.x; |
| 197 | break; | 220 | break; |
| 198 | } | 221 | } |
| 199 | if (gdispColor2Native(g->p.color) != Black) | 222 | if (gdispColor2Native(g->p.color) != Black) |
| 200 | RAM(g)[xyaddr(x, y)] |= xybit(y); | 223 | RAM(g)[xyaddr(x, y)] |= xybit(y); |
| 201 | else | 224 | else |
| 202 | RAM(g)[xyaddr(x, y)] &= ~xybit(y); | 225 | RAM(g)[xyaddr(x, y)] &= ~xybit(y); |
| 203 | g->flags |= GDISP_FLG_NEEDFLUSH; | 226 | g->flags |= GDISP_FLG_NEEDFLUSH; |
| 204 | } | 227 | } |
| 205 | #endif | 228 | #endif |
| 206 | 229 | ||
| 207 | #if GDISP_HARDWARE_PIXELREAD | 230 | #if GDISP_HARDWARE_PIXELREAD |
| 208 | LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { | 231 | LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { |
| 209 | coord_t x, y; | 232 | coord_t x, y; |
| 210 | 233 | ||
| 211 | switch(g->g.Orientation) { | 234 | switch(g->g.Orientation) { |
| 212 | default: | 235 | default: |
| 213 | case GDISP_ROTATE_0: | 236 | case GDISP_ROTATE_0: |
| 214 | x = g->p.x; | 237 | x = g->p.x; |
| 215 | y = g->p.y; | 238 | y = g->p.y; |
| 216 | break; | 239 | break; |
| 217 | case GDISP_ROTATE_90: | 240 | case GDISP_ROTATE_90: |
| 218 | x = g->p.y; | 241 | x = g->p.y; |
| 219 | y = GDISP_SCREEN_HEIGHT-1 - g->p.x; | 242 | y = GDISP_SCREEN_HEIGHT-1 - g->p.x; |
| 220 | break; | 243 | break; |
| 221 | case GDISP_ROTATE_180: | 244 | case GDISP_ROTATE_180: |
| 222 | x = GDISP_SCREEN_WIDTH-1 - g->p.x; | 245 | x = GDISP_SCREEN_WIDTH-1 - g->p.x; |
| 223 | y = GDISP_SCREEN_HEIGHT-1 - g->p.y; | 246 | y = GDISP_SCREEN_HEIGHT-1 - g->p.y; |
| 224 | break; | 247 | break; |
| 225 | case GDISP_ROTATE_270: | 248 | case GDISP_ROTATE_270: |
| 226 | x = GDISP_SCREEN_HEIGHT-1 - g->p.y; | 249 | x = GDISP_SCREEN_HEIGHT-1 - g->p.y; |
| 227 | y = g->p.x; | 250 | y = g->p.x; |
| 228 | break; | 251 | break; |
| 229 | } | 252 | } |
| 230 | return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; | 253 | return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; |
| 231 | } | 254 | } |
| 232 | #endif | 255 | #endif |
| 233 | 256 | ||
| 234 | #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | 257 | #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL |
| 235 | LLDSPEC void gdisp_lld_control(GDisplay *g) { | 258 | LLDSPEC void gdisp_lld_control(GDisplay *g) { |
| 236 | switch(g->p.x) { | 259 | switch(g->p.x) { |
| 237 | case GDISP_CONTROL_POWER: | 260 | case GDISP_CONTROL_POWER: |
| 238 | if (g->g.Powermode == (powermode_t)g->p.ptr) | 261 | if (g->g.Powermode == (powermode_t)g->p.ptr) |
| 239 | return; | 262 | return; |
| 240 | switch((powermode_t)g->p.ptr) { | 263 | switch((powermode_t)g->p.ptr) { |
| 241 | case powerOff: | 264 | case powerOff: |
| 242 | case powerSleep: | 265 | case powerSleep: |
| 243 | case powerDeepSleep: | 266 | case powerDeepSleep: |
| 244 | acquire_bus(g); | 267 | acquire_bus(g); |
| 245 | write_cmd(g, ST7565_DISPLAY_OFF); | 268 | enter_cmd_mode(g); |
| 246 | release_bus(g); | 269 | write_cmd(g, ST7565_DISPLAY_OFF); |
| 247 | break; | 270 | flush_cmd(g); |
| 248 | case powerOn: | 271 | release_bus(g); |
| 249 | acquire_bus(g); | 272 | break; |
| 250 | write_cmd(g, ST7565_DISPLAY_ON); | 273 | case powerOn: |
| 251 | release_bus(g); | 274 | acquire_bus(g); |
| 252 | break; | 275 | enter_cmd_mode(g); |
| 253 | default: | 276 | write_cmd(g, ST7565_DISPLAY_ON); |
| 254 | return; | 277 | flush_cmd(g); |
| 255 | } | 278 | release_bus(g); |
| 256 | g->g.Powermode = (powermode_t)g->p.ptr; | 279 | break; |
| 257 | return; | 280 | default: |
| 258 | 281 | return; | |
| 259 | case GDISP_CONTROL_ORIENTATION: | 282 | } |
| 260 | if (g->g.Orientation == (orientation_t)g->p.ptr) | 283 | g->g.Powermode = (powermode_t)g->p.ptr; |
| 261 | return; | 284 | return; |
| 262 | switch((orientation_t)g->p.ptr) { | 285 | |
| 263 | /* Rotation is handled by the drawing routines */ | 286 | case GDISP_CONTROL_ORIENTATION: |
| 264 | case GDISP_ROTATE_0: | 287 | if (g->g.Orientation == (orientation_t)g->p.ptr) |
| 265 | case GDISP_ROTATE_180: | 288 | return; |
| 266 | g->g.Height = GDISP_SCREEN_HEIGHT; | 289 | switch((orientation_t)g->p.ptr) { |
| 267 | g->g.Width = GDISP_SCREEN_WIDTH; | 290 | /* Rotation is handled by the drawing routines */ |
| 268 | break; | 291 | case GDISP_ROTATE_0: |
| 269 | case GDISP_ROTATE_90: | 292 | case GDISP_ROTATE_180: |
| 270 | case GDISP_ROTATE_270: | 293 | g->g.Height = GDISP_SCREEN_HEIGHT; |
| 271 | g->g.Height = GDISP_SCREEN_WIDTH; | 294 | g->g.Width = GDISP_SCREEN_WIDTH; |
| 272 | g->g.Width = GDISP_SCREEN_HEIGHT; | 295 | break; |
| 273 | break; | 296 | case GDISP_ROTATE_90: |
| 274 | default: | 297 | case GDISP_ROTATE_270: |
| 275 | return; | 298 | g->g.Height = GDISP_SCREEN_WIDTH; |
| 276 | } | 299 | g->g.Width = GDISP_SCREEN_HEIGHT; |
| 277 | g->g.Orientation = (orientation_t)g->p.ptr; | 300 | break; |
| 278 | return; | 301 | default: |
| 279 | 302 | return; | |
| 280 | case GDISP_CONTROL_CONTRAST: | 303 | } |
| 281 | if ((unsigned)g->p.ptr > 100) | 304 | g->g.Orientation = (orientation_t)g->p.ptr; |
| 282 | g->p.ptr = (void *)100; | 305 | return; |
| 283 | acquire_bus(g); | 306 | |
| 284 | write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); | 307 | case GDISP_CONTROL_CONTRAST: |
| 285 | release_bus(g); | 308 | if ((unsigned)g->p.ptr > 100) |
| 286 | g->g.Contrast = (unsigned)g->p.ptr; | 309 | g->p.ptr = (void *)100; |
| 287 | return; | 310 | acquire_bus(g); |
| 288 | } | 311 | enter_cmd_mode(g); |
| 289 | } | 312 | write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); |
| 313 | flush_cmd(g); | ||
| 314 | release_bus(g); | ||
| 315 | g->g.Contrast = (unsigned)g->p.ptr; | ||
| 316 | return; | ||
| 317 | } | ||
| 318 | } | ||
| 290 | #endif // GDISP_NEED_CONTROL | 319 | #endif // GDISP_NEED_CONTROL |
| 291 | 320 | ||
| 292 | #endif // GFX_USE_GDISP | 321 | #endif // GFX_USE_GDISP |
