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_ESP32LCD8.cpp (7036B)
1 /* 2 * start rewrite from: 3 * https://github.com/lovyan03/LovyanGFX/blob/master/src/lgfx/v0/platforms/LGFX_PARALLEL_ESP32.hpp 4 */ 5 #include "Arduino_ESP32LCD8.h" 6 7 #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) 8 9 #define WAIT_LCD_NOT_BUSY while (LCD_CAM.lcd_user.val & LCD_CAM_LCD_START) 10 11 Arduino_ESP32LCD8::Arduino_ESP32LCD8( 12 int8_t dc, int8_t cs, int8_t wr, int8_t rd, 13 int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7) 14 : _dc(dc), _cs(cs), _wr(wr), _rd(rd), 15 _d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7) 16 { 17 } 18 19 bool Arduino_ESP32LCD8::begin(int32_t speed, int8_t dataMode) 20 { 21 if (speed == GFX_NOT_DEFINED) 22 { 23 _speed = 24000000UL; 24 } 25 else 26 { 27 _speed = speed; 28 } 29 pinMode(_dc, OUTPUT); 30 digitalWrite(_dc, HIGH); 31 32 if (_cs != GFX_NOT_DEFINED) 33 { 34 pinMode(_cs, OUTPUT); 35 digitalWrite(_cs, HIGH); // disable chip select 36 } 37 if (_cs >= 32) 38 { 39 _csPinMask = digitalPinToBitMask(_cs); 40 _csPortSet = (PORTreg_t)&GPIO.out1_w1ts.val; 41 _csPortClr = (PORTreg_t)&GPIO.out1_w1tc.val; 42 } 43 else if (_cs != GFX_NOT_DEFINED) 44 { 45 _csPinMask = digitalPinToBitMask(_cs); 46 _csPortSet = (PORTreg_t)&GPIO.out_w1ts; 47 _csPortClr = (PORTreg_t)&GPIO.out_w1tc; 48 } 49 50 pinMode(_wr, OUTPUT); 51 digitalWrite(_wr, HIGH); 52 53 if (_rd != GFX_NOT_DEFINED) 54 { 55 pinMode(_rd, OUTPUT); 56 digitalWrite(_rd, HIGH); 57 } 58 59 esp_lcd_i80_bus_config_t bus_config = { 60 .dc_gpio_num = _dc, 61 .wr_gpio_num = _wr, 62 .clk_src = LCD_CLK_SRC_PLL160M, 63 .data_gpio_nums = { 64 _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7}, 65 .bus_width = 8, 66 .max_transfer_bytes = 2, 67 .psram_trans_align = 0, 68 .sram_trans_align = 0}; 69 esp_lcd_new_i80_bus(&bus_config, &_i80_bus); 70 71 uint32_t diff = INT32_MAX; 72 uint32_t div_n = 256; 73 uint32_t div_a = 63; 74 uint32_t div_b = 62; 75 uint32_t clkcnt = 64; 76 uint32_t start_cnt = std::min<uint32_t>(64u, (F_CPU / (_speed * 2) + 1)); 77 uint32_t end_cnt = std::max<uint32_t>(2u, F_CPU / 256u / _speed); 78 if (start_cnt <= 2) 79 { 80 end_cnt = 1; 81 } 82 for (uint32_t cnt = start_cnt; diff && cnt >= end_cnt; --cnt) 83 { 84 float fdiv = (float)F_CPU / cnt / _speed; 85 uint32_t n = std::max<uint32_t>(2u, (uint32_t)fdiv); 86 fdiv -= n; 87 88 for (uint32_t a = 63; diff && a > 0; --a) 89 { 90 uint32_t b = roundf(fdiv * a); 91 if (a == b && n == 256) 92 { 93 break; 94 } 95 uint32_t freq = F_CPU / ((n * cnt) + (float)(b * cnt) / (float)a); 96 uint32_t d = abs(_speed - (int)freq); 97 if (diff <= d) 98 { 99 continue; 100 } 101 diff = d; 102 clkcnt = cnt; 103 div_n = n; 104 div_b = b; 105 div_a = a; 106 if (b == 0 || a == b) 107 { 108 break; 109 } 110 } 111 } 112 if (div_a == div_b) 113 { 114 div_b = 0; 115 div_n += 1; 116 } 117 118 lcd_cam_lcd_clock_reg_t lcd_clock; 119 lcd_clock.lcd_clkcnt_n = std::max(1u, clkcnt - 1); 120 lcd_clock.lcd_clk_equ_sysclk = (clkcnt == 1); 121 lcd_clock.lcd_ck_idle_edge = true; 122 lcd_clock.lcd_ck_out_edge = false; 123 lcd_clock.lcd_clkm_div_num = div_n; 124 lcd_clock.lcd_clkm_div_b = div_b; 125 lcd_clock.lcd_clkm_div_a = div_a; 126 lcd_clock.lcd_clk_sel = 2; // clock_select: 1=XTAL CLOCK / 2=240MHz / 3=160MHz 127 lcd_clock.clk_en = true; 128 129 LCD_CAM.lcd_clock.val = lcd_clock.val; 130 131 return true; 132 } 133 134 void Arduino_ESP32LCD8::beginWrite() 135 { 136 CS_LOW(); 137 138 LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; 139 LCD_CAM.lcd_user.val = 0; 140 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG; 141 } 142 143 void Arduino_ESP32LCD8::endWrite() 144 { 145 WAIT_LCD_NOT_BUSY; 146 147 CS_HIGH(); 148 } 149 150 void Arduino_ESP32LCD8::writeCommand(uint8_t c) 151 { 152 WRITECOMMAND(c); 153 } 154 155 void Arduino_ESP32LCD8::writeCommand16(uint16_t c) 156 { 157 WRITECOMMAND16(c); 158 } 159 160 void Arduino_ESP32LCD8::write(uint8_t d) 161 { 162 WRITE(d); 163 } 164 165 void Arduino_ESP32LCD8::write16(uint16_t d) 166 { 167 WRITE16(d); 168 } 169 170 void Arduino_ESP32LCD8::writeRepeat(uint16_t p, uint32_t len) 171 { 172 while (len--) 173 { 174 WRITE16(p); 175 } 176 } 177 178 void Arduino_ESP32LCD8::writePixels(uint16_t *data, uint32_t len) 179 { 180 LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; 181 while (len--) 182 { 183 _data16.value = *data++; 184 LCD_CAM.lcd_cmd_val.lcd_cmd_value = _data16.msb; 185 WAIT_LCD_NOT_BUSY; 186 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 187 LCD_CAM.lcd_cmd_val.lcd_cmd_value = _data16.lsb; 188 WAIT_LCD_NOT_BUSY; 189 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 190 } 191 } 192 193 void Arduino_ESP32LCD8::writeBytes(uint8_t *data, uint32_t len) 194 { 195 LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; 196 while (len--) 197 { 198 LCD_CAM.lcd_cmd_val.lcd_cmd_value = *data++; 199 WAIT_LCD_NOT_BUSY; 200 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 201 } 202 } 203 204 void Arduino_ESP32LCD8::writePattern(uint8_t *data, uint8_t len, uint32_t repeat) 205 { 206 while (repeat--) 207 { 208 writeBytes(data, len); 209 } 210 } 211 212 void Arduino_ESP32LCD8::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) 213 { 214 while (len--) 215 { 216 WRITE16(idx[*data++]); 217 } 218 } 219 220 void Arduino_ESP32LCD8::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) 221 { 222 while (len--) 223 { 224 WRITE16(idx[*data]); 225 WRITE16(idx[*data++]); 226 } 227 } 228 229 INLINE void Arduino_ESP32LCD8::WRITECOMMAND(uint8_t c) 230 { 231 LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE | LCD_CAM_LCD_CD_CMD_SET; 232 LCD_CAM.lcd_cmd_val.lcd_cmd_value = c; 233 WAIT_LCD_NOT_BUSY; 234 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 235 } 236 237 INLINE void Arduino_ESP32LCD8::WRITECOMMAND16(uint16_t c) 238 { 239 _data16.value = c; 240 LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE | LCD_CAM_LCD_CD_CMD_SET; 241 LCD_CAM.lcd_cmd_val.lcd_cmd_value = _data16.msb; 242 WAIT_LCD_NOT_BUSY; 243 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 244 LCD_CAM.lcd_cmd_val.lcd_cmd_value = _data16.lsb; 245 WAIT_LCD_NOT_BUSY; 246 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 247 } 248 249 INLINE void Arduino_ESP32LCD8::WRITE(uint8_t d) 250 { 251 LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; 252 LCD_CAM.lcd_cmd_val.lcd_cmd_value = d; 253 WAIT_LCD_NOT_BUSY; 254 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 255 } 256 257 INLINE void Arduino_ESP32LCD8::WRITE16(uint16_t d) 258 { 259 _data16.value = d; 260 LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; 261 LCD_CAM.lcd_cmd_val.lcd_cmd_value = _data16.msb; 262 WAIT_LCD_NOT_BUSY; 263 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 264 LCD_CAM.lcd_cmd_val.lcd_cmd_value = _data16.lsb; 265 WAIT_LCD_NOT_BUSY; 266 LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; 267 } 268 269 /******** low level bit twiddling **********/ 270 271 INLINE void Arduino_ESP32LCD8::CS_HIGH(void) 272 { 273 if (_cs != GFX_NOT_DEFINED) 274 { 275 *_csPortSet = _csPinMask; 276 } 277 } 278 279 INLINE void Arduino_ESP32LCD8::CS_LOW(void) 280 { 281 if (_cs != GFX_NOT_DEFINED) 282 { 283 *_csPortClr = _csPinMask; 284 } 285 } 286 287 #endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)