Emulation of the 1970's Chip-8 machine. The emulator has 7 games that are unmodified from the original Chip-8 format.
LCD_ST7735/LCD_ST7735.cpp@0:bc3f11b1b41f, 2015-02-08 (annotated)
- Committer:
- taylorza
- Date:
- Sun Feb 08 01:58:57 2015 +0000
- Revision:
- 0:bc3f11b1b41f
Chip-8 Emulator
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
taylorza | 0:bc3f11b1b41f | 1 | #include "mbed.h" |
taylorza | 0:bc3f11b1b41f | 2 | #include "LCD_ST7735.h" |
taylorza | 0:bc3f11b1b41f | 3 | #include "Base.h" |
taylorza | 0:bc3f11b1b41f | 4 | |
taylorza | 0:bc3f11b1b41f | 5 | const uint16_t LCD_ST7735::DefaultPalette[] = { |
taylorza | 0:bc3f11b1b41f | 6 | 0x0000, // 0 - Black |
taylorza | 0:bc3f11b1b41f | 7 | 0x0019, // 1 - Blue |
taylorza | 0:bc3f11b1b41f | 8 | 0xc800, // 2 - Red |
taylorza | 0:bc3f11b1b41f | 9 | 0xc819, // 3 - Magenta |
taylorza | 0:bc3f11b1b41f | 10 | 0x0660, // 4 - Green |
taylorza | 0:bc3f11b1b41f | 11 | 0x0679, // 5 - Cyan |
taylorza | 0:bc3f11b1b41f | 12 | 0xce60, // 6 - Yellow |
taylorza | 0:bc3f11b1b41f | 13 | 0xce79, // 7 - White |
taylorza | 0:bc3f11b1b41f | 14 | 0x001f, // 8 - Bright Blue |
taylorza | 0:bc3f11b1b41f | 15 | 0xf800, // 9 - Bright Red |
taylorza | 0:bc3f11b1b41f | 16 | 0xf81f, // 10 - Bright Magenta |
taylorza | 0:bc3f11b1b41f | 17 | 0x07e0, // 11 - Bright Green |
taylorza | 0:bc3f11b1b41f | 18 | 0x07ff, // 12 - Bright Cyan |
taylorza | 0:bc3f11b1b41f | 19 | 0xffe0, // 13 - Bright Yellow |
taylorza | 0:bc3f11b1b41f | 20 | 0xffff, // 14 - Bright White |
taylorza | 0:bc3f11b1b41f | 21 | }; |
taylorza | 0:bc3f11b1b41f | 22 | |
taylorza | 0:bc3f11b1b41f | 23 | LCD_ST7735::LCD_ST7735( |
taylorza | 0:bc3f11b1b41f | 24 | PinName backlightPin, |
taylorza | 0:bc3f11b1b41f | 25 | PinName resetPin, |
taylorza | 0:bc3f11b1b41f | 26 | PinName dsPin, |
taylorza | 0:bc3f11b1b41f | 27 | PinName mosiPin, |
taylorza | 0:bc3f11b1b41f | 28 | PinName misoPin, |
taylorza | 0:bc3f11b1b41f | 29 | PinName clkPin, |
taylorza | 0:bc3f11b1b41f | 30 | PinName csPin, |
taylorza | 0:bc3f11b1b41f | 31 | PanelColorFilter colorFilter |
taylorza | 0:bc3f11b1b41f | 32 | ) : |
taylorza | 0:bc3f11b1b41f | 33 | _colorFilter(colorFilter), |
taylorza | 0:bc3f11b1b41f | 34 | _backlight(backlightPin, 0), |
taylorza | 0:bc3f11b1b41f | 35 | _reset(resetPin, 1), |
taylorza | 0:bc3f11b1b41f | 36 | _ds(dsPin, 0), |
taylorza | 0:bc3f11b1b41f | 37 | _cs(csPin, 1), |
taylorza | 0:bc3f11b1b41f | 38 | _spi(mosiPin, misoPin, clkPin) |
taylorza | 0:bc3f11b1b41f | 39 | { |
taylorza | 0:bc3f11b1b41f | 40 | _spi.format(8, 3); |
taylorza | 0:bc3f11b1b41f | 41 | _spi.frequency(15000000); |
taylorza | 0:bc3f11b1b41f | 42 | |
taylorza | 0:bc3f11b1b41f | 43 | initDisplay(); |
taylorza | 0:bc3f11b1b41f | 44 | clearScreen(); |
taylorza | 0:bc3f11b1b41f | 45 | setForegroundColor(0xffff); |
taylorza | 0:bc3f11b1b41f | 46 | setBackgroundColor(0x0000); |
taylorza | 0:bc3f11b1b41f | 47 | |
taylorza | 0:bc3f11b1b41f | 48 | _palette = (uint16_t*)DefaultPalette; |
taylorza | 0:bc3f11b1b41f | 49 | } |
taylorza | 0:bc3f11b1b41f | 50 | |
taylorza | 0:bc3f11b1b41f | 51 | void LCD_ST7735::setOrientation(Orientation orientation, bool flip) |
taylorza | 0:bc3f11b1b41f | 52 | { |
taylorza | 0:bc3f11b1b41f | 53 | const static uint8_t my = 0x80; |
taylorza | 0:bc3f11b1b41f | 54 | const static uint8_t mx = 0x40; |
taylorza | 0:bc3f11b1b41f | 55 | const static uint8_t mv = 0x20; |
taylorza | 0:bc3f11b1b41f | 56 | |
taylorza | 0:bc3f11b1b41f | 57 | uint8_t madctlData = _colorFilter; |
taylorza | 0:bc3f11b1b41f | 58 | switch(orientation) |
taylorza | 0:bc3f11b1b41f | 59 | { |
taylorza | 0:bc3f11b1b41f | 60 | case Rotate0: |
taylorza | 0:bc3f11b1b41f | 61 | _width = 128; |
taylorza | 0:bc3f11b1b41f | 62 | _height = 160; |
taylorza | 0:bc3f11b1b41f | 63 | madctlData |= flip ? mx : 0; |
taylorza | 0:bc3f11b1b41f | 64 | break; |
taylorza | 0:bc3f11b1b41f | 65 | |
taylorza | 0:bc3f11b1b41f | 66 | case Rotate90: |
taylorza | 0:bc3f11b1b41f | 67 | _width = 160; |
taylorza | 0:bc3f11b1b41f | 68 | _height = 128; |
taylorza | 0:bc3f11b1b41f | 69 | madctlData |= flip ? my | mv | mx : mv | mx; |
taylorza | 0:bc3f11b1b41f | 70 | break; |
taylorza | 0:bc3f11b1b41f | 71 | |
taylorza | 0:bc3f11b1b41f | 72 | case Rotate180: |
taylorza | 0:bc3f11b1b41f | 73 | _width = 128; |
taylorza | 0:bc3f11b1b41f | 74 | _height = 160; |
taylorza | 0:bc3f11b1b41f | 75 | madctlData |= flip ? my : mx | my; |
taylorza | 0:bc3f11b1b41f | 76 | break; |
taylorza | 0:bc3f11b1b41f | 77 | |
taylorza | 0:bc3f11b1b41f | 78 | case Rotate270: |
taylorza | 0:bc3f11b1b41f | 79 | _width = 160; |
taylorza | 0:bc3f11b1b41f | 80 | _height = 128; |
taylorza | 0:bc3f11b1b41f | 81 | madctlData |= flip ? mv : mv | my; |
taylorza | 0:bc3f11b1b41f | 82 | break; |
taylorza | 0:bc3f11b1b41f | 83 | } |
taylorza | 0:bc3f11b1b41f | 84 | write(CMD_MADCTL, (uint8_t[]){madctlData}, 1); |
taylorza | 0:bc3f11b1b41f | 85 | } |
taylorza | 0:bc3f11b1b41f | 86 | |
taylorza | 0:bc3f11b1b41f | 87 | int LCD_ST7735::getWidth() |
taylorza | 0:bc3f11b1b41f | 88 | { |
taylorza | 0:bc3f11b1b41f | 89 | return _width; |
taylorza | 0:bc3f11b1b41f | 90 | } |
taylorza | 0:bc3f11b1b41f | 91 | |
taylorza | 0:bc3f11b1b41f | 92 | int LCD_ST7735::getHeight() |
taylorza | 0:bc3f11b1b41f | 93 | { |
taylorza | 0:bc3f11b1b41f | 94 | return _height; |
taylorza | 0:bc3f11b1b41f | 95 | } |
taylorza | 0:bc3f11b1b41f | 96 | |
taylorza | 0:bc3f11b1b41f | 97 | void LCD_ST7735::setBacklight(bool state) |
taylorza | 0:bc3f11b1b41f | 98 | { |
taylorza | 0:bc3f11b1b41f | 99 | _backlight = state ? 1 : 0; |
taylorza | 0:bc3f11b1b41f | 100 | } |
taylorza | 0:bc3f11b1b41f | 101 | |
taylorza | 0:bc3f11b1b41f | 102 | void LCD_ST7735::clearScreen(uint16_t color) |
taylorza | 0:bc3f11b1b41f | 103 | { |
taylorza | 0:bc3f11b1b41f | 104 | clipRect(0, 0, _width - 1, _height - 1); |
taylorza | 0:bc3f11b1b41f | 105 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 106 | uint8_t colorHigh = color >> 8; |
taylorza | 0:bc3f11b1b41f | 107 | uint8_t colorLow = color; |
taylorza | 0:bc3f11b1b41f | 108 | for(int i = 0; i < 128 * 160 * 2; ++i) |
taylorza | 0:bc3f11b1b41f | 109 | { |
taylorza | 0:bc3f11b1b41f | 110 | writeBatchData(colorHigh, colorLow); |
taylorza | 0:bc3f11b1b41f | 111 | } |
taylorza | 0:bc3f11b1b41f | 112 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 113 | } |
taylorza | 0:bc3f11b1b41f | 114 | |
taylorza | 0:bc3f11b1b41f | 115 | void LCD_ST7735::setPixel(int x, int y, uint16_t color) |
taylorza | 0:bc3f11b1b41f | 116 | { |
taylorza | 0:bc3f11b1b41f | 117 | write(CMD_CASET, (uint8_t[]){0, x, 0, x}, 4); |
taylorza | 0:bc3f11b1b41f | 118 | write(CMD_RASET, (uint8_t[]){0, y, 0, y}, 4); |
taylorza | 0:bc3f11b1b41f | 119 | write(CMD_RAMWR, color); |
taylorza | 0:bc3f11b1b41f | 120 | } |
taylorza | 0:bc3f11b1b41f | 121 | |
taylorza | 0:bc3f11b1b41f | 122 | void LCD_ST7735::drawLine(int x1, int y1, int x2, int y2, uint16_t color) |
taylorza | 0:bc3f11b1b41f | 123 | { |
taylorza | 0:bc3f11b1b41f | 124 | int dx = abs(x2 - x1); |
taylorza | 0:bc3f11b1b41f | 125 | int dy = abs(y2 - y1); |
taylorza | 0:bc3f11b1b41f | 126 | |
taylorza | 0:bc3f11b1b41f | 127 | if (dx == 0) |
taylorza | 0:bc3f11b1b41f | 128 | { |
taylorza | 0:bc3f11b1b41f | 129 | drawVertLine(x1, y1, y2, color); |
taylorza | 0:bc3f11b1b41f | 130 | return; |
taylorza | 0:bc3f11b1b41f | 131 | } |
taylorza | 0:bc3f11b1b41f | 132 | else if(dy == 0) |
taylorza | 0:bc3f11b1b41f | 133 | { |
taylorza | 0:bc3f11b1b41f | 134 | drawHorizLine(x1, y1, x2, color); |
taylorza | 0:bc3f11b1b41f | 135 | return; |
taylorza | 0:bc3f11b1b41f | 136 | } |
taylorza | 0:bc3f11b1b41f | 137 | |
taylorza | 0:bc3f11b1b41f | 138 | int sx = (x1 < x2) ? 1 : -1; |
taylorza | 0:bc3f11b1b41f | 139 | int sy = (y1 < y2) ? 1 : -1; |
taylorza | 0:bc3f11b1b41f | 140 | int err = dx - dy; |
taylorza | 0:bc3f11b1b41f | 141 | while(x1 != x2 || y1 != y2) |
taylorza | 0:bc3f11b1b41f | 142 | { |
taylorza | 0:bc3f11b1b41f | 143 | setPixel(x1, y1, color); |
taylorza | 0:bc3f11b1b41f | 144 | int e2 = err << 1; |
taylorza | 0:bc3f11b1b41f | 145 | if (e2 > -dy) |
taylorza | 0:bc3f11b1b41f | 146 | { |
taylorza | 0:bc3f11b1b41f | 147 | err -= dy; |
taylorza | 0:bc3f11b1b41f | 148 | x1 += sx; |
taylorza | 0:bc3f11b1b41f | 149 | } |
taylorza | 0:bc3f11b1b41f | 150 | if (e2 < dx) |
taylorza | 0:bc3f11b1b41f | 151 | { |
taylorza | 0:bc3f11b1b41f | 152 | err += dx; |
taylorza | 0:bc3f11b1b41f | 153 | y1 += sy; |
taylorza | 0:bc3f11b1b41f | 154 | } |
taylorza | 0:bc3f11b1b41f | 155 | } |
taylorza | 0:bc3f11b1b41f | 156 | setPixel(x2, y2, color); |
taylorza | 0:bc3f11b1b41f | 157 | } |
taylorza | 0:bc3f11b1b41f | 158 | |
taylorza | 0:bc3f11b1b41f | 159 | void LCD_ST7735::drawRect(int x1, int y1, int x2, int y2, uint16_t color) |
taylorza | 0:bc3f11b1b41f | 160 | { |
taylorza | 0:bc3f11b1b41f | 161 | if (x1 > x2) swap(x1, x2); |
taylorza | 0:bc3f11b1b41f | 162 | if (y1 > y2) swap(y1, y2); |
taylorza | 0:bc3f11b1b41f | 163 | |
taylorza | 0:bc3f11b1b41f | 164 | drawHorizLine(x1, y1, x2, color); |
taylorza | 0:bc3f11b1b41f | 165 | drawHorizLine(x1, y2, x2, color); |
taylorza | 0:bc3f11b1b41f | 166 | drawVertLine(x1, y1, y2, color); |
taylorza | 0:bc3f11b1b41f | 167 | drawVertLine(x2, y1, y2, color); |
taylorza | 0:bc3f11b1b41f | 168 | } |
taylorza | 0:bc3f11b1b41f | 169 | |
taylorza | 0:bc3f11b1b41f | 170 | void LCD_ST7735::drawCircle(int x, int y, int r, uint16_t color) |
taylorza | 0:bc3f11b1b41f | 171 | { |
taylorza | 0:bc3f11b1b41f | 172 | int ix = r; |
taylorza | 0:bc3f11b1b41f | 173 | int iy = 0; |
taylorza | 0:bc3f11b1b41f | 174 | int err = 1 - r; |
taylorza | 0:bc3f11b1b41f | 175 | |
taylorza | 0:bc3f11b1b41f | 176 | while(ix >= iy) |
taylorza | 0:bc3f11b1b41f | 177 | { |
taylorza | 0:bc3f11b1b41f | 178 | setPixel(x + ix, y + iy, color); |
taylorza | 0:bc3f11b1b41f | 179 | setPixel(x + iy, y + ix, color); |
taylorza | 0:bc3f11b1b41f | 180 | setPixel(x - ix, y + iy, color); |
taylorza | 0:bc3f11b1b41f | 181 | setPixel(x - iy, y + ix, color); |
taylorza | 0:bc3f11b1b41f | 182 | setPixel(x - ix, y - iy, color); |
taylorza | 0:bc3f11b1b41f | 183 | setPixel(x - iy, y - ix, color); |
taylorza | 0:bc3f11b1b41f | 184 | setPixel(x + ix, y - iy, color); |
taylorza | 0:bc3f11b1b41f | 185 | setPixel(x + iy, y - ix, color); |
taylorza | 0:bc3f11b1b41f | 186 | iy++; |
taylorza | 0:bc3f11b1b41f | 187 | if (err < 0) |
taylorza | 0:bc3f11b1b41f | 188 | { |
taylorza | 0:bc3f11b1b41f | 189 | err += 2 * iy + 1; |
taylorza | 0:bc3f11b1b41f | 190 | } |
taylorza | 0:bc3f11b1b41f | 191 | else |
taylorza | 0:bc3f11b1b41f | 192 | { |
taylorza | 0:bc3f11b1b41f | 193 | ix--; |
taylorza | 0:bc3f11b1b41f | 194 | err += 2 * (iy - ix + 1); |
taylorza | 0:bc3f11b1b41f | 195 | } |
taylorza | 0:bc3f11b1b41f | 196 | } |
taylorza | 0:bc3f11b1b41f | 197 | } |
taylorza | 0:bc3f11b1b41f | 198 | |
taylorza | 0:bc3f11b1b41f | 199 | void LCD_ST7735::drawEllipse(int x, int y, int rx, int ry, uint16_t color) |
taylorza | 0:bc3f11b1b41f | 200 | { |
taylorza | 0:bc3f11b1b41f | 201 | int a2 = rx * rx; |
taylorza | 0:bc3f11b1b41f | 202 | int b2 = ry * ry; |
taylorza | 0:bc3f11b1b41f | 203 | int fa2 = 4 * a2; |
taylorza | 0:bc3f11b1b41f | 204 | int fb2 = 4 * b2; |
taylorza | 0:bc3f11b1b41f | 205 | |
taylorza | 0:bc3f11b1b41f | 206 | int ix, iy, sigma; |
taylorza | 0:bc3f11b1b41f | 207 | for (ix = 0, iy = ry, sigma = 2 * b2 + a2 * (1 - 2 * ry); b2 * ix <= a2 * iy; ix++) |
taylorza | 0:bc3f11b1b41f | 208 | { |
taylorza | 0:bc3f11b1b41f | 209 | setPixel(x + ix, y + iy, color); |
taylorza | 0:bc3f11b1b41f | 210 | setPixel(x - ix, y + iy, color); |
taylorza | 0:bc3f11b1b41f | 211 | setPixel(x + ix, y - iy, color); |
taylorza | 0:bc3f11b1b41f | 212 | setPixel(x - ix, y - iy, color); |
taylorza | 0:bc3f11b1b41f | 213 | if (sigma >= 0) |
taylorza | 0:bc3f11b1b41f | 214 | { |
taylorza | 0:bc3f11b1b41f | 215 | sigma+= fa2 * (1 - iy); |
taylorza | 0:bc3f11b1b41f | 216 | iy--; |
taylorza | 0:bc3f11b1b41f | 217 | } |
taylorza | 0:bc3f11b1b41f | 218 | sigma += b2 * ((4 * ix) + 6); |
taylorza | 0:bc3f11b1b41f | 219 | } |
taylorza | 0:bc3f11b1b41f | 220 | |
taylorza | 0:bc3f11b1b41f | 221 | for (ix = rx, iy = 0, sigma = 2 * a2 + b2 * (1 - 2 * rx); a2 * iy <= b2 * ix; iy++) |
taylorza | 0:bc3f11b1b41f | 222 | { |
taylorza | 0:bc3f11b1b41f | 223 | setPixel(x + ix, y + iy, color); |
taylorza | 0:bc3f11b1b41f | 224 | setPixel(x - ix, y + iy, color); |
taylorza | 0:bc3f11b1b41f | 225 | setPixel(x + ix, y - iy, color); |
taylorza | 0:bc3f11b1b41f | 226 | setPixel(x - ix, y - iy, color); |
taylorza | 0:bc3f11b1b41f | 227 | if (sigma >= 0) |
taylorza | 0:bc3f11b1b41f | 228 | { |
taylorza | 0:bc3f11b1b41f | 229 | sigma+= fb2 * (1 - ix); |
taylorza | 0:bc3f11b1b41f | 230 | ix--; |
taylorza | 0:bc3f11b1b41f | 231 | } |
taylorza | 0:bc3f11b1b41f | 232 | sigma += a2 * ((4 * iy) + 6); |
taylorza | 0:bc3f11b1b41f | 233 | } |
taylorza | 0:bc3f11b1b41f | 234 | } |
taylorza | 0:bc3f11b1b41f | 235 | void LCD_ST7735::fillRect(int x1, int y1, int x2, int y2, uint16_t fillColor) |
taylorza | 0:bc3f11b1b41f | 236 | { |
taylorza | 0:bc3f11b1b41f | 237 | if (x1 > x2) swap(x1, x2); |
taylorza | 0:bc3f11b1b41f | 238 | if (y1 > y2) swap(y1, y2); |
taylorza | 0:bc3f11b1b41f | 239 | |
taylorza | 0:bc3f11b1b41f | 240 | clipRect(x1, y1, x2, y2); |
taylorza | 0:bc3f11b1b41f | 241 | int c = ((x2 + 1 - x1) * (y2 + 1 - y1)) << 1; |
taylorza | 0:bc3f11b1b41f | 242 | uint8_t colorHigh = fillColor >> 8; |
taylorza | 0:bc3f11b1b41f | 243 | uint8_t colorLow = fillColor; |
taylorza | 0:bc3f11b1b41f | 244 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 245 | while(c--) |
taylorza | 0:bc3f11b1b41f | 246 | { |
taylorza | 0:bc3f11b1b41f | 247 | writeBatchData(colorHigh, colorLow); |
taylorza | 0:bc3f11b1b41f | 248 | } |
taylorza | 0:bc3f11b1b41f | 249 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 250 | } |
taylorza | 0:bc3f11b1b41f | 251 | |
taylorza | 0:bc3f11b1b41f | 252 | void LCD_ST7735::fillRect(int x1, int y1, int x2, int y2, uint16_t borderColor, uint16_t fillColor) |
taylorza | 0:bc3f11b1b41f | 253 | { |
taylorza | 0:bc3f11b1b41f | 254 | if (x1 > x2) swap(x1, x2); |
taylorza | 0:bc3f11b1b41f | 255 | if (y1 > y2) swap(y1, y2); |
taylorza | 0:bc3f11b1b41f | 256 | |
taylorza | 0:bc3f11b1b41f | 257 | drawRect(x1, y1, x2, y2, borderColor); |
taylorza | 0:bc3f11b1b41f | 258 | ++x1; ++y1; --x2; --y2; |
taylorza | 0:bc3f11b1b41f | 259 | if (x2 >= x1 && y2 >= y1) |
taylorza | 0:bc3f11b1b41f | 260 | { |
taylorza | 0:bc3f11b1b41f | 261 | int c = ((x2 + 1 - x1) * (y2 + 1 - y1)) << 1; |
taylorza | 0:bc3f11b1b41f | 262 | |
taylorza | 0:bc3f11b1b41f | 263 | clipRect(x1, y1, x2, y2); |
taylorza | 0:bc3f11b1b41f | 264 | uint8_t colorHigh = fillColor >> 8; |
taylorza | 0:bc3f11b1b41f | 265 | uint8_t colorLow = fillColor; |
taylorza | 0:bc3f11b1b41f | 266 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 267 | while(c--) |
taylorza | 0:bc3f11b1b41f | 268 | { |
taylorza | 0:bc3f11b1b41f | 269 | writeBatchData(colorHigh, colorLow); |
taylorza | 0:bc3f11b1b41f | 270 | } |
taylorza | 0:bc3f11b1b41f | 271 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 272 | } |
taylorza | 0:bc3f11b1b41f | 273 | } |
taylorza | 0:bc3f11b1b41f | 274 | |
taylorza | 0:bc3f11b1b41f | 275 | void LCD_ST7735::fillCircle(int x, int y, int r, uint16_t borderColor, uint16_t fillColor) |
taylorza | 0:bc3f11b1b41f | 276 | { |
taylorza | 0:bc3f11b1b41f | 277 | int ix = r; |
taylorza | 0:bc3f11b1b41f | 278 | int iy = 0; |
taylorza | 0:bc3f11b1b41f | 279 | int err = 1 - r; |
taylorza | 0:bc3f11b1b41f | 280 | |
taylorza | 0:bc3f11b1b41f | 281 | while(ix >= iy) |
taylorza | 0:bc3f11b1b41f | 282 | { |
taylorza | 0:bc3f11b1b41f | 283 | setPixel(x - ix, y + iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 284 | setPixel(x + ix, y + iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 285 | drawHorizLine(x - ix + 1, y + iy, x + ix - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 286 | |
taylorza | 0:bc3f11b1b41f | 287 | setPixel(x - iy, y + ix, borderColor); |
taylorza | 0:bc3f11b1b41f | 288 | setPixel(x + iy, y + ix, borderColor); |
taylorza | 0:bc3f11b1b41f | 289 | drawHorizLine(x - iy + 1, y + ix, x + iy - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 290 | |
taylorza | 0:bc3f11b1b41f | 291 | setPixel(x - ix, y - iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 292 | setPixel(x + ix, y - iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 293 | drawHorizLine(x - ix + 1, y - iy, x + ix - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 294 | |
taylorza | 0:bc3f11b1b41f | 295 | setPixel(x - iy, y - ix, borderColor); |
taylorza | 0:bc3f11b1b41f | 296 | setPixel(x + iy, y - ix, borderColor); |
taylorza | 0:bc3f11b1b41f | 297 | drawHorizLine(x - iy + 1, y - ix, x + iy - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 298 | iy++; |
taylorza | 0:bc3f11b1b41f | 299 | if (err < 0) |
taylorza | 0:bc3f11b1b41f | 300 | { |
taylorza | 0:bc3f11b1b41f | 301 | err += 2 * iy + 1; |
taylorza | 0:bc3f11b1b41f | 302 | } |
taylorza | 0:bc3f11b1b41f | 303 | else |
taylorza | 0:bc3f11b1b41f | 304 | { |
taylorza | 0:bc3f11b1b41f | 305 | ix--; |
taylorza | 0:bc3f11b1b41f | 306 | err += 2 * (iy - ix + 1); |
taylorza | 0:bc3f11b1b41f | 307 | } |
taylorza | 0:bc3f11b1b41f | 308 | } |
taylorza | 0:bc3f11b1b41f | 309 | } |
taylorza | 0:bc3f11b1b41f | 310 | |
taylorza | 0:bc3f11b1b41f | 311 | void LCD_ST7735::fillEllipse(int x, int y, int rx, int ry, uint16_t borderColor, uint16_t fillColor) |
taylorza | 0:bc3f11b1b41f | 312 | { |
taylorza | 0:bc3f11b1b41f | 313 | int a2 = rx * rx; |
taylorza | 0:bc3f11b1b41f | 314 | int b2 = ry * ry; |
taylorza | 0:bc3f11b1b41f | 315 | int fa2 = 4 * a2; |
taylorza | 0:bc3f11b1b41f | 316 | int fb2 = 4 * b2; |
taylorza | 0:bc3f11b1b41f | 317 | |
taylorza | 0:bc3f11b1b41f | 318 | int ix, iy, sigma; |
taylorza | 0:bc3f11b1b41f | 319 | for (ix = 0, iy = ry, sigma = 2 * b2 + a2 * (1 - 2 * ry); b2 * ix <= a2 * iy; ix++) |
taylorza | 0:bc3f11b1b41f | 320 | { |
taylorza | 0:bc3f11b1b41f | 321 | setPixel(x + ix, y + iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 322 | setPixel(x - ix, y + iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 323 | drawHorizLine(x - ix + 1, y + iy, x + ix - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 324 | |
taylorza | 0:bc3f11b1b41f | 325 | setPixel(x + ix, y - iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 326 | setPixel(x - ix, y - iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 327 | drawHorizLine(x - ix + 1, y - iy, x + ix - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 328 | |
taylorza | 0:bc3f11b1b41f | 329 | if (sigma >= 0) |
taylorza | 0:bc3f11b1b41f | 330 | { |
taylorza | 0:bc3f11b1b41f | 331 | sigma+= fa2 * (1 - iy); |
taylorza | 0:bc3f11b1b41f | 332 | iy--; |
taylorza | 0:bc3f11b1b41f | 333 | } |
taylorza | 0:bc3f11b1b41f | 334 | sigma += b2 * ((4 * ix) + 6); |
taylorza | 0:bc3f11b1b41f | 335 | } |
taylorza | 0:bc3f11b1b41f | 336 | |
taylorza | 0:bc3f11b1b41f | 337 | for (ix = rx, iy = 0, sigma = 2 * a2 + b2 * (1 - 2 * rx); a2 * iy <= b2 * ix; iy++) |
taylorza | 0:bc3f11b1b41f | 338 | { |
taylorza | 0:bc3f11b1b41f | 339 | setPixel(x + ix, y + iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 340 | setPixel(x - ix, y + iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 341 | drawHorizLine(x - ix + 1, y + iy, x + ix - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 342 | |
taylorza | 0:bc3f11b1b41f | 343 | setPixel(x + ix, y - iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 344 | setPixel(x - ix, y - iy, borderColor); |
taylorza | 0:bc3f11b1b41f | 345 | drawHorizLine(x - ix + 1, y - iy, x + ix - 1, fillColor); |
taylorza | 0:bc3f11b1b41f | 346 | if (sigma >= 0) |
taylorza | 0:bc3f11b1b41f | 347 | { |
taylorza | 0:bc3f11b1b41f | 348 | sigma+= fb2 * (1 - ix); |
taylorza | 0:bc3f11b1b41f | 349 | ix--; |
taylorza | 0:bc3f11b1b41f | 350 | } |
taylorza | 0:bc3f11b1b41f | 351 | sigma += a2 * ((4 * iy) + 6); |
taylorza | 0:bc3f11b1b41f | 352 | } |
taylorza | 0:bc3f11b1b41f | 353 | } |
taylorza | 0:bc3f11b1b41f | 354 | |
taylorza | 0:bc3f11b1b41f | 355 | void LCD_ST7735::drawBitmap(int x, int y, const uint16_t *pbmp) |
taylorza | 0:bc3f11b1b41f | 356 | { |
taylorza | 0:bc3f11b1b41f | 357 | int w = *pbmp++; |
taylorza | 0:bc3f11b1b41f | 358 | int h = *pbmp++; |
taylorza | 0:bc3f11b1b41f | 359 | |
taylorza | 0:bc3f11b1b41f | 360 | clip(x, y, w, h); |
taylorza | 0:bc3f11b1b41f | 361 | int c = w * h; |
taylorza | 0:bc3f11b1b41f | 362 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 363 | while(c--) |
taylorza | 0:bc3f11b1b41f | 364 | { |
taylorza | 0:bc3f11b1b41f | 365 | writeBatchData(*pbmp++); |
taylorza | 0:bc3f11b1b41f | 366 | } |
taylorza | 0:bc3f11b1b41f | 367 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 368 | } |
taylorza | 0:bc3f11b1b41f | 369 | |
taylorza | 0:bc3f11b1b41f | 370 | void LCD_ST7735::drawBitmap(int x, int y, const uint16_t *pbmp, int srcX, int srcY, int srcWidth, int srcHeight) |
taylorza | 0:bc3f11b1b41f | 371 | { |
taylorza | 0:bc3f11b1b41f | 372 | int w = *pbmp++; |
taylorza | 0:bc3f11b1b41f | 373 | int h = *pbmp++; |
taylorza | 0:bc3f11b1b41f | 374 | |
taylorza | 0:bc3f11b1b41f | 375 | clip(x, y, srcWidth, srcHeight); |
taylorza | 0:bc3f11b1b41f | 376 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 377 | const uint16_t *p = pbmp + srcX + (srcY * w); |
taylorza | 0:bc3f11b1b41f | 378 | for(int iy = 0; iy < srcHeight; ++iy) |
taylorza | 0:bc3f11b1b41f | 379 | { |
taylorza | 0:bc3f11b1b41f | 380 | for(int ix = 0; ix < srcWidth; ++ix) |
taylorza | 0:bc3f11b1b41f | 381 | { |
taylorza | 0:bc3f11b1b41f | 382 | writeBatchData(*(p + ix)); |
taylorza | 0:bc3f11b1b41f | 383 | } |
taylorza | 0:bc3f11b1b41f | 384 | p += w; |
taylorza | 0:bc3f11b1b41f | 385 | } |
taylorza | 0:bc3f11b1b41f | 386 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 387 | } |
taylorza | 0:bc3f11b1b41f | 388 | |
taylorza | 0:bc3f11b1b41f | 389 | void LCD_ST7735::drawBitmap(int x, int y, Bitmap1bpp &bmp, int srcX, int srcY, int srcWidth, int srcHeight, uint16_t foregroundColor, uint16_t backgroundColor) |
taylorza | 0:bc3f11b1b41f | 390 | { |
taylorza | 0:bc3f11b1b41f | 391 | // Clip if out of screen |
taylorza | 0:bc3f11b1b41f | 392 | if ((x >= _width) || (x + srcWidth < 0) || |
taylorza | 0:bc3f11b1b41f | 393 | (y >= _height) || (y + srcHeight < 0)) |
taylorza | 0:bc3f11b1b41f | 394 | { |
taylorza | 0:bc3f11b1b41f | 395 | return; |
taylorza | 0:bc3f11b1b41f | 396 | } |
taylorza | 0:bc3f11b1b41f | 397 | |
taylorza | 0:bc3f11b1b41f | 398 | // Clip X |
taylorza | 0:bc3f11b1b41f | 399 | if (x < 0) { srcX += -x; srcWidth += x; x = 0; } |
taylorza | 0:bc3f11b1b41f | 400 | if (x + srcWidth >= _width) { srcWidth += _width - (x + srcWidth); } |
taylorza | 0:bc3f11b1b41f | 401 | |
taylorza | 0:bc3f11b1b41f | 402 | // Clip Y |
taylorza | 0:bc3f11b1b41f | 403 | if (y < 0) {srcY += -y; srcHeight += y; y = 0; } |
taylorza | 0:bc3f11b1b41f | 404 | if (y + srcHeight >= _height) { srcHeight += _height - (y + srcHeight); } |
taylorza | 0:bc3f11b1b41f | 405 | |
taylorza | 0:bc3f11b1b41f | 406 | uint8_t fch = foregroundColor >> 8; |
taylorza | 0:bc3f11b1b41f | 407 | uint8_t fcl = foregroundColor; |
taylorza | 0:bc3f11b1b41f | 408 | uint8_t bch = backgroundColor >> 8; |
taylorza | 0:bc3f11b1b41f | 409 | uint8_t bcl = backgroundColor; |
taylorza | 0:bc3f11b1b41f | 410 | |
taylorza | 0:bc3f11b1b41f | 411 | clip(x, y, srcWidth, srcHeight); |
taylorza | 0:bc3f11b1b41f | 412 | |
taylorza | 0:bc3f11b1b41f | 413 | int offset = (bmp.getStride() * srcY) + (srcX / 8); |
taylorza | 0:bc3f11b1b41f | 414 | int startbits = srcX % 8; |
taylorza | 0:bc3f11b1b41f | 415 | |
taylorza | 0:bc3f11b1b41f | 416 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 417 | for(int r = 0; r < srcHeight; ++r) |
taylorza | 0:bc3f11b1b41f | 418 | { |
taylorza | 0:bc3f11b1b41f | 419 | const uint8_t *p = bmp.getBitmapData() + offset; |
taylorza | 0:bc3f11b1b41f | 420 | |
taylorza | 0:bc3f11b1b41f | 421 | uint8_t b = *p; |
taylorza | 0:bc3f11b1b41f | 422 | for (int c = 0, shift = startbits; c < srcWidth; ++c, ++shift) |
taylorza | 0:bc3f11b1b41f | 423 | { |
taylorza | 0:bc3f11b1b41f | 424 | if (shift == 8) |
taylorza | 0:bc3f11b1b41f | 425 | { |
taylorza | 0:bc3f11b1b41f | 426 | shift = 0; |
taylorza | 0:bc3f11b1b41f | 427 | b = *++p; |
taylorza | 0:bc3f11b1b41f | 428 | } |
taylorza | 0:bc3f11b1b41f | 429 | |
taylorza | 0:bc3f11b1b41f | 430 | if ((b << shift) & 0x80) |
taylorza | 0:bc3f11b1b41f | 431 | { |
taylorza | 0:bc3f11b1b41f | 432 | writeBatchData(fch, fcl); |
taylorza | 0:bc3f11b1b41f | 433 | } |
taylorza | 0:bc3f11b1b41f | 434 | else |
taylorza | 0:bc3f11b1b41f | 435 | { |
taylorza | 0:bc3f11b1b41f | 436 | writeBatchData(bch, bcl); |
taylorza | 0:bc3f11b1b41f | 437 | } |
taylorza | 0:bc3f11b1b41f | 438 | } |
taylorza | 0:bc3f11b1b41f | 439 | offset += bmp.getStride(); |
taylorza | 0:bc3f11b1b41f | 440 | } |
taylorza | 0:bc3f11b1b41f | 441 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 442 | } |
taylorza | 0:bc3f11b1b41f | 443 | |
taylorza | 0:bc3f11b1b41f | 444 | void LCD_ST7735::setForegroundColor(uint16_t color) |
taylorza | 0:bc3f11b1b41f | 445 | { |
taylorza | 0:bc3f11b1b41f | 446 | _foregroundColorHigh = color >> 8; |
taylorza | 0:bc3f11b1b41f | 447 | _foregroundColorLow = color; |
taylorza | 0:bc3f11b1b41f | 448 | } |
taylorza | 0:bc3f11b1b41f | 449 | |
taylorza | 0:bc3f11b1b41f | 450 | void LCD_ST7735::setBackgroundColor(uint16_t color) |
taylorza | 0:bc3f11b1b41f | 451 | { |
taylorza | 0:bc3f11b1b41f | 452 | _backgroundColorHigh = color >> 8; |
taylorza | 0:bc3f11b1b41f | 453 | _backgroundColorLow = color; |
taylorza | 0:bc3f11b1b41f | 454 | } |
taylorza | 0:bc3f11b1b41f | 455 | |
taylorza | 0:bc3f11b1b41f | 456 | void LCD_ST7735::drawString(const uint8_t *pFont, int x, int y, const char *pString) |
taylorza | 0:bc3f11b1b41f | 457 | { |
taylorza | 0:bc3f11b1b41f | 458 | uint8_t w = *pFont; |
taylorza | 0:bc3f11b1b41f | 459 | uint8_t h = *(pFont + 1); |
taylorza | 0:bc3f11b1b41f | 460 | uint8_t offset = *(pFont + 2); |
taylorza | 0:bc3f11b1b41f | 461 | uint8_t leftPad = *(pFont + 3); |
taylorza | 0:bc3f11b1b41f | 462 | uint8_t rightPad = *(pFont + 4); |
taylorza | 0:bc3f11b1b41f | 463 | uint8_t topPad = *(pFont + 5); |
taylorza | 0:bc3f11b1b41f | 464 | uint8_t bottomPad = *(pFont + 6); |
taylorza | 0:bc3f11b1b41f | 465 | |
taylorza | 0:bc3f11b1b41f | 466 | if (y + topPad + h + bottomPad < 0) return; |
taylorza | 0:bc3f11b1b41f | 467 | if (y >= _height) return; |
taylorza | 0:bc3f11b1b41f | 468 | if (x + leftPad + w + rightPad < 0) return; |
taylorza | 0:bc3f11b1b41f | 469 | |
taylorza | 0:bc3f11b1b41f | 470 | char *p = (char*)pString; |
taylorza | 0:bc3f11b1b41f | 471 | while(*p != 0) |
taylorza | 0:bc3f11b1b41f | 472 | { |
taylorza | 0:bc3f11b1b41f | 473 | if (x >= _width) return; |
taylorza | 0:bc3f11b1b41f | 474 | drawChar(pFont, x, y, *p++, w, h, offset, leftPad, rightPad, topPad, bottomPad); |
taylorza | 0:bc3f11b1b41f | 475 | x += (w + leftPad + rightPad); |
taylorza | 0:bc3f11b1b41f | 476 | } |
taylorza | 0:bc3f11b1b41f | 477 | } |
taylorza | 0:bc3f11b1b41f | 478 | |
taylorza | 0:bc3f11b1b41f | 479 | void LCD_ST7735::measureString(const uint8_t *pFont, const char *pString, uint8_t &width, uint8_t &height) |
taylorza | 0:bc3f11b1b41f | 480 | { |
taylorza | 0:bc3f11b1b41f | 481 | uint8_t w = *pFont; |
taylorza | 0:bc3f11b1b41f | 482 | uint8_t h = *(pFont + 1); |
taylorza | 0:bc3f11b1b41f | 483 | uint8_t leftPad = *(pFont + 3); |
taylorza | 0:bc3f11b1b41f | 484 | uint8_t rightPad = *(pFont + 4); |
taylorza | 0:bc3f11b1b41f | 485 | uint8_t topPad = *(pFont + 5); |
taylorza | 0:bc3f11b1b41f | 486 | uint8_t bottomPad = *(pFont + 6); |
taylorza | 0:bc3f11b1b41f | 487 | |
taylorza | 0:bc3f11b1b41f | 488 | width = (w + leftPad + rightPad) * strlen(pString); |
taylorza | 0:bc3f11b1b41f | 489 | height = (h + topPad + bottomPad); |
taylorza | 0:bc3f11b1b41f | 490 | } |
taylorza | 0:bc3f11b1b41f | 491 | |
taylorza | 0:bc3f11b1b41f | 492 | void LCD_ST7735::selectDevice() |
taylorza | 0:bc3f11b1b41f | 493 | { |
taylorza | 0:bc3f11b1b41f | 494 | _spi.prepareFastSPI(); |
taylorza | 0:bc3f11b1b41f | 495 | } |
taylorza | 0:bc3f11b1b41f | 496 | |
taylorza | 0:bc3f11b1b41f | 497 | void LCD_ST7735::drawVertLine(int x1, int y1, int y2, uint16_t color) |
taylorza | 0:bc3f11b1b41f | 498 | { |
taylorza | 0:bc3f11b1b41f | 499 | clipRect(x1, y1, x1, y2); |
taylorza | 0:bc3f11b1b41f | 500 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 501 | int c = (y2 - y1) << 1; |
taylorza | 0:bc3f11b1b41f | 502 | uint8_t colorHigh = color >> 8; |
taylorza | 0:bc3f11b1b41f | 503 | uint8_t colorLow = color; |
taylorza | 0:bc3f11b1b41f | 504 | for (int i = 0; i < c; ++i) |
taylorza | 0:bc3f11b1b41f | 505 | { |
taylorza | 0:bc3f11b1b41f | 506 | writeBatchData(colorHigh, colorLow); |
taylorza | 0:bc3f11b1b41f | 507 | } |
taylorza | 0:bc3f11b1b41f | 508 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 509 | } |
taylorza | 0:bc3f11b1b41f | 510 | |
taylorza | 0:bc3f11b1b41f | 511 | void LCD_ST7735::drawHorizLine(int x1, int y1, int x2, uint16_t color) |
taylorza | 0:bc3f11b1b41f | 512 | { |
taylorza | 0:bc3f11b1b41f | 513 | clipRect(x1, y1, x2, y1); |
taylorza | 0:bc3f11b1b41f | 514 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 515 | int c = (x2 - x1) << 1; |
taylorza | 0:bc3f11b1b41f | 516 | uint8_t colorHigh = color >> 8; |
taylorza | 0:bc3f11b1b41f | 517 | uint8_t colorLow = color; |
taylorza | 0:bc3f11b1b41f | 518 | for (int i = 0; i < c; ++i) |
taylorza | 0:bc3f11b1b41f | 519 | { |
taylorza | 0:bc3f11b1b41f | 520 | writeBatchData(colorHigh, colorLow); |
taylorza | 0:bc3f11b1b41f | 521 | } |
taylorza | 0:bc3f11b1b41f | 522 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 523 | } |
taylorza | 0:bc3f11b1b41f | 524 | |
taylorza | 0:bc3f11b1b41f | 525 | void LCD_ST7735::drawChar(const uint8_t *pFont, int x, int y, char c, uint8_t w, uint8_t h, uint8_t offset, uint8_t leftPad, uint8_t rightPad, uint8_t topPad, uint8_t bottomPad) |
taylorza | 0:bc3f11b1b41f | 526 | { |
taylorza | 0:bc3f11b1b41f | 527 | const uint8_t *pChar = (pFont + 7) + ((c - offset) * h); |
taylorza | 0:bc3f11b1b41f | 528 | |
taylorza | 0:bc3f11b1b41f | 529 | clip(x, y, w + leftPad + rightPad, h + topPad + bottomPad); |
taylorza | 0:bc3f11b1b41f | 530 | |
taylorza | 0:bc3f11b1b41f | 531 | beginBatchCommand(CMD_RAMWR); |
taylorza | 0:bc3f11b1b41f | 532 | |
taylorza | 0:bc3f11b1b41f | 533 | // Render top spacing |
taylorza | 0:bc3f11b1b41f | 534 | for (int r = 0; r < topPad; ++r) |
taylorza | 0:bc3f11b1b41f | 535 | { |
taylorza | 0:bc3f11b1b41f | 536 | for (int c = 0; c < w + leftPad + rightPad; ++c) |
taylorza | 0:bc3f11b1b41f | 537 | { |
taylorza | 0:bc3f11b1b41f | 538 | writeBatchData(_backgroundColorHigh); |
taylorza | 0:bc3f11b1b41f | 539 | writeBatchData(_backgroundColorLow); |
taylorza | 0:bc3f11b1b41f | 540 | } |
taylorza | 0:bc3f11b1b41f | 541 | } |
taylorza | 0:bc3f11b1b41f | 542 | |
taylorza | 0:bc3f11b1b41f | 543 | // Render character |
taylorza | 0:bc3f11b1b41f | 544 | for(int r = 0; r < h; ++r) |
taylorza | 0:bc3f11b1b41f | 545 | { |
taylorza | 0:bc3f11b1b41f | 546 | uint8_t b = pChar[r]; |
taylorza | 0:bc3f11b1b41f | 547 | |
taylorza | 0:bc3f11b1b41f | 548 | // Render left spacing |
taylorza | 0:bc3f11b1b41f | 549 | for (int c = 0; c < leftPad; ++c) |
taylorza | 0:bc3f11b1b41f | 550 | { |
taylorza | 0:bc3f11b1b41f | 551 | writeBatchData(_backgroundColorHigh); |
taylorza | 0:bc3f11b1b41f | 552 | writeBatchData(_backgroundColorLow); |
taylorza | 0:bc3f11b1b41f | 553 | } |
taylorza | 0:bc3f11b1b41f | 554 | for(int c = 0; c < w; ++c) |
taylorza | 0:bc3f11b1b41f | 555 | { |
taylorza | 0:bc3f11b1b41f | 556 | if (b & 0x80) |
taylorza | 0:bc3f11b1b41f | 557 | { |
taylorza | 0:bc3f11b1b41f | 558 | writeBatchData(_foregroundColorHigh); |
taylorza | 0:bc3f11b1b41f | 559 | writeBatchData(_foregroundColorLow); |
taylorza | 0:bc3f11b1b41f | 560 | } |
taylorza | 0:bc3f11b1b41f | 561 | else |
taylorza | 0:bc3f11b1b41f | 562 | { |
taylorza | 0:bc3f11b1b41f | 563 | writeBatchData(_backgroundColorHigh); |
taylorza | 0:bc3f11b1b41f | 564 | writeBatchData(_backgroundColorLow); |
taylorza | 0:bc3f11b1b41f | 565 | } |
taylorza | 0:bc3f11b1b41f | 566 | |
taylorza | 0:bc3f11b1b41f | 567 | b <<= 1; |
taylorza | 0:bc3f11b1b41f | 568 | } |
taylorza | 0:bc3f11b1b41f | 569 | |
taylorza | 0:bc3f11b1b41f | 570 | for (int c = 0; c < rightPad; ++c) |
taylorza | 0:bc3f11b1b41f | 571 | { |
taylorza | 0:bc3f11b1b41f | 572 | writeBatchData(_backgroundColorHigh); |
taylorza | 0:bc3f11b1b41f | 573 | writeBatchData(_backgroundColorLow); |
taylorza | 0:bc3f11b1b41f | 574 | } |
taylorza | 0:bc3f11b1b41f | 575 | } |
taylorza | 0:bc3f11b1b41f | 576 | |
taylorza | 0:bc3f11b1b41f | 577 | // Render bottom spacing |
taylorza | 0:bc3f11b1b41f | 578 | for (int r = 0; r < bottomPad; ++r) |
taylorza | 0:bc3f11b1b41f | 579 | { |
taylorza | 0:bc3f11b1b41f | 580 | for (int c = 0; c < w + leftPad + rightPad; ++c) |
taylorza | 0:bc3f11b1b41f | 581 | { |
taylorza | 0:bc3f11b1b41f | 582 | writeBatchData(_backgroundColorHigh); |
taylorza | 0:bc3f11b1b41f | 583 | writeBatchData(_backgroundColorLow); |
taylorza | 0:bc3f11b1b41f | 584 | } |
taylorza | 0:bc3f11b1b41f | 585 | } |
taylorza | 0:bc3f11b1b41f | 586 | endBatchCommand(); |
taylorza | 0:bc3f11b1b41f | 587 | } |
taylorza | 0:bc3f11b1b41f | 588 | |
taylorza | 0:bc3f11b1b41f | 589 | void LCD_ST7735::initDisplay() |
taylorza | 0:bc3f11b1b41f | 590 | { |
taylorza | 0:bc3f11b1b41f | 591 | selectDevice(); |
taylorza | 0:bc3f11b1b41f | 592 | reset(); |
taylorza | 0:bc3f11b1b41f | 593 | |
taylorza | 0:bc3f11b1b41f | 594 | writeCommand(CMD_SLPOUT); |
taylorza | 0:bc3f11b1b41f | 595 | |
taylorza | 0:bc3f11b1b41f | 596 | write(CMD_FRMCTR1, (uint8_t[]){0x01, 0x2c, 0x2d}, 3); |
taylorza | 0:bc3f11b1b41f | 597 | write(CMD_FRMCTR2, (uint8_t[]){0x01, 0x2c, 0x2d}, 3); |
taylorza | 0:bc3f11b1b41f | 598 | write(CMD_FRMCTR3, (uint8_t[]){0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d}, 6); |
taylorza | 0:bc3f11b1b41f | 599 | |
taylorza | 0:bc3f11b1b41f | 600 | write(CMD_INVCTR, (uint8_t[]){0x07}, 1); |
taylorza | 0:bc3f11b1b41f | 601 | |
taylorza | 0:bc3f11b1b41f | 602 | write(CMD_PWCTR1, (uint8_t[]){0xa2, 0x02, 0x84}, 3); |
taylorza | 0:bc3f11b1b41f | 603 | write(CMD_PWCTR2, (uint8_t[]){0xc5}, 1); |
taylorza | 0:bc3f11b1b41f | 604 | write(CMD_PWCTR3, (uint8_t[]){0x0a, 0x00}, 2); |
taylorza | 0:bc3f11b1b41f | 605 | write(CMD_PWCTR4, (uint8_t[]){0x8a, 0x2a}, 2); |
taylorza | 0:bc3f11b1b41f | 606 | write(CMD_PWCTR5, (uint8_t[]){0x8a, 0xee}, 2); |
taylorza | 0:bc3f11b1b41f | 607 | |
taylorza | 0:bc3f11b1b41f | 608 | write(CMD_VMCTR1, (uint8_t[]){0x0e}, 1); |
taylorza | 0:bc3f11b1b41f | 609 | |
taylorza | 0:bc3f11b1b41f | 610 | write(CMD_MADCTL, (uint8_t[]){0xc0 | _colorFilter}, 1); |
taylorza | 0:bc3f11b1b41f | 611 | |
taylorza | 0:bc3f11b1b41f | 612 | // Gama sequence |
taylorza | 0:bc3f11b1b41f | 613 | write(CMD_GAMCTRP1, (uint8_t[]) |
taylorza | 0:bc3f11b1b41f | 614 | { |
taylorza | 0:bc3f11b1b41f | 615 | 0x0f, 0x1a, |
taylorza | 0:bc3f11b1b41f | 616 | 0x0f, 0x18, |
taylorza | 0:bc3f11b1b41f | 617 | 0x2f, 0x28, |
taylorza | 0:bc3f11b1b41f | 618 | 0x20, 0x22, |
taylorza | 0:bc3f11b1b41f | 619 | 0x1f, 0x1b, |
taylorza | 0:bc3f11b1b41f | 620 | 0x23, 0x37, |
taylorza | 0:bc3f11b1b41f | 621 | 0x00, 0x07, |
taylorza | 0:bc3f11b1b41f | 622 | 0x02, 0x10 |
taylorza | 0:bc3f11b1b41f | 623 | }, 16); |
taylorza | 0:bc3f11b1b41f | 624 | |
taylorza | 0:bc3f11b1b41f | 625 | write(CMD_GAMCTRN1, (uint8_t[]) |
taylorza | 0:bc3f11b1b41f | 626 | { |
taylorza | 0:bc3f11b1b41f | 627 | 0x0f, 0x1b, |
taylorza | 0:bc3f11b1b41f | 628 | 0x0f, 0x17, |
taylorza | 0:bc3f11b1b41f | 629 | 0x33, 0x2c, |
taylorza | 0:bc3f11b1b41f | 630 | 0x29, 0x2e, |
taylorza | 0:bc3f11b1b41f | 631 | 0x30, 0x30, |
taylorza | 0:bc3f11b1b41f | 632 | 0x39, 0x3f, |
taylorza | 0:bc3f11b1b41f | 633 | 0x00, 0x07, |
taylorza | 0:bc3f11b1b41f | 634 | 0x03, 0x10 |
taylorza | 0:bc3f11b1b41f | 635 | }, 16); |
taylorza | 0:bc3f11b1b41f | 636 | |
taylorza | 0:bc3f11b1b41f | 637 | write(CMD_CASET, (uint8_t[]){0x00, 0x00, 0x00, 0x7f}, 4); |
taylorza | 0:bc3f11b1b41f | 638 | write(CMD_RASET, (uint8_t[]){0x00, 0x00, 0x00, 0x9f}, 4); |
taylorza | 0:bc3f11b1b41f | 639 | |
taylorza | 0:bc3f11b1b41f | 640 | write(CMD_EXTCTRL, (uint8_t[]){0x01}, 1); |
taylorza | 0:bc3f11b1b41f | 641 | |
taylorza | 0:bc3f11b1b41f | 642 | // Disable RAM power save |
taylorza | 0:bc3f11b1b41f | 643 | write(0xf6, (uint8_t[]){0x00}, 1); |
taylorza | 0:bc3f11b1b41f | 644 | |
taylorza | 0:bc3f11b1b41f | 645 | // 65k color mode |
taylorza | 0:bc3f11b1b41f | 646 | write(CMD_COLMOD, (uint8_t[]){0x05}, 1); |
taylorza | 0:bc3f11b1b41f | 647 | |
taylorza | 0:bc3f11b1b41f | 648 | // Enable display |
taylorza | 0:bc3f11b1b41f | 649 | writeCommand(CMD_DISPON); |
taylorza | 0:bc3f11b1b41f | 650 | |
taylorza | 0:bc3f11b1b41f | 651 | setBacklight(true); |
taylorza | 0:bc3f11b1b41f | 652 | } |
taylorza | 0:bc3f11b1b41f | 653 | |
taylorza | 0:bc3f11b1b41f | 654 | void LCD_ST7735::reset() |
taylorza | 0:bc3f11b1b41f | 655 | { |
taylorza | 0:bc3f11b1b41f | 656 | _reset = 0; |
taylorza | 0:bc3f11b1b41f | 657 | wait_us(100); |
taylorza | 0:bc3f11b1b41f | 658 | _reset = 1; |
taylorza | 0:bc3f11b1b41f | 659 | wait_us(100); |
taylorza | 0:bc3f11b1b41f | 660 | } |
taylorza | 0:bc3f11b1b41f | 661 | |
taylorza | 0:bc3f11b1b41f | 662 | void LCD_ST7735::clip(int x, int y, int w, int h) |
taylorza | 0:bc3f11b1b41f | 663 | { |
taylorza | 0:bc3f11b1b41f | 664 | clipRect(x, y, (x + w) - 1, (y + h) - 1); |
taylorza | 0:bc3f11b1b41f | 665 | } |
taylorza | 0:bc3f11b1b41f | 666 | |
taylorza | 0:bc3f11b1b41f | 667 | void LCD_ST7735::clipRect(int x1, int y1, int x2, int y2) |
taylorza | 0:bc3f11b1b41f | 668 | { |
taylorza | 0:bc3f11b1b41f | 669 | uint8_t x1l = (uint8_t)x1; |
taylorza | 0:bc3f11b1b41f | 670 | uint8_t x1h = (uint8_t)(x1 >> 8); |
taylorza | 0:bc3f11b1b41f | 671 | uint8_t x2l = (uint8_t)x2; |
taylorza | 0:bc3f11b1b41f | 672 | uint8_t x2h = (uint8_t)(x2 >> 8); |
taylorza | 0:bc3f11b1b41f | 673 | write(CMD_CASET, (uint8_t[]){x1h, x1l, x2h, x2l}, 4); |
taylorza | 0:bc3f11b1b41f | 674 | |
taylorza | 0:bc3f11b1b41f | 675 | uint8_t y1l = (uint8_t)y1; |
taylorza | 0:bc3f11b1b41f | 676 | uint8_t y1h = (uint8_t)(y1 >> 8); |
taylorza | 0:bc3f11b1b41f | 677 | uint8_t y2l = (uint8_t)y2; |
taylorza | 0:bc3f11b1b41f | 678 | uint8_t y2h = (uint8_t)(y2 >> 8); |
taylorza | 0:bc3f11b1b41f | 679 | write(CMD_RASET, (uint8_t[]){y1h, y1l, y2h, y2l}, 4); |
taylorza | 0:bc3f11b1b41f | 680 | } |
taylorza | 0:bc3f11b1b41f | 681 | |
taylorza | 0:bc3f11b1b41f | 682 | void LCD_ST7735::writeCommand(uint8_t cmd) |
taylorza | 0:bc3f11b1b41f | 683 | { |
taylorza | 0:bc3f11b1b41f | 684 | _cs = 0; |
taylorza | 0:bc3f11b1b41f | 685 | _ds = 0; |
taylorza | 0:bc3f11b1b41f | 686 | _spi.fastWrite(cmd); |
taylorza | 0:bc3f11b1b41f | 687 | _spi.waitWhileBusy(); |
taylorza | 0:bc3f11b1b41f | 688 | _spi.clearRx(); |
taylorza | 0:bc3f11b1b41f | 689 | _cs = 1; |
taylorza | 0:bc3f11b1b41f | 690 | } |
taylorza | 0:bc3f11b1b41f | 691 | |
taylorza | 0:bc3f11b1b41f | 692 | void LCD_ST7735::write(uint8_t cmd, uint8_t data[], int dataLen) |
taylorza | 0:bc3f11b1b41f | 693 | { |
taylorza | 0:bc3f11b1b41f | 694 | _cs = 0; |
taylorza | 0:bc3f11b1b41f | 695 | _ds = 0; |
taylorza | 0:bc3f11b1b41f | 696 | _spi.fastWrite(cmd); |
taylorza | 0:bc3f11b1b41f | 697 | _spi.waitWhileBusy(); |
taylorza | 0:bc3f11b1b41f | 698 | if (data != NULL & dataLen > 0) |
taylorza | 0:bc3f11b1b41f | 699 | { |
taylorza | 0:bc3f11b1b41f | 700 | _ds = 1; |
taylorza | 0:bc3f11b1b41f | 701 | for(int i = 0; i < dataLen; ++i) |
taylorza | 0:bc3f11b1b41f | 702 | { |
taylorza | 0:bc3f11b1b41f | 703 | _spi.fastWrite(data[i]); |
taylorza | 0:bc3f11b1b41f | 704 | } |
taylorza | 0:bc3f11b1b41f | 705 | _spi.waitWhileBusy(); |
taylorza | 0:bc3f11b1b41f | 706 | _ds = 0; |
taylorza | 0:bc3f11b1b41f | 707 | } |
taylorza | 0:bc3f11b1b41f | 708 | _spi.clearRx(); |
taylorza | 0:bc3f11b1b41f | 709 | _cs = 1; |
taylorza | 0:bc3f11b1b41f | 710 | } |
taylorza | 0:bc3f11b1b41f | 711 | |
taylorza | 0:bc3f11b1b41f | 712 | void LCD_ST7735::write(uint8_t cmd, uint16_t data) |
taylorza | 0:bc3f11b1b41f | 713 | { |
taylorza | 0:bc3f11b1b41f | 714 | _cs = 0; |
taylorza | 0:bc3f11b1b41f | 715 | _ds = 0; |
taylorza | 0:bc3f11b1b41f | 716 | _spi.fastWrite(cmd); |
taylorza | 0:bc3f11b1b41f | 717 | _spi.waitWhileBusy(); |
taylorza | 0:bc3f11b1b41f | 718 | _ds = 1; |
taylorza | 0:bc3f11b1b41f | 719 | _spi.fastWrite(data >> 8); |
taylorza | 0:bc3f11b1b41f | 720 | _spi.fastWrite(data); |
taylorza | 0:bc3f11b1b41f | 721 | _spi.waitWhileBusy(); |
taylorza | 0:bc3f11b1b41f | 722 | _spi.clearRx(); |
taylorza | 0:bc3f11b1b41f | 723 | _ds = 0; |
taylorza | 0:bc3f11b1b41f | 724 | _cs = 1; |
taylorza | 0:bc3f11b1b41f | 725 | } |
taylorza | 0:bc3f11b1b41f | 726 | |
taylorza | 0:bc3f11b1b41f | 727 | void LCD_ST7735::beginBatchCommand(uint8_t cmd) |
taylorza | 0:bc3f11b1b41f | 728 | { |
taylorza | 0:bc3f11b1b41f | 729 | _cs = 0; |
taylorza | 0:bc3f11b1b41f | 730 | _ds = 0; |
taylorza | 0:bc3f11b1b41f | 731 | _spi.fastWrite(cmd); |
taylorza | 0:bc3f11b1b41f | 732 | _spi.waitWhileBusy(); |
taylorza | 0:bc3f11b1b41f | 733 | _ds = 1; |
taylorza | 0:bc3f11b1b41f | 734 | } |
taylorza | 0:bc3f11b1b41f | 735 | |
taylorza | 0:bc3f11b1b41f | 736 | void LCD_ST7735::writeBatchData(uint8_t data) |
taylorza | 0:bc3f11b1b41f | 737 | { |
taylorza | 0:bc3f11b1b41f | 738 | _spi.fastWrite(data); |
taylorza | 0:bc3f11b1b41f | 739 | } |
taylorza | 0:bc3f11b1b41f | 740 | |
taylorza | 0:bc3f11b1b41f | 741 | void LCD_ST7735::writeBatchData(uint8_t dataHigh, uint8_t dataLow) |
taylorza | 0:bc3f11b1b41f | 742 | { |
taylorza | 0:bc3f11b1b41f | 743 | _spi.fastWrite(dataHigh); |
taylorza | 0:bc3f11b1b41f | 744 | _spi.fastWrite(dataLow); |
taylorza | 0:bc3f11b1b41f | 745 | } |
taylorza | 0:bc3f11b1b41f | 746 | |
taylorza | 0:bc3f11b1b41f | 747 | |
taylorza | 0:bc3f11b1b41f | 748 | void LCD_ST7735::writeBatchData(uint16_t data) |
taylorza | 0:bc3f11b1b41f | 749 | { |
taylorza | 0:bc3f11b1b41f | 750 | _spi.fastWrite(data >> 8); |
taylorza | 0:bc3f11b1b41f | 751 | _spi.fastWrite(data); |
taylorza | 0:bc3f11b1b41f | 752 | } |
taylorza | 0:bc3f11b1b41f | 753 | |
taylorza | 0:bc3f11b1b41f | 754 | void LCD_ST7735::endBatchCommand() |
taylorza | 0:bc3f11b1b41f | 755 | { |
taylorza | 0:bc3f11b1b41f | 756 | _spi.waitWhileBusy(); |
taylorza | 0:bc3f11b1b41f | 757 | _spi.clearRx(); |
taylorza | 0:bc3f11b1b41f | 758 | _ds = 0; |
taylorza | 0:bc3f11b1b41f | 759 | _cs = 1; |
taylorza | 0:bc3f11b1b41f | 760 | } |
taylorza | 0:bc3f11b1b41f | 761 |