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_DataBus.h (11941B)
1 /* 2 * start rewrite from: 3 * https://github.com/adafruit/Adafruit-GFX-Library.git 4 */ 5 #ifndef _ARDUINO_DATABUS_H_ 6 #define _ARDUINO_DATABUS_H_ 7 8 #include <Arduino.h> 9 10 #define GFX_SKIP_OUTPUT_BEGIN -2 11 #define GFX_NOT_DEFINED -1 12 #define GFX_STR_HELPER(x) #x 13 #define GFX_STR(x) GFX_STR_HELPER(x) 14 15 #if defined(__AVR__) 16 #define LITTLE_FOOT_PRINT // reduce program size for limited flash MCU 17 #define USE_FAST_PINIO ///< Use direct PORT register access 18 typedef uint8_t ARDUINOGFX_PORT_t; 19 #elif defined(ARDUINO_ARCH_NRF52840) 20 #define USE_FAST_PINIO ///< Use direct PORT register access 21 #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers 22 typedef uint32_t ARDUINOGFX_PORT_t; 23 #elif defined(TARGET_RP2040) 24 #define USE_FAST_PINIO ///< Use direct PORT register access 25 #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers 26 typedef uint32_t ARDUINOGFX_PORT_t; 27 #elif defined(ESP32) 28 #define USE_FAST_PINIO ///< Use direct PORT register access 29 #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers 30 typedef uint32_t ARDUINOGFX_PORT_t; 31 #elif defined(ESP8266) 32 #define ESP8266SAFEBATCHBITSIZE (2048 * 8 * 9) 33 #define USE_FAST_PINIO ///< Use direct PORT register access 34 typedef uint32_t ARDUINOGFX_PORT_t; 35 #elif defined(ARDUINO_ARCH_STM32) 36 #define USE_FAST_PINIO ///< Use direct PORT register access 37 typedef uint32_t ARDUINOGFX_PORT_t; 38 #elif defined(__arm__) 39 #if defined(ARDUINO_ARCH_SAMD) 40 // Adafruit M0, M4 41 #define USE_FAST_PINIO ///< Use direct PORT register access 42 #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers 43 typedef uint32_t ARDUINOGFX_PORT_t; 44 #elif defined(CONFIG_ARCH_CHIP_CXD56XX) // Sony Spresense 45 #define USE_FAST_PINIO ///< Use direct PORT register access 46 typedef uint8_t ARDUINOGFX_PORT_t; 47 #elif defined(RTL8722DM) 48 #define USE_FAST_PINIO ///< Use direct PORT register access 49 typedef uint32_t ARDUINOGFX_PORT_t; 50 #elif defined(CORE_TEENSY) 51 #define USE_FAST_PINIO ///< Use direct PORT register access 52 #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers 53 #if defined(__IMXRT1052__) || defined(__IMXRT1062__) 54 // PJRC Teensy 4.x 55 typedef uint32_t ARDUINOGFX_PORT_t; 56 #else 57 // PJRC Teensy 3.x 58 typedef uint8_t ARDUINOGFX_PORT_t; 59 #endif 60 #else 61 // Arduino Due? 62 // USE_FAST_PINIO not available here (yet)...Due has a totally different 63 // GPIO register set and will require some changes elsewhere (e.g. in 64 // constructors especially). 65 #endif 66 #else // !ARM 67 // Unknow architecture, USE_FAST_PINIO is not available here (yet) 68 // but don't worry about it too much...the digitalWrite() implementation 69 // on these platforms is reasonably efficient and already RAM-resident, 70 // only gotcha then is no parallel connection support for now. 71 #endif // !ARM 72 73 #ifdef USE_FAST_PINIO 74 typedef volatile ARDUINOGFX_PORT_t *PORTreg_t; 75 #endif 76 77 #if defined(ARDUINO_ARCH_ARC32) || defined(ARDUINO_MAXIM) 78 #define SPI_DEFAULT_FREQ 16000000 79 // Teensy 3.0, 3.1/3.2, 3.5, 3.6 80 #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) 81 #define SPI_DEFAULT_FREQ 40000000 82 // Teensy 4.x 83 #elif defined(__IMXRT1052__) || defined(__IMXRT1062__) 84 #define SPI_DEFAULT_FREQ 40000000 85 #elif defined(__AVR__) || defined(TEENSYDUINO) 86 #define SPI_DEFAULT_FREQ 8000000 87 #elif defined(ARDUINO_ARCH_NRF52840) 88 #define SPI_DEFAULT_FREQ 8000000 89 #elif defined(ESP8266) || defined(ESP32) 90 #define SPI_DEFAULT_FREQ 40000000 91 #elif defined(RTL8722DM) 92 #define SPI_DEFAULT_FREQ 20000000 93 #elif defined(RASPI) 94 #define SPI_DEFAULT_FREQ 80000000 95 #elif defined(ARDUINO_ARCH_STM32F1) 96 #define SPI_DEFAULT_FREQ 36000000 97 #elif defined(ARDUINO_BLACKPILL_F411CE) 98 #define SPI_DEFAULT_FREQ 50000000 99 #elif defined(F_CPU) 100 #define SPI_DEFAULT_FREQ (F_CPU / 4) 101 #else 102 #define SPI_DEFAULT_FREQ 24000000 ///< Default SPI data clock frequency 103 #endif 104 105 #ifndef UNUSED 106 #define UNUSED(x) (void)(x) 107 #endif 108 #define ATTR_UNUSED __attribute__((unused)) 109 110 #define MSB_16_SET(var, val) \ 111 { \ 112 (var) = (((val)&0xFF00) >> 8) | (((val)&0xFF) << 8); \ 113 } 114 #define MSB_32_SET(var, val) \ 115 { \ 116 uint8_t *v = (uint8_t *)&(val); \ 117 (var) = v[3] | (v[2] << 8) | (v[1] << 16) | (v[0] << 24); \ 118 } 119 #define MSB_32_16_16_SET(var, v1, v2) \ 120 { \ 121 (var) = (((uint32_t)v2 & 0xff00) << 8) | (((uint32_t)v2 & 0xff) << 24) | ((v1 & 0xff00) >> 8) | ((v1 & 0xff) << 8); \ 122 } 123 #define MSB_32_8_ARRAY_SET(var, a) \ 124 { \ 125 (var) = ((uint32_t)a[0] << 8 | a[1] | a[2] << 24 | a[3] << 16); \ 126 } 127 128 #if defined(ESP32) 129 #define INLINE __attribute__((always_inline)) inline 130 #else 131 #define INLINE inline 132 #endif 133 134 #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) 135 #include <esp_lcd_panel_io.h> 136 #include <esp_lcd_panel_io_interface.h> 137 #include <esp_pm.h> 138 #include <esp_private/gdma.h> 139 #include <hal/dma_types.h> 140 #include <hal/lcd_hal.h> 141 #include <soc/dport_reg.h> 142 #include <soc/gpio_sig_map.h> 143 #include <soc/lcd_cam_reg.h> 144 #include <soc/lcd_cam_struct.h> 145 146 typedef struct esp_lcd_i80_bus_t esp_lcd_i80_bus_t; 147 typedef struct lcd_panel_io_i80_t lcd_panel_io_i80_t; 148 typedef struct lcd_i80_trans_descriptor_t lcd_i80_trans_descriptor_t; 149 150 struct esp_lcd_i80_bus_t 151 { 152 int bus_id; // Bus ID, index from 0 153 portMUX_TYPE spinlock; // spinlock used to protect i80 bus members(hal, device_list, cur_trans) 154 lcd_hal_context_t hal; // Hal object 155 size_t bus_width; // Number of data lines 156 intr_handle_t intr; // LCD peripheral interrupt handle 157 esp_pm_lock_handle_t pm_lock; // Power management lock 158 size_t num_dma_nodes; // Number of DMA descriptors 159 uint8_t *format_buffer; // The driver allocates an internal buffer for DMA to do data format transformer 160 size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source 161 gdma_channel_handle_t dma_chan; // DMA channel handle 162 size_t psram_trans_align; // DMA transfer alignment for data allocated from PSRAM 163 size_t sram_trans_align; // DMA transfer alignment for data allocated from SRAM 164 lcd_i80_trans_descriptor_t *cur_trans; // Current transaction 165 lcd_panel_io_i80_t *cur_device; // Current working device 166 LIST_HEAD(i80_device_list, lcd_panel_io_i80_t) 167 device_list; // Head of i80 device list 168 struct 169 { 170 unsigned int exclusive : 1; // Indicate whether the I80 bus is owned by one device (whose CS GPIO is not assigned) exclusively 171 } flags; 172 dma_descriptor_t dma_nodes[]; // DMA descriptor pool, the descriptors are shared by all i80 devices 173 }; 174 175 struct lcd_i80_trans_descriptor_t 176 { 177 lcd_panel_io_i80_t *i80_device; // i80 device issuing this transaction 178 int cmd_value; // Command value 179 uint32_t cmd_cycles; // Command cycles 180 const void *data; // Data buffer 181 uint32_t data_length; // Data buffer size 182 void *user_ctx; // private data used by trans_done_cb 183 esp_lcd_panel_io_color_trans_done_cb_t trans_done_cb; // transaction done callback 184 }; 185 186 struct lcd_panel_io_i80_t 187 { 188 esp_lcd_panel_io_t base; // Base class of generic lcd panel io 189 esp_lcd_i80_bus_t *bus; // Which bus the device is attached to 190 int cs_gpio_num; // GPIO used for CS line 191 unsigned int pclk_hz; // PCLK clock frequency 192 size_t clock_prescale; // Prescaler coefficient, determined by user's configured PCLK frequency 193 QueueHandle_t trans_queue; // Transaction queue, transactions in this queue are pending for scheduler to dispatch 194 QueueHandle_t done_queue; // Transaction done queue, transactions in this queue are finished but not recycled by the caller 195 size_t queue_size; // Size of transaction queue 196 size_t num_trans_inflight; // Number of transactions that are undergoing (the descriptor not recycled yet) 197 int lcd_cmd_bits; // Bit width of LCD command 198 int lcd_param_bits; // Bit width of LCD parameter 199 void *user_ctx; // private data used when transfer color data 200 esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; // color data trans done callback 201 LIST_ENTRY(lcd_panel_io_i80_t) 202 device_list_entry; // Entry of i80 device list 203 struct 204 { 205 unsigned int dc_idle_level : 1; // Level of DC line in IDLE phase 206 unsigned int dc_cmd_level : 1; // Level of DC line in CMD phase 207 unsigned int dc_dummy_level : 1; // Level of DC line in DUMMY phase 208 unsigned int dc_data_level : 1; // Level of DC line in DATA phase 209 } dc_levels; 210 struct 211 { 212 unsigned int cs_active_high : 1; // Whether the CS line is active on high level 213 unsigned int reverse_color_bits : 1; // Reverse the data bits, D[N:0] -> D[0:N] 214 unsigned int swap_color_bytes : 1; // Swap adjacent two data bytes before sending out 215 unsigned int pclk_active_neg : 1; // The display will write data lines when there's a falling edge on WR line 216 unsigned int pclk_idle_low : 1; // The WR line keeps at low level in IDLE phase 217 } flags; 218 lcd_i80_trans_descriptor_t trans_pool[]; // Transaction pool 219 }; 220 #endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) 221 222 typedef enum 223 { 224 BEGIN_WRITE, 225 WRITE_COMMAND_8, 226 WRITE_COMMAND_16, 227 WRITE_DATA_8, 228 WRITE_DATA_16, 229 WRITE_BYTES, 230 WRITE_C8_D8, 231 WRITE_C8_D16, 232 WRITE_C16_D16, 233 END_WRITE, 234 DELAY, 235 } spi_operation_type_t; 236 237 union 238 { 239 uint16_t value; 240 struct 241 { 242 uint8_t lsb; 243 uint8_t msb; 244 }; 245 } _data16; 246 247 class Arduino_DataBus 248 { 249 public: 250 Arduino_DataBus(); 251 252 void unused() { UNUSED(_data16); } // avoid compiler warning 253 254 virtual bool begin(int32_t speed = SPI_DEFAULT_FREQ, int8_t dataMode = GFX_NOT_DEFINED) = 0; 255 virtual void beginWrite() = 0; 256 virtual void endWrite() = 0; 257 virtual void writeCommand(uint8_t c) = 0; 258 virtual void writeCommand16(uint16_t c) = 0; 259 virtual void write(uint8_t) = 0; 260 virtual void write16(uint16_t) = 0; 261 virtual void writeC8D8(uint8_t c, uint8_t d); 262 virtual void writeC16D16(uint16_t c, uint16_t d); 263 virtual void writeC8D16(uint8_t c, uint16_t d); 264 virtual void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2); 265 virtual void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2); 266 virtual void writeRepeat(uint16_t p, uint32_t len) = 0; 267 virtual void writePixels(uint16_t *data, uint32_t len) = 0; 268 269 void sendCommand(uint8_t c); 270 void sendCommand16(uint16_t c); 271 void sendData(uint8_t d); 272 void sendData16(uint16_t d); 273 274 void batchOperation(const uint8_t *operations, size_t len); 275 276 #if !defined(LITTLE_FOOT_PRINT) 277 virtual void writeBytes(uint8_t *data, uint32_t len) = 0; 278 virtual void writePattern(uint8_t *data, uint8_t len, uint32_t repeat) = 0; 279 virtual void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len); 280 virtual void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len); 281 #endif // !defined(LITTLE_FOOT_PRINT) 282 283 protected: 284 int32_t _speed; 285 int8_t _dataMode; 286 }; 287 288 #endif // _ARDUINO_DATABUS_H_