acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
Arduino_RGB_Display.cpp (10878B)
1 #include "../Arduino_DataBus.h" 2 3 #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) 4 5 #include "../Arduino_GFX.h" 6 #include "Arduino_RGB_Display.h" 7 8 Arduino_RGB_Display::Arduino_RGB_Display( 9 int16_t w, int16_t h, Arduino_ESP32RGBPanel *rgbpanel, uint8_t r, bool auto_flush, 10 Arduino_DataBus *bus, int8_t rst, const uint8_t *init_operations, size_t init_operations_len) 11 : Arduino_GFX(w, h), _rgbpanel(rgbpanel), _auto_flush(auto_flush), 12 _bus(bus), _rst(rst), _init_operations(init_operations), _init_operations_len(init_operations_len) 13 { 14 _framebuffer_size = w * h * 2; 15 MAX_X = WIDTH - 1; 16 MAX_Y = HEIGHT - 1; 17 setRotation(r); 18 } 19 20 bool Arduino_RGB_Display::begin(int32_t speed) 21 { 22 if (_bus) 23 { 24 if (!_bus->begin()) 25 { 26 return false; 27 } 28 } 29 30 if (_rst != GFX_NOT_DEFINED) 31 { 32 pinMode(_rst, OUTPUT); 33 digitalWrite(_rst, HIGH); 34 delay(100); 35 digitalWrite(_rst, LOW); 36 delay(120); 37 digitalWrite(_rst, HIGH); 38 delay(120); 39 } 40 else 41 { 42 if (_bus) 43 { 44 // Software Rest 45 _bus->sendCommand(0x01); 46 delay(120); 47 } 48 } 49 50 if (_bus) 51 { 52 if (_init_operations_len > 0) 53 { 54 _bus->batchOperation((uint8_t *)_init_operations, _init_operations_len); 55 } 56 } 57 58 _rgbpanel->begin(speed); 59 _framebuffer = _rgbpanel->getFrameBuffer(WIDTH, HEIGHT); 60 61 if (!_framebuffer) 62 { 63 return false; 64 } 65 66 return true; 67 } 68 69 void Arduino_RGB_Display::writePixelPreclipped(int16_t x, int16_t y, uint16_t color) 70 { 71 uint16_t *fb = _framebuffer; 72 switch (_rotation) 73 { 74 case 1: 75 fb += (int32_t)x * _height; 76 fb += _max_y - y; 77 *fb = color; 78 if (_auto_flush) 79 { 80 Cache_WriteBack_Addr((uint32_t)fb, 2); 81 } 82 break; 83 case 2: 84 fb += (int32_t)(_max_y - y) * _width; 85 fb += _max_x - x; 86 *fb = color; 87 if (_auto_flush) 88 { 89 Cache_WriteBack_Addr((uint32_t)fb, 2); 90 } 91 break; 92 case 3: 93 fb += (int32_t)(_max_x - x) * _height; 94 fb += y; 95 *fb = color; 96 if (_auto_flush) 97 { 98 Cache_WriteBack_Addr((uint32_t)fb, 2); 99 } 100 break; 101 default: // case 0: 102 fb += (int32_t)y * _width; 103 fb += x; 104 *fb = color; 105 if (_auto_flush) 106 { 107 Cache_WriteBack_Addr((uint32_t)fb, 2); 108 } 109 } 110 } 111 112 void Arduino_RGB_Display::writeFastVLine(int16_t x, int16_t y, 113 int16_t h, uint16_t color) 114 { 115 // log_i("writeFastVLine(x: %d, y: %d, h: %d)", x, y, h); 116 switch (_rotation) 117 { 118 case 1: 119 writeFastHLineCore(_height - y - h, x, h, color); 120 break; 121 case 2: 122 writeFastVLineCore(_max_x - x, _height - y - h, h, color); 123 break; 124 case 3: 125 writeFastHLineCore(y, _max_x - x, h, color); 126 break; 127 default: // case 0: 128 writeFastVLineCore(x, y, h, color); 129 } 130 } 131 132 void Arduino_RGB_Display::writeFastVLineCore(int16_t x, int16_t y, 133 int16_t h, uint16_t color) 134 { 135 // log_i("writeFastVLineCore(x: %d, y: %d, h: %d)", x, y, h); 136 if (_ordered_in_range(x, 0, MAX_X) && h) 137 { // X on screen, nonzero height 138 if (h < 0) 139 { // If negative height... 140 y += h + 1; // Move Y to top edge 141 h = -h; // Use positive height 142 } 143 if (y <= MAX_Y) 144 { // Not off bottom 145 int16_t y2 = y + h - 1; 146 if (y2 >= 0) 147 { // Not off top 148 // Line partly or fully overlaps screen 149 if (y < 0) 150 { 151 y = 0; 152 h = y2 + 1; 153 } // Clip top 154 if (y2 > MAX_Y) 155 { 156 h = MAX_Y - y + 1; 157 } // Clip bottom 158 159 uint16_t *fb = _framebuffer + ((int32_t)y * WIDTH) + x; 160 if (_auto_flush) 161 { 162 while (h--) 163 { 164 *fb = color; 165 Cache_WriteBack_Addr((uint32_t)fb, 2); 166 fb += WIDTH; 167 } 168 } 169 else 170 { 171 while (h--) 172 { 173 *fb = color; 174 fb += WIDTH; 175 } 176 } 177 } 178 } 179 } 180 } 181 182 void Arduino_RGB_Display::writeFastHLine(int16_t x, int16_t y, 183 int16_t w, uint16_t color) 184 { 185 // log_i("writeFastHLine(x: %d, y: %d, w: %d)", x, y, w); 186 switch (_rotation) 187 { 188 case 1: 189 writeFastVLineCore(_max_y - y, x, w, color); 190 break; 191 case 2: 192 writeFastHLineCore(_width - x - w, _max_y - y, w, color); 193 break; 194 case 3: 195 writeFastVLineCore(y, _width - x - w, w, color); 196 break; 197 default: // case 0: 198 writeFastHLineCore(x, y, w, color); 199 } 200 } 201 202 void Arduino_RGB_Display::writeFastHLineCore(int16_t x, int16_t y, 203 int16_t w, uint16_t color) 204 { 205 // log_i("writeFastHLineCore(x: %d, y: %d, w: %d)", x, y, w); 206 if (_ordered_in_range(y, 0, MAX_Y) && w) 207 { // Y on screen, nonzero width 208 if (w < 0) 209 { // If negative width... 210 x += w + 1; // Move X to left edge 211 w = -w; // Use positive width 212 } 213 if (x <= MAX_X) 214 { // Not off right 215 int16_t x2 = x + w - 1; 216 if (x2 >= 0) 217 { // Not off left 218 // Line partly or fully overlaps screen 219 if (x < 0) 220 { 221 x = 0; 222 w = x2 + 1; 223 } // Clip left 224 if (x2 > MAX_X) 225 { 226 w = MAX_X - x + 1; 227 } // Clip right 228 229 uint16_t *fb = _framebuffer + ((int32_t)y * WIDTH) + x; 230 uint32_t cachePos = (uint32_t)fb; 231 int16_t writeSize = w * 2; 232 while (w--) 233 { 234 *(fb++) = color; 235 } 236 if (_auto_flush) 237 { 238 Cache_WriteBack_Addr(cachePos, writeSize); 239 } 240 } 241 } 242 } 243 } 244 245 void Arduino_RGB_Display::writeFillRectPreclipped(int16_t x, int16_t y, 246 int16_t w, int16_t h, uint16_t color) 247 { 248 // log_i("writeFillRectPreclipped(x: %d, y: %d, w: %d, h: %d)", x, y, w, h); 249 if (_rotation > 0) 250 { 251 int16_t t = x; 252 switch (_rotation) 253 { 254 case 1: 255 x = WIDTH - y - h; 256 y = t; 257 t = w; 258 w = h; 259 h = t; 260 break; 261 case 2: 262 x = WIDTH - x - w; 263 y = HEIGHT - y - h; 264 break; 265 case 3: 266 x = y; 267 y = HEIGHT - t - w; 268 t = w; 269 w = h; 270 h = t; 271 break; 272 } 273 } 274 // log_i("adjusted writeFillRectPreclipped(x: %d, y: %d, w: %d, h: %d)", x, y, w, h); 275 uint16_t *row = _framebuffer; 276 row += y * WIDTH; 277 uint32_t cachePos = (uint32_t)row; 278 row += x; 279 for (int j = 0; j < h; j++) 280 { 281 for (int i = 0; i < w; i++) 282 { 283 row[i] = color; 284 } 285 row += WIDTH; 286 } 287 if (_auto_flush) 288 { 289 Cache_WriteBack_Addr(cachePos, WIDTH * h * 2); 290 } 291 } 292 293 void Arduino_RGB_Display::drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h) 294 { 295 if ( 296 ((x + w - 1) < 0) || // Outside left 297 ((y + h - 1) < 0) || // Outside top 298 (x > _max_x) || // Outside right 299 (y > _max_y) // Outside bottom 300 ) 301 { 302 return; 303 } 304 else 305 { 306 if (_rotation > 0) 307 { 308 Arduino_GFX::drawIndexedBitmap(x, y, bitmap, color_index, w, h); 309 } 310 else 311 { 312 int16_t xskip = 0; 313 if ((y + h - 1) > _max_y) 314 { 315 h -= (y + h - 1) - _max_y; 316 } 317 if (y < 0) 318 { 319 bitmap -= y * w; 320 h += y; 321 y = 0; 322 } 323 if ((x + w - 1) > _max_x) 324 { 325 xskip = (x + w - 1) - _max_x; 326 w -= xskip; 327 } 328 if (x < 0) 329 { 330 bitmap -= x; 331 xskip -= x; 332 w += x; 333 x = 0; 334 } 335 uint16_t *row = _framebuffer; 336 row += y * _width; 337 uint32_t cachePos = (uint32_t)row; 338 row += x; 339 for (int j = 0; j < h; j++) 340 { 341 for (int i = 0; i < w; i++) 342 { 343 row[i] = color_index[*bitmap++]; 344 } 345 bitmap += xskip; 346 row += _width; 347 } 348 if (_auto_flush) 349 { 350 Cache_WriteBack_Addr(cachePos, _width * h * 2); 351 } 352 } 353 } 354 } 355 356 void Arduino_RGB_Display::draw16bitRGBBitmap(int16_t x, int16_t y, 357 uint16_t *bitmap, int16_t w, int16_t h) 358 { 359 bool result; 360 361 switch (_rotation) 362 { 363 case 1: 364 result = gfx_draw_bitmap_to_framebuffer_rotate_1(bitmap, w, h, _framebuffer, x, y, _width, _height); 365 break; 366 case 2: 367 result = gfx_draw_bitmap_to_framebuffer_rotate_2(bitmap, w, h, _framebuffer, x, y, _width, _height); 368 break; 369 case 3: 370 result = gfx_draw_bitmap_to_framebuffer_rotate_3(bitmap, w, h, _framebuffer, x, y, _width, _height); 371 break; 372 default: // case 0: 373 result = gfx_draw_bitmap_to_framebuffer(bitmap, w, h, _framebuffer, x, y, _width, _height); 374 } 375 376 if (result) 377 { 378 if (_auto_flush) 379 { 380 uint32_t cachePos; 381 size_t cache_size; 382 switch (_rotation) 383 { 384 case 1: 385 cachePos = (uint32_t)(_framebuffer + (x * WIDTH)); 386 cache_size = HEIGHT * w * 2; 387 break; 388 case 2: 389 cachePos = (uint32_t)(_framebuffer + ((MAX_Y - y) * WIDTH)); 390 cache_size = HEIGHT * h * 2; 391 break; 392 case 3: 393 cachePos = (uint32_t)(_framebuffer + ((MAX_Y - x) * WIDTH)); 394 cache_size = HEIGHT * w * 2; 395 break; 396 default: // case 0: 397 cachePos = (uint32_t)(_framebuffer + (y * WIDTH)); 398 cache_size = HEIGHT * h * 2; 399 } 400 Cache_WriteBack_Addr(cachePos, cache_size); 401 } 402 } 403 } 404 405 void Arduino_RGB_Display::draw16bitBeRGBBitmap(int16_t x, int16_t y, 406 uint16_t *bitmap, int16_t w, int16_t h) 407 { 408 if ( 409 ((x + w - 1) < 0) || // Outside left 410 ((y + h - 1) < 0) || // Outside top 411 (x > _max_x) || // Outside right 412 (y > _max_y) // Outside bottom 413 ) 414 { 415 return; 416 } 417 else 418 { 419 if (_rotation > 0) 420 { 421 Arduino_GFX::draw16bitBeRGBBitmap(x, y, bitmap, w, h); 422 } 423 else 424 { 425 int16_t xskip = 0; 426 if ((y + h - 1) > _max_y) 427 { 428 h -= (y + h - 1) - _max_y; 429 } 430 if (y < 0) 431 { 432 bitmap -= y * w; 433 h += y; 434 y = 0; 435 } 436 if ((x + w - 1) > _max_x) 437 { 438 xskip = (x + w - 1) - _max_x; 439 w -= xskip; 440 } 441 if (x < 0) 442 { 443 bitmap -= x; 444 xskip -= x; 445 w += x; 446 x = 0; 447 } 448 uint16_t *row = _framebuffer; 449 row += y * _width; 450 uint32_t cachePos = (uint32_t)row; 451 row += x; 452 uint16_t color; 453 for (int j = 0; j < h; j++) 454 { 455 for (int i = 0; i < w; i++) 456 { 457 color = *bitmap++; 458 MSB_16_SET(row[i], color); 459 } 460 bitmap += xskip; 461 row += _width; 462 } 463 if (_auto_flush) 464 { 465 Cache_WriteBack_Addr(cachePos, _width * h * 2); 466 } 467 } 468 } 469 } 470 471 void Arduino_RGB_Display::flush(void) 472 { 473 if (!_auto_flush) 474 { 475 Cache_WriteBack_Addr((uint32_t)_framebuffer, _framebuffer_size); 476 } 477 } 478 479 uint16_t *Arduino_RGB_Display::getFramebuffer() 480 { 481 return _framebuffer; 482 } 483 484 #endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)