This commit is contained in:
2026-02-12 01:27:25 -08:00
parent 0e91b56966
commit bf3aca0d38
322 changed files with 297928 additions and 93 deletions

View File

@@ -0,0 +1,218 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#include "Arduino_DataBus.h"
Arduino_DataBus::Arduino_DataBus() {}
void Arduino_DataBus::writeC8D8(uint8_t c, uint8_t d)
{
writeCommand(c);
write(d);
}
void Arduino_DataBus::writeC8D16(uint8_t c, uint16_t d)
{
writeCommand(c);
write16(d);
}
void Arduino_DataBus::writeC16D16(uint16_t c, uint16_t d)
{
writeCommand16(c);
write16(d);
}
void Arduino_DataBus::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
writeCommand(c);
write16(d1);
write16(d2);
}
void Arduino_DataBus::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
writeCommand(c);
_data16.value = d1;
write(_data16.msb);
write(_data16.lsb);
_data16.value = d2;
write(_data16.msb);
write(_data16.lsb);
}
void Arduino_DataBus::sendCommand(uint8_t c)
{
beginWrite();
writeCommand(c);
endWrite();
}
void Arduino_DataBus::sendCommand16(uint16_t c)
{
beginWrite();
writeCommand16(c);
endWrite();
}
void Arduino_DataBus::sendData(uint8_t d)
{
beginWrite();
write(d);
endWrite();
}
void Arduino_DataBus::sendData16(uint16_t d)
{
beginWrite();
write16(d);
endWrite();
}
void Arduino_DataBus::batchOperation(const uint8_t *operations, size_t len)
{
for (size_t i = 0; i < len; ++i)
{
uint8_t l = 0;
switch (operations[i])
{
case BEGIN_WRITE:
beginWrite();
break;
case WRITE_C8_D16:
l++;
/* fall through */
case WRITE_C8_D8:
l++;
/* fall through */
case WRITE_COMMAND_8:
writeCommand(operations[++i]);
break;
case WRITE_C16_D16:
l = 2;
/* fall through */
case WRITE_COMMAND_16:
_data16.msb = operations[++i];
_data16.lsb = operations[++i];
writeCommand16(_data16.value);
break;
case WRITE_COMMAND_BYTES:
l = operations[++i];
writeCommandBytes((uint8_t *)(operations + i + 1), l);
i += l;
l = 0;
break;
case WRITE_DATA_8:
l = 1;
break;
case WRITE_DATA_16:
l = 2;
break;
case WRITE_BYTES:
l = operations[++i];
break;
case WRITE_C8_BYTES:
writeCommand(operations[++i]);
l = operations[++i];
break;
case END_WRITE:
endWrite();
break;
case DELAY:
delay(operations[++i]);
break;
default:
printf("Unknown operation id at %d: %d\n", i, operations[i]);
break;
}
while (l--)
{
write(operations[++i]);
}
}
}
#if !defined(LITTLE_FOOT_PRINT)
void Arduino_DataBus::write16bitBeRGBBitmapR1(uint16_t *bitmap, int16_t w, int16_t h)
{
uint16_t *p;
for (int16_t i = 0; i < w; i++)
{
p = bitmap + ((h - 1) * w) + i;
for (int16_t j = 0; j < h; j++)
{
_data16.value = *p;
write(_data16.lsb);
write(_data16.msb);
p -= w;
}
}
}
void Arduino_DataBus::writePattern(uint8_t *data, uint8_t len, uint32_t repeat)
{
while (repeat--)
{
writeBytes(data, len);
}
}
void Arduino_DataBus::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
write16(idx[*(data++)]);
}
}
void Arduino_DataBus::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
uint8_t *d = data;
while (len--)
{
_data16.value = idx[*(d++)];
write(_data16.msb);
write(_data16.lsb);
write(_data16.msb);
write(_data16.lsb);
}
}
void Arduino_DataBus::writeYCbCrPixels(uint8_t *yData, uint8_t *cbData, uint8_t *crData, uint16_t w, uint16_t h)
{
int cols = w >> 1;
uint8_t pxCb, pxCr;
int16_t pxR, pxG, pxB, pxY;
for (int row = 0; row < h;)
{
for (int col = 0; col < cols; ++col)
{
pxCb = *cbData++;
pxCr = *crData++;
pxR = CR2R16[pxCr];
pxG = -CB2G16[pxCb] - CR2G16[pxCr];
pxB = CB2B16[pxCb];
pxY = Y2I16[*yData++];
_data16.value = CLIPRBE[pxY + pxR] | CLIPGBE[pxY + pxG] | CLIPBBE[pxY + pxB];
write(_data16.lsb);
write(_data16.msb);
pxY = Y2I16[*yData++];
_data16.value = CLIPRBE[pxY + pxR] | CLIPGBE[pxY + pxG] | CLIPBBE[pxY + pxB];
write(_data16.lsb);
write(_data16.msb);
}
if (++row & 1)
{
// rollback CbCr data
cbData -= cols;
crData -= cols;
}
}
}
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,309 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#ifndef _ARDUINO_DATABUS_H_
#define _ARDUINO_DATABUS_H_
#include <Arduino.h>
#include "YCbCr2RGB.h"
#define GFX_SKIP_DATABUS_UNDERLAYING_BEGIN -4
#define GFX_SKIP_DATABUS_BEGIN -3
#define GFX_SKIP_OUTPUT_BEGIN -2
#define GFX_NOT_DEFINED -1
#define GFX_STR_HELPER(x) #x
#define GFX_STR(x) GFX_STR_HELPER(x)
#if defined(__AVR__)
#define LITTLE_FOOT_PRINT // reduce program size for limited flash MCU
#define USE_FAST_PINIO ///< Use direct PORT register access
typedef uint8_t ARDUINOGFX_PORT_t;
#elif defined(ARDUINO_ARCH_AIRMCU)
#define LITTLE_FOOT_PRINT // reduce program size for limited flash MCU
#define USE_FAST_PINIO ///< Use direct PORT register access
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(ARDUINO_ARCH_NRF52840)
#define USE_FAST_PINIO ///< Use direct PORT register access
#define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
#define USE_FAST_PINIO ///< Use direct PORT register access
#define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
typedef uint16_t ARDUINOGFX_PORT_t;
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#define USE_FAST_PINIO ///< Use direct PORT register access
#define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(ESP32)
#define USE_FAST_PINIO ///< Use direct PORT register access
#define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(ESP8266)
#define ESP8266SAFEBATCHBITSIZE (2048 * 8 * 9)
#define USE_FAST_PINIO ///< Use direct PORT register access
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(ARDUINO_ARCH_STM32)
#define USE_FAST_PINIO ///< Use direct PORT register access
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(__arm__)
#if defined(ARDUINO_ARCH_SAMD)
// Adafruit M0, M4
#define USE_FAST_PINIO ///< Use direct PORT register access
#define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(CONFIG_ARCH_CHIP_CXD56XX) // Sony Spresense
#define USE_FAST_PINIO ///< Use direct PORT register access
typedef uint8_t ARDUINOGFX_PORT_t;
#elif defined(RTL8722DM)
#define USE_FAST_PINIO ///< Use direct PORT register access
typedef uint32_t ARDUINOGFX_PORT_t;
#elif defined(CORE_TEENSY)
#define USE_FAST_PINIO ///< Use direct PORT register access
#define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
// PJRC Teensy 4.x
typedef uint32_t ARDUINOGFX_PORT_t;
#else
// PJRC Teensy 3.x
typedef uint8_t ARDUINOGFX_PORT_t;
#endif
#else
// Arduino Due?
// USE_FAST_PINIO not available here (yet)...Due has a totally different
// GPIO register set and will require some changes elsewhere (e.g. in
// constructors especially).
#endif
#else // !ARM
// Unknow architecture, USE_FAST_PINIO is not available here (yet)
// but don't worry about it too much...the digitalWrite() implementation
// on these platforms is reasonably efficient and already RAM-resident,
// only gotcha then is no parallel connection support for now.
#endif // !ARM
#ifdef USE_FAST_PINIO
typedef volatile ARDUINOGFX_PORT_t *PORTreg_t;
#endif
#if defined(ARDUINO_ARCH_ARC32) || defined(ARDUINO_MAXIM)
#define SPI_DEFAULT_FREQ 16000000
// Teensy 3.0, 3.1/3.2, 3.5, 3.6
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define SPI_DEFAULT_FREQ 40000000
// Teensy 4.x
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
#define SPI_DEFAULT_FREQ 40000000
#elif defined(__AVR__) || defined(TEENSYDUINO)
#define SPI_DEFAULT_FREQ 8000000
#elif defined(ARDUINO_ARCH_NRF52840)
#define SPI_DEFAULT_FREQ 8000000
#elif defined(ESP8266) || defined(ESP32)
#define SPI_DEFAULT_FREQ 40000000
#elif defined(RTL8722DM)
#define SPI_DEFAULT_FREQ 20000000
#elif defined(RASPI)
#define SPI_DEFAULT_FREQ 80000000
#elif defined(ARDUINO_ARCH_STM32F1)
#define SPI_DEFAULT_FREQ 36000000
#elif defined(ARDUINO_BLACKPILL_F411CE)
#define SPI_DEFAULT_FREQ 50000000
#elif defined(F_CPU)
#define SPI_DEFAULT_FREQ (F_CPU / 4)
#else
#define SPI_DEFAULT_FREQ 24000000 ///< Default SPI data clock frequency
#endif
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif
#define ATTR_UNUSED __attribute__((unused))
#define MSB_16(val) (((val) & 0xFF00) >> 8) | (((val) & 0xFF) << 8)
#define MSB_16_SET(var, val) \
{ \
(var) = MSB_16(val); \
}
#define MSB_32_SET(var, val) \
{ \
uint8_t *v = (uint8_t *)&(val); \
(var) = v[3] | (v[2] << 8) | (v[1] << 16) | (v[0] << 24); \
}
#define MSB_32_16_16_SET(var, v1, v2) \
{ \
(var) = (((uint32_t)v2 & 0xff00) << 8) | (((uint32_t)v2 & 0xff) << 24) | ((v1 & 0xff00) >> 8) | ((v1 & 0xff) << 8); \
}
#define MSB_32_8_ARRAY_SET(var, a) \
{ \
(var) = ((uint32_t)a[0] << 8 | a[1] | a[2] << 24 | a[3] << 16); \
}
#if !defined(LITTLE_FOOT_PRINT)
#define GFX_INLINE __attribute__((always_inline)) inline
#else
#define GFX_INLINE inline
#endif // !defined(LITTLE_FOOT_PRINT)
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_io_interface.h>
#include <esp_pm.h>
#include <esp_private/gdma.h>
#include <hal/dma_types.h>
#include <hal/lcd_hal.h>
#include <soc/dport_reg.h>
#include <soc/gpio_sig_map.h>
#include <soc/lcd_cam_reg.h>
#include <soc/lcd_cam_struct.h>
typedef struct esp_lcd_i80_bus_t esp_lcd_i80_bus_t;
typedef struct lcd_panel_io_i80_t lcd_panel_io_i80_t;
typedef struct lcd_i80_trans_descriptor_t lcd_i80_trans_descriptor_t;
struct esp_lcd_i80_bus_t
{
int bus_id; // Bus ID, index from 0
portMUX_TYPE spinlock; // spinlock used to protect i80 bus members(hal, device_list, cur_trans)
lcd_hal_context_t hal; // Hal object
size_t bus_width; // Number of data lines
intr_handle_t intr; // LCD peripheral interrupt handle
esp_pm_lock_handle_t pm_lock; // Power management lock
size_t num_dma_nodes; // Number of DMA descriptors
uint8_t *format_buffer; // The driver allocates an internal buffer for DMA to do data format transformer
size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source
gdma_channel_handle_t dma_chan; // DMA channel handle
size_t psram_trans_align; // DMA transfer alignment for data allocated from PSRAM
size_t sram_trans_align; // DMA transfer alignment for data allocated from SRAM
lcd_i80_trans_descriptor_t *cur_trans; // Current transaction
lcd_panel_io_i80_t *cur_device; // Current working device
LIST_HEAD(i80_device_list, lcd_panel_io_i80_t)
device_list; // Head of i80 device list
struct
{
unsigned int exclusive : 1; // Indicate whether the I80 bus is owned by one device (whose CS GPIO is not assigned) exclusively
} flags;
dma_descriptor_t dma_nodes[]; // DMA descriptor pool, the descriptors are shared by all i80 devices
};
struct lcd_i80_trans_descriptor_t
{
lcd_panel_io_i80_t *i80_device; // i80 device issuing this transaction
int cmd_value; // Command value
uint32_t cmd_cycles; // Command cycles
const void *data; // Data buffer
uint32_t data_length; // Data buffer size
void *user_ctx; // private data used by trans_done_cb
esp_lcd_panel_io_color_trans_done_cb_t trans_done_cb; // transaction done callback
};
struct lcd_panel_io_i80_t
{
esp_lcd_panel_io_t base; // Base class of generic lcd panel io
esp_lcd_i80_bus_t *bus; // Which bus the device is attached to
int cs_gpio_num; // GPIO used for CS line
unsigned int pclk_hz; // PCLK clock frequency
size_t clock_prescale; // Prescaler coefficient, determined by user's configured PCLK frequency
QueueHandle_t trans_queue; // Transaction queue, transactions in this queue are pending for scheduler to dispatch
QueueHandle_t done_queue; // Transaction done queue, transactions in this queue are finished but not recycled by the caller
size_t queue_size; // Size of transaction queue
size_t num_trans_inflight; // Number of transactions that are undergoing (the descriptor not recycled yet)
int lcd_cmd_bits; // Bit width of LCD command
int lcd_param_bits; // Bit width of LCD parameter
void *user_ctx; // private data used when transfer color data
esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; // color data trans done callback
LIST_ENTRY(lcd_panel_io_i80_t)
device_list_entry; // Entry of i80 device list
struct
{
unsigned int dc_idle_level : 1; // Level of DC line in IDLE phase
unsigned int dc_cmd_level : 1; // Level of DC line in CMD phase
unsigned int dc_dummy_level : 1; // Level of DC line in DUMMY phase
unsigned int dc_data_level : 1; // Level of DC line in DATA phase
} dc_levels;
struct
{
unsigned int cs_active_high : 1; // Whether the CS line is active on high level
unsigned int reverse_color_bits : 1; // Reverse the data bits, D[N:0] -> D[0:N]
unsigned int swap_color_bytes : 1; // Swap adjacent two data bytes before sending out
unsigned int pclk_active_neg : 1; // The display will write data lines when there's a falling edge on WR line
unsigned int pclk_idle_low : 1; // The WR line keeps at low level in IDLE phase
} flags;
lcd_i80_trans_descriptor_t trans_pool[]; // Transaction pool
};
#endif // #if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
typedef enum
{
BEGIN_WRITE,
WRITE_COMMAND_8,
WRITE_COMMAND_16,
WRITE_COMMAND_BYTES,
WRITE_DATA_8,
WRITE_DATA_16,
WRITE_BYTES,
WRITE_C8_D8,
WRITE_C8_D16,
WRITE_C8_BYTES,
WRITE_C16_D16,
END_WRITE,
DELAY,
} spi_operation_type_t;
union
{
uint16_t value;
struct
{
uint8_t lsb;
uint8_t msb;
};
} _data16;
class Arduino_DataBus
{
public:
Arduino_DataBus();
void unused() { UNUSED(_data16); } // avoid compiler warning
virtual bool begin(int32_t speed = SPI_DEFAULT_FREQ, int8_t dataMode = GFX_NOT_DEFINED) = 0;
virtual void beginWrite() = 0;
virtual void endWrite() = 0;
virtual void writeCommand(uint8_t c) = 0;
virtual void writeCommand16(uint16_t c) = 0;
virtual void writeCommandBytes(uint8_t *data, uint32_t len) = 0;
virtual void write(uint8_t) = 0;
virtual void write16(uint16_t) = 0;
virtual void writeC8D8(uint8_t c, uint8_t d);
virtual void writeC16D16(uint16_t c, uint16_t d);
virtual void writeC8D16(uint8_t c, uint16_t d);
virtual void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2);
virtual void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2);
virtual void writeRepeat(uint16_t p, uint32_t len) = 0;
virtual void writeBytes(uint8_t *data, uint32_t len) = 0;
virtual void writePixels(uint16_t *data, uint32_t len) = 0;
void sendCommand(uint8_t c);
void sendCommand16(uint16_t c);
void sendData(uint8_t d);
void sendData16(uint16_t d);
#if !defined(LITTLE_FOOT_PRINT)
virtual void write16bitBeRGBBitmapR1(uint16_t *bitmap, int16_t w, int16_t h);
virtual void batchOperation(const uint8_t *operations, size_t len);
virtual void writePattern(uint8_t *data, uint8_t len, uint32_t repeat);
virtual void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len);
virtual void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len);
virtual void writeYCbCrPixels(uint8_t *yData, uint8_t *cbData, uint8_t *crData, uint16_t w, uint16_t h);
#else
void batchOperation(const uint8_t *operations, size_t len);
#endif // !defined(LITTLE_FOOT_PRINT)
protected:
int32_t _speed;
int8_t _dataMode;
};
#endif // _ARDUINO_DATABUS_H_

View File

@@ -0,0 +1,275 @@
#include "Arduino_G.h"
/**************************************************************************/
/*!
@brief Instatiate a GFX context for graphics! Can only be done by a superclass
@param w Display width, in pixels
@param h Display height, in pixels
*/
/**************************************************************************/
Arduino_G::Arduino_G(int16_t w, int16_t h) : WIDTH(w), HEIGHT(h)
{
}
// utility functions
bool gfx_draw_bitmap_to_framebuffer(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h)
{
int16_t max_X = framebuffer_w - 1;
int16_t max_Y = framebuffer_h - 1;
if (
((x + bitmap_w - 1) < 0) || // Outside left
((y + bitmap_h - 1) < 0) || // Outside top
(x > max_X) || // Outside right
(y > max_Y) // Outside bottom
)
{
return false;
}
else
{
int16_t x_skip = 0;
if ((y + bitmap_h - 1) > max_Y)
{
bitmap_h -= (y + bitmap_h - 1) - max_Y;
}
if (y < 0)
{
from_bitmap -= y * bitmap_w;
bitmap_h += y;
y = 0;
}
if ((x + bitmap_w - 1) > max_X)
{
x_skip = (x + bitmap_w - 1) - max_X;
bitmap_w -= x_skip;
}
if (x < 0)
{
from_bitmap -= x;
x_skip -= x;
bitmap_w += x;
x = 0;
}
uint16_t *row = framebuffer;
row += y * framebuffer_w; // shift framebuffer to y offset
row += x; // shift framebuffer to x offset
if (((framebuffer_w & 1) == 0) && ((x_skip & 1) == 0) && ((bitmap_w & 1) == 0))
{
uint32_t *row2 = (uint32_t *)row;
uint32_t *from_bitmap2 = (uint32_t *)from_bitmap;
int16_t framebuffer_w2 = framebuffer_w >> 1;
int16_t xskip2 = x_skip >> 1;
int16_t w2 = bitmap_w >> 1;
int16_t j = bitmap_h;
while (j--)
{
for (int16_t i = 0; i < w2; ++i)
{
row2[i] = *from_bitmap2++;
}
from_bitmap2 += xskip2;
row2 += framebuffer_w2;
}
}
else
{
int16_t j = bitmap_h;
while (j--)
{
for (int i = 0; i < bitmap_w; ++i)
{
row[i] = *from_bitmap++;
}
from_bitmap += x_skip;
row += framebuffer_w;
}
}
return true;
}
}
bool gfx_draw_bitmap_to_framebuffer_rotate_1(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h)
{
int16_t max_X = framebuffer_w - 1;
int16_t max_Y = framebuffer_h - 1;
if (
((x + bitmap_w - 1) < 0) || // Outside left
((y + bitmap_h - 1) < 0) || // Outside top
(x > max_X) || // Outside right
(y > max_Y) // Outside bottom
)
{
return false;
}
else
{
int16_t x_skip = 0;
if ((y + bitmap_h - 1) > max_Y)
{
bitmap_h -= (y + bitmap_h - 1) - max_Y;
}
if (y < 0)
{
from_bitmap -= y * bitmap_w;
bitmap_h += y;
y = 0;
}
if ((x + bitmap_w - 1) > max_X)
{
x_skip = (x + bitmap_w - 1) - max_X;
bitmap_w -= x_skip;
}
if (x < 0)
{
from_bitmap -= x;
x_skip -= x;
bitmap_w += x;
x = 0;
}
uint16_t *p;
int16_t i;
for (int16_t j = 0; j < bitmap_h; j++)
{
p = framebuffer;
p += (x * framebuffer_h); // shift framebuffer to y offset
p += (framebuffer_h - y - j - 1); // shift framebuffer to x offset
i = bitmap_w;
while (i--)
{
*p = *from_bitmap++;
p += framebuffer_h;
}
from_bitmap += x_skip;
}
return true;
}
}
bool gfx_draw_bitmap_to_framebuffer_rotate_2(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h)
{
int16_t max_X = framebuffer_w - 1;
int16_t max_Y = framebuffer_h - 1;
if (
((x + bitmap_w - 1) < 0) || // Outside left
((y + bitmap_h - 1) < 0) || // Outside top
(x > max_X) || // Outside right
(y > max_Y) // Outside bottom
)
{
return false;
}
else
{
int16_t x_skip = 0;
if ((y + bitmap_h - 1) > max_Y)
{
bitmap_h -= (y + bitmap_h - 1) - max_Y;
}
if (y < 0)
{
from_bitmap -= y * bitmap_w;
bitmap_h += y;
y = 0;
}
if ((x + bitmap_w - 1) > max_X)
{
x_skip = (x + bitmap_w - 1) - max_X;
bitmap_w -= x_skip;
}
if (x < 0)
{
from_bitmap -= x;
x_skip -= x;
bitmap_w += x;
x = 0;
}
uint16_t *row = framebuffer;
row += (max_Y - y) * framebuffer_w; // shift framebuffer to y offset
row += framebuffer_w - x - bitmap_w; // shift framebuffer to x offset
int16_t i;
int16_t j = bitmap_h;
while (j--)
{
i = bitmap_w;
while (i--)
{
row[i] = *from_bitmap++;
}
from_bitmap += x_skip;
row -= framebuffer_w;
}
return true;
}
}
bool gfx_draw_bitmap_to_framebuffer_rotate_3(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h)
{
int16_t max_X = framebuffer_w - 1;
int16_t max_Y = framebuffer_h - 1;
if (
((x + bitmap_w - 1) < 0) || // Outside left
((y + bitmap_h - 1) < 0) || // Outside top
(x > max_X) || // Outside right
(y > max_Y) // Outside bottom
)
{
return false;
}
else
{
int16_t x_skip = 0;
if ((y + bitmap_h - 1) > max_Y)
{
bitmap_h -= (y + bitmap_h - 1) - max_Y;
}
if (y < 0)
{
from_bitmap -= y * bitmap_w;
bitmap_h += y;
y = 0;
}
if ((x + bitmap_w - 1) > max_X)
{
x_skip = (x + bitmap_w - 1) - max_X;
bitmap_w -= x_skip;
}
if (x < 0)
{
from_bitmap -= x;
x_skip -= x;
bitmap_w += x;
x = 0;
}
uint16_t *p;
int16_t i;
for (int16_t j = 0; j < bitmap_h; j++)
{
p = framebuffer;
p += ((max_X - x) * framebuffer_h); // shift framebuffer to y offset
p += y + j; // shift framebuffer to x offset
i = bitmap_w;
while (i--)
{
*p = *from_bitmap++;
p -= framebuffer_h;
}
from_bitmap += x_skip;
}
return true;
}
}

View File

@@ -0,0 +1,44 @@
#ifndef _ARDUINO_G_H_
#define _ARDUINO_G_H_
#include "Arduino_DataBus.h"
/// A generic graphics superclass that can handle all sorts of drawing. At a minimum you can subclass and provide drawPixel(). At a maximum you can do a ton of overriding to optimize. Used for any/all Adafruit displays!
class Arduino_G
{
public:
Arduino_G(int16_t w, int16_t h); // Constructor
// This MUST be defined by the subclass:
virtual bool begin(int32_t speed = GFX_NOT_DEFINED) = 0;
virtual void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) = 0;
virtual void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip = 0) = 0;
virtual void draw3bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h) = 0;
virtual void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) = 0;
virtual void draw24bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h) = 0;
protected:
int16_t
WIDTH, ///< This is the 'raw' display width - never changes
HEIGHT; ///< This is the 'raw' display height - never changes
};
#endif // _ARDUINO_G_H_
// utility functions
bool gfx_draw_bitmap_to_framebuffer(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h);
bool gfx_draw_bitmap_to_framebuffer_rotate_1(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h);
bool gfx_draw_bitmap_to_framebuffer_rotate_2(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h);
bool gfx_draw_bitmap_to_framebuffer_rotate_3(
uint16_t *from_bitmap, int16_t bitmap_w, int16_t bitmap_h,
uint16_t *framebuffer, int16_t x, int16_t y, int16_t framebuffer_w, int16_t framebuffer_h);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,591 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#ifndef _ARDUINO_GFX_H_
#define _ARDUINO_GFX_H_
#include "Arduino_G.h"
#include "Arduino_DataBus.h"
#include <Print.h>
#if !defined(ATTINY_CORE)
#include "gfxfont.h"
#endif // !defined(ATTINY_CORE)
#ifndef DEGTORAD
#define DEGTORAD 0.017453292519943295769236907684886F
#endif
#if __has_include(<U8g2lib.h>)
#include <U8g2lib.h>
#define U8G2_FONT_SUPPORT
#include "font/u8g2_font_chill7_h_cjk.h"
#include "font/u8g2_font_cubic11_h_cjk.h"
#include "font/u8g2_font_quan7_h_cjk.h"
#include "font/u8g2_font_unifont_h_chinese.h"
#include "font/u8g2_font_unifont_h_chinese4.h"
#include "font/u8g2_font_unifont_h_cjk.h"
#include "font/u8g2_font_unifont_h_utf8.h"
#endif
#define RGB565(r, g, b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3))
#define RGB16TO24(c) ((((uint32_t)c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x1F) << 3))
/* https://www.w3.org/wiki/CSS/Properties/color/keywords */
#define RGB565_ALICEBLUE RGB565(240, 248, 248)
#define RGB565_ANTIQUEWHITE RGB565(248, 236, 216)
#define RGB565_AQUA RGB565(0, 252, 248)
#define RGB565_AQUAMARINE RGB565(128, 252, 216)
#define RGB565_AZURE RGB565(240, 252, 248)
#define RGB565_BEIGE RGB565(248, 244, 224)
#define RGB565_BISQUE RGB565(248, 228, 200)
#define RGB565_BLACK RGB565(0, 0, 0)
#define RGB565_BLANCHEDALMOND RGB565(248, 236, 208)
#define RGB565_BLUE RGB565(0, 0, 248)
#define RGB565_BLUEVIOLET RGB565(136, 44, 224)
#define RGB565_BROWN RGB565(168, 44, 40)
#define RGB565_BURLYWOOD RGB565(224, 184, 136)
#define RGB565_CADETBLUE RGB565(96, 160, 160)
#define RGB565_CHARTREUSE RGB565(128, 252, 0)
#define RGB565_CHOCOLATE RGB565(208, 104, 32)
#define RGB565_CORAL RGB565(248, 128, 80)
#define RGB565_CORNFLOWERBLUE RGB565(104, 148, 240)
#define RGB565_CORNSILK RGB565(248, 248, 224)
#define RGB565_CRIMSON RGB565(224, 20, 64)
#define RGB565_CYAN RGB565(0, 252, 248)
#define RGB565_DARKBLUE RGB565(0, 0, 136)
#define RGB565_DARKCYAN RGB565(0, 140, 136)
#define RGB565_DARKGOLDENROD RGB565(184, 136, 8)
#define RGB565_DARKGRAY RGB565(168, 168, 168)
#define RGB565_DARKGREEN RGB565(0, 100, 0)
#define RGB565_DARKGREY RGB565(168, 168, 168)
#define RGB565_DARKKHAKI RGB565(192, 184, 104)
#define RGB565_DARKMAGENTA RGB565(136, 0, 136)
#define RGB565_DARKOLIVEGREEN RGB565(88, 108, 48)
#define RGB565_DARKORANGE RGB565(248, 140, 0)
#define RGB565_DARKORCHID RGB565(152, 52, 208)
#define RGB565_DARKRED RGB565(136, 0, 0)
#define RGB565_DARKSALMON RGB565(232, 152, 120)
#define RGB565_DARKSEAGREEN RGB565(144, 188, 144)
#define RGB565_DARKSLATEBLUE RGB565(72, 60, 136)
#define RGB565_DARKSLATEGRAY RGB565(48, 80, 80)
#define RGB565_DARKSLATEGREY RGB565(48, 80, 80)
#define RGB565_DARKTURQUOISE RGB565(0, 208, 208)
#define RGB565_DARKVIOLET RGB565(152, 0, 208)
#define RGB565_DEEPPINK RGB565(248, 20, 144)
#define RGB565_DEEPSKYBLUE RGB565(0, 192, 248)
#define RGB565_DIMGRAY RGB565(104, 104, 104)
#define RGB565_DIMGREY RGB565(104, 104, 104)
#define RGB565_DODGERBLUE RGB565(32, 144, 248)
#define RGB565_FIREBRICK RGB565(176, 36, 32)
#define RGB565_FLORALWHITE RGB565(248, 252, 240)
#define RGB565_FORESTGREEN RGB565(32, 140, 32)
#define RGB565_FUCHSIA RGB565(248, 0, 248)
#define RGB565_GAINSBORO RGB565(224, 220, 224)
#define RGB565_GHOSTWHITE RGB565(248, 248, 248)
#define RGB565_GOLD RGB565(248, 216, 0)
#define RGB565_GOLDENROD RGB565(216, 164, 32)
#define RGB565_GRAY RGB565(128, 128, 128)
#define RGB565_GREEN RGB565(0, 128, 0)
#define RGB565_GREENYELLOW RGB565(176, 252, 48)
#define RGB565_GREY RGB565(128, 128, 128)
#define RGB565_HONEYDEW RGB565(240, 252, 240)
#define RGB565_HOTPINK RGB565(248, 104, 184)
#define RGB565_INDIANRED RGB565(208, 92, 96)
#define RGB565_INDIGO RGB565(72, 0, 128)
#define RGB565_IVORY RGB565(248, 252, 240)
#define RGB565_KHAKI RGB565(240, 232, 144)
#define RGB565_LAVENDER RGB565(232, 232, 248)
#define RGB565_LAVENDERBLUSH RGB565(248, 240, 248)
#define RGB565_LAWNGREEN RGB565(128, 252, 0)
#define RGB565_LEMONCHIFFON RGB565(248, 252, 208)
#define RGB565_LIGHTBLUE RGB565(176, 216, 232)
#define RGB565_LIGHTCORAL RGB565(240, 128, 128)
#define RGB565_LIGHTCYAN RGB565(224, 252, 248)
#define RGB565_LIGHTGOLDENRODYELLOW RGB565(248, 252, 208)
#define RGB565_LIGHTGRAY RGB565(208, 212, 208)
#define RGB565_LIGHTGREEN RGB565(144, 240, 144)
#define RGB565_LIGHTGREY RGB565(208, 212, 208)
#define RGB565_LIGHTPINK RGB565(248, 184, 192)
#define RGB565_LIGHTSALMON RGB565(248, 160, 120)
#define RGB565_LIGHTSEAGREEN RGB565(32, 180, 168)
#define RGB565_LIGHTSKYBLUE RGB565(136, 208, 248)
#define RGB565_LIGHTSLATEGRAY RGB565(120, 136, 152)
#define RGB565_LIGHTSLATEGREY RGB565(120, 136, 152)
#define RGB565_LIGHTSTEELBLUE RGB565(176, 196, 224)
#define RGB565_LIGHTYELLOW RGB565(248, 252, 224)
#define RGB565_LIME RGB565(0, 252, 0)
#define RGB565_LIMEGREEN RGB565(48, 204, 48)
#define RGB565_LINEN RGB565(248, 240, 232)
#define RGB565_MAGENTA RGB565(248, 0, 248)
#define RGB565_MAROON RGB565(128, 0, 0)
#define RGB565_MEDIUMAQUAMARINE RGB565(104, 204, 168)
#define RGB565_MEDIUMBLUE RGB565(0, 0, 208)
#define RGB565_MEDIUMORCHID RGB565(184, 84, 208)
#define RGB565_MEDIUMPURPLE RGB565(144, 112, 216)
#define RGB565_MEDIUMSEAGREEN RGB565(64, 180, 112)
#define RGB565_MEDIUMSLATEBLUE RGB565(120, 104, 240)
#define RGB565_MEDIUMSPRINGGREEN RGB565(0, 252, 152)
#define RGB565_MEDIUMTURQUOISE RGB565(72, 208, 208)
#define RGB565_MEDIUMVIOLETRED RGB565(200, 20, 136)
#define RGB565_MIDNIGHTBLUE RGB565(24, 24, 112)
#define RGB565_MINTCREAM RGB565(248, 252, 248)
#define RGB565_MISTYROSE RGB565(248, 228, 224)
#define RGB565_MOCCASIN RGB565(248, 228, 184)
#define RGB565_NAVAJOWHITE RGB565(248, 224, 176)
#define RGB565_NAVY RGB565(0, 0, 128)
#define RGB565_OLDLACE RGB565(248, 244, 232)
#define RGB565_OLIVE RGB565(128, 128, 0)
#define RGB565_OLIVEDRAB RGB565(104, 144, 32)
#define RGB565_ORANGE RGB565(248, 164, 0)
#define RGB565_ORANGERED RGB565(248, 68, 0)
#define RGB565_ORCHID RGB565(216, 112, 216)
#define RGB565_PALEGOLDENROD RGB565(240, 232, 168)
#define RGB565_PALEGREEN RGB565(152, 252, 152)
#define RGB565_PALETURQUOISE RGB565(176, 240, 240)
#define RGB565_PALEVIOLETRED RGB565(216, 112, 144)
#define RGB565_PAPAYAWHIP RGB565(248, 240, 216)
#define RGB565_PEACHPUFF RGB565(248, 220, 184)
#define RGB565_PERU RGB565(208, 132, 64)
#define RGB565_PINK RGB565(248, 192, 200)
#define RGB565_PLUM RGB565(224, 160, 224)
#define RGB565_POWDERBLUE RGB565(176, 224, 232)
#define RGB565_PURPLE RGB565(128, 0, 128)
#define RGB565_RED RGB565(248, 0, 0)
#define RGB565_ROSYBROWN RGB565(192, 144, 144)
#define RGB565_ROYALBLUE RGB565(64, 104, 224)
#define RGB565_SADDLEBROWN RGB565(136, 68, 16)
#define RGB565_SALMON RGB565(248, 128, 112)
#define RGB565_SANDYBROWN RGB565(248, 164, 96)
#define RGB565_SEAGREEN RGB565(48, 140, 88)
#define RGB565_SEASHELL RGB565(248, 244, 240)
#define RGB565_SIENNA RGB565(160, 84, 48)
#define RGB565_SILVER RGB565(192, 192, 192)
#define RGB565_SKYBLUE RGB565(136, 208, 232)
#define RGB565_SLATEBLUE RGB565(104, 92, 208)
#define RGB565_SLATEGRAY RGB565(112, 128, 144)
#define RGB565_SLATEGREY RGB565(112, 128, 144)
#define RGB565_SNOW RGB565(248, 252, 248)
#define RGB565_SPRINGGREEN RGB565(0, 252, 128)
#define RGB565_STEELBLUE RGB565(72, 132, 184)
#define RGB565_TAN RGB565(208, 180, 144)
#define RGB565_TEAL RGB565(0, 128, 128)
#define RGB565_THISTLE RGB565(216, 192, 216)
#define RGB565_TOMATO RGB565(248, 100, 72)
#define RGB565_TURQUOISE RGB565(64, 224, 208)
#define RGB565_VIOLET RGB565(240, 132, 240)
#define RGB565_WHEAT RGB565(248, 224, 176)
#define RGB565_WHITE RGB565(248, 252, 248)
#define RGB565_WHITESMOKE RGB565(248, 244, 248)
#define RGB565_YELLOW RGB565(248, 252, 0)
#define RGB565_YELLOWGREEN RGB565(152, 204, 48)
// Many (but maybe not all) non-AVR board installs define macros
// for compatibility with existing PROGMEM-reading AVR code.
// Do our own checks and defines here for good measure...
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#endif
#ifndef pgm_read_sbyte
#define pgm_read_sbyte(addr) (*(const signed char *)(addr))
#endif
#ifndef pgm_read_word
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#endif
#ifndef pgm_read_dword
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#endif
// workaround of a15 asm compile error
#ifdef ESP8266
#undef pgm_read_word
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#endif
// Pointers are a peculiar case...typically 16-bit on AVR boards,
// 32 bits elsewhere. Try to accommodate both...
#if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF)
#define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr))
#else
#define pgm_read_pointer(addr) ((void *)pgm_read_word(addr))
#endif
#ifndef _swap_uint8_t
#define _swap_uint8_t(a, b) \
{ \
uint8_t t = a; \
a = b; \
b = t; \
}
#endif
#ifndef _swap_int16_t
#define _swap_int16_t(a, b) \
{ \
int16_t t = a; \
a = b; \
b = t; \
}
#endif
#ifndef _diff
#define _diff(a, b) ((a > b) ? (a - b) : (b - a))
#endif
#ifndef _ordered_in_range
#define _ordered_in_range(v, a, b) ((a <= v) && (v <= b))
#endif
#ifndef _in_range
#define _in_range(v, a, b) ((a > b) ? _ordered_in_range(v, b, a) : _ordered_in_range(v, a, b))
#endif
#if !defined(ATTINY_CORE)
GFX_INLINE static GFXglyph *pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c)
{
#ifdef __AVR__
return &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]);
#else
// expression in __AVR__ section may generate "dereferencing type-punned pointer will break strict-aliasing rules" warning
// In fact, on other platforms (such as STM32) there is no need to do this pointer magic as program memory may be read in a usual way
// So expression may be simplified
return gfxFont->glyph + c;
#endif //__AVR__
}
GFX_INLINE static uint8_t *pgm_read_bitmap_ptr(const GFXfont *gfxFont)
{
#ifdef __AVR__
return (uint8_t *)pgm_read_pointer(&gfxFont->bitmap);
#else
// expression in __AVR__ section generates "dereferencing type-punned pointer will break strict-aliasing rules" warning
// In fact, on other platforms (such as STM32) there is no need to do this pointer magic as program memory may be read in a usual way
// So expression may be simplified
return gfxFont->bitmap;
#endif //__AVR__
}
#endif // !defined(ATTINY_CORE)
/// A generic graphics superclass that can handle all sorts of drawing. At a minimum you can subclass and provide drawPixel(). At a maximum you can do a ton of overriding to optimize. Used for any/all Adafruit displays!
#if defined(LITTLE_FOOT_PRINT)
class Arduino_GFX : public Print
#else
class Arduino_GFX : public Print, public Arduino_G
#endif // !defined(LITTLE_FOOT_PRINT)
{
public:
Arduino_GFX(int16_t w, int16_t h); // Constructor
// This MUST be defined by the subclass:
virtual bool begin(int32_t speed = GFX_NOT_DEFINED) = 0;
virtual void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) = 0;
// TRANSACTION API / CORE DRAW API
// These MAY be overridden by the subclass to provide device-specific
// optimized code. Otherwise 'generic' versions are used.
virtual void startWrite();
virtual void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
virtual void endWrite(void);
// CONTROL API
// These MAY be overridden by the subclass to provide device-specific
// optimized code. Otherwise 'generic' versions are used.
virtual void setRotation(uint8_t r);
virtual void invertDisplay(bool i);
virtual void displayOn();
virtual void displayOff();
bool enableRoundMode();
// BASIC DRAW API
// These MAY be overridden by the subclass to provide device-specific
// optimized code. Otherwise 'generic' versions are used.
// It's good to implement those, even if using transaction API
void writePixel(int16_t x, int16_t y, uint16_t color);
void drawPixel(int16_t x, int16_t y, uint16_t color);
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void fillScreen(uint16_t color);
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color);
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);
void drawXBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color);
void drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], const uint8_t mask[], int16_t w, int16_t h);
void drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint8_t *mask, int16_t w, int16_t h);
void draw16bitRGBBitmapWithMask(int16_t x, int16_t y, const uint16_t bitmap[], const uint8_t mask[], int16_t w, int16_t h);
void draw24bitRGBBitmap(int16_t x, int16_t y, const uint8_t bitmap[], const uint8_t mask[], int16_t w, int16_t h);
void draw24bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint8_t *mask, int16_t w, int16_t h);
void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
void getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
void setTextSize(uint8_t s);
void setTextSize(uint8_t sx, uint8_t sy);
void setTextSize(uint8_t sx, uint8_t sy, uint8_t pixel_margin);
#if !defined(ATTINY_CORE)
void setFont(const GFXfont *f = NULL);
#if defined(U8G2_FONT_SUPPORT)
void setFont(const uint8_t *font);
void setUTF8Print(bool isEnable);
uint16_t u8g2_font_get_word(const uint8_t *font, uint8_t offset);
uint8_t u8g2_font_decode_get_unsigned_bits(uint8_t cnt);
int8_t u8g2_font_decode_get_signed_bits(uint8_t cnt);
void u8g2_font_decode_len(uint8_t len, uint8_t is_foreground, uint16_t color, uint16_t bg);
#endif // defined(U8G2_FONT_SUPPORT)
virtual void flush(bool force_flush = false);
#endif // !defined(ATTINY_CORE)
// adopt from LovyanGFX
void drawEllipse(int16_t x, int16_t y, int16_t rx, int16_t ry, uint16_t color);
void writeEllipseHelper(int32_t x, int32_t y, int32_t rx, int32_t ry, uint8_t cornername, uint16_t color);
void fillEllipse(int16_t x, int16_t y, int16_t rx, int16_t ry, uint16_t color);
void writeFillEllipseHelper(int32_t x, int32_t y, int32_t rx, int32_t ry, uint8_t cornername, int16_t delta, uint16_t color);
void drawArc(int16_t x, int16_t y, int16_t r1, int16_t r2, float start, float end, uint16_t color);
void fillArc(int16_t x, int16_t y, int16_t r1, int16_t r2, float start, float end, uint16_t color);
void writeFillArcHelper(int16_t cx, int16_t cy, int16_t oradius, int16_t iradius, float start, float end, uint16_t color);
// TFT optimization code, too big for ATMEL family
#if defined(LITTLE_FOOT_PRINT)
void writeSlashLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg);
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg);
void drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h);
void drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h);
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip = 0);
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, uint8_t chroma_key, int16_t w, int16_t h, int16_t x_skip = 0);
void draw3bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h);
void draw16bitRGBBitmapWithMask(int16_t x, int16_t y, uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h);
void draw16bitRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h);
void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h);
void draw16bitRGBBitmapWithTranColor(int16_t x, int16_t y, uint16_t *bitmap, uint16_t transparent_color, int16_t w, int16_t h);
void draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h);
void draw24bitRGBBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h);
void draw24bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h);
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg);
#else // !defined(LITTLE_FOOT_PRINT)
virtual void writeSlashLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
virtual void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg);
virtual void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg);
virtual void drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h);
virtual void drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h);
virtual void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip = 0);
virtual void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, uint8_t chroma_key, int16_t w, int16_t h, int16_t x_skip = 0);
virtual void draw3bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h);
virtual void draw16bitRGBBitmapWithMask(int16_t x, int16_t y, uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h);
virtual void draw16bitRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h);
virtual void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h);
virtual void draw16bitRGBBitmapWithTranColor(int16_t x, int16_t y, uint16_t *bitmap, uint16_t transparent_color, int16_t w, int16_t h);
virtual void draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h);
virtual void draw24bitRGBBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h);
virtual void draw24bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h);
virtual void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg);
virtual void draw16bitBeRGBBitmapR1(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h);
#endif // !defined(LITTLE_FOOT_PRINT)
/**********************************************************************/
/*!
@brief Set text cursor location
@param x X coordinate in pixels
@param y Y coordinate in pixels
*/
/**********************************************************************/
void setCursor(int16_t x, int16_t y)
{
cursor_x = x;
cursor_y = y;
}
/**********************************************************************/
/*!
@brief Set text bound for printing
@param x X coordinate in pixels
@param y Y coordinate in pixels
*/
void setTextBound(int16_t x, int16_t y, int16_t w, int16_t h)
{
_min_text_x = x;
_min_text_y = y;
_max_text_x = x + w - 1;
_max_text_y = y + h - 1;
}
/**********************************************************************/
/*!
@brief Set text font color with transparant background
@param c 16-bit 5-6-5 Color to draw text with
@note For 'transparent' background, background and foreground
are set to same color rather than using a separate flag.
*/
/**********************************************************************/
void setTextColor(uint16_t c) { textcolor = textbgcolor = c; }
/**********************************************************************/
/*!
@brief Set text font color with custom background color
@param c 16-bit 5-6-5 Color to draw text with
@param bg 16-bit 5-6-5 Color to draw background/fill with
*/
/**********************************************************************/
void setTextColor(uint16_t c, uint16_t bg)
{
textcolor = c;
textbgcolor = bg;
}
/**********************************************************************/
/*!
@brief Set whether text that is too long for the screen width should
automatically wrap around to the next line (else clip right).
@param w true for wrapping, false for clipping
*/
/**********************************************************************/
void setTextWrap(bool w) { wrap = w; }
virtual size_t write(uint8_t);
/************************************************************************/
/*!
@brief Get width of the display, accounting for current rotation
@returns Width in pixels
*/
/************************************************************************/
int16_t width(void) const { return _width; };
/************************************************************************/
/*!
@brief Get height of the display, accounting for current rotation
@returns Height in pixels
*/
/************************************************************************/
int16_t height(void) const { return _height; }
/************************************************************************/
/*!
@brief Get rotation setting for display
@returns 0 thru 3 corresponding to 4 cardinal rotations
*/
/************************************************************************/
uint8_t getRotation(void) const { return _rotation; }
// get current cursor position (get rotation safe maximum values,
// using: width() for x, height() for y)
/************************************************************************/
/*!
@brief Get text cursor X location
@returns X coordinate in pixels
*/
/************************************************************************/
int16_t getCursorX(void) const { return cursor_x; }
/************************************************************************/
/*!
@brief Get text cursor Y location
@returns Y coordinate in pixels
*/
/************************************************************************/
int16_t getCursorY(void) const { return cursor_y; };
/*!
@brief Given 8-bit red, green and blue values, return a 'packed'
16-bit color value in '565' RGB format (5 bits red, 6 bits
green, 5 bits blue). This is just a mathematical operation,
no hardware is touched.
@param red 8-bit red brightnesss (0 = off, 255 = max).
@param green 8-bit green brightnesss (0 = off, 255 = max).
@param blue 8-bit blue brightnesss (0 = off, 255 = max).
@return 'Packed' 16-bit color value (565 format).
*/
uint16_t color565(uint8_t red, uint8_t green, uint8_t blue)
{
return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
}
protected:
void charBounds(char c, int16_t *x, int16_t *y, int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy);
int16_t
_width, ///< Display width as modified by current rotation
_height, ///< Display height as modified by current rotation
_max_x, ///< x zero base bound (_width - 1)
_max_y, ///< y zero base bound (_height - 1)
_min_text_x,
_min_text_y,
_max_text_x,
_max_text_y,
cursor_x, ///< x location to start print()ing text
cursor_y; ///< y location to start print()ing text
uint16_t
textcolor, ///< 16-bit background color for print()
textbgcolor; ///< 16-bit text color for print()
uint8_t
textsize_x, ///< Desired magnification in X-axis of text to print()
textsize_y, ///< Desired magnification in Y-axis of text to print()
text_pixel_margin, ///< Margin for each text pixel
_rotation; ///< Display rotation (0 thru 3)
bool
wrap; ///< If set, 'wrap' text at right edge of display
#if !defined(ATTINY_CORE)
GFXfont *gfxFont; ///< Pointer to special font
#endif // !defined(ATTINY_CORE)
#if defined(U8G2_FONT_SUPPORT)
uint8_t *u8g2Font;
bool _enableUTF8Print = false;
uint8_t _utf8_state = 0;
uint16_t _encoding;
uint8_t _u8g2_glyph_cnt;
uint8_t _u8g2_bits_per_0;
uint8_t _u8g2_bits_per_1;
uint8_t _u8g2_bits_per_char_width;
uint8_t _u8g2_bits_per_char_height;
uint8_t _u8g2_bits_per_char_x;
uint8_t _u8g2_bits_per_char_y;
uint8_t _u8g2_bits_per_delta_x;
int8_t _u8g2_max_char_width;
int8_t _u8g2_max_char_height;
uint16_t _u8g2_start_pos_upper_A;
uint16_t _u8g2_start_pos_lower_a;
uint16_t _u8g2_start_pos_unicode;
uint8_t _u8g2_first_char;
uint8_t _u8g2_char_width;
uint8_t _u8g2_char_height;
int8_t _u8g2_char_x;
int8_t _u8g2_char_y;
int8_t _u8g2_delta_x;
int8_t _u8g2_dx;
int8_t _u8g2_dy;
int16_t _u8g2_target_x;
int16_t _u8g2_target_y;
const uint8_t *_u8g2_decode_ptr;
uint8_t _u8g2_decode_bit_pos;
#endif // defined(U8G2_FONT_SUPPORT)
#if defined(LITTLE_FOOT_PRINT)
int16_t
WIDTH, ///< This is the 'raw' display width - never changes
HEIGHT; ///< This is the 'raw' display height - never changes
#endif // defined(LITTLE_FOOT_PRINT)
bool _isRoundMode = false;
int16_t *_roundMinX;
int16_t *_roundMaxX;
};
#endif // _ARDUINO_GFX_H_

View File

@@ -0,0 +1,38 @@
#include "Arduino_GFX_Library.h"
Arduino_DataBus *create_default_Arduino_DataBus()
{
#if defined(ARDUINO_ARCH_NRF52840)
return new Arduino_NRFXSPI(DF_GFX_DC, DF_GFX_CS, DF_GFX_SCK, DF_GFX_MOSI, DF_GFX_MISO);
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
return new Arduino_RPiPicoSPI(DF_GFX_DC, DF_GFX_CS, DF_GFX_SCK, DF_GFX_MOSI, DF_GFX_MISO, DF_GFX_SPI);
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3)
return new Arduino_ESP32SPI(DF_GFX_DC, DF_GFX_CS, DF_GFX_SCK, DF_GFX_MOSI, DF_GFX_MISO);
#elif defined(ESP8266)
return new Arduino_ESP8266SPI(DF_GFX_DC, DF_GFX_CS);
#else
return new Arduino_HWSPI(DF_GFX_DC, DF_GFX_CS);
#endif
}
Arduino_GFX *create_default_Arduino_GFX()
{
Arduino_DataBus *bus = create_default_Arduino_DataBus();
#if defined(WIO_TERMINAL)
return new Arduino_ILI9341(bus, DF_GFX_RST, 1 /* rotation */);
#elif defined(ESP32_S3_BOX)
return new Arduino_ILI9342(bus, DF_GFX_RST, 0 /* rotation */);
#elif defined(M5STACK_CORE)
return new Arduino_ILI9342(bus, DF_GFX_RST, 2 /* rotation */);
#elif defined(M5STACK_ATOMS3)
return new Arduino_GC9107(bus, 34 /* RST */, 0 /* rotation */, true /* IPS */);
#elif defined(ODROID_GO)
return new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */);
#elif defined(TTGO_T_WATCH)
return new Arduino_ST7789(bus, DF_GFX_RST, 0 /* rotation */, true /* IPS */, 240, 240, 0, 80);
#elif defined(WAVESHARE_RP2040_LCD_1_28)
return new Arduino_ST7789(bus, DF_GFX_RST, 0 /* rotation */, true /* IPS */, 240, 240, 0, 80);
#else
return new Arduino_GC9A01(bus, DF_GFX_RST, 0 /* rotation */, true /* IPS */);
#endif
}

View File

@@ -0,0 +1,334 @@
#ifndef _ARDUINO_GFX_LIBRARIES_H_
#define _ARDUINO_GFX_LIBRARIES_H_
#include "Arduino_DataBus.h"
#include "databus/Arduino_AVRPAR8.h"
#include "databus/Arduino_UNOPAR8.h"
#include "databus/Arduino_AVRPAR16.h"
#include "databus/Arduino_DUEPAR16.h"
#include "databus/Arduino_ESP32DSIPanel.h"
#include "databus/Arduino_ESP32LCD8.h"
#include "databus/Arduino_ESP32LCD16.h"
#include "databus/Arduino_ESP32PAR8.h"
#include "databus/Arduino_ESP32PAR8Q.h"
#include "databus/Arduino_ESP32PAR8QQ.h"
#include "databus/Arduino_ESP32PAR8QQQ.h"
#include "databus/Arduino_ESP32PAR16.h"
#include "databus/Arduino_ESP32PAR16Q.h"
#include "databus/Arduino_ESP32PAR16QQ.h"
#include "databus/Arduino_ESP32QSPI.h"
#include "databus/Arduino_ESP32RGBPanel.h"
#include "databus/Arduino_ESP32S2PAR8.h"
#include "databus/Arduino_ESP32S2PAR8Q.h"
#include "databus/Arduino_ESP32S2PAR16.h"
#include "databus/Arduino_ESP32S2PAR16Q.h"
#include "databus/Arduino_ESP32SPI.h"
#include "databus/Arduino_ESP32SPIDMA.h"
#include "databus/Arduino_ESP8266SPI.h"
#include "databus/Arduino_HWSPI.h"
#include "databus/Arduino_mbedSPI.h"
#include "databus/Arduino_NRFXSPI.h"
#include "databus/Arduino_RPiPicoPAR8.h"
#include "databus/Arduino_RPiPicoPAR16.h"
#include "databus/Arduino_RPiPicoSPI.h"
#include "databus/Arduino_RTLPAR8.h"
#include "databus/Arduino_STM32PAR8.h"
#include "databus/Arduino_SWPAR8.h"
#include "databus/Arduino_SWPAR16.h"
#include "databus/Arduino_SWSPI.h"
#include "databus/Arduino_Wire.h"
#include "databus/Arduino_XL9535SWSPI.h"
#include "databus/Arduino_XCA9554SWSPI.h"
#include "Arduino_GFX.h" // Core graphics library
#if !defined(LITTLE_FOOT_PRINT)
#include "canvas/Arduino_Canvas.h"
#include "canvas/Arduino_Canvas_Indexed.h"
#include "canvas/Arduino_Canvas_3bit.h"
#include "canvas/Arduino_Canvas_Mono.h"
#include "display/Arduino_ILI9488_3bit.h"
#endif // !defined(LITTLE_FOOT_PRINT)
#include "display/Arduino_AXS15231B.h"
#include "display/Arduino_CO5300.h"
#include "display/Arduino_DSI_Display.h"
#include "display/Arduino_GC9A01.h"
#include "display/Arduino_GC9C01.h"
#include "display/Arduino_GC9D01.h"
#include "display/Arduino_GC9106.h"
#include "display/Arduino_GC9107.h"
#include "display/Arduino_HX8347C.h"
#include "display/Arduino_HX8347D.h"
#include "display/Arduino_HX8352C.h"
#include "display/Arduino_HX8357A.h"
#include "display/Arduino_HX8357B.h"
#include "display/Arduino_HX8369A.h"
#include "display/Arduino_ILI9225.h"
#include "display/Arduino_ILI9331.h"
#include "display/Arduino_ILI9341.h"
#include "display/Arduino_ILI9342.h"
#include "display/Arduino_ILI9481_18bit.h"
#include "display/Arduino_ILI9486.h"
#include "display/Arduino_ILI9486_18bit.h"
#include "display/Arduino_ILI9488.h"
#include "display/Arduino_ILI9488_18bit.h"
#include "display/Arduino_ILI9806.h"
#include "display/Arduino_JBT6K71.h"
#include "display/Arduino_JD9613.h"
#include "display/Arduino_NT35310.h"
#include "display/Arduino_NT35510.h"
#include "display/Arduino_NT39125.h"
#include "display/Arduino_NV3007.h"
#include "display/Arduino_NV3023.h"
#include "display/Arduino_NV3041A.h"
#include "display/Arduino_OTM8009A.h"
#include "display/Arduino_R61529.h"
#include "display/Arduino_RM67162.h"
#include "display/Arduino_RM690B0.h"
#include "display/Arduino_RGB_Display.h"
#include "display/Arduino_SEPS525.h"
#include "display/Arduino_SH1106.h"
#include "display/Arduino_SH8601.h"
#include "display/Arduino_SPD2010.h"
#include "display/Arduino_SSD1283A.h"
#include "display/Arduino_SSD1306.h"
#include "display/Arduino_SSD1331.h"
#include "display/Arduino_SSD1351.h"
#include "display/Arduino_ST7735.h"
#include "display/Arduino_ST7789.h"
#include "display/Arduino_ST77916.h"
#include "display/Arduino_ST7796.h"
#include "display/Arduino_WEA2012.h"
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#define DISPLAY_DEV_KIT
#define WIO_TERMINAL
#define DF_GFX_CS LCD_SS_PIN
#define DF_GFX_DC LCD_DC
#define DF_GFX_RST GFX_NOT_DEFINED
#define DF_GFX_BL LCD_BACKLIGHT
#elif defined(ARDUINO_ESP32_S3_BOX)
#define DISPLAY_DEV_KIT
#define ESP32_S3_BOX
#define DF_GFX_SCK TFT_CLK
#define DF_GFX_MOSI TFT_MOSI
#define DF_GFX_MISO TFT_MISO
#define DF_GFX_CS TFT_CS
#define DF_GFX_DC TFT_DC
#define DF_GFX_RST TFT_RST
#define DF_GFX_BL TFT_BL
#elif defined(ARDUINO_M5Stack_Core_ESP32) || defined(ARDUINO_M5STACK_FIRE)
#define DISPLAY_DEV_KIT
#define M5STACK_CORE
#define DF_GFX_SCK 18
#define DF_GFX_MOSI 23
#define DF_GFX_MISO 19
#define DF_GFX_CS 14
#define DF_GFX_DC 27
#define DF_GFX_RST 33
#define DF_GFX_BL 32
#elif defined(ARDUINO_M5Stack_ATOMS3)
#define DISPLAY_DEV_KIT
#define M5STACK_ATOMS3
#define DF_GFX_SCK 17
#define DF_GFX_MOSI 21
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 15
#define DF_GFX_DC 33
#define DF_GFX_RST 34
#define DF_GFX_BL 16
#elif defined(ARDUINO_ODROID_ESP32)
#define DISPLAY_DEV_KIT
#define ODROID_GO
#define DF_GFX_SCK 18
#define DF_GFX_MOSI 23
#define DF_GFX_MISO 19
#define DF_GFX_CS 5
#define DF_GFX_DC 21
#define DF_GFX_RST GFX_NOT_DEFINED
#define DF_GFX_BL 14
/* TTGO T-Watch */
#elif defined(ARDUINO_T) || defined(ARDUINO_TWATCH_BASE) || defined(ARDUINO_TWATCH_2020_V1) || defined(ARDUINO_TWATCH_2020_V2)
#define DISPLAY_DEV_KIT
#define TTGO_T_WATCH
#define DF_GFX_SCK 18
#define DF_GFX_MOSI 19
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 5
#define DF_GFX_DC 27
#define DF_GFX_RST GFX_NOT_DEFINED
#define DF_GFX_BL 12
/* Waveshare RP2040-LCD-1.28 */
#elif defined(ARDUINO_WAVESHARE_RP2040_LCD_1_28)
#define DISPLAY_DEV_KIT
#define WAVESHARE_RP2040_LCD_1_28
#define DF_GFX_SCK 10
#define DF_GFX_MOSI 11
#define DF_GFX_MISO 12
#define DF_GFX_CS 9
#define DF_GFX_DC 8
#define DF_GFX_RST 12
#define DF_GFX_BL 25
#define DF_GFX_SPI spi1
#elif defined(ARDUINO_ARCH_NRF52840)
#define DF_GFX_SCK 13
#define DF_GFX_MOSI 11
#define DF_GFX_MISO 12
#define DF_GFX_CS 9
#define DF_GFX_DC 8
#define DF_GFX_RST 7
#define DF_GFX_BL 6
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
// PJRC Teensy 4.x
#define DF_GFX_SCK 13
#define DF_GFX_MOSI 11
#define DF_GFX_MISO 12
#define DF_GFX_CS 39 // GFX_NOT_DEFINED for display without CS pin
#define DF_GFX_DC 41
#define DF_GFX_RST 40
#define DF_GFX_BL 22
#elif defined(ARDUINO_BLACKPILL_F411CE)
#define DF_GFX_SCK 5
#define DF_GFX_MOSI 7
#define DF_GFX_MISO 6
#define DF_GFX_CS 4
#define DF_GFX_DC 3
#define DF_GFX_RST 2
#define DF_GFX_BL 1
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#define DF_GFX_SCK 18
#define DF_GFX_MOSI 19
#define DF_GFX_MISO 16
#define DF_GFX_CS 17
#define DF_GFX_DC 27
#define DF_GFX_RST 26
#define DF_GFX_BL 28
#define DF_GFX_SPI spi0
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32)
#define DF_GFX_SCK 18
#define DF_GFX_MOSI 23
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 5
#define DF_GFX_DC 27
#define DF_GFX_RST 33
#define DF_GFX_BL 22
#elif defined(ESP32) && ((CONFIG_IDF_TARGET_ESP32C2) || (CONFIG_IDF_TARGET_ESP32C3))
#define DF_GFX_SCK 4
#define DF_GFX_MOSI 6
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 7
#define DF_GFX_DC 2
#define DF_GFX_RST 1
#define DF_GFX_BL 3
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32C5)
#define DF_GFX_SCK 10
#define DF_GFX_MOSI 8
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 23
#define DF_GFX_DC 24
#define DF_GFX_RST 25
#define DF_GFX_BL 26
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32C6)
#define DF_GFX_SCK 21
#define DF_GFX_MOSI 19
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 18
#define DF_GFX_DC 22
#define DF_GFX_RST 23
#define DF_GFX_BL 15
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32H2)
#define DF_GFX_SCK 10
#define DF_GFX_MOSI 25
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 0
#define DF_GFX_DC 12
#define DF_GFX_RST 8
#define DF_GFX_BL 22
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32P4)
#define DF_GFX_SCK 36
#define DF_GFX_MOSI 32
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 26
#define DF_GFX_DC 27
#define DF_GFX_RST 25
#define DF_GFX_BL 24
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2)
#define DF_GFX_SCK 36
#define DF_GFX_MOSI 35
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 34
#define DF_GFX_DC 38
#define DF_GFX_RST 33
#define DF_GFX_BL 21
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#define DF_GFX_SCK 36
#define DF_GFX_MOSI 35
#define DF_GFX_MISO GFX_NOT_DEFINED
#define DF_GFX_CS 40
#define DF_GFX_DC 41
#define DF_GFX_RST 42
#define DF_GFX_BL 48
#elif defined(ESP8266)
#define DF_GFX_SCK 14
#define DF_GFX_MOSI 13
#define DF_GFX_MISO 12
#define DF_GFX_CS 15
#define DF_GFX_DC 4
#define DF_GFX_RST 2
#define DF_GFX_BL 5
#elif defined(RTL8722DM)
#if defined(BOARD_RTL8720DN_BW16)
#define DF_GFX_SCK 10
#define DF_GFX_MOSI 12
#define DF_GFX_MISO 11
#define DF_GFX_CS 9
#define DF_GFX_DC 8
#define DF_GFX_RST 6
#define DF_GFX_BL 3
#elif defined(BOARD_RTL8722DM)
#define DF_GFX_SCK 13
#define DF_GFX_MOSI 11
#define DF_GFX_MISO 12
#define DF_GFX_CS 18
#define DF_GFX_DC 17
#define DF_GFX_RST 22
#define DF_GFX_BL 23
#elif defined(BOARD_RTL8722DM_MINI)
#define DF_GFX_SCK 11
#define DF_GFX_MOSI 9
#define DF_GFX_MISO 10
#define DF_GFX_CS 12
#define DF_GFX_DC 14
#define DF_GFX_RST 15
#define DF_GFX_BL 13
#else // old version
#define DF_GFX_SCK 19
#define DF_GFX_MOSI 21
#define DF_GFX_MISO 20
#define DF_GFX_CS 18 // GFX_NOT_DEFINED for display without CS pin
#define DF_GFX_DC 17
#define DF_GFX_RST 2
#define DF_GFX_BL 23
#endif
#elif defined(SEEED_XIAO_M0)
#define DF_GFX_SCK 8
#define DF_GFX_MOSI 10
#define DF_GFX_MISO 9
#define DF_GFX_CS 3 // GFX_NOT_DEFINED for display without CS pin
#define DF_GFX_DC 2
#define DF_GFX_RST 1
#define DF_GFX_BL 0
#else // default pins for Arduino Nano, Mini, Micro and more
#define DF_GFX_SCK 13
#define DF_GFX_MOSI 11
#define DF_GFX_MISO 12
#define DF_GFX_CS 9
#define DF_GFX_DC 8
#define DF_GFX_RST 7
#define DF_GFX_BL 6
#endif
Arduino_DataBus *create_default_Arduino_DataBus();
Arduino_GFX *create_default_Arduino_GFX();
#endif // _ARDUINO_GFX_LIBRARIES_H_

View File

@@ -0,0 +1,13 @@
#include "Arduino_DataBus.h"
#include "Arduino_GFX.h"
#include "Arduino_TFT.h"
#include "Arduino_OLED.h"
Arduino_OLED::Arduino_OLED(
Arduino_DataBus *bus, int8_t rst, uint8_t r, int16_t w, int16_t h,
uint8_t col_offset1, uint8_t row_offset1, uint8_t col_offset2, uint8_t row_offset2)
: Arduino_TFT(
bus, rst, r, false /* ips */, w, h,
col_offset1, row_offset1, col_offset2, row_offset2)
{
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "Arduino_DataBus.h"
#include "Arduino_GFX.h"
#include "Arduino_OLED.h"
class Arduino_OLED : public Arduino_TFT
{
public:
Arduino_OLED(Arduino_DataBus *bus, int8_t rst, uint8_t r, int16_t w, int16_t h, uint8_t col_offset1, uint8_t row_offset1, uint8_t col_offset2, uint8_t row_offset2);
// This MUST be defined by the subclass:
virtual void setBrightness(uint8_t brightness) = 0;
virtual void setContrast(uint8_t contrast) = 0;
protected:
private:
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#ifndef _ARDUINO_TFT_H_
#define _ARDUINO_TFT_H_
#include "Arduino_DataBus.h"
#include "Arduino_GFX.h"
class Arduino_TFT : public Arduino_GFX
{
public:
Arduino_TFT(Arduino_DataBus *bus, int8_t rst, uint8_t r, bool ips, int16_t w, int16_t h, uint8_t col_offset1, uint8_t row_offset1, uint8_t col_offset2, uint8_t row_offset2);
// This SHOULD be defined by the subclass:
void setRotation(uint8_t r) override;
// This MUST be defined by the subclass:
// and also protected function: tftInit()
virtual void writeAddrWindow(int16_t x, int16_t y, uint16_t w, uint16_t h) = 0;
bool begin(int32_t speed = GFX_NOT_DEFINED);
void startWrite(void) override;
void endWrite(void) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override;
virtual void writeRepeat(uint16_t color, uint32_t len);
void setAddrWindow(int16_t x, int16_t y, uint16_t w, uint16_t h);
virtual void writeColor(uint16_t color);
// TFT optimization code, too big for ATMEL family
#if !defined(LITTLE_FOOT_PRINT)
virtual void writePixels(uint16_t *data, uint32_t size);
virtual void writeIndexedPixels(uint8_t *bitmap, uint16_t *color_index, uint32_t len);
virtual void writeIndexedPixelsDouble(uint8_t *bitmap, uint16_t *color_index, uint32_t len);
virtual void drawYCbCrBitmap(int16_t x, int16_t y, uint8_t *yData, uint8_t *cbData, uint8_t *crData, int16_t w, int16_t h);
void writeBytes(uint8_t *data, uint32_t size);
void pushColor(uint16_t color);
void writeSlashLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) override;
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg) override;
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) override;
void drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h) override;
void drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h) override;
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip = 0) override;
void draw16bitRGBBitmapWithMask(int16_t x, int16_t y, uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h) override;
void draw16bitRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h) override;
void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw16bitBeRGBBitmapR1(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw24bitRGBBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h) override;
void draw24bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h) override;
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg) override;
#endif // !defined(LITTLE_FOOT_PRINT)
protected:
virtual void tftInit() = 0;
Arduino_DataBus *_bus;
int8_t _rst;
bool _ips;
uint8_t COL_OFFSET1, ROW_OFFSET1;
uint8_t COL_OFFSET2, ROW_OFFSET2;
uint8_t _xStart, _yStart;
int16_t _currentX, _currentY;
uint16_t _currentW, _currentH;
int8_t _override_datamode = GFX_NOT_DEFINED;
private:
};
#endif

View File

@@ -0,0 +1,584 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#include "Arduino_DataBus.h"
#include "Arduino_GFX.h"
#include "Arduino_TFT_18bit.h"
Arduino_TFT_18bit::Arduino_TFT_18bit(
Arduino_DataBus *bus, int8_t rst, uint8_t r,
bool ips, int16_t w, int16_t h,
uint8_t col_offset1, uint8_t row_offset1, uint8_t col_offset2, uint8_t row_offset2)
: Arduino_TFT(bus, rst, r, ips, w, h, col_offset1, row_offset1, col_offset2, row_offset2)
{
}
void Arduino_TFT_18bit::writeColor(uint16_t color)
{
_bus->write((color & 0xF800) >> 8);
_bus->write((color & 0x07E0) >> 3);
_bus->write(color << 3);
}
void Arduino_TFT_18bit::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
{
writeAddrWindow(x, y, 1, 1);
_bus->write((color & 0xF800) >> 8);
_bus->write((color & 0x07E0) >> 3);
_bus->write(color << 3);
}
void Arduino_TFT_18bit::writeRepeat(uint16_t color, uint32_t len)
{
#if defined(ESP8266) || defined(ESP32)
uint8_t c[3] = {(uint8_t)((color & 0xF800) >> 8), (uint8_t)((color & 0x07E0) >> 3), (uint8_t)((color & 0x001F) << 3)};
_bus->writePattern(c, 3, len);
#else
uint8_t c1 = (uint8_t)((color & 0xF800) >> 8);
uint8_t c2 = (uint8_t)((color & 0x07E0) >> 3);
uint8_t c3 = (uint8_t)((color & 0x001F) << 3);
while (len--)
{
_bus->write(c1);
_bus->write(c2);
_bus->write(c3);
}
#endif
}
// TFT optimization code, too big for ATMEL family
#if !defined(LITTLE_FOOT_PRINT)
void Arduino_TFT_18bit::writePixels(uint16_t *data, uint32_t len)
{
uint16_t d;
while (len--)
{
d = *data++;
_bus->write((d & 0xF800) >> 8);
_bus->write((d & 0x07E0) >> 3);
_bus->write(d << 3);
}
}
// TFT tuned BITMAP / XBITMAP / GRAYSCALE / RGB BITMAP FUNCTIONS ---------------------
void Arduino_TFT_18bit::writeIndexedPixels(uint8_t *bitmap, uint16_t *color_index, uint32_t len)
{
uint16_t d;
while (len--)
{
d = color_index[*(bitmap++)];
_bus->write((d & 0xF800) >> 8);
_bus->write((d & 0x07E0) >> 3);
_bus->write(d << 3);
}
}
void Arduino_TFT_18bit::writeIndexedPixelsDouble(uint8_t *bitmap, uint16_t *color_index, uint32_t len)
{
uint8_t r, g, b;
uint16_t d;
while (len--)
{
d = color_index[*(bitmap++)];
r = (d & 0xF800) >> 8;
g = (d & 0x07E0) >> 3;
b = d << 3;
_bus->write(r);
_bus->write(g);
_bus->write(b);
_bus->write(r);
_bus->write(g);
_bus->write(b);
}
}
void Arduino_TFT_18bit::drawBitmap(
int16_t x, int16_t y,
const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::drawBitmap(x, y, bitmap, w, h, color, bg);
}
else
{
uint16_t c;
int32_t pixels = w * h;
uint8_t byte = 0;
uint16_t idx = 0;
startWrite();
writeAddrWindow(x, y, w, h);
for (int32_t i = 0; i < pixels; i++)
{
if (i & 7)
{
byte <<= 1;
}
else
{
byte = pgm_read_byte(&bitmap[idx++]);
}
c = (byte & 0x80) ? color : bg;
_bus->write((c & 0xF800) >> 8);
_bus->write((c & 0x07E0) >> 3);
_bus->write((c & 0x001F) << 3);
}
endWrite();
}
}
void Arduino_TFT_18bit::drawBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::drawBitmap(x, y, bitmap, w, h, color, bg);
}
else
{
uint16_t c;
int32_t pixels = w * h;
uint8_t byte = 0;
startWrite();
writeAddrWindow(x, y, w, h);
for (int32_t i = 0; i < pixels; i++)
{
if (i & 7)
{
byte <<= 1;
}
else
{
byte = *(bitmap++);
}
c = (byte & 0x80) ? color : bg;
_bus->write((c & 0xF800) >> 8);
_bus->write((c & 0x07E0) >> 3);
_bus->write((c & 0x001F) << 3);
}
endWrite();
}
}
void Arduino_TFT_18bit::drawGrayscaleBitmap(
int16_t x, int16_t y,
const uint8_t bitmap[], int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::drawGrayscaleBitmap(x, y, bitmap, w, h);
}
else
{
uint8_t v;
startWrite();
writeAddrWindow(x, y, w, h);
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
v = pgm_read_byte(&bitmap[j * w + i]);
_bus->write(v);
_bus->write(v);
_bus->write(v);
}
}
endWrite();
}
}
void Arduino_TFT_18bit::drawGrayscaleBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::drawGrayscaleBitmap(x, y, bitmap, w, h);
}
else
{
uint8_t v;
startWrite();
writeAddrWindow(x, y, w, h);
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
v = bitmap[j * w + i];
_bus->write(v);
_bus->write(v);
_bus->write(v);
}
}
endWrite();
}
}
void Arduino_TFT_18bit::drawIndexedBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::drawIndexedBitmap(x, y, bitmap, color_index, w, h, x_skip);
}
else
{
startWrite();
writeAddrWindow(x, y, w, h);
while (h--)
{
writeIndexedPixels(bitmap, color_index, w);
bitmap += w + x_skip;
}
endWrite();
}
}
void Arduino_TFT_18bit::draw16bitRGBBitmap(
int16_t x, int16_t y,
const uint16_t bitmap[], int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::draw16bitRGBBitmap(x, y, bitmap, w, h);
}
else
{
uint16_t d;
startWrite();
writeAddrWindow(x, y, w, h);
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
d = pgm_read_word(&bitmap[j * w + i]);
_bus->write((d & 0xF800) >> 8);
_bus->write((d & 0x07E0) >> 3);
_bus->write(d << 3);
}
}
endWrite();
}
}
void Arduino_TFT_18bit::draw16bitRGBBitmapWithMask(
int16_t x, int16_t y,
uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::draw16bitRGBBitmapWithMask(x, y, bitmap, mask, w, h);
}
else
{
uint16_t d;
int32_t offset = 0, maskIdx = 0, len = 0;
uint8_t byte = 0;
startWrite();
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
if (i & 7)
{
byte <<= 1;
}
else
{
byte = mask[maskIdx++];
}
if (byte & 0x80)
{
len++;
}
else
{
if (len)
{
writeAddrWindow(x + i - len, y, len, 1);
for (int16_t i = len; i > 0; i--)
{
d = bitmap[offset - i];
_bus->write((d & 0xF800) >> 8);
_bus->write((d & 0x07E0) >> 3);
_bus->write(d << 3);
}
len = 0;
}
}
offset++;
}
if (len)
{
writeAddrWindow(x + w - 1 - len, y, len, 1);
for (int16_t i = len; i > 0; i--)
{
d = bitmap[offset - i];
_bus->write((d & 0xF800) >> 8);
_bus->write((d & 0x07E0) >> 3);
_bus->write(d << 3);
}
len = 0;
}
}
endWrite();
}
}
void Arduino_TFT_18bit::draw16bitRGBBitmap(
int16_t x, int16_t y,
uint16_t *bitmap, int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::draw16bitRGBBitmap(x, y, bitmap, w, h);
}
else
{
uint16_t d;
startWrite();
writeAddrWindow(x, y, w, h);
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
d = bitmap[j * w + i];
_bus->write((d & 0xF800) >> 8);
_bus->write((d & 0x07E0) >> 3);
_bus->write(d << 3);
}
}
endWrite();
}
}
void Arduino_TFT_18bit::draw16bitBeRGBBitmap(
int16_t x, int16_t y,
uint16_t *bitmap, int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::draw16bitBeRGBBitmap(x, y, bitmap, w, h);
}
else
{
uint16_t d;
startWrite();
writeAddrWindow(x, y, w, h);
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
d = bitmap[j * w + i];
_bus->write((d & 0x00F8));
_bus->write(((d & 0xE000) >> 11) | (d & 0x0007) << 5);
_bus->write((d & 0x1F00) >> 5);
}
}
endWrite();
}
}
void Arduino_TFT_18bit::draw24bitRGBBitmap(
int16_t x, int16_t y,
const uint8_t bitmap[], int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::draw24bitRGBBitmap(x, y, bitmap, w, h);
}
else
{
int16_t offset = 0;
startWrite();
writeAddrWindow(x, y, w, h);
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
_bus->write(pgm_read_byte(&bitmap[offset++]));
_bus->write(pgm_read_byte(&bitmap[offset++]));
_bus->write(pgm_read_byte(&bitmap[offset++]));
}
}
endWrite();
}
}
void Arduino_TFT_18bit::draw24bitRGBBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, int16_t w, int16_t h)
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else if (
(x < 0) || // Clip left
(y < 0) || // Clip top
((x + w - 1) > _max_x) || // Clip right
((y + h - 1) > _max_y) // Clip bottom
)
{
Arduino_GFX::draw24bitRGBBitmap(x, y, bitmap, w, h);
}
else
{
startWrite();
writeAddrWindow(x, y, w, h);
_bus->writeBytes(bitmap, w * h * 3);
endWrite();
}
}
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,44 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#ifndef _ARDUINO_TFT_18BIT_H_
#define _ARDUINO_TFT_18BIT_H_
#include "Arduino_DataBus.h"
#include "Arduino_GFX.h"
#include "Arduino_TFT.h"
class Arduino_TFT_18bit : public Arduino_TFT
{
public:
Arduino_TFT_18bit(Arduino_DataBus *bus, int8_t rst, uint8_t r, bool ips, int16_t w, int16_t h, uint8_t col_offset1, uint8_t row_offset1, uint8_t col_offset2, uint8_t row_offset2);
void writeColor(uint16_t color) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void writeRepeat(uint16_t color, uint32_t len) override;
// TFT optimization code, too big for ATMEL family
#if !defined(LITTLE_FOOT_PRINT)
void writePixels(uint16_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *bitmap, uint16_t *color_index, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *bitmap, uint16_t *color_index, uint32_t len) override;
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg) override;
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) override;
void drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h) override;
void drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h) override;
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip = 0) override;
void draw16bitRGBBitmapWithMask(int16_t x, int16_t y, uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h) override;
void draw16bitRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h) override;
void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw24bitRGBBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h) override;
void draw24bitRGBBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h) override;
#endif // !defined(LITTLE_FOOT_PRINT)
protected:
private:
};
#endif

View File

@@ -0,0 +1,32 @@
#pragma once
/*
https://en.wikipedia.org/wiki/YCbCr
Y2I16 = (Y - 16) * 255 / 219
CR2R16 = ((Cr - 128) * 255 / 224 * 1.402) + 223
CR2G16 = ((Cr - 128) * 255 / 224 * 1.402 *0.299 / 0.587) - 172
CB2G16 = ((Cb - 128) * 255 / 224 * 1.772 * 0.114 / 0.587)
CB2B16 = ((Cb - 128) * 255 / 224 * 1.772) + 277
Note:
- The extra CR2R16 + 223, CR2G16 - 172 and CB2B16 + 277 are designed
for making the conversion result become zero based integer
- CLIP* mapping will clip value to 0-255
- CLIP*BE mapping will clip value to 0-255 at the same time shift bit
to big endian RGB565 format
*/
static const int16_t Y2I16[] = {-19, -17, -16, -15, -14, -13, -12, -10, -9, -8, -7, -6, -5, -3, -2, -1, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 79, 80, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108, 109, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 132, 133, 134, 135, 136, 137, 139, 140, 141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 153, 154, 155, 156, 157, 158, 160, 161, 162, 163, 164, 165, 167, 168, 169, 170, 171, 172, 173, 175, 176, 177, 178, 179, 180, 182, 183, 184, 185, 186, 187, 189, 190, 191, 192, 193, 194, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206, 207, 208, 210, 211, 212, 213, 214, 215, 217, 218, 219, 220, 221, 222, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235, 236, 238, 239, 240, 241, 242, 243, 245, 246, 247, 248, 249, 250, 252, 253, 254, 255, 256, 257, 258, 260, 261, 262, 263, 264, 265, 267, 268, 269, 270, 271, 272, 274, 275, 276, 277, 278};
static const int16_t CR2R16[] = {19, 20, 22, 23, 25, 27, 28, 30, 31, 33, 35, 36, 38, 39, 41, 43, 44, 46, 47, 49, 51, 52, 54, 55, 57, 59, 60, 62, 63, 65, 67, 68, 70, 71, 73, 75, 76, 78, 79, 81, 83, 84, 86, 87, 89, 91, 92, 94, 95, 97, 99, 100, 102, 103, 105, 106, 108, 110, 111, 113, 114, 116, 118, 119, 121, 122, 124, 126, 127, 129, 130, 132, 134, 135, 137, 138, 140, 142, 143, 145, 146, 148, 150, 151, 153, 154, 156, 158, 159, 161, 162, 164, 166, 167, 169, 170, 172, 174, 175, 177, 178, 180, 182, 183, 185, 186, 188, 189, 191, 193, 194, 196, 197, 199, 201, 202, 204, 205, 207, 209, 210, 212, 213, 215, 217, 218, 220, 221, 223, 225, 226, 228, 229, 231, 233, 234, 236, 237, 239, 241, 242, 244, 245, 247, 249, 250, 252, 253, 255, 257, 258, 260, 261, 263, 264, 266, 268, 269, 271, 272, 274, 276, 277, 279, 280, 282, 284, 285, 287, 288, 290, 292, 293, 295, 296, 298, 300, 301, 303, 304, 306, 308, 309, 311, 312, 314, 316, 317, 319, 320, 322, 324, 325, 327, 328, 330, 332, 333, 335, 336, 338, 340, 341, 343, 344, 346, 347, 349, 351, 352, 354, 355, 357, 359, 360, 362, 363, 365, 367, 368, 370, 371, 373, 375, 376, 378, 379, 381, 383, 384, 386, 387, 389, 391, 392, 394, 395, 397, 399, 400, 402, 403, 405, 407, 408, 410, 411, 413, 415, 416, 418, 419, 421, 423, 424, 426};
static const int16_t CR2G16[] = {-276, -275, -274, -274, -273, -272, -271, -270, -270, -269, -268, -267, -266, -265, -265, -264, -263, -262, -261, -261, -260, -259, -258, -257, -257, -256, -255, -254, -253, -252, -252, -251, -250, -249, -248, -248, -247, -246, -245, -244, -244, -243, -242, -241, -240, -239, -239, -238, -237, -236, -235, -235, -234, -233, -232, -231, -231, -230, -229, -228, -227, -226, -226, -225, -224, -223, -222, -222, -221, -220, -219, -218, -218, -217, -216, -215, -214, -213, -213, -212, -211, -210, -209, -209, -208, -207, -206, -205, -205, -204, -203, -202, -201, -200, -200, -199, -198, -197, -196, -196, -195, -194, -193, -192, -192, -191, -190, -189, -188, -187, -187, -186, -185, -184, -183, -183, -182, -181, -180, -179, -179, -178, -177, -176, -175, -174, -174, -173, -172, -171, -170, -170, -169, -168, -167, -166, -165, -165, -164, -163, -162, -161, -161, -160, -159, -158, -157, -157, -156, -155, -154, -153, -152, -152, -151, -150, -149, -148, -148, -147, -146, -145, -144, -144, -143, -142, -141, -140, -139, -139, -138, -137, -136, -135, -135, -134, -133, -132, -131, -131, -130, -129, -128, -127, -126, -126, -125, -124, -123, -122, -122, -121, -120, -119, -118, -118, -117, -116, -115, -114, -113, -113, -112, -111, -110, -109, -109, -108, -107, -106, -105, -105, -104, -103, -102, -101, -100, -100, -99, -98, -97, -96, -96, -95, -94, -93, -92, -92, -91, -90, -89, -88, -87, -87, -86, -85, -84, -83, -83, -82, -81, -80, -79, -79, -78, -77, -76, -75, -74, -74, -73, -72, -71, -70, -70, -69};
static const int16_t CB2G16[] = {-50, -50, -49, -49, -49, -48, -48, -47, -47, -47, -46, -46, -45, -45, -45, -44, -44, -43, -43, -43, -42, -42, -42, -41, -41, -40, -40, -40, -39, -39, -38, -38, -38, -37, -37, -36, -36, -36, -35, -35, -34, -34, -34, -33, -33, -33, -32, -32, -31, -31, -31, -30, -30, -29, -29, -29, -28, -28, -27, -27, -27, -26, -26, -25, -25, -25, -24, -24, -24, -23, -23, -22, -22, -22, -21, -21, -20, -20, -20, -19, -19, -18, -18, -18, -17, -17, -16, -16, -16, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -11, -11, -11, -10, -10, -9, -9, -9, -8, -8, -7, -7, -7, -6, -6, -5, -5, -5, -4, -4, -4, -3, -3, -2, -2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 27, 27, 27, 28, 28, 29, 29, 29, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 36, 36, 36, 37, 37, 38, 38, 38, 39, 39, 40, 40, 40, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 45, 45, 45, 46, 46, 47, 47, 47, 48, 48, 49, 49, 49, 50};
static const int16_t CB2B16[] = {19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, 325, 327, 329, 331, 333, 335, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, 390, 392, 394, 396, 398, 400, 402, 404, 406, 408, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 455, 457, 459, 461, 463, 465, 467, 469, 471, 473, 475, 477, 479, 481, 483, 485, 487, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533};
static const uint16_t CLIPR[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 14336, 14336, 14336, 14336, 14336, 14336, 14336, 14336, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 22528, 22528, 22528, 22528, 22528, 22528, 22528, 22528, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 26624, 26624, 26624, 26624, 26624, 26624, 26624, 26624, 28672, 28672, 28672, 28672, 28672, 28672, 28672, 28672, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 34816, 34816, 34816, 34816, 34816, 34816, 34816, 34816, 36864, 36864, 36864, 36864, 36864, 36864, 36864, 36864, 38912, 38912, 38912, 38912, 38912, 38912, 38912, 38912, 40960, 40960, 40960, 40960, 40960, 40960, 40960, 40960, 43008, 43008, 43008, 43008, 43008, 43008, 43008, 43008, 45056, 45056, 45056, 45056, 45056, 45056, 45056, 45056, 47104, 47104, 47104, 47104, 47104, 47104, 47104, 47104, 49152, 49152, 49152, 49152, 49152, 49152, 49152, 49152, 51200, 51200, 51200, 51200, 51200, 51200, 51200, 51200, 53248, 53248, 53248, 53248, 53248, 53248, 53248, 53248, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 57344, 57344, 57344, 57344, 57344, 57344, 57344, 57344, 59392, 59392, 59392, 59392, 59392, 59392, 59392, 59392, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488, 63488};
static const uint16_t CLIPG[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 64, 64, 64, 64, 96, 96, 96, 96, 128, 128, 128, 128, 160, 160, 160, 160, 192, 192, 192, 192, 224, 224, 224, 224, 256, 256, 256, 256, 288, 288, 288, 288, 320, 320, 320, 320, 352, 352, 352, 352, 384, 384, 384, 384, 416, 416, 416, 416, 448, 448, 448, 448, 480, 480, 480, 480, 512, 512, 512, 512, 544, 544, 544, 544, 576, 576, 576, 576, 608, 608, 608, 608, 640, 640, 640, 640, 672, 672, 672, 672, 704, 704, 704, 704, 736, 736, 736, 736, 768, 768, 768, 768, 800, 800, 800, 800, 832, 832, 832, 832, 864, 864, 864, 864, 896, 896, 896, 896, 928, 928, 928, 928, 960, 960, 960, 960, 992, 992, 992, 992, 1024, 1024, 1024, 1024, 1056, 1056, 1056, 1056, 1088, 1088, 1088, 1088, 1120, 1120, 1120, 1120, 1152, 1152, 1152, 1152, 1184, 1184, 1184, 1184, 1216, 1216, 1216, 1216, 1248, 1248, 1248, 1248, 1280, 1280, 1280, 1280, 1312, 1312, 1312, 1312, 1344, 1344, 1344, 1344, 1376, 1376, 1376, 1376, 1408, 1408, 1408, 1408, 1440, 1440, 1440, 1440, 1472, 1472, 1472, 1472, 1504, 1504, 1504, 1504, 1536, 1536, 1536, 1536, 1568, 1568, 1568, 1568, 1600, 1600, 1600, 1600, 1632, 1632, 1632, 1632, 1664, 1664, 1664, 1664, 1696, 1696, 1696, 1696, 1728, 1728, 1728, 1728, 1760, 1760, 1760, 1760, 1792, 1792, 1792, 1792, 1824, 1824, 1824, 1824, 1856, 1856, 1856, 1856, 1888, 1888, 1888, 1888, 1920, 1920, 1920, 1920, 1952, 1952, 1952, 1952, 1984, 1984, 1984, 1984, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016};
static const uint16_t CLIPB[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31};
static const uint16_t CLIPRBE[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56, 64, 64, 64, 64, 64, 64, 64, 64, 72, 72, 72, 72, 72, 72, 72, 72, 80, 80, 80, 80, 80, 80, 80, 80, 88, 88, 88, 88, 88, 88, 88, 88, 96, 96, 96, 96, 96, 96, 96, 96, 104, 104, 104, 104, 104, 104, 104, 104, 112, 112, 112, 112, 112, 112, 112, 112, 120, 120, 120, 120, 120, 120, 120, 120, 128, 128, 128, 128, 128, 128, 128, 128, 136, 136, 136, 136, 136, 136, 136, 136, 144, 144, 144, 144, 144, 144, 144, 144, 152, 152, 152, 152, 152, 152, 152, 152, 160, 160, 160, 160, 160, 160, 160, 160, 168, 168, 168, 168, 168, 168, 168, 168, 176, 176, 176, 176, 176, 176, 176, 176, 184, 184, 184, 184, 184, 184, 184, 184, 192, 192, 192, 192, 192, 192, 192, 192, 200, 200, 200, 200, 200, 200, 200, 200, 208, 208, 208, 208, 208, 208, 208, 208, 216, 216, 216, 216, 216, 216, 216, 216, 224, 224, 224, 224, 224, 224, 224, 224, 232, 232, 232, 232, 232, 232, 232, 232, 240, 240, 240, 240, 240, 240, 240, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248};
static const uint16_t CLIPGBE[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 8192, 8192, 8192, 16384, 16384, 16384, 16384, 24576, 24576, 24576, 24576, 32768, 32768, 32768, 32768, 40960, 40960, 40960, 40960, 49152, 49152, 49152, 49152, 57344, 57344, 57344, 57344, 1, 1, 1, 1, 8193, 8193, 8193, 8193, 16385, 16385, 16385, 16385, 24577, 24577, 24577, 24577, 32769, 32769, 32769, 32769, 40961, 40961, 40961, 40961, 49153, 49153, 49153, 49153, 57345, 57345, 57345, 57345, 2, 2, 2, 2, 8194, 8194, 8194, 8194, 16386, 16386, 16386, 16386, 24578, 24578, 24578, 24578, 32770, 32770, 32770, 32770, 40962, 40962, 40962, 40962, 49154, 49154, 49154, 49154, 57346, 57346, 57346, 57346, 3, 3, 3, 3, 8195, 8195, 8195, 8195, 16387, 16387, 16387, 16387, 24579, 24579, 24579, 24579, 32771, 32771, 32771, 32771, 40963, 40963, 40963, 40963, 49155, 49155, 49155, 49155, 57347, 57347, 57347, 57347, 4, 4, 4, 4, 8196, 8196, 8196, 8196, 16388, 16388, 16388, 16388, 24580, 24580, 24580, 24580, 32772, 32772, 32772, 32772, 40964, 40964, 40964, 40964, 49156, 49156, 49156, 49156, 57348, 57348, 57348, 57348, 5, 5, 5, 5, 8197, 8197, 8197, 8197, 16389, 16389, 16389, 16389, 24581, 24581, 24581, 24581, 32773, 32773, 32773, 32773, 40965, 40965, 40965, 40965, 49157, 49157, 49157, 49157, 57349, 57349, 57349, 57349, 6, 6, 6, 6, 8198, 8198, 8198, 8198, 16390, 16390, 16390, 16390, 24582, 24582, 24582, 24582, 32774, 32774, 32774, 32774, 40966, 40966, 40966, 40966, 49158, 49158, 49158, 49158, 57350, 57350, 57350, 57350, 7, 7, 7, 7, 8199, 8199, 8199, 8199, 16391, 16391, 16391, 16391, 24583, 24583, 24583, 24583, 32775, 32775, 32775, 32775, 40967, 40967, 40967, 40967, 49159, 49159, 49159, 49159, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351, 57351};
static const uint16_t CLIPBBE[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 256, 256, 256, 256, 256, 256, 256, 512, 512, 512, 512, 512, 512, 512, 512, 768, 768, 768, 768, 768, 768, 768, 768, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3584, 3584, 3584, 3584, 3584, 3584, 3584, 3584, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5632, 5632, 5632, 5632, 5632, 5632, 5632, 5632, 5888, 5888, 5888, 5888, 5888, 5888, 5888, 5888, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6656, 6656, 6656, 6656, 6656, 6656, 6656, 6656, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 7168, 7168, 7168, 7168, 7168, 7168, 7168, 7168, 7424, 7424, 7424, 7424, 7424, 7424, 7424, 7424, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936, 7936};

View File

@@ -0,0 +1,661 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#include "../Arduino_GFX.h"
#include "Arduino_Canvas.h"
Arduino_Canvas::Arduino_Canvas(
int16_t w, int16_t h, Arduino_G *output, int16_t output_x, int16_t output_y, uint8_t r)
: Arduino_GFX(w, h), _output(output), _output_x(output_x), _output_y(output_y)
{
MAX_X = WIDTH - 1;
MAX_Y = HEIGHT - 1;
setRotation(r);
}
Arduino_Canvas::~Arduino_Canvas()
{
if (_framebuffer)
{
free(_framebuffer);
}
}
bool Arduino_Canvas::begin(int32_t speed)
{
if (
(speed != GFX_SKIP_OUTPUT_BEGIN) && (_output))
{
if (!_output->begin(speed))
{
return false;
}
}
if (!_framebuffer)
{
size_t s = _width * _height * 2;
#if defined(ESP32)
_framebuffer = (uint16_t *)aligned_alloc(16, s);
#else
_framebuffer = (uint16_t *)malloc(s);
#endif
if (!_framebuffer)
{
return false;
}
}
return true;
}
void Arduino_Canvas::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
{
uint16_t *fb = _framebuffer;
switch (_rotation)
{
case 1:
fb += (int32_t)x * _height;
fb += _max_y - y;
*fb = color;
break;
case 2:
fb += (int32_t)(_max_y - y) * _width;
fb += _max_x - x;
*fb = color;
break;
case 3:
fb += (int32_t)(_max_x - x) * _height;
fb += y;
*fb = color;
break;
default: // case 0:
fb += (int32_t)y * _width;
fb += x;
*fb = color;
}
}
void Arduino_Canvas::writeFastVLine(int16_t x, int16_t y,
int16_t h, uint16_t color)
{
switch (_rotation)
{
case 1:
writeFastHLineCore(_height - y - h, x, h, color);
break;
case 2:
writeFastVLineCore(_max_x - x, _height - y - h, h, color);
break;
case 3:
writeFastHLineCore(y, _max_x - x, h, color);
break;
default: // case 0:
writeFastVLineCore(x, y, h, color);
}
}
void Arduino_Canvas::writeFastVLineCore(int16_t x, int16_t y,
int16_t h, uint16_t color)
{
// log_i("writeFastVLineCore(x: %d, y: %d, h: %d)", x, y, h);
if (_ordered_in_range(x, 0, MAX_X) && h)
{ // X on screen, nonzero height
if (h < 0)
{ // If negative height...
y += h + 1; // Move Y to top edge
h = -h; // Use positive height
}
if (y <= MAX_Y)
{ // Not off bottom
int16_t y2 = y + h - 1;
if (y2 >= 0)
{ // Not off top
// Line partly or fully overlaps screen
if (y < 0)
{
y = 0;
h = y2 + 1;
} // Clip top
if (y2 > MAX_Y)
{
h = MAX_Y - y + 1;
} // Clip bottom
uint16_t *fb = _framebuffer + ((int32_t)y * WIDTH) + x;
while (h--)
{
*fb = color;
fb += WIDTH;
}
}
}
}
}
void Arduino_Canvas::writeFastHLine(int16_t x, int16_t y,
int16_t w, uint16_t color)
{
// log_i("writeFastHLine(x: %d, y: %d, w: %d)", x, y, w);
switch (_rotation)
{
case 1:
writeFastVLineCore(_max_y - y, x, w, color);
break;
case 2:
writeFastHLineCore(_width - x - w, _max_y - y, w, color);
break;
case 3:
writeFastVLineCore(y, _width - x - w, w, color);
break;
default: // case 0:
writeFastHLineCore(x, y, w, color);
}
}
void Arduino_Canvas::writeFastHLineCore(int16_t x, int16_t y,
int16_t w, uint16_t color)
{
// log_i("writeFastHLineCore(x: %d, y: %d, w: %d)", x, y, w);
if (_ordered_in_range(y, 0, MAX_Y) && w)
{ // Y on screen, nonzero width
if (w < 0)
{ // If negative width...
x += w + 1; // Move X to left edge
w = -w; // Use positive width
}
if (x <= MAX_X)
{ // Not off right
int16_t x2 = x + w - 1;
if (x2 >= 0)
{ // Not off left
// Line partly or fully overlaps screen
if (x < 0)
{
x = 0;
w = x2 + 1;
} // Clip left
if (x2 > MAX_X)
{
w = MAX_X - x + 1;
} // Clip right
uint16_t *fb = _framebuffer + ((int32_t)y * WIDTH) + x;
while (w--)
{
*(fb++) = color;
}
}
}
}
}
void Arduino_Canvas::writeFillRectPreclipped(int16_t x, int16_t y,
int16_t w, int16_t h, uint16_t color)
{
// log_i("writeFillRectPreclipped(x: %d, y: %d, w: %d, h: %d)", x, y, w, h);
if (_rotation > 0)
{
int16_t t = x;
switch (_rotation)
{
case 1:
x = WIDTH - y - h;
y = t;
t = w;
w = h;
h = t;
break;
case 2:
x = WIDTH - x - w;
y = HEIGHT - y - h;
break;
case 3:
x = y;
y = HEIGHT - t - w;
t = w;
w = h;
h = t;
break;
}
}
// log_i("adjusted writeFillRectPreclipped(x: %d, y: %d, w: %d, h: %d)", x, y, w, h);
uint16_t *row = _framebuffer;
row += y * WIDTH;
row += x;
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
row[i] = color;
}
row += WIDTH;
}
}
void Arduino_Canvas::drawIndexedBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip)
{
if (_rotation > 0)
{
Arduino_GFX::drawIndexedBitmap(x, y, bitmap, color_index, w, h, x_skip);
}
else
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else
{
if ((y + h - 1) > _max_y)
{
h -= (y + h - 1) - _max_y;
}
if (y < 0)
{
bitmap -= y * (w + x_skip);
h += y;
y = 0;
}
if ((x + w - 1) > _max_x)
{
x_skip += (x + w - 1) - _max_x;
w -= (x + w - 1) - _max_x;
}
if (x < 0)
{
bitmap -= x;
x_skip -= x;
w += x;
x = 0;
}
uint16_t *row = _framebuffer;
row += y * _width;
row += x;
int16_t i;
int16_t wi;
while (h--)
{
i = 0;
wi = w;
while (wi >= 4)
{
uint32_t b32 = *((uint32_t *)bitmap);
row[i++] = color_index[(b32 & 0xff)];
row[i++] = color_index[(b32 & 0xff00) >> 8];
row[i++] = color_index[(b32 & 0xff0000) >> 16];
row[i++] = color_index[(b32 & 0xff000000) >> 24];
wi -= 4;
bitmap += 4;
}
while (i < w)
{
row[i++] = color_index[*bitmap++];
}
bitmap += x_skip;
row += _width;
}
}
}
}
void Arduino_Canvas::drawIndexedBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, uint16_t *color_index, uint8_t chroma_key, int16_t w, int16_t h, int16_t x_skip)
{
if (_rotation > 0)
{
Arduino_GFX::drawIndexedBitmap(x, y, bitmap, color_index, chroma_key, w, h, x_skip);
}
else
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else
{
if ((y + h - 1) > _max_y)
{
h -= (y + h - 1) - _max_y;
}
if (y < 0)
{
bitmap -= y * (w + x_skip);
h += y;
y = 0;
}
if ((x + w - 1) > _max_x)
{
x_skip += (x + w - 1) - _max_x;
w -= (x + w - 1) - _max_x;
}
if (x < 0)
{
bitmap -= x;
x_skip -= x;
w += x;
x = 0;
}
uint16_t *row = _framebuffer;
row += y * _width;
row += x;
int16_t i;
int16_t wi;
uint8_t color_key;
while (h--)
{
i = 0;
wi = w;
while (wi >= 4)
{
uint32_t b32 = *((uint32_t *)bitmap);
color_key = (b32 & 0xff);
if (color_key != chroma_key)
{
row[i] = color_index[color_key];
}
++i;
color_key = (b32 & 0xff00) >> 8;
if (color_key != chroma_key)
{
row[i] = color_index[color_key];
}
++i;
color_key = (b32 & 0xff0000) >> 16;
if (color_key != chroma_key)
{
row[i] = color_index[color_key];
}
++i;
color_key = (b32 & 0xff000000) >> 24;
if (color_key != chroma_key)
{
row[i] = color_index[color_key];
}
++i;
wi -= 4;
bitmap += 4;
}
while (i < w)
{
color_key = *bitmap++;
if (color_key != chroma_key)
{
row[i] = color_index[color_key];
}
++i;
}
bitmap += x_skip;
row += _width;
}
}
}
}
void Arduino_Canvas::draw16bitRGBBitmap(int16_t x, int16_t y,
uint16_t *bitmap, int16_t w, int16_t h)
{
switch (_rotation)
{
case 1:
gfx_draw_bitmap_to_framebuffer_rotate_1(bitmap, w, h, _framebuffer, x, y, _width, _height);
break;
case 2:
gfx_draw_bitmap_to_framebuffer_rotate_2(bitmap, w, h, _framebuffer, x, y, _width, _height);
break;
case 3:
gfx_draw_bitmap_to_framebuffer_rotate_3(bitmap, w, h, _framebuffer, x, y, _width, _height);
break;
default: // case 0:
gfx_draw_bitmap_to_framebuffer(bitmap, w, h, _framebuffer, x, y, _width, _height);
}
}
void Arduino_Canvas::draw16bitRGBBitmapWithTranColor(
int16_t x, int16_t y,
uint16_t *bitmap, uint16_t transparent_color, int16_t w, int16_t h)
{
if (_rotation > 0)
{
Arduino_GFX::draw16bitRGBBitmapWithTranColor(x, y, bitmap, transparent_color, w, h);
}
else
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else
{
int16_t x_skip = 0;
if ((y + h - 1) > _max_y)
{
h -= (y + h - 1) - _max_y;
}
if (y < 0)
{
bitmap -= y * w;
h += y;
y = 0;
}
if ((x + w - 1) > _max_x)
{
x_skip = (x + w - 1) - _max_x;
w -= x_skip;
}
if (x < 0)
{
bitmap -= x;
x_skip -= x;
w += x;
x = 0;
}
uint16_t *row = _framebuffer;
row += y * _width;
row += x;
int16_t i;
int16_t wi;
uint16_t p;
while (h--)
{
i = 0;
wi = w;
while (wi >= 4)
{
uint32_t b32 = *((uint32_t *)bitmap);
p = (b32 & 0xffff);
if (p != transparent_color)
{
row[i] = p;
}
++i;
p = (b32 & 0xffff0000) >> 16;
if (p != transparent_color)
{
row[i] = p;
}
++i;
wi -= 2;
bitmap += 2;
}
while (i < w)
{
p = *bitmap++;
if (p != transparent_color)
{
row[i] = p;
}
++i;
}
bitmap += x_skip;
row += _width;
}
}
}
}
void Arduino_Canvas::draw16bitBeRGBBitmap(int16_t x, int16_t y,
uint16_t *bitmap, int16_t w, int16_t h)
{
if (_rotation > 0)
{
Arduino_GFX::draw16bitBeRGBBitmap(x, y, bitmap, w, h);
}
else
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else
{
int16_t x_skip = 0;
if ((y + h - 1) > _max_y)
{
h -= (y + h - 1) - _max_y;
}
if (y < 0)
{
bitmap -= y * w;
h += y;
y = 0;
}
if ((x + w - 1) > _max_x)
{
x_skip = (x + w - 1) - _max_x;
w -= x_skip;
}
if (x < 0)
{
bitmap -= x;
x_skip -= x;
w += x;
x = 0;
}
uint16_t *row = _framebuffer;
row += y * _width;
row += x;
uint16_t color;
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
color = *bitmap++;
MSB_16_SET(row[i], color);
}
bitmap += x_skip;
row += _width;
}
}
}
}
void Arduino_Canvas::flush(bool force_flush)
{
if (_output)
{
_output->draw16bitRGBBitmap(_output_x, _output_y, _framebuffer, WIDTH, HEIGHT);
}
}
void Arduino_Canvas::flushQuad(bool force_flush)
{
int16_t y = _output_y;
uint16_t *row1 = _framebuffer;
uint16_t *row2 = _framebuffer + WIDTH;
if (_output)
{
int16_t hQuad = HEIGHT / 2;
int16_t wQuad = WIDTH / 2;
if (!_rowBuf)
{
_rowBuf = (uint16_t *)malloc(wQuad * 2);
}
uint16_t p;
while (hQuad--)
{
for (int16_t i = 0; i < wQuad; ++i)
{
p = (*row1++ & 0b1110011110011100) >> 2;
p += (*row1++ & 0b1110011110011100) >> 2;
p += (*row2++ & 0b1110011110011100) >> 2;
p += (*row2++ & 0b1110011110011100) >> 2;
_rowBuf[i] = p;
}
_output->draw16bitRGBBitmap(_output_x, _output_y + y++, _rowBuf, wQuad, 1);
row1 += WIDTH;
row2 += WIDTH;
}
}
}
void Arduino_Canvas::shade(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t shade_mask)
{
if (_rotation > 0)
{
int16_t t = x;
switch (_rotation)
{
case 1:
x = WIDTH - y - h;
y = t;
t = w;
w = h;
h = t;
break;
case 2:
x = WIDTH - x - w;
y = HEIGHT - y - h;
break;
case 3:
x = y;
y = HEIGHT - t - w;
t = w;
w = h;
h = t;
break;
}
}
uint16_t *row = _framebuffer;
row += y * WIDTH;
row += x;
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
row[i] &= shade_mask;
}
row += WIDTH;
}
}
uint16_t *Arduino_Canvas::getFramebuffer()
{
return _framebuffer;
}
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,47 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#ifndef _ARDUINO_CANVAS_H_
#define _ARDUINO_CANVAS_H_
#include "../Arduino_GFX.h"
class Arduino_Canvas : public Arduino_GFX
{
public:
Arduino_Canvas(int16_t w, int16_t h, Arduino_G *output, int16_t output_x = 0, int16_t output_y = 0, uint8_t rotation = 0);
~Arduino_Canvas();
bool begin(int32_t speed = GFX_NOT_DEFINED) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
void writeFastVLineCore(int16_t x, int16_t y, int16_t h, uint16_t color);
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
void writeFastHLineCore(int16_t x, int16_t y, int16_t w, uint16_t color);
void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override;
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip = 0) override;
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, uint8_t chroma_key, int16_t w, int16_t h, int16_t x_skip = 0) override;
void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw16bitRGBBitmapWithTranColor(int16_t x, int16_t y, uint16_t *bitmap, uint16_t transparent_color, int16_t w, int16_t h) override;
void draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void flush(bool force_flush = false) override;
void flushQuad(bool force_flush = false);
void shade(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t shade_mask);
uint16_t *getFramebuffer();
protected:
uint16_t *_framebuffer = nullptr;
Arduino_G *_output = nullptr;
int16_t _output_x, _output_y;
int16_t MAX_X, MAX_Y;
// for flushQuad() only
uint16_t *_rowBuf = nullptr;
private:
};
#endif // _ARDUINO_CANVAS_H_
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,84 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#include "../Arduino_GFX.h"
#include "Arduino_Canvas_3bit.h"
Arduino_Canvas_3bit::Arduino_Canvas_3bit(int16_t w, int16_t h, Arduino_G *output, int16_t output_x, int16_t output_y)
: Arduino_GFX(w, h), _output(output), _output_x(output_x), _output_y(output_y)
{
}
Arduino_Canvas_3bit::~Arduino_Canvas_3bit()
{
if (_framebuffer)
{
free(_framebuffer);
}
}
bool Arduino_Canvas_3bit::begin(int32_t speed)
{
if (speed != GFX_SKIP_OUTPUT_BEGIN)
{
if (!_output->begin(speed))
{
return false;
}
}
if (!_framebuffer)
{
size_t s = (_width * _height + 1) / 2;
#if defined(ESP32)
if (psramFound())
{
_framebuffer = (uint8_t *)ps_malloc(s);
}
else
{
_framebuffer = (uint8_t *)malloc(s);
}
#else
_framebuffer = (uint8_t *)malloc(s);
#endif
if (!_framebuffer)
{
return false;
}
}
return true;
}
void Arduino_Canvas_3bit::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
{
int32_t pos = x + (y * _width);
int32_t idx = pos >> 1;
uint8_t c = (((color & 0b1000000000000000) ? 0b100 : 0) |
((color & 0b0000010000000000) ? 0b010 : 0) |
((color & 0b0000000000010000) ? 0b001 : 0));
if (pos & 1)
{
_framebuffer[idx] = (_framebuffer[idx] & 0b00111000) | c;
}
else
{
_framebuffer[idx] = (_framebuffer[idx] & 0b00000111) | (c << 3);
}
}
void Arduino_Canvas_3bit::flush(bool force_flush)
{
if (_output)
{
_output->draw3bitRGBBitmap(_output_x, _output_y, _framebuffer, _width, _height);
}
}
uint8_t *Arduino_Canvas_3bit::getFramebuffer()
{
return _framebuffer;
}
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,31 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#ifndef _ARDUINO_CANVAS_3BIT_H_
#define _ARDUINO_CANVAS_3BIT_H_
#include "../Arduino_GFX.h"
class Arduino_Canvas_3bit : public Arduino_GFX
{
public:
Arduino_Canvas_3bit(int16_t w, int16_t h, Arduino_G *output, int16_t output_x = 0, int16_t output_y = 0);
~Arduino_Canvas_3bit();
bool begin(int32_t speed = GFX_NOT_DEFINED) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void flush(bool force_flush = false) override;
uint8_t *getFramebuffer();
protected:
uint8_t *_framebuffer = nullptr;
Arduino_G *_output = nullptr;
int16_t _output_x, _output_y;
private:
};
#endif // _ARDUINO_CANVAS_3BIT_H_
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,564 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#include "../Arduino_GFX.h"
#include "Arduino_Canvas_Indexed.h"
Arduino_Canvas_Indexed::Arduino_Canvas_Indexed(int16_t w, int16_t h, Arduino_G *output, int16_t output_x, int16_t output_y, uint8_t r, uint8_t mask_level)
: Arduino_GFX(w, h), _output(output), _output_x(output_x), _output_y(output_y)
{
MAX_X = WIDTH - 1;
MAX_Y = HEIGHT - 1;
setRotation(r);
if (mask_level >= MAXMASKLEVEL)
{
mask_level = MAXMASKLEVEL - 1;
}
_current_mask_level = mask_level;
_color_mask = mask_level_list[_current_mask_level];
}
Arduino_Canvas_Indexed::~Arduino_Canvas_Indexed()
{
if (_framebuffer)
{
free(_framebuffer);
}
}
bool Arduino_Canvas_Indexed::begin(int32_t speed)
{
if (speed != GFX_SKIP_OUTPUT_BEGIN)
{
if (!_output->begin(speed))
{
return false;
}
}
if (!_framebuffer)
{
size_t s = _width * _height;
#if defined(ESP32)
if (psramFound())
{
_framebuffer = (uint8_t *)ps_malloc(s);
}
else
{
_framebuffer = (uint8_t *)malloc(s);
}
#else
_framebuffer = (uint8_t *)malloc(s);
#endif
if (!_framebuffer)
{
return false;
}
}
return true;
}
void Arduino_Canvas_Indexed::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
{
uint8_t idx;
if (_isDirectUseColorIndex)
{
idx = (uint8_t)color;
}
else
{
idx = get_color_index(color);
}
uint8_t *fb = _framebuffer;
switch (_rotation)
{
case 1:
fb += (int32_t)x * _height;
fb += _max_y - y;
*fb = idx;
break;
case 2:
fb += (int32_t)(_max_y - y) * _width;
fb += _max_x - x;
*fb = idx;
break;
case 3:
fb += (int32_t)(_max_x - x) * _height;
fb += y;
*fb = idx;
break;
default: // case 0:
fb += (int32_t)y * _width;
fb += x;
*fb = idx;
}
}
void Arduino_Canvas_Indexed::writeFastVLine(int16_t x, int16_t y,
int16_t h, uint16_t color)
{
uint8_t idx;
if (_isDirectUseColorIndex)
{
idx = (uint8_t)color;
}
else
{
idx = get_color_index(color);
}
switch (_rotation)
{
case 1:
writeFastHLineCore(_height - y - h, x, h, idx);
break;
case 2:
writeFastVLineCore(_max_x - x, _height - y - h, h, idx);
break;
case 3:
writeFastHLineCore(y, _max_x - x, h, idx);
break;
default: // case 0:
writeFastVLineCore(x, y, h, idx);
}
}
void Arduino_Canvas_Indexed::writeFastVLineCore(int16_t x, int16_t y,
int16_t h, uint8_t idx)
{
if (_ordered_in_range(x, 0, MAX_X) && h)
{ // X on screen, nonzero height
if (h < 0)
{ // If negative height...
y += h + 1; // Move Y to top edge
h = -h; // Use positive height
}
if (y <= MAX_Y)
{ // Not off bottom
int16_t y2 = y + h - 1;
if (y2 >= 0)
{ // Not off top
// Line partly or fully overlaps screen
if (y < 0)
{
y = 0;
h = y2 + 1;
} // Clip top
if (y2 > MAX_Y)
{
h = MAX_Y - y + 1;
} // Clip bottom
uint8_t *fb = _framebuffer + ((int32_t)y * WIDTH) + x;
while (h--)
{
*fb = idx;
fb += WIDTH;
}
}
}
}
}
void Arduino_Canvas_Indexed::writeFastHLine(int16_t x, int16_t y,
int16_t w, uint16_t color)
{
uint8_t idx;
if (_isDirectUseColorIndex)
{
idx = (uint8_t)color;
}
else
{
idx = get_color_index(color);
}
switch (_rotation)
{
case 1:
writeFastVLineCore(_max_y - y, x, w, idx);
break;
case 2:
writeFastHLineCore(_width - x - w, _max_y - y, w, idx);
break;
case 3:
writeFastVLineCore(y, _width - x - w, w, idx);
break;
default: // case 0:
writeFastHLineCore(x, y, w, idx);
}
}
void Arduino_Canvas_Indexed::writeFastHLineCore(int16_t x, int16_t y,
int16_t w, uint8_t idx)
{
if (_ordered_in_range(y, 0, MAX_Y) && w)
{ // Y on screen, nonzero width
if (w < 0)
{ // If negative width...
x += w + 1; // Move X to left edge
w = -w; // Use positive width
}
if (x <= MAX_X)
{ // Not off right
int16_t x2 = x + w - 1;
if (x2 >= 0)
{ // Not off left
// Line partly or fully overlaps screen
if (x < 0)
{
x = 0;
w = x2 + 1;
} // Clip left
if (x2 > MAX_X)
{
w = MAX_X - x + 1;
} // Clip right
uint8_t *fb = _framebuffer + ((int32_t)y * WIDTH) + x;
while (w--)
{
*(fb++) = idx;
}
}
}
}
}
void Arduino_Canvas_Indexed::writeFillRectPreclipped(int16_t x, int16_t y,
int16_t w, int16_t h, uint16_t color)
{
uint8_t idx;
if (_isDirectUseColorIndex)
{
idx = (uint8_t)color;
}
else
{
idx = get_color_index(color);
}
if (_rotation > 0)
{
int16_t t = x;
switch (_rotation)
{
case 1:
x = WIDTH - y - h;
y = t;
t = w;
w = h;
h = t;
break;
case 2:
x = WIDTH - x - w;
y = HEIGHT - y - h;
break;
case 3:
x = y;
y = HEIGHT - t - w;
t = w;
w = h;
h = t;
break;
}
}
// log_i("adjusted writeFillRectPreclipped(x: %d, y: %d, w: %d, h: %d)", x, y, w, h);
uint8_t *row = _framebuffer;
row += y * WIDTH;
row += x;
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
row[i] = idx;
}
row += WIDTH;
}
}
void Arduino_Canvas_Indexed::drawIndexedBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip)
{
if (_rotation > 0)
{
if (!_isDirectUseColorIndex)
{
Arduino_GFX::drawIndexedBitmap(x, y, bitmap, color_index, w, h, x_skip);
}
else
{
int32_t offset = 0;
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
writePixel(x + i, y, bitmap[offset++]);
}
offset += x_skip;
}
}
}
else
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else
{
if ((y + h - 1) > _max_y)
{
h -= (y + h - 1) - _max_y;
}
if (y < 0)
{
bitmap -= y * (w + x_skip);
h += y;
y = 0;
}
if ((x + w - 1) > _max_x)
{
x_skip += (x + w - 1) - _max_x;
w -= (x + w - 1) - _max_x;
}
if (x < 0)
{
bitmap -= x;
x_skip -= x;
w += x;
x = 0;
}
uint8_t *row = _framebuffer;
row += y * _width;
row += x;
int16_t i;
int16_t wi;
if (_isDirectUseColorIndex)
{
while (h--)
{
i = 0;
wi = w;
while (wi >= 4)
{
*((uint32_t *)&row[i]) = *((uint32_t *)bitmap);
i += 4;
wi -= 4;
bitmap += 4;
}
while (i < w)
{
row[i++] = *bitmap++;
}
bitmap += x_skip;
row += _width;
}
}
else
{
while (h--)
{
for (int i = 0; i < w; i++)
{
row[i] = get_color_index(color_index[*bitmap++]);
}
bitmap += x_skip;
row += _width;
}
}
}
}
}
void Arduino_Canvas_Indexed::drawIndexedBitmap(
int16_t x, int16_t y,
uint8_t *bitmap, uint16_t *color_index, uint8_t chroma_key, int16_t w, int16_t h, int16_t x_skip)
{
if (_rotation > 0)
{
if (!_isDirectUseColorIndex)
{
Arduino_GFX::drawIndexedBitmap(x, y, bitmap, color_index, chroma_key, w, h, x_skip);
}
else
{
int32_t offset = 0;
uint8_t color_key;
for (int16_t j = 0; j < h; j++, y++)
{
for (int16_t i = 0; i < w; i++)
{
color_key = bitmap[offset++];
if (color_key != chroma_key)
{
writePixel(x + i, y, color_key);
}
}
offset += x_skip;
}
}
}
else
{
if (
((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top
(x > _max_x) || // Outside right
(y > _max_y) // Outside bottom
)
{
return;
}
else
{
if ((y + h - 1) > _max_y)
{
h -= (y + h - 1) - _max_y;
}
if (y < 0)
{
bitmap -= y * (w + x_skip);
h += y;
y = 0;
}
if ((x + w - 1) > _max_x)
{
x_skip += (x + w - 1) - _max_x;
w -= (x + w - 1) - _max_x;
}
if (x < 0)
{
bitmap -= x;
x_skip -= x;
w += x;
x = 0;
}
uint8_t *row = _framebuffer;
row += y * _width;
row += x;
uint8_t color_key;
if (_isDirectUseColorIndex)
{
while (h--)
{
for (int i = 0; i < w; i++)
{
color_key = *bitmap++;
if (color_key != chroma_key)
{
row[i] = color_key;
}
}
bitmap += x_skip;
row += _width;
}
}
else
{
while (h--)
{
for (int i = 0; i < w; i++)
{
color_key = *bitmap++;
if (color_key != chroma_key)
{
row[i] = get_color_index(color_index[color_key]);
}
}
bitmap += x_skip;
row += _width;
}
}
}
}
}
void Arduino_Canvas_Indexed::flush(bool force_flush)
{
if (_output)
{
_output->drawIndexedBitmap(_output_x, _output_y, _framebuffer, _color_index, WIDTH, HEIGHT);
}
}
uint8_t *Arduino_Canvas_Indexed::getFramebuffer()
{
return _framebuffer;
}
uint16_t *Arduino_Canvas_Indexed::getColorIndex()
{
return _color_index;
}
void Arduino_Canvas_Indexed::setDirectUseColorIndex(bool isEnable)
{
_isDirectUseColorIndex = isEnable;
}
uint8_t Arduino_Canvas_Indexed::get_color_index(uint16_t color)
{
color &= _color_mask;
for (uint8_t i = 0; i < _indexed_size; i++)
{
if (_color_index[i] == color)
{
return i;
}
}
if (_indexed_size == (COLOR_IDX_SIZE - 1)) // overflowed
{
raise_mask_level();
}
_color_index[_indexed_size] = color;
// print("color_index[");
// print(_indexed_size);
// print("] = ");
// println(color);
return _indexed_size++;
}
GFX_INLINE uint16_t Arduino_Canvas_Indexed::get_index_color(uint8_t idx)
{
return _color_index[idx];
}
void Arduino_Canvas_Indexed::raise_mask_level()
{
if ((_current_mask_level + 1) < MAXMASKLEVEL)
{
int32_t buffer_size = _width * _height;
uint8_t old_indexed_size = _indexed_size;
uint8_t new_color;
_indexed_size = 0;
_color_mask = mask_level_list[++_current_mask_level];
// print("Raised mask level: ");
// println(_current_mask_level);
// update _framebuffer color index, it is a time consuming job
for (uint8_t old_color = 0; old_color < old_indexed_size; old_color++)
{
new_color = get_color_index(_color_index[old_color]);
for (int32_t i = 0; i < buffer_size; i++)
{
if (_framebuffer[i] == old_color)
{
_framebuffer[i] = new_color;
}
}
}
}
}
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,60 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#ifndef _ARDUINO_CANVAS_INDEXED_H_
#define _ARDUINO_CANVAS_INDEXED_H_
#include "../Arduino_GFX.h"
#define COLOR_IDX_SIZE 256
class Arduino_Canvas_Indexed : public Arduino_GFX
{
public:
Arduino_Canvas_Indexed(int16_t w, int16_t h, Arduino_G *output, int16_t output_x = 0, int16_t output_y = 0, uint8_t rotation = 0, uint8_t mask_level = 0);
~Arduino_Canvas_Indexed();
bool begin(int32_t speed = GFX_NOT_DEFINED) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
void writeFastVLineCore(int16_t x, int16_t y, int16_t h, uint8_t idx);
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
void writeFastHLineCore(int16_t x, int16_t y, int16_t w, uint8_t idx);
void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override;
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, int16_t w, int16_t h, int16_t x_skip = 0) override;
void drawIndexedBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint16_t *color_index, uint8_t chroma_key, int16_t w, int16_t h, int16_t x_skip = 0) override;
void flush(bool force_flush = false) override;
uint8_t *getFramebuffer();
uint16_t *getColorIndex();
void setDirectUseColorIndex(bool isEnable);
uint8_t get_color_index(uint16_t color);
uint16_t get_index_color(uint8_t idx);
void raise_mask_level();
protected:
uint8_t *_framebuffer = nullptr;
Arduino_G *_output = nullptr;
int16_t _output_x, _output_y;
int16_t MAX_X, MAX_Y;
uint16_t _color_index[COLOR_IDX_SIZE];
uint8_t _indexed_size = 0;
bool _isDirectUseColorIndex = false;
uint8_t _current_mask_level;
uint16_t _color_mask;
#define MAXMASKLEVEL 3
uint16_t mask_level_list[MAXMASKLEVEL] = {
0b1111111111111111, // 16-bit, 65536 colors
0b1111011110011110, // 12-bit, 4096 colors
0b1100011100011000 // 7-bit, 128 colors
};
private:
};
#endif // _ARDUINO_CANVAS_INDEXED_H_
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,116 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#include "../Arduino_GFX.h"
#include "Arduino_Canvas_Mono.h"
Arduino_Canvas_Mono::Arduino_Canvas_Mono(int16_t w, int16_t h, Arduino_G *output, int16_t output_x, int16_t output_y, bool verticalByte)
: Arduino_GFX(w, h), _output(output), _output_x(output_x), _output_y(output_y), _verticalByte(verticalByte),
_canvas_width(w), _canvas_height(h)
{
}
Arduino_Canvas_Mono::~Arduino_Canvas_Mono()
{
if (_framebuffer)
{
free(_framebuffer);
}
}
bool Arduino_Canvas_Mono::begin(int32_t speed)
{
if (speed != GFX_SKIP_OUTPUT_BEGIN)
{
if (_output)
{
if (!_output->begin(speed))
{
return false;
}
}
}
if (!_framebuffer)
{
size_t s;
// allocate memory by full bytes.
if (_verticalByte)
{
s = _canvas_width * (_canvas_height + 7) / 8;
}
else
{
s = (_canvas_width + 7) / 8 * _canvas_height;
}
#if defined(ESP32)
if (psramFound())
{
_framebuffer = (uint8_t *)ps_malloc(s);
}
else
{
_framebuffer = (uint8_t *)malloc(s);
}
#else
_framebuffer = (uint8_t *)malloc(s);
#endif
if (!_framebuffer)
{
return false;
}
}
return true;
}
void Arduino_Canvas_Mono::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
{
// change the pixel in the original orientation of the bitmap buffer
if (_verticalByte)
{
// vertical buffer layout: 1 byte in the buffer contains 8 vertical pixels
int32_t pos = x + (y / 8) * _canvas_width;
if (color & 0b1000010000010000)
{
_framebuffer[pos] |= (1 << (y & 7));
}
else
{
_framebuffer[pos] &= ~(1 << (y & 7));
}
}
else
{
// horizontal buffer layout: 1 byte in the buffer contains 8 horizontal pixels
int16_t w = (_canvas_width + 7) / 8;
int32_t pos = (y * w) + (x / 8);
if (color & 0b1000010000010000)
{
_framebuffer[pos] |= 0x80 >> (x & 7);
}
else
{
_framebuffer[pos] &= ~(0x80 >> (x & 7));
}
}
}
void Arduino_Canvas_Mono::flush(bool force_flush)
{
if (_output)
{
_output->drawBitmap(_output_x, _output_y, _framebuffer, _canvas_width, _canvas_height, RGB565_WHITE, RGB565_BLACK);
}
}
uint8_t *Arduino_Canvas_Mono::getFramebuffer()
{
return _framebuffer;
}
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,33 @@
#include "../Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#ifndef _ARDUINO_CANVAS_MONO_H_
#define _ARDUINO_CANVAS_MONO_H_
#include "../Arduino_GFX.h"
class Arduino_Canvas_Mono : public Arduino_GFX
{
public:
Arduino_Canvas_Mono(int16_t w, int16_t h, Arduino_G *output, int16_t output_x = 0, int16_t output_y = 0, bool verticalByte = false);
~Arduino_Canvas_Mono();
bool begin(int32_t speed = GFX_NOT_DEFINED) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void flush(bool force_flush = false) override;
uint8_t *getFramebuffer();
protected:
uint8_t *_framebuffer = nullptr;
Arduino_G *_output = nullptr;
int16_t _output_x, _output_y;
bool _verticalByte;
int16_t _canvas_width, _canvas_height; // width and height of canvas buffer
private:
};
#endif // _ARDUINO_CANVAS_MONO_H_
#endif // !defined(LITTLE_FOOT_PRINT)

View File

@@ -0,0 +1,15 @@
# About the canvas mono class of the GFX library
There are some Display Chips on the market that can display a small amount of graphic data but
don't offer much functionality on it's own on other than data transfer. Examples are the OLED
Displays Chips SSD1306 or SH1106.
These displays need an in memory copy of the graphics and updating the display is implemented by
a bulk data transfer of the internal memory to the display.
Therefore the Canvas Mono class must be initialized in a way the internal memory fits to the
memory inside the graphic driver chip including the width and height of the display memory and
the orientation of a byte to either horizontal or vertical.
Bei changing the orientation of the canvas the graphics elements like lines or characters are positioned on the display memory accordingly. When the rotating in 90 or 270 degrees der width and height of the logical display will be swapped but not the memory organization.

View File

@@ -0,0 +1,243 @@
#ifdef __AVR__
#include "Arduino_AVRPAR16.h"
Arduino_AVRPAR16::Arduino_AVRPAR16(int8_t dc, int8_t cs, int8_t wr, int8_t rd, uint8_t portLow, uint8_t portHigh)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd), _portLow(portLow), _portHigh(portHigh)
{
}
bool Arduino_AVRPAR16::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
_dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc));
_dcPinMaskSet = digitalPinToBitMask(_dc);
_dcPinMaskClr = ~_dcPinMaskSet;
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // Disable chip select
_csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs));
_csPinMaskSet = digitalPinToBitMask(_cs);
}
_csPinMaskClr = ~_csPinMaskSet;
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
_wrPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_wr));
_wrPinMaskSet = digitalPinToBitMask(_wr);
_wrPinMaskClr = ~_wrPinMaskSet;
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH); // Disable RD
}
*(portModeRegister(_portLow)) = 0xFF;
_dataPortLow = portOutputRegister(_portLow);
*_dataPortLow = 0xFF;
*(portModeRegister(_portHigh)) = 0xFF;
_dataPortHigh = portOutputRegister(_portHigh);
*_dataPortHigh = 0xFF;
return true;
}
void Arduino_AVRPAR16::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_AVRPAR16::endWrite()
{
CS_HIGH();
}
void Arduino_AVRPAR16::writeCommand(uint8_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_AVRPAR16::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_AVRPAR16::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE16(*data++);
}
DC_HIGH();
}
void Arduino_AVRPAR16::write(uint8_t d)
{
WRITE16(d);
}
void Arduino_AVRPAR16::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_AVRPAR16::writeRepeat(uint16_t p, uint32_t len)
{
uint8_t wrMaskBase = *_wrPort & _wrPinMaskClr;
uint8_t wrMaskSet = wrMaskBase | _wrPinMaskSet;
_data16.value = p;
*_dataPortLow = _data16.lsb;
*_dataPortHigh = _data16.msb;
while (len--)
{
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
void Arduino_AVRPAR16::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
void Arduino_AVRPAR16::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_AVRPAR16::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_AVRPAR16::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_AVRPAR16::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
uint8_t wrMaskBase = *_wrPort & _wrPinMaskClr;
_data16.value = c;
*_dataPortLow = _data16.lsb;
*_dataPortHigh = _data16.msb;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
DC_HIGH();
_data16.value = d1;
*_dataPortLow = _data16.msb;
*_dataPortHigh = 0;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
*_dataPortLow = _data16.lsb;
*_dataPortHigh = 0;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
_data16.value = d2;
*_dataPortLow = _data16.msb;
*_dataPortHigh = 0;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
*_dataPortLow = _data16.lsb;
*_dataPortHigh = 0;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
}
void Arduino_AVRPAR16::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE16(*data);
}
}
GFX_INLINE void Arduino_AVRPAR16::WRITE16(uint16_t d)
{
uint8_t wrMaskBase = *_wrPort & _wrPinMaskClr;
_data16.value = d;
*_dataPortLow = _data16.lsb;
*_dataPortHigh = _data16.msb;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_AVRPAR16::DC_HIGH(void)
{
*_dcPort |= _dcPinMaskSet;
}
GFX_INLINE void Arduino_AVRPAR16::DC_LOW(void)
{
*_dcPort &= _dcPinMaskClr;
}
GFX_INLINE void Arduino_AVRPAR16::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort |= _csPinMaskSet;
}
}
GFX_INLINE void Arduino_AVRPAR16::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort &= _csPinMaskClr;
}
}
#endif // #ifdef __AVR__

View File

@@ -0,0 +1,61 @@
#ifdef __AVR__
#ifndef _ARDUINO_AVRPAR16_H_
#define _ARDUINO_AVRPAR16_H_
#include "Arduino_DataBus.h"
class Arduino_AVRPAR16 : public Arduino_DataBus
{
public:
Arduino_AVRPAR16(int8_t dc, int8_t cs, int8_t wr, int8_t rd, uint8_t portLow, uint8_t portHigh); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITEREPEAT(uint16_t p, uint32_t len);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
uint8_t _portLow;
uint8_t _portHigh;
PORTreg_t _dcPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _csPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _csPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _csPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _wrPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _wrPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _wrPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _dataPortLow; ///< PORT register for data/command
PORTreg_t _dataPortHigh; ///< PORT register for data/command
};
#endif // _ARDUINO_AVRPAR16_H_
#endif // #ifdef __AVR__

View File

@@ -0,0 +1,227 @@
#ifdef __AVR__
#include "Arduino_AVRPAR8.h"
Arduino_AVRPAR8::Arduino_AVRPAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd, uint8_t port)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd), _port(port)
{
}
bool Arduino_AVRPAR8::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
_dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc));
_dcPinMaskSet = digitalPinToBitMask(_dc);
_dcPinMaskClr = ~_dcPinMaskSet;
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // Disable chip select
_csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs));
_csPinMaskSet = digitalPinToBitMask(_cs);
}
_csPinMaskClr = ~_csPinMaskSet;
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
_wrPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_wr));
_wrPinMaskSet = digitalPinToBitMask(_wr);
_wrPinMaskClr = ~_wrPinMaskSet;
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH); // Disable RD
}
*(portModeRegister(_port)) = 0xFF;
_dataPort = portOutputRegister(_port);
*_dataPort = 0xFF;
return true;
}
void Arduino_AVRPAR8::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_AVRPAR8::endWrite()
{
CS_HIGH();
}
void Arduino_AVRPAR8::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_AVRPAR8::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_AVRPAR8::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_AVRPAR8::write(uint8_t d)
{
WRITE(d);
}
void Arduino_AVRPAR8::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_AVRPAR8::writeRepeat(uint16_t p, uint32_t len)
{
uint8_t wrMaskBase = *_wrPort & _wrPinMaskClr;
uint8_t wrMaskSet = wrMaskBase | _wrPinMaskSet;
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
*_dataPort = _data16.msb;
while (len--)
{
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
else
{
while (len--)
{
*_dataPort = _data16.msb;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_dataPort = _data16.lsb;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
}
void Arduino_AVRPAR8::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_AVRPAR8::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_AVRPAR8::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_AVRPAR8::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_AVRPAR8::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
GFX_INLINE void Arduino_AVRPAR8::WRITE(uint8_t d)
{
uint8_t wrMaskBase = *_wrPort & _wrPinMaskClr;
*_dataPort = d;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_AVRPAR8::DC_HIGH(void)
{
*_dcPort |= _dcPinMaskSet;
}
GFX_INLINE void Arduino_AVRPAR8::DC_LOW(void)
{
*_dcPort &= _dcPinMaskClr;
}
GFX_INLINE void Arduino_AVRPAR8::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort |= _csPinMaskSet;
}
}
GFX_INLINE void Arduino_AVRPAR8::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort &= _csPinMaskClr;
}
}
#endif // #ifdef __AVR__

View File

@@ -0,0 +1,57 @@
#ifdef __AVR__
#ifndef _ARDUINO_AVRPAR8_H_
#define _ARDUINO_AVRPAR8_H_
#include "Arduino_DataBus.h"
class Arduino_AVRPAR8 : public Arduino_DataBus
{
public:
Arduino_AVRPAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd, uint8_t port); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
uint8_t _port;
PORTreg_t _dcPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _csPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _csPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _csPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _wrPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _wrPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _wrPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _dataPort; ///< PORT register for data/command
};
#endif // _ARDUINO_AVRPAR8_H_
#endif // #ifdef __AVR__

View File

@@ -0,0 +1,246 @@
#if defined(ARDUINO_ARCH_SAM)
#include "Arduino_DUEPAR16.h"
Arduino_DUEPAR16::Arduino_DUEPAR16()
{
}
bool Arduino_DUEPAR16::begin(int32_t speed, int8_t dataMode)
{
UNUSED(speed);
UNUSED(dataMode);
_cs = 40;
_dc = 38;
_wr = 39;
_rd = 43;
digitalWrite(_dc, HIGH);
digitalWrite(_cs, HIGH);
digitalWrite(_wr, HIGH);
digitalWrite(_rd, HIGH);
pinMode(_dc, OUTPUT);
pinMode(_cs, OUTPUT);
pinMode(_wr, OUTPUT);
pinMode(_rd, OUTPUT);
setDataPins(OUTPUT);
return true;
}
void Arduino_DUEPAR16::setDataPins(uint8_t mode)
{
pinMode(29, mode);
pinMode(28, mode);
pinMode(27, mode);
pinMode(26, mode);
pinMode(25, mode);
pinMode(24, mode);
pinMode(23, mode);
pinMode(22, mode);
pinMode(30, mode);
pinMode(31, mode);
pinMode(32, mode);
pinMode(33, mode);
pinMode(34, mode);
pinMode(35, mode);
pinMode(36, mode);
pinMode(37, mode);
}
void Arduino_DUEPAR16::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_DUEPAR16::endWrite()
{
CS_HIGH();
}
void Arduino_DUEPAR16::writeCommand(uint8_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_DUEPAR16::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_DUEPAR16::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE16(*data++);
}
DC_HIGH();
}
void Arduino_DUEPAR16::write(uint8_t d)
{
WRITE16(d);
}
void Arduino_DUEPAR16::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_DUEPAR16::writeRepeat(uint16_t p, uint32_t len)
{
writeData16(p, len);
}
void Arduino_DUEPAR16::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
#if !defined(LITTLE_FOOT_PRINT)
void Arduino_DUEPAR16::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_DUEPAR16::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_DUEPAR16::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_DUEPAR16::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_DUEPAR16::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE16(*data);
}
}
void Arduino_DUEPAR16::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
WRITE16(idx[*data++]);
}
}
void Arduino_DUEPAR16::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE16(_data16.value);
WRITE16(_data16.value);
}
}
#endif // !defined(LITTLE_FOOT_PRINT)
GFX_INLINE void Arduino_DUEPAR16::WRITE16(uint16_t d)
{
writeData16(d, 1);
}
void Arduino_DUEPAR16::writeData16(uint16_t d, uint32_t num)
{
// | | | | Ruler for byte MS bits 31, 23, 15 and 7
// B AA DD AD DDDD Marker for register bits used
REG_PIOA_CODR = 0b00000000000000001100000010000000; // Clear bits
REG_PIOB_CODR = 0b00000100000000000000000000000000; // Clear bits
// W CCCCC // WR bit
REG_PIOC_CODR = 0b00000000000000000000000010111110; // Clear WR bit as well
REG_PIOD_CODR = 0b00000000000000000000011001001111; // Clear bits
// The compiler efficiently codes this
// so it is quite quick. Port.bit
if (d & 0x8000) REG_PIOD_SODR = 0x1 << 6; // D.6
if (d & 0x4000) REG_PIOD_SODR = 0x1 << 3; // D.3
if (d & 0x2000) REG_PIOD_SODR = 0x1 << 2; // D.2
if (d & 0x1000) REG_PIOD_SODR = 0x1 << 1; // D.1
if (d & 0x0800) REG_PIOD_SODR = 0x1 << 0; // D.0
if (d & 0x0400) REG_PIOA_SODR = 0x1 << 15; // A.15
if (d & 0x0200) REG_PIOA_SODR = 0x1 << 14; // A.14
if (d & 0x0100) REG_PIOB_SODR = 0x1 << 26; // B.26
// so it is quite quick. Port.bit
if (d & 0x0080) REG_PIOD_SODR = 0x1 << 9; // D.9
if (d & 0x0040) REG_PIOA_SODR = 0x1 << 7; // A.7
if (d & 0x0020) REG_PIOD_SODR = 0x1 << 10; // D.10
if (d & 0x0010) REG_PIOC_SODR = 0x1 << 1; // C.1
if (d & 0x0008) REG_PIOC_SODR = 0x1 << 2; // C.2
if (d & 0x0004) REG_PIOC_SODR = 0x1 << 3; // C.3
if (d & 0x0002) REG_PIOC_SODR = 0x1 << 4; // C.4
if (d & 0x0001) REG_PIOC_SODR = 0x1 << 5; // C.5
while (num > 0)
{
// WR_STB;
REG_PIOC_CODR = 0x1 << 7;
REG_PIOC_CODR = 0x1 << 7;
REG_PIOC_CODR = 0x1 << 7;
REG_PIOC_SODR = 0x1 << 7;
num--;
}
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_DUEPAR16::DC_HIGH(void)
{
digitalWrite(_dc, HIGH);
}
GFX_INLINE void Arduino_DUEPAR16::DC_LOW(void)
{
digitalWrite(_dc, LOW);
}
GFX_INLINE void Arduino_DUEPAR16::CS_HIGH(void)
{
digitalWrite(_cs, HIGH);
}
GFX_INLINE void Arduino_DUEPAR16::CS_LOW(void)
{
digitalWrite(_cs, LOW);
}
#endif // #if defined(ARDUINO_ARCH_SAM)

View File

@@ -0,0 +1,52 @@
#if defined(ARDUINO_ARCH_SAM)
#ifndef _ARDUINO_DUEPAR16_H_
#define _ARDUINO_DUEPAR16_H_
#include "Arduino_DataBus.h"
// for MCUFriend MEGA kind of shields on Arduino DUE. -jz-
class Arduino_DUEPAR16 : public Arduino_DataBus
{
public:
Arduino_DUEPAR16(); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
#if !defined(LITTLE_FOOT_PRINT)
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
#endif // !defined(LITTLE_FOOT_PRINT)
protected:
private:
void setDataPins(uint8_t mode);
void writeData16(uint16_t d, uint32_t num = 1);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITEREPEAT(uint16_t p, uint32_t len);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _cs, _dc, _wr, _rd;
};
#endif // _ARDUINO_DUEPAR16_H_
#endif // #if defined(ARDUINO_ARCH_SAM)

View File

@@ -0,0 +1,108 @@
#include "Arduino_ESP32DSIPanel.h"
#define TAG "Arduino_ESP32DSIPanel"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32P4)
Arduino_ESP32DSIPanel::Arduino_ESP32DSIPanel(
uint32_t hsync_pulse_width, uint32_t hsync_back_porch, uint32_t hsync_front_porch,
uint32_t vsync_pulse_width, uint32_t vsync_back_porch, uint32_t vsync_front_porch,
uint32_t prefer_speed,uint32_t lane_bit_rate /*新增成员变量*/)
: _hsync_pulse_width(hsync_pulse_width), _hsync_back_porch(hsync_back_porch), _hsync_front_porch(hsync_front_porch),
_vsync_pulse_width(vsync_pulse_width), _vsync_back_porch(vsync_back_porch), _vsync_front_porch(vsync_front_porch),
_prefer_speed(prefer_speed),
_lane_bit_rate(lane_bit_rate)/*新增成员变量*/
{
}
bool Arduino_ESP32DSIPanel::begin(int16_t w, int16_t h, int32_t speed, const lcd_init_cmd_t *init_operations, size_t init_operations_len)
{
if (speed == GFX_NOT_DEFINED)
{
if (_prefer_speed != GFX_NOT_DEFINED)
{
speed = _prefer_speed;
}
else
{
speed = 56000000L;
}
}
esp_ldo_channel_handle_t ldo_mipi_phy = NULL;
esp_ldo_channel_config_t ldo_mipi_phy_config = {
.chan_id = EXAMPLE_MIPI_DSI_PHY_PWR_LDO_CHAN,
.voltage_mv = EXAMPLE_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV,
};
ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy));
ESP_LOGI(TAG, "MIPI DSI PHY Powered on");
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = _lane_bit_rate, /*新增成员变量*/
};
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
ESP_LOGI(TAG, "Install MIPI DSI LCD control panel");
esp_lcd_dbi_io_config_t dbi_config = {
.virtual_channel = 0,
.lcd_cmd_bits = 8,
.lcd_param_bits = 8,
};
esp_lcd_panel_io_handle_t io_handle = NULL;
ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &io_handle));
esp_lcd_dpi_panel_config_t dpi_config = {
.virtual_channel = 0,
.dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT,
.dpi_clock_freq_mhz = speed / 1000000,
.pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565,
.num_fbs = 1,
.video_timing = {
.h_size = w,
.v_size = h,
.hsync_pulse_width = _hsync_pulse_width,
.hsync_back_porch = _hsync_back_porch,
.hsync_front_porch = _hsync_front_porch,
.vsync_pulse_width = _vsync_pulse_width,
.vsync_back_porch = _vsync_back_porch,
.vsync_front_porch = _vsync_front_porch,
},
.flags = {
.use_dma2d = true,
},
};
const esp_lcd_panel_dev_config_t panel_config = {
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
// Create MIPI DPI panel
ESP_ERROR_CHECK(esp_lcd_new_panel_dpi(mipi_dsi_bus, &dpi_config, &_panel_handle));
for (int i = 0; i < init_operations_len; i++)
{
// Send command
ESP_ERROR_CHECK(esp_lcd_panel_io_tx_param(io_handle, init_operations[i].cmd, init_operations[i].data, init_operations[i].data_bytes));
vTaskDelay(pdMS_TO_TICKS(init_operations[i].delay_ms));
}
ESP_LOGD(TAG, "send init commands success");
ESP_ERROR_CHECK(esp_lcd_panel_init(_panel_handle));
return true;
}
uint16_t *Arduino_ESP32DSIPanel::getFrameBuffer()
{
void *frame_buffer = nullptr;
ESP_ERROR_CHECK(esp_lcd_dpi_panel_get_frame_buffer(_panel_handle, 1, &frame_buffer));
return ((uint16_t *)frame_buffer);
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32P4)

View File

@@ -0,0 +1,61 @@
#pragma once
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32P4)
#include <stdio.h>
#include <sdkconfig.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
#include <esp_timer.h>
#include <esp_check.h>
#include <esp_lcd_panel_ops.h>
#include <esp_lcd_panel_vendor.h>
#include <esp_lcd_mipi_dsi.h>
#include <esp_lcd_panel_io.h>
#include <esp_ldo_regulator.h>
#include <driver/gpio.h>
#include <esp_err.h>
#include <esp_log.h>
#define EXAMPLE_MIPI_DSI_PHY_PWR_LDO_CHAN 3 // LDO_VO3 连接至 VDD_MIPI_DPHY
#define EXAMPLE_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV 2500
#define DEFAULT_MIPI_DSI_LANE_BIT_RATE_MBPS 750 // 新增宏定义
typedef struct
{
int cmd; /*<! The specific LCD command */
const void *data; /*<! Buffer that holds the command specific data */
size_t data_bytes; /*<! Size of `data` in memory, in bytes */
unsigned int delay_ms; /*<! Delay in milliseconds after this command */
} lcd_init_cmd_t;
class Arduino_ESP32DSIPanel
{
public:
Arduino_ESP32DSIPanel(
uint32_t hsync_pulse_width, uint32_t hsync_back_porch, uint32_t hsync_front_porch,
uint32_t vsync_pulse_width, uint32_t vsync_back_porch, uint32_t vsync_front_porch,
uint32_t prefer_speed = GFX_NOT_DEFINED,uint32_t lane_bit_rate = DEFAULT_MIPI_DSI_LANE_BIT_RATE_MBPS /*新增成员变量*/);
bool begin(int16_t w, int16_t h, int32_t speed = GFX_NOT_DEFINED, const lcd_init_cmd_t *init_operations = NULL, size_t init_operations_len = GFX_NOT_DEFINED);
uint16_t *getFrameBuffer();
protected:
private:
uint32_t _hsync_pulse_width;
uint32_t _hsync_back_porch;
uint32_t _hsync_front_porch;
uint32_t _vsync_pulse_width;
uint32_t _vsync_back_porch;
uint32_t _vsync_front_porch;
uint32_t _prefer_speed;
uint32_t _lane_bit_rate; // 新增成员变量
esp_lcd_panel_handle_t _panel_handle = NULL;
};
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32P4)

View File

@@ -0,0 +1,600 @@
/*
* start rewrite from:
* https://github.com/lovyan03/LovyanGFX/blob/master/src/lgfx/v0/platforms/LGFX_PARALLEL_ESP32.hpp
*/
#include "Arduino_ESP32LCD16.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#define WAIT_LCD_NOT_BUSY while (LCD_CAM.lcd_user.val & LCD_CAM_LCD_START)
Arduino_ESP32LCD16::Arduino_ESP32LCD16(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7),
_d8(d8), _d9(d9), _d10(d10), _d11(d11), _d12(d12), _d13(d13), _d14(d14), _d15(d15)
{
}
bool Arduino_ESP32LCD16::begin(int32_t speed, int8_t dataMode)
{
if (speed == GFX_NOT_DEFINED)
{
_speed = 8000000UL; // safe frequency
}
else
{
_speed = speed;
}
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
esp_lcd_i80_bus_config_t bus_config = {
.dc_gpio_num = _dc,
.wr_gpio_num = _wr,
.clk_src = LCD_CLK_SRC_PLL160M,
.data_gpio_nums = {
_d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7,
_d8, _d9, _d10, _d11, _d12, _d13, _d14, _d15},
.bus_width = 16,
.max_transfer_bytes = LCD_MAX_PIXELS_AT_ONCE * 2,
.psram_trans_align = 0,
.sram_trans_align = 0};
esp_lcd_new_i80_bus(&bus_config, &_i80_bus);
uint32_t diff = INT32_MAX;
uint32_t div_n = 256;
uint32_t div_a = 63;
uint32_t div_b = 62;
uint32_t clkcnt = 64;
uint32_t start_cnt = std::min<uint32_t>(64u, (F_CPU / (_speed * 2) + 1));
uint32_t end_cnt = std::max<uint32_t>(2u, F_CPU / 256u / _speed);
if (start_cnt <= 2)
{
end_cnt = 1;
}
for (uint32_t cnt = start_cnt; diff && cnt >= end_cnt; --cnt)
{
float fdiv = (float)F_CPU / cnt / _speed;
uint32_t n = std::max<uint32_t>(2u, (uint32_t)fdiv);
fdiv -= n;
for (uint32_t a = 63; diff && a > 0; --a)
{
uint32_t b = roundf(fdiv * a);
if (a == b && n == 256)
{
break;
}
uint32_t freq = F_CPU / ((n * cnt) + (float)(b * cnt) / (float)a);
uint32_t d = abs(_speed - (int)freq);
if (diff <= d)
{
continue;
}
diff = d;
clkcnt = cnt;
div_n = n;
div_b = b;
div_a = a;
if (b == 0 || a == b)
{
break;
}
}
}
if (div_a == div_b)
{
div_b = 0;
div_n += 1;
}
int wait = 24 - (div_n * clkcnt);
_fast_wait = (wait < 0) ? 0 : wait;
lcd_cam_lcd_clock_reg_t lcd_clock;
lcd_clock.lcd_clkcnt_n = std::max(1u, clkcnt - 1);
lcd_clock.lcd_clk_equ_sysclk = (clkcnt == 1);
lcd_clock.lcd_ck_idle_edge = true;
lcd_clock.lcd_ck_out_edge = false;
lcd_clock.lcd_clkm_div_num = div_n;
lcd_clock.lcd_clkm_div_b = div_b;
lcd_clock.lcd_clkm_div_a = div_a;
lcd_clock.lcd_clk_sel = 2; // clock_select: 1=XTAL CLOCK / 2=240MHz / 3=160MHz
lcd_clock.clk_en = true;
LCD_CAM.lcd_clock.val = lcd_clock.val;
_dma_chan = _i80_bus->dma_chan;
_dmadesc = (dma_descriptor_t *)heap_caps_malloc(sizeof(dma_descriptor_t), MALLOC_CAP_DMA);
_buffer = (uint8_t *)heap_caps_aligned_alloc(16, LCD_MAX_PIXELS_AT_ONCE * 2, MALLOC_CAP_DMA);
if (!_buffer)
{
return false;
}
_2nd_buffer = (uint8_t *)heap_caps_aligned_alloc(16, LCD_MAX_PIXELS_AT_ONCE * 2, MALLOC_CAP_DMA);
if (!_2nd_buffer)
{
return false;
}
return true;
}
void Arduino_ESP32LCD16::beginWrite()
{
CS_LOW();
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_user.val = 0;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG;
}
void Arduino_ESP32LCD16::endWrite()
{
WAIT_LCD_NOT_BUSY;
CS_HIGH();
}
void Arduino_ESP32LCD16::writeCommand(uint8_t c)
{
WRITECOMMAND16(c);
}
void Arduino_ESP32LCD16::writeCommand16(uint16_t c)
{
WRITECOMMAND16(c);
}
void Arduino_ESP32LCD16::writeCommandBytes(uint8_t *data, uint32_t len)
{
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE | LCD_CAM_LCD_CD_CMD_SET;
while (len--)
{
LCD_CAM.lcd_cmd_val.val = *data++;
WAIT_LCD_NOT_BUSY;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
}
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
}
void Arduino_ESP32LCD16::write(uint8_t d)
{
WRITE16(d);
}
void Arduino_ESP32LCD16::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_ESP32LCD16::writeRepeat(uint16_t p, uint32_t len)
{
if (len < USE_DMA_THRESHOLD)
{
while (len--)
{
WRITE16(p);
}
}
else
{
uint32_t bufLen = (len < LCD_MAX_PIXELS_AT_ONCE) ? len : LCD_MAX_PIXELS_AT_ONCE;
uint32_t xferLen, l;
uint32_t c32 = p * 0x10001;
l = (bufLen + 1) / 2;
for (uint32_t i = 0; i < l; i++)
{
_buffer32[i] = c32;
}
while (len) // While pixels remain
{
xferLen = (bufLen <= len) ? bufLen : len; // How many this pass?
l = (xferLen - 2) * 2;
*(uint32_t *)_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000;
_dmadesc->buffer = _buffer;
_dmadesc->next = nullptr;
gdma_start(_dma_chan, (intptr_t)(_dmadesc));
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = c32;
uint32_t wait = _fast_wait;
if (wait > 0)
{
do
{
__asm__ __volatile__("nop");
} while (--wait);
}
len -= xferLen;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
WAIT_LCD_NOT_BUSY;
}
}
}
void Arduino_ESP32LCD16::writePixels(uint16_t *data, uint32_t len)
{
uint32_t xferLen, l;
while (len > USE_DMA_THRESHOLD) // While pixels remain
{
xferLen = (len < LCD_MAX_PIXELS_AT_ONCE) ? len : LCD_MAX_PIXELS_AT_ONCE; // How many this pass?
_data32.value16 = *data++;
_data32.value16_2 = *data++;
l = xferLen - 2;
l <<= 1;
*(uint32_t *)_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000;
_dmadesc->buffer = data;
_dmadesc->next = nullptr;
gdma_start(_dma_chan, (intptr_t)(_dmadesc));
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = _data32.value;
uint32_t wait = _fast_wait;
while (wait--)
{
__asm__ __volatile__("nop");
}
data += xferLen - 2;
len -= xferLen;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
WAIT_LCD_NOT_BUSY;
}
while (len--)
{
WRITE16(*data++);
}
}
void Arduino_ESP32LCD16::writeC8D8(uint8_t c, uint8_t d)
{
WRITECOMMAND16(c);
WRITE16(d);
}
void Arduino_ESP32LCD16::writeC8D16(uint8_t c, uint16_t d)
{
WRITECOMMAND16(c);
WRITE16(d);
}
void Arduino_ESP32LCD16::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
WRITECOMMAND16(c);
WRITE16(d1);
WRITE16(d2);
}
void Arduino_ESP32LCD16::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
WRITECOMMAND16(c);
_data16.value = d1;
WRITE16(_data16.msb);
WRITE16(_data16.lsb);
_data16.value = d2;
WRITE16(_data16.msb);
WRITE16(_data16.lsb);
}
void Arduino_ESP32LCD16::writeBytes(uint8_t *data, uint32_t len)
{
uint32_t xferLen, l;
while (len > (USE_DMA_THRESHOLD * 2)) // While pixels remain
{
xferLen = (len < (LCD_MAX_PIXELS_AT_ONCE * 2)) ? len : (LCD_MAX_PIXELS_AT_ONCE * 2); // How many this pass?
_data32.msb = *data++;
_data32.lsb = *data++;
_data32.msb_2 = *data++;
_data32.lsb_2 = *data++;
l = xferLen - 4;
l >>= 1;
for (int i = 0; i < l; ++i)
{
_buffer[(i * 2) + 1] = *data++;
_buffer[i * 2] = *data++;
}
l <<= 1;
*(uint32_t *)_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000;
_dmadesc->buffer = _buffer;
_dmadesc->next = nullptr;
gdma_start(_dma_chan, (intptr_t)(_dmadesc));
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = _data32.value;
uint32_t wait = _fast_wait;
while (wait--)
{
__asm__ __volatile__("nop");
}
len -= xferLen;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
WAIT_LCD_NOT_BUSY;
}
while (len)
{
if (len == 1)
{
WRITE16(*data);
len--;
}
else
{
_data16.lsb = *data++;
_data16.msb = *data++;
WRITE16(_data16.value);
len -= 2;
}
}
}
void Arduino_ESP32LCD16::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
uint32_t xferLen, l;
uint32_t p;
while (len > USE_DMA_THRESHOLD) // While pixels remain
{
xferLen = (len < LCD_MAX_PIXELS_AT_ONCE) ? len : LCD_MAX_PIXELS_AT_ONCE; // How many this pass?
l = xferLen - 2;
p = idx[*data++];
p <<= 16;
p |= idx[*data++];
for (int i = 0; i < l; ++i)
{
_buffer16[i] = idx[*data++];
}
l <<= 1;
*(uint32_t *)_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000;
_dmadesc->buffer = _buffer;
_dmadesc->next = nullptr;
gdma_start(_dma_chan, (intptr_t)(_dmadesc));
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = p;
uint32_t wait = _fast_wait;
while (wait--)
{
__asm__ __volatile__("nop");
}
len -= xferLen;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
WAIT_LCD_NOT_BUSY;
}
while (len--)
{
WRITE16(idx[*data++]);
}
}
void Arduino_ESP32LCD16::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
len <<= 1; // double length
uint32_t xferLen, l;
uint32_t p;
while (len > USE_DMA_THRESHOLD) // While pixels remain
{
xferLen = (len < LCD_MAX_PIXELS_AT_ONCE) ? len : LCD_MAX_PIXELS_AT_ONCE; // How many this pass?
l = (xferLen - 2) / 2;
p = idx[*data++] * 0x10001;
for (int i = 0; i < l; ++i)
{
_buffer32[i] = idx[*data++] * 0x10001;
}
l <<= 2;
*(uint32_t *)_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000;
_dmadesc->buffer = _buffer;
_dmadesc->next = nullptr;
gdma_start(_dma_chan, (intptr_t)(_dmadesc));
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = p;
uint32_t wait = _fast_wait;
while (wait--)
{
__asm__ __volatile__("nop");
}
len -= xferLen;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
WAIT_LCD_NOT_BUSY;
}
len >>= 1;
while (len--)
{
p = idx[*data++] * 0x10001;
WRITE32(p);
}
}
void Arduino_ESP32LCD16::writeYCbCrPixels(uint8_t *yData, uint8_t *cbData, uint8_t *crData, uint16_t w, uint16_t h)
{
if (w > (LCD_MAX_PIXELS_AT_ONCE / 2))
{
Arduino_DataBus::writeYCbCrPixels(yData, cbData, crData, w, h);
}
else
{
int cols = w >> 1;
int rows = h >> 1;
uint8_t *yData2 = yData + w;
uint16_t *dest = _buffer16;
uint16_t *dest2 = dest + w;
uint8_t pxCb, pxCr;
int16_t pxR, pxG, pxB, pxY;
uint16_t l = (w * 4) - 4;
uint32_t out_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000;
bool poll_started = false;
for (int row = 0; row < rows; ++row)
{
for (int col = 0; col < cols; ++col)
{
pxCb = *cbData++;
pxCr = *crData++;
pxR = CR2R16[pxCr];
pxG = -CB2G16[pxCb] - CR2G16[pxCr];
pxB = CB2B16[pxCb];
pxY = Y2I16[*yData++];
*dest++ = CLIPR[pxY + pxR] | CLIPG[pxY + pxG] | CLIPB[pxY + pxB];
pxY = Y2I16[*yData++];
*dest++ = CLIPR[pxY + pxR] | CLIPG[pxY + pxG] | CLIPB[pxY + pxB];
pxY = Y2I16[*yData2++];
*dest2++ = CLIPR[pxY + pxR] | CLIPG[pxY + pxG] | CLIPB[pxY + pxB];
pxY = Y2I16[*yData2++];
*dest2++ = CLIPR[pxY + pxR] | CLIPG[pxY + pxG] | CLIPB[pxY + pxB];
}
yData += w;
yData2 += w;
if (poll_started)
{
WAIT_LCD_NOT_BUSY;
}
else
{
poll_started = true;
}
*(uint32_t *)_dmadesc = out_dmadesc;
if (row & 1)
{
_dmadesc->buffer = _2nd_buffer32 + 1;
_dmadesc->next = nullptr;
gdma_start(_dma_chan, (intptr_t)(_dmadesc));
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = *_2nd_buffer32;
dest = _buffer16;
}
else
{
_dmadesc->buffer = _buffer32 + 1;
_dmadesc->next = nullptr;
gdma_start(_dma_chan, (intptr_t)(_dmadesc));
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = *_buffer32;
dest = _2nd_buffer16;
}
uint32_t wait = _fast_wait;
while (wait--)
{
__asm__ __volatile__("nop");
}
LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
dest2 = dest + w;
}
WAIT_LCD_NOT_BUSY;
}
}
GFX_INLINE void Arduino_ESP32LCD16::WRITECOMMAND16(uint16_t c)
{
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE | LCD_CAM_LCD_CD_CMD_SET;
LCD_CAM.lcd_cmd_val.val = c;
WAIT_LCD_NOT_BUSY;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
}
GFX_INLINE void Arduino_ESP32LCD16::WRITE16(uint16_t d)
{
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = d;
WAIT_LCD_NOT_BUSY;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
}
GFX_INLINE void Arduino_ESP32LCD16::WRITE32(uint32_t d)
{
LCD_CAM.lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE;
LCD_CAM.lcd_cmd_val.val = d;
WAIT_LCD_NOT_BUSY;
LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32LCD16::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32LCD16::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,98 @@
#pragma once
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#ifndef LCD_MAX_PIXELS_AT_ONCE
#define LCD_MAX_PIXELS_AT_ONCE 2046
#endif
#ifndef USE_DMA_THRESHOLD
#define USE_DMA_THRESHOLD 6
#endif
class Arduino_ESP32LCD16 : public Arduino_DataBus
{
public:
Arduino_ESP32LCD16(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeYCbCrPixels(uint8_t *yData, uint8_t *cbData, uint8_t *crData, uint16_t w, uint16_t h) override;
protected:
private:
GFX_INLINE void WRITECOMMAND16(uint16_t c);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITE32(uint32_t d);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
int8_t _d8, _d9, _d10, _d11, _d12, _d13, _d14, _d15;
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
uint32_t _fast_wait;
esp_lcd_i80_bus_handle_t _i80_bus = nullptr;
dma_descriptor_t *_dmadesc = nullptr;
gdma_channel_handle_t _dma_chan;
union
{
uint32_t value;
struct
{
uint16_t value16;
uint16_t value16_2;
};
struct
{
uint8_t lsb;
uint8_t msb;
uint8_t lsb_2;
uint8_t msb_2;
};
} _data32;
union
{
uint8_t* _buffer;
uint16_t* _buffer16;
uint32_t* _buffer32;
};
union
{
uint8_t *_2nd_buffer;
uint16_t *_2nd_buffer16;
uint32_t *_2nd_buffer32;
};
};
#endif // #if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
#pragma once
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#ifndef LCD_MAX_PIXELS_AT_ONCE
#define LCD_MAX_PIXELS_AT_ONCE 2046
#endif
#ifndef USE_DMA_THRESHOLD
#define USE_DMA_THRESHOLD 6
#endif
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
class Arduino_ESP32LCD8 : public Arduino_DataBus
{
public:
Arduino_ESP32LCD8(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
uint32_t _csPinMask; ///< Bitmask for chip select
esp_lcd_i80_bus_handle_t _i80_bus = nullptr;
dma_descriptor_t *_dmadesc = nullptr;
gdma_channel_handle_t _dma_chan;
union
{
uint32_t value;
struct
{
uint16_t value16;
uint16_t value16_2;
};
struct
{
uint8_t lsb;
uint8_t msb;
uint8_t lsb_2;
uint8_t msb_2;
};
} _data32;
union
{
uint8_t* _buffer;
uint16_t* _buffer16;
uint32_t* _buffer32;
};
};
#else // (ESP_ARDUINO_VERSION_MAJOR >= 3)
#include "esp_lcd_panel_interface.h"
#include "esp_lcd_panel_io.h"
#include <esp_private/gdma.h>
#include <hal/dma_types.h>
// The Arduino_ESP32LCD8 bus can send bytes. Sending 16-bit commands is not supported.
// Sending 16-bit pixel data is sending in msb,lsb order.
class Arduino_ESP32LCD8 : public Arduino_DataBus
{
public:
Arduino_ESP32LCD8(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
// flush _cmd and _buffer
void flushBuffer();
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
uint32_t _csPinMask; ///< Bitmask for chip select
esp_lcd_i80_bus_handle_t _i80_bus = nullptr;
esp_lcd_panel_io_handle_t _io_handle = nullptr;
dma_descriptor_t *_dmadesc = nullptr;
gdma_channel_handle_t _dma_chan;
// record command and parameters in _cmd and _buffer
/// command byte for next DMA transfer
int _cmd = -1;
/// buffer is in use for color data
bool _isColor = false;
/// data size in _buffer for next DMA transfer
int _bufferLen = 0;
union
{
uint32_t value;
struct
{
uint16_t value16;
uint16_t value16_2;
};
struct
{
uint8_t lsb;
uint8_t msb;
uint8_t lsb_2;
uint8_t msb_2;
};
} _data32;
union
{
uint8_t* _buffer;
uint16_t* _buffer16;
uint32_t* _buffer32;
};
};
#endif // #if ... ESP_ARDUINO_VERSION_MAJOR
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,774 @@
#include "Arduino_ESP32PAR16.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32PAR16::Arduino_ESP32PAR16(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7),
_d8(d8), _d9(d9), _d10(d10), _d11(d11), _d12(d12), _d13(d13), _d14(d14), _d15(d15)
{
}
bool Arduino_ESP32PAR16::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
pinMode(_d0, OUTPUT);
pinMode(_d1, OUTPUT);
pinMode(_d2, OUTPUT);
pinMode(_d3, OUTPUT);
pinMode(_d4, OUTPUT);
pinMode(_d5, OUTPUT);
pinMode(_d6, OUTPUT);
pinMode(_d7, OUTPUT);
pinMode(_d8, OUTPUT);
pinMode(_d9, OUTPUT);
pinMode(_d10, OUTPUT);
pinMode(_d11, OUTPUT);
pinMode(_d12, OUTPUT);
pinMode(_d13, OUTPUT);
pinMode(_d14, OUTPUT);
pinMode(_d15, OUTPUT);
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
_data1PortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_data1PortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
_data2PortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_data2PortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
// INIT 16-bit mask
_data1ClrMask = 0;
_data2ClrMask = 0;
if (_d0 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d0);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d0);
}
if (_d1 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d1);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d1);
}
if (_d2 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d2);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d2);
}
if (_d3 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d3);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d3);
}
if (_d4 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d4);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d4);
}
if (_d5 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d5);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d5);
}
if (_d6 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d6);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d6);
}
if (_d7 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d7);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d7);
}
if (_d8 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d8);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d8);
}
if (_d9 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d9);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d9);
}
if (_d10 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d10);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d10);
}
if (_d11 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d11);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d11);
}
if (_d12 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d12);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d12);
}
if (_d13 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d13);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d13);
}
if (_d14 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d14);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d14);
}
if (_d15 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d15);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d15);
}
for (int32_t c = 0; c < 256; c++)
{
_xset_mask1_lo[c] = 0;
_xset_mask2_lo[c] = 0;
if (c & 0x01)
{
if (_d0 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d0);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d0);
}
}
if (c & 0x02)
{
if (_d1 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d1);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d1);
}
}
if (c & 0x04)
{
if (_d2 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d2);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d2);
}
}
if (c & 0x08)
{
if (_d3 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d3);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d3);
}
}
if (c & 0x10)
{
if (_d4 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d4);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d4);
}
}
if (c & 0x20)
{
if (_d5 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d5);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d5);
}
}
if (c & 0x40)
{
if (_d6 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d6);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d6);
}
}
if (c & 0x80)
{
if (_d7 >= 32)
{
_xset_mask2_lo[c] |= digitalPinToBitMask(_d7);
}
else
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d7);
}
}
}
for (int32_t c = 0; c < 256; c++)
{
_xset_mask1_hi[c] = 0;
_xset_mask2_hi[c] = 0;
if (c & 0x01)
{
if (_d8 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d8);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d8);
}
}
if (c & 0x02)
{
if (_d9 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d9);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d9);
}
}
if (c & 0x04)
{
if (_d10 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d10);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d10);
}
}
if (c & 0x08)
{
if (_d11 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d11);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d11);
}
}
if (c & 0x10)
{
if (_d12 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d12);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d12);
}
}
if (c & 0x20)
{
if (_d13 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d13);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d13);
}
}
if (c & 0x40)
{
if (_d14 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d14);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d14);
}
}
if (c & 0x80)
{
if (_d15 >= 32)
{
_xset_mask2_hi[c] |= digitalPinToBitMask(_d15);
}
else
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d15);
}
}
}
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
#else
_data1PortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_data1PortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
// INIT 16-bit mask
_data1ClrMask = 0;
_data1ClrMask |= digitalPinToBitMask(_d0);
_data1ClrMask |= digitalPinToBitMask(_d1);
_data1ClrMask |= digitalPinToBitMask(_d2);
_data1ClrMask |= digitalPinToBitMask(_d3);
_data1ClrMask |= digitalPinToBitMask(_d4);
_data1ClrMask |= digitalPinToBitMask(_d5);
_data1ClrMask |= digitalPinToBitMask(_d6);
_data1ClrMask |= digitalPinToBitMask(_d7);
_data1ClrMask |= digitalPinToBitMask(_d8);
_data1ClrMask |= digitalPinToBitMask(_d9);
_data1ClrMask |= digitalPinToBitMask(_d10);
_data1ClrMask |= digitalPinToBitMask(_d11);
_data1ClrMask |= digitalPinToBitMask(_d12);
_data1ClrMask |= digitalPinToBitMask(_d13);
_data1ClrMask |= digitalPinToBitMask(_d14);
_data1ClrMask |= digitalPinToBitMask(_d15);
for (int32_t c = 0; c < 256; c++)
{
_xset_mask1_lo[c] = 0;
if (c & 0x01)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d0);
}
if (c & 0x02)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d1);
}
if (c & 0x04)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d2);
}
if (c & 0x08)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d3);
}
if (c & 0x10)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d4);
}
if (c & 0x20)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d5);
}
if (c & 0x40)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d6);
}
if (c & 0x80)
{
_xset_mask1_lo[c] |= digitalPinToBitMask(_d7);
}
}
for (int32_t c = 0; c < 256; c++)
{
_xset_mask1_hi[c] = 0;
if (c & 0x01)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d8);
}
if (c & 0x02)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d9);
}
if (c & 0x04)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d10);
}
if (c & 0x08)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d11);
}
if (c & 0x10)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d12);
}
if (c & 0x20)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d13);
}
if (c & 0x40)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d14);
}
if (c & 0x80)
{
_xset_mask1_hi[c] |= digitalPinToBitMask(_d15);
}
}
*_data1PortClr = _data1ClrMask;
#endif
return true;
}
void Arduino_ESP32PAR16::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32PAR16::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32PAR16::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32PAR16::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_ESP32PAR16::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32PAR16::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32PAR16::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_ESP32PAR16::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
uint32_t d1 = _xset_mask1_hi[_data16.msb] | _xset_mask1_lo[_data16.lsb];
uint32_t d2 = _xset_mask2_hi[_data16.msb] | _xset_mask2_lo[_data16.lsb];
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = d1;
*_data2PortSet = d2;
#else
uint32_t d1 = _xset_mask1_hi[_data16.msb] | _xset_mask1_lo[_data16.lsb];
*_data1PortClr = _data1ClrMask;
*_data1PortSet = d1;
#endif
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
void Arduino_ESP32PAR16::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
void Arduino_ESP32PAR16::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32PAR16::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_ESP32PAR16::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_ESP32PAR16::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR16::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE(*data);
}
}
void Arduino_ESP32PAR16::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
WRITE16(idx[*data++]);
}
}
void Arduino_ESP32PAR16::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = _xset_mask1_hi[_data16.msb] | _xset_mask1_lo[_data16.lsb];
*_data2PortSet = _xset_mask2_hi[_data16.msb] | _xset_mask2_lo[_data16.lsb];
#else
*_data1PortClr = _data1ClrMask;
*_data1PortSet = _xset_mask1_hi[_data16.msb] | _xset_mask1_lo[_data16.lsb];
#endif
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR16::WRITE(uint8_t d)
{
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = _xset_mask1_lo[d];
*_data2PortSet = _xset_mask2_lo[d];
#else
*_data1PortClr = _data1ClrMask;
*_data1PortSet = _xset_mask1_lo[d];
#endif
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16::WRITE16(uint16_t d)
{
_data16.value = d;
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
uint32_t d1 = _xset_mask1_hi[_data16.msb] | _xset_mask1_lo[_data16.lsb];
uint32_t d2 = _xset_mask2_hi[_data16.msb] | _xset_mask2_lo[_data16.lsb];
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = d1;
*_data2PortSet = d2;
#else
uint32_t d1 = _xset_mask1_hi[_data16.msb] | _xset_mask1_lo[_data16.lsb];
*_data1PortClr = _data1ClrMask;
*_data1PortSet = d1;
#endif
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32PAR16::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR16::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,81 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#ifndef _ARDUINO_ESP32PAR16_H_
#define _ARDUINO_ESP32PAR16_H_
class Arduino_ESP32PAR16 : public Arduino_DataBus
{
public:
Arduino_ESP32PAR16(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
int8_t _d8, _d9, _d10, _d11, _d12, _d13, _d14, _d15;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _data1PortSet;
PORTreg_t _data1PortClr;
uint32_t _data1ClrMask;
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
PORTreg_t _data2PortSet;
PORTreg_t _data2PortClr;
uint32_t _data2ClrMask;
#endif
// Lookup table for ESP32 parallel bus interface uses 4kbyte RAM
uint32_t _xset_mask1_lo[256];
uint32_t _xset_mask1_hi[256];
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
uint32_t _xset_mask2_lo[256];
uint32_t _xset_mask2_hi[256];
#endif
};
#endif // _ARDUINO_ESP32PAR16_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,396 @@
#include "Arduino_ESP32PAR16Q.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32PAR16Q::Arduino_ESP32PAR16Q(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7),
_d8(d8), _d9(d9), _d10(d10), _d11(d11), _d12(d12), _d13(d13), _d14(d14), _d15(d15)
{
}
bool Arduino_ESP32PAR16Q::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
// TODO: check pin range 0-31
pinMode(_d0, OUTPUT);
pinMode(_d1, OUTPUT);
pinMode(_d2, OUTPUT);
pinMode(_d3, OUTPUT);
pinMode(_d4, OUTPUT);
pinMode(_d5, OUTPUT);
pinMode(_d6, OUTPUT);
pinMode(_d7, OUTPUT);
pinMode(_d8, OUTPUT);
pinMode(_d9, OUTPUT);
pinMode(_d10, OUTPUT);
pinMode(_d11, OUTPUT);
pinMode(_d12, OUTPUT);
pinMode(_d13, OUTPUT);
pinMode(_d14, OUTPUT);
pinMode(_d15, OUTPUT);
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
// INIT 16-bit mask
_dataClrMask = (1 << _wr) | (1 << _d0) | (1 << _d1) | (1 << _d2) | (1 << _d3) | (1 << _d4) | (1 << _d5) | (1 << _d6) | (1 << _d7) | (1 << _d8) | (1 << _d9) | (1 << _d10) | (1 << _d11) | (1 << _d12) | (1 << _d13) | (1 << _d14) | (1 << _d15);
for (int32_t c = 0; c < 256; c++)
{
_xset_mask_lo[c] = 0;
if (c & 0x01)
{
_xset_mask_lo[c] |= (1 << _d0);
}
if (c & 0x02)
{
_xset_mask_lo[c] |= (1 << _d1);
}
if (c & 0x04)
{
_xset_mask_lo[c] |= (1 << _d2);
}
if (c & 0x08)
{
_xset_mask_lo[c] |= (1 << _d3);
}
if (c & 0x10)
{
_xset_mask_lo[c] |= (1 << _d4);
}
if (c & 0x20)
{
_xset_mask_lo[c] |= (1 << _d5);
}
if (c & 0x40)
{
_xset_mask_lo[c] |= (1 << _d6);
}
if (c & 0x80)
{
_xset_mask_lo[c] |= (1 << _d7);
}
}
for (int32_t c = 0; c < 256; c++)
{
_xset_mask_hi[c] = 0;
if (c & 0x01)
{
_xset_mask_hi[c] |= (1 << _d8);
}
if (c & 0x02)
{
_xset_mask_hi[c] |= (1 << _d9);
}
if (c & 0x04)
{
_xset_mask_hi[c] |= (1 << _d10);
}
if (c & 0x08)
{
_xset_mask_hi[c] |= (1 << _d11);
}
if (c & 0x10)
{
_xset_mask_hi[c] |= (1 << _d12);
}
if (c & 0x20)
{
_xset_mask_hi[c] |= (1 << _d13);
}
if (c & 0x40)
{
_xset_mask_hi[c] |= (1 << _d14);
}
if (c & 0x80)
{
_xset_mask_hi[c] |= (1 << _d15);
}
}
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32PAR16Q::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32PAR16Q::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32PAR16Q::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32PAR16Q::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_ESP32PAR16Q::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32PAR16Q::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32PAR16Q::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_ESP32PAR16Q::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
uint32_t d = _xset_mask_hi[_data16.msb] | _xset_mask_lo[_data16.lsb];
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
void Arduino_ESP32PAR16Q::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
void Arduino_ESP32PAR16Q::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32PAR16Q::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_ESP32PAR16Q::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_ESP32PAR16Q::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR16Q::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE(*data);
}
}
void Arduino_ESP32PAR16Q::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
WRITE16(idx[*data++]);
}
}
void Arduino_ESP32PAR16Q::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
*_dataPortClr = _dataClrMask;
*_dataPortSet = _xset_mask_hi[_data16.msb] | _xset_mask_lo[_data16.lsb];
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR16Q::WRITE(uint8_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = _xset_mask_lo[d];
*_wrPortSet = _wrPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16Q::WRITE16(uint16_t d)
{
_data16.value = d;
*_dataPortClr = _dataClrMask;
*_dataPortSet = _xset_mask_hi[_data16.msb] | _xset_mask_lo[_data16.lsb];
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32PAR16Q::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16Q::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16Q::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR16Q::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,71 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#ifndef _ARDUINO_ESP32PAR16Q_H_
#define _ARDUINO_ESP32PAR16Q_H_
class Arduino_ESP32PAR16Q : public Arduino_DataBus
{
public:
Arduino_ESP32PAR16Q(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
int8_t _d8, _d9, _d10, _d11, _d12, _d13, _d14, _d15;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet;
PORTreg_t _dataPortClr;
uint32_t _dataClrMask;
// Lookup table for ESP32 parallel bus interface uses 2kbyte RAM,
uint32_t _xset_mask_lo[256];
uint32_t _xset_mask_hi[256];
};
#endif // _ARDUINO_ESP32PAR16Q_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,391 @@
#include "Arduino_ESP32PAR16QQ.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32PAR16QQ::Arduino_ESP32PAR16QQ(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7),
_d8(d8), _d9(d9), _d10(d10), _d11(d11), _d12(d12), _d13(d13), _d14(d14), _d15(d15)
{
}
bool Arduino_ESP32PAR16QQ::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
// TODO: check pin range 0-31
pinMode(_d0, OUTPUT);
pinMode(_d1, OUTPUT);
pinMode(_d2, OUTPUT);
pinMode(_d3, OUTPUT);
pinMode(_d4, OUTPUT);
pinMode(_d5, OUTPUT);
pinMode(_d6, OUTPUT);
pinMode(_d7, OUTPUT);
pinMode(_d8, OUTPUT);
pinMode(_d9, OUTPUT);
pinMode(_d10, OUTPUT);
pinMode(_d11, OUTPUT);
pinMode(_d12, OUTPUT);
pinMode(_d13, OUTPUT);
pinMode(_d14, OUTPUT);
pinMode(_d15, OUTPUT);
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
// INIT 16-bit mask
_dataClrMask = (1 << _wr) | (1 << _d0) | (1 << _d1) | (1 << _d2) | (1 << _d3) | (1 << _d4) | (1 << _d5) | (1 << _d6) | (1 << _d7) | (1 << _d8) | (1 << _d9) | (1 << _d10) | (1 << _d11) | (1 << _d12) | (1 << _d13) | (1 << _d14) | (1 << _d15);
for (int32_t c = 0; c < 256; c++)
{
_xset_mask_lo[c] = (1 << _wr);
if (c & 0x01)
{
_xset_mask_lo[c] |= (1 << _d0);
}
if (c & 0x02)
{
_xset_mask_lo[c] |= (1 << _d1);
}
if (c & 0x04)
{
_xset_mask_lo[c] |= (1 << _d2);
}
if (c & 0x08)
{
_xset_mask_lo[c] |= (1 << _d3);
}
if (c & 0x10)
{
_xset_mask_lo[c] |= (1 << _d4);
}
if (c & 0x20)
{
_xset_mask_lo[c] |= (1 << _d5);
}
if (c & 0x40)
{
_xset_mask_lo[c] |= (1 << _d6);
}
if (c & 0x80)
{
_xset_mask_lo[c] |= (1 << _d7);
}
}
for (int32_t c = 0; c < 256; c++)
{
_xset_mask_hi[c] = 0;
if (c & 0x01)
{
_xset_mask_hi[c] |= (1 << _d8);
}
if (c & 0x02)
{
_xset_mask_hi[c] |= (1 << _d9);
}
if (c & 0x04)
{
_xset_mask_hi[c] |= (1 << _d10);
}
if (c & 0x08)
{
_xset_mask_hi[c] |= (1 << _d11);
}
if (c & 0x10)
{
_xset_mask_hi[c] |= (1 << _d12);
}
if (c & 0x20)
{
_xset_mask_hi[c] |= (1 << _d13);
}
if (c & 0x40)
{
_xset_mask_hi[c] |= (1 << _d14);
}
if (c & 0x80)
{
_xset_mask_hi[c] |= (1 << _d15);
}
}
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32PAR16QQ::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32PAR16QQ::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32PAR16QQ::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32PAR16QQ::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_ESP32PAR16QQ::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32PAR16QQ::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32PAR16QQ::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_ESP32PAR16QQ::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
uint32_t d = _xset_mask_hi[_data16.msb] | _xset_mask_lo[_data16.lsb];
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
}
}
void Arduino_ESP32PAR16QQ::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
void Arduino_ESP32PAR16QQ::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32PAR16QQ::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_ESP32PAR16QQ::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_ESP32PAR16QQ::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR16QQ::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE(*data);
}
}
void Arduino_ESP32PAR16QQ::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
WRITE16(idx[*data++]);
}
}
void Arduino_ESP32PAR16QQ::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
*_dataPortClr = _dataClrMask;
*_dataPortSet = _xset_mask_hi[_data16.msb] | _xset_mask_lo[_data16.lsb];
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR16QQ::WRITE(uint8_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = _xset_mask_lo[d];
}
GFX_INLINE void Arduino_ESP32PAR16QQ::WRITE16(uint16_t d)
{
_data16.value = d;
*_dataPortClr = _dataClrMask;
*_dataPortSet = _xset_mask_hi[_data16.msb] | _xset_mask_lo[_data16.lsb];
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32PAR16QQ::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16QQ::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR16QQ::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR16QQ::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,71 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#ifndef _ARDUINO_ESP32PAR16QQ_H_
#define _ARDUINO_ESP32PAR16QQ_H_
class Arduino_ESP32PAR16QQ : public Arduino_DataBus
{
public:
Arduino_ESP32PAR16QQ(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
int8_t _d8, _d9, _d10, _d11, _d12, _d13, _d14, _d15;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet;
PORTreg_t _dataPortClr;
uint32_t _dataClrMask;
// Lookup table for ESP32 parallel bus interface uses 2kbyte RAM,
uint32_t _xset_mask_lo[256];
uint32_t _xset_mask_hi[256];
};
#endif // _ARDUINO_ESP32PAR16QQ_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,590 @@
#include "Arduino_ESP32PAR8.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32PAR8::Arduino_ESP32PAR8(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7)
{
}
bool Arduino_ESP32PAR8::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
pinMode(_d0, OUTPUT);
pinMode(_d1, OUTPUT);
pinMode(_d2, OUTPUT);
pinMode(_d3, OUTPUT);
pinMode(_d4, OUTPUT);
pinMode(_d5, OUTPUT);
pinMode(_d6, OUTPUT);
pinMode(_d7, OUTPUT);
_data1PortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_data1PortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
_data2PortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_data2PortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
#endif
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
// INIT 8-bit mask
_data1ClrMask = 0;
_data2ClrMask = 0;
if (_d0 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d0);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d0);
}
if (_d1 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d1);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d1);
}
if (_d2 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d2);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d2);
}
if (_d3 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d3);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d3);
}
if (_d4 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d4);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d4);
}
if (_d5 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d5);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d5);
}
if (_d6 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d6);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d6);
}
if (_d7 >= 32)
{
_data2ClrMask |= digitalPinToBitMask(_d7);
}
else
{
_data1ClrMask |= digitalPinToBitMask(_d7);
}
for (int32_t c = 0; c < 256; c++)
{
_xset_mask1[c] = 0;
_xset_mask2[c] = 0;
if (c & 0x01)
{
if (_d0 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d0);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d0);
}
}
if (c & 0x02)
{
if (_d1 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d1);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d1);
}
}
if (c & 0x04)
{
if (_d2 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d2);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d2);
}
}
if (c & 0x08)
{
if (_d3 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d3);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d3);
}
}
if (c & 0x10)
{
if (_d4 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d4);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d4);
}
}
if (c & 0x20)
{
if (_d5 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d5);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d5);
}
}
if (c & 0x40)
{
if (_d6 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d6);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d6);
}
}
if (c & 0x80)
{
if (_d7 >= 32)
{
_xset_mask2[c] |= digitalPinToBitMask(_d7);
}
else
{
_xset_mask1[c] |= digitalPinToBitMask(_d7);
}
}
}
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
#else
// INIT 8-bit mask
_data1ClrMask = 0;
_data1ClrMask |= digitalPinToBitMask(_d0);
_data1ClrMask |= digitalPinToBitMask(_d1);
_data1ClrMask |= digitalPinToBitMask(_d2);
_data1ClrMask |= digitalPinToBitMask(_d3);
_data1ClrMask |= digitalPinToBitMask(_d4);
_data1ClrMask |= digitalPinToBitMask(_d5);
_data1ClrMask |= digitalPinToBitMask(_d6);
_data1ClrMask |= digitalPinToBitMask(_d7);
for (int32_t c = 0; c < 256; c++)
{
_xset_mask1[c] = 0;
if (c & 0x01)
{
_xset_mask1[c] |= digitalPinToBitMask(_d0);
}
if (c & 0x02)
{
_xset_mask1[c] |= digitalPinToBitMask(_d1);
}
if (c & 0x04)
{
_xset_mask1[c] |= digitalPinToBitMask(_d2);
}
if (c & 0x08)
{
_xset_mask1[c] |= digitalPinToBitMask(_d3);
}
if (c & 0x10)
{
_xset_mask1[c] |= digitalPinToBitMask(_d4);
}
if (c & 0x20)
{
_xset_mask1[c] |= digitalPinToBitMask(_d5);
}
if (c & 0x40)
{
_xset_mask1[c] |= digitalPinToBitMask(_d6);
}
if (c & 0x80)
{
_xset_mask1[c] |= digitalPinToBitMask(_d7);
}
}
*_data1PortClr = _data1ClrMask;
#endif
return true;
}
void Arduino_ESP32PAR8::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32PAR8::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32PAR8::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32PAR8::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_ESP32PAR8::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32PAR8::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32PAR8::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
uint32_t setMask1 = _xset_mask1[_data16.msb];
uint32_t setMask2 = _xset_mask2[_data16.msb];
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = setMask1;
*_data2PortSet = setMask2;
#else
uint32_t setMask1 = _xset_mask1[_data16.msb];
*_data1PortClr = _data1ClrMask;
*_data1PortSet = setMask1;
#endif
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
else
{
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
uint32_t hiMask1 = _xset_mask1[_data16.msb];
uint32_t hiMask2 = _xset_mask2[_data16.msb];
uint32_t loMask1 = _xset_mask1[_data16.lsb];
uint32_t loMask2 = _xset_mask2[_data16.lsb];
while (len--)
{
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = hiMask1;
*_data2PortSet = hiMask2;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = loMask1;
*_data2PortSet = loMask2;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
#else
uint32_t hiMask1 = _xset_mask1[_data16.msb];
uint32_t loMask1 = _xset_mask1[_data16.lsb];
while (len--)
{
*_data1PortClr = _data1ClrMask;
*_data1PortSet = hiMask1;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_data1PortClr = _data1ClrMask;
*_data1PortSet = loMask1;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
#endif
}
}
void Arduino_ESP32PAR8::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32PAR8::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_ESP32PAR8::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_ESP32PAR8::WRITE(uint8_t d)
{
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
uint32_t setMask1 = _xset_mask1[d];
uint32_t setMask2 = _xset_mask2[d];
*_data1PortClr = _data1ClrMask;
*_data2PortClr = _data2ClrMask;
*_data1PortSet = setMask1;
*_data2PortSet = setMask2;
#else
uint32_t setMask1 = _xset_mask1[d];
*_data1PortClr = _data1ClrMask;
*_data1PortSet = setMask1;
#endif
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32PAR8::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR8::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,75 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#ifndef _ARDUINO_ESP32PAR8_H_
#define _ARDUINO_ESP32PAR8_H_
class Arduino_ESP32PAR8 : public Arduino_DataBus
{
public:
Arduino_ESP32PAR8(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _data1PortSet;
PORTreg_t _data1PortClr;
uint32_t _data1ClrMask;
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
PORTreg_t _data2PortSet;
PORTreg_t _data2PortClr;
uint32_t _data2ClrMask;
#endif
// Lookup table for ESP32 parallel bus interface uses 1kbyte RAM,
uint32_t _xset_mask1[256];
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
uint32_t _xset_mask2[256];
#endif
};
#endif // _ARDUINO_ESP32PAR8_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,385 @@
#include "Arduino_ESP32PAR8Q.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32PAR8Q::Arduino_ESP32PAR8Q(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7)
{
}
bool Arduino_ESP32PAR8Q::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
// TODO: check pin range 0-31
pinMode(_d0, OUTPUT);
pinMode(_d1, OUTPUT);
pinMode(_d2, OUTPUT);
pinMode(_d3, OUTPUT);
pinMode(_d4, OUTPUT);
pinMode(_d5, OUTPUT);
pinMode(_d6, OUTPUT);
pinMode(_d7, OUTPUT);
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_d0 >= 32)
{
_dataPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
// INIT 8-bit mask
_dataClrMask = digitalPinToBitMask(_d0) | digitalPinToBitMask(_d1) | digitalPinToBitMask(_d2) | digitalPinToBitMask(_d3) | digitalPinToBitMask(_d4) | digitalPinToBitMask(_d5) | digitalPinToBitMask(_d6) | digitalPinToBitMask(_d7);
for (int32_t c = 0; c < 256; c++)
{
_xset_mask[c] = 0;
if (c & 0x01)
{
_xset_mask[c] |= digitalPinToBitMask(_d0);
}
if (c & 0x02)
{
_xset_mask[c] |= digitalPinToBitMask(_d1);
}
if (c & 0x04)
{
_xset_mask[c] |= digitalPinToBitMask(_d2);
}
if (c & 0x08)
{
_xset_mask[c] |= digitalPinToBitMask(_d3);
}
if (c & 0x10)
{
_xset_mask[c] |= digitalPinToBitMask(_d4);
}
if (c & 0x20)
{
_xset_mask[c] |= digitalPinToBitMask(_d5);
}
if (c & 0x40)
{
_xset_mask[c] |= digitalPinToBitMask(_d6);
}
if (c & 0x80)
{
_xset_mask[c] |= digitalPinToBitMask(_d7);
}
}
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32PAR8Q::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32PAR8Q::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32PAR8Q::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32PAR8Q::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_ESP32PAR8Q::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32PAR8Q::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32PAR8Q::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8Q::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
uint32_t setMask = _xset_mask[_data16.msb];
*_dataPortClr = _dataClrMask;
*_dataPortSet = setMask;
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
else
{
uint32_t hiMask = _xset_mask[_data16.msb];
uint32_t loMask = _xset_mask[_data16.lsb];
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = hiMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_dataPortClr = _dataClrMask;
*_dataPortSet = loMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
}
void Arduino_ESP32PAR8Q::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8Q::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32PAR8Q::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8Q::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8Q::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8Q::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_ESP32PAR8Q::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8Q::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_ESP32PAR8Q::WRITE(uint8_t d)
{
uint32_t setMask = _xset_mask[d];
*_dataPortClr = _dataClrMask;
*_dataPortSet = setMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32PAR8Q::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8Q::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8Q::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR8Q::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,67 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#ifndef _ARDUINO_ESP32PAR8Q_H_
#define _ARDUINO_ESP32PAR8Q_H_
class Arduino_ESP32PAR8Q : public Arduino_DataBus
{
public:
Arduino_ESP32PAR8Q(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet;
PORTreg_t _dataPortClr;
uint32_t _dataClrMask;
// Lookup table for ESP32 parallel bus interface uses 1kbyte RAM,
uint32_t _xset_mask[256];
};
#endif // _ARDUINO_ESP32PAR8Q_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,385 @@
#include "Arduino_ESP32PAR8QQ.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32PAR8QQ::Arduino_ESP32PAR8QQ(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7)
{
}
bool Arduino_ESP32PAR8QQ::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
// TODO: check pin range 0-31
pinMode(_d0, OUTPUT);
pinMode(_d1, OUTPUT);
pinMode(_d2, OUTPUT);
pinMode(_d3, OUTPUT);
pinMode(_d4, OUTPUT);
pinMode(_d5, OUTPUT);
pinMode(_d6, OUTPUT);
pinMode(_d7, OUTPUT);
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_d0 >= 32)
{
_dataPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
// INIT 8-bit mask
_dataClrMask = digitalPinToBitMask(_d0) | digitalPinToBitMask(_d1) | digitalPinToBitMask(_d2) | digitalPinToBitMask(_d3) | digitalPinToBitMask(_d4) | digitalPinToBitMask(_d5) | digitalPinToBitMask(_d6) | digitalPinToBitMask(_d7);
for (int32_t c = 0; c < 256; c++)
{
_xset_mask[c] = 0;
if (c & 0x01)
{
_xset_mask[c] |= digitalPinToBitMask(_d0);
}
if (c & 0x02)
{
_xset_mask[c] |= digitalPinToBitMask(_d1);
}
if (c & 0x04)
{
_xset_mask[c] |= digitalPinToBitMask(_d2);
}
if (c & 0x08)
{
_xset_mask[c] |= digitalPinToBitMask(_d3);
}
if (c & 0x10)
{
_xset_mask[c] |= digitalPinToBitMask(_d4);
}
if (c & 0x20)
{
_xset_mask[c] |= digitalPinToBitMask(_d5);
}
if (c & 0x40)
{
_xset_mask[c] |= digitalPinToBitMask(_d6);
}
if (c & 0x80)
{
_xset_mask[c] |= digitalPinToBitMask(_d7);
}
}
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32PAR8QQ::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32PAR8QQ::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32PAR8QQ::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32PAR8QQ::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_ESP32PAR8QQ::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32PAR8QQ::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32PAR8QQ::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQ::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
uint32_t setMask = _xset_mask[_data16.msb];
*_dataPortClr = _dataClrMask;
*_dataPortSet = setMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
while (--len)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
else
{
uint32_t hiMask = _xset_mask[_data16.msb];
uint32_t loMask = _xset_mask[_data16.lsb];
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = hiMask;
*_wrPortSet = _wrPinMask;
*_dataPortClr = _dataClrMask;
*_dataPortSet = loMask;
*_wrPortSet = _wrPinMask;
}
}
}
void Arduino_ESP32PAR8QQ::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8QQ::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32PAR8QQ::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQ::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQ::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQ::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_ESP32PAR8QQ::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8QQ::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_ESP32PAR8QQ::WRITE(uint8_t d)
{
uint32_t setMask = _xset_mask[d];
*_dataPortClr = _dataClrMask;
*_dataPortSet = setMask;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32PAR8QQ::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8QQ::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8QQ::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR8QQ::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,67 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#ifndef _ARDUINO_ESP32PAR8QQ_H_
#define _ARDUINO_ESP32PAR8QQ_H_
class Arduino_ESP32PAR8QQ : public Arduino_DataBus
{
public:
Arduino_ESP32PAR8QQ(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet;
PORTreg_t _dataPortClr;
uint32_t _dataClrMask;
// Lookup table for ESP32 parallel bus interface uses 1kbyte RAM,
uint32_t _xset_mask[256];
};
#endif // _ARDUINO_ESP32PAR8QQ_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,379 @@
#include "Arduino_ESP32PAR8QQQ.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32PAR8QQQ::Arduino_ESP32PAR8QQQ(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7)
{
}
bool Arduino_ESP32PAR8QQQ::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
// TODO: check pin range 0-31
pinMode(_d0, OUTPUT);
pinMode(_d1, OUTPUT);
pinMode(_d2, OUTPUT);
pinMode(_d3, OUTPUT);
pinMode(_d4, OUTPUT);
pinMode(_d5, OUTPUT);
pinMode(_d6, OUTPUT);
pinMode(_d7, OUTPUT);
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_d0 >= 32)
{
_dataPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
// INIT 8-bit mask
_dataClrMask = digitalPinToBitMask(_d0) | digitalPinToBitMask(_d1) | digitalPinToBitMask(_d2) | digitalPinToBitMask(_d3) | digitalPinToBitMask(_d4) | digitalPinToBitMask(_d5) | digitalPinToBitMask(_d6) | digitalPinToBitMask(_d7);
for (int32_t c = 0; c < 256; c++)
{
_xset_mask[c] = digitalPinToBitMask(_wr);
if (c & 0x01)
{
_xset_mask[c] |= digitalPinToBitMask(_d0);
}
if (c & 0x02)
{
_xset_mask[c] |= digitalPinToBitMask(_d1);
}
if (c & 0x04)
{
_xset_mask[c] |= digitalPinToBitMask(_d2);
}
if (c & 0x08)
{
_xset_mask[c] |= digitalPinToBitMask(_d3);
}
if (c & 0x10)
{
_xset_mask[c] |= digitalPinToBitMask(_d4);
}
if (c & 0x20)
{
_xset_mask[c] |= digitalPinToBitMask(_d5);
}
if (c & 0x40)
{
_xset_mask[c] |= digitalPinToBitMask(_d6);
}
if (c & 0x80)
{
_xset_mask[c] |= digitalPinToBitMask(_d7);
}
}
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32PAR8QQQ::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32PAR8QQQ::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32PAR8QQQ::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32PAR8QQQ::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_ESP32PAR8QQQ::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32PAR8QQQ::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32PAR8QQQ::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQQ::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
uint32_t setMask = _xset_mask[_data16.msb];
*_dataPortClr = _dataClrMask;
*_dataPortSet = setMask;
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
else
{
uint32_t hiMask = _xset_mask[_data16.msb];
uint32_t loMask = _xset_mask[_data16.lsb];
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = hiMask;
*_dataPortClr = _dataClrMask;
*_dataPortSet = loMask;
}
}
}
void Arduino_ESP32PAR8QQQ::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8QQQ::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32PAR8QQQ::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQQ::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQQ::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32PAR8QQQ::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_ESP32PAR8QQQ::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32PAR8QQQ::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_ESP32PAR8QQQ::WRITE(uint8_t d)
{
uint32_t setMask = _xset_mask[d];
*_dataPortClr = _dataClrMask;
*_dataPortSet = setMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32PAR8QQQ::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8QQQ::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32PAR8QQQ::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32PAR8QQQ::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,67 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#ifndef _ARDUINO_ESP32PAR8QQQ_H_
#define _ARDUINO_ESP32PAR8QQQ_H_
class Arduino_ESP32PAR8QQQ : public Arduino_DataBus
{
public:
Arduino_ESP32PAR8QQQ(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet;
PORTreg_t _dataPortClr;
uint32_t _dataClrMask;
// Lookup table for ESP32 parallel bus interface uses 1kbyte RAM,
uint32_t _xset_mask[256];
};
#endif // _ARDUINO_ESP32PAR8QQQ_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,700 @@
#include "Arduino_ESP32QSPI.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
Arduino_ESP32QSPI::Arduino_ESP32QSPI(
int8_t cs, int8_t sck, int8_t mosi, int8_t miso, int8_t quadwp, int8_t quadhd, bool is_shared_interface /* = false */)
: _cs(cs), _sck(sck), _mosi(mosi), _miso(miso), _quadwp(quadwp), _quadhd(quadhd), _is_shared_interface(is_shared_interface)
{
}
bool Arduino_ESP32QSPI::begin(int32_t speed, int8_t dataMode)
{
// set SPI parameters
_speed = (speed <= GFX_NOT_DEFINED) ? ESP32QSPI_FREQUENCY : speed;
_dataMode = (dataMode == GFX_NOT_DEFINED) ? ESP32QSPI_SPI_MODE : dataMode;
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
if (speed != GFX_SKIP_DATABUS_UNDERLAYING_BEGIN)
{
spi_bus_config_t buscfg = {
.mosi_io_num = _mosi,
.miso_io_num = _miso,
.sclk_io_num = _sck,
.quadwp_io_num = _quadwp,
.quadhd_io_num = _quadhd,
.data4_io_num = -1,
.data5_io_num = -1,
.data6_io_num = -1,
.data7_io_num = -1,
.max_transfer_sz = (ESP32QSPI_MAX_PIXELS_AT_ONCE * 16) + 8,
.flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_GPIO_PINS,
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
// skip this
#else
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
#endif
.intr_flags = 0};
esp_err_t ret = spi_bus_initialize(ESP32QSPI_SPI_HOST, &buscfg, ESP32QSPI_DMA_CHANNEL);
if (ret != ESP_OK)
{
ESP_ERROR_CHECK(ret);
return false;
}
}
spi_device_interface_config_t devcfg = {
.command_bits = 8,
.address_bits = 24,
.dummy_bits = 0,
.mode = (uint8_t)_dataMode,
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
.clock_source = SPI_CLK_SRC_DEFAULT,
#endif
.duty_cycle_pos = 0,
.cs_ena_pretrans = 0,
.cs_ena_posttrans = 0,
.clock_speed_hz = _speed,
.input_delay_ns = 0,
.spics_io_num = -1, // avoid use system CS control
.flags = SPI_DEVICE_HALFDUPLEX,
.queue_size = 1,
.pre_cb = nullptr,
.post_cb = nullptr};
esp_err_t ret = spi_bus_add_device(ESP32QSPI_SPI_HOST, &devcfg, &_handle);
if (ret != ESP_OK)
{
ESP_ERROR_CHECK(ret);
return false;
}
if (!_is_shared_interface)
{
spi_device_acquire_bus(_handle, portMAX_DELAY);
}
memset(&_spi_tran_ext, 0, sizeof(_spi_tran_ext));
_spi_tran = (spi_transaction_t *)&_spi_tran_ext;
_buffer = (uint8_t *)heap_caps_aligned_alloc(16, ESP32QSPI_MAX_PIXELS_AT_ONCE * 2, MALLOC_CAP_DMA);
if (!_buffer)
{
return false;
}
_2nd_buffer = (uint8_t *)heap_caps_aligned_alloc(16, ESP32QSPI_MAX_PIXELS_AT_ONCE * 2, MALLOC_CAP_DMA);
if (!_2nd_buffer)
{
return false;
}
return true;
}
void Arduino_ESP32QSPI::beginWrite()
{
if (_is_shared_interface)
{
spi_device_acquire_bus(_handle, portMAX_DELAY);
}
}
void Arduino_ESP32QSPI::endWrite()
{
if (_is_shared_interface)
{
spi_device_release_bus(_handle);
}
}
void Arduino_ESP32QSPI::writeCommand(uint8_t c)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.cmd = 0x02;
_spi_tran_ext.base.addr = ((uint32_t)c) << 8;
_spi_tran_ext.base.tx_buffer = NULL;
_spi_tran_ext.base.length = 0;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeCommand16(uint16_t c)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.cmd = 0x02;
_spi_tran_ext.base.addr = c;
_spi_tran_ext.base.tx_buffer = NULL;
_spi_tran_ext.base.length = 0;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
CS_LOW();
uint32_t l;
while (len)
{
l = (len >= (ESP32QSPI_MAX_PIXELS_AT_ONCE << 1)) ? (ESP32QSPI_MAX_PIXELS_AT_ONCE << 1) : len;
_spi_tran_ext.base.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.tx_buffer = data;
_spi_tran_ext.base.length = l << 3;
POLL_START();
POLL_END();
len -= l;
data += l;
}
CS_HIGH();
}
void Arduino_ESP32QSPI::write(uint8_t d)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
_spi_tran_ext.base.tx_data[0] = d;
_spi_tran_ext.base.length = 8;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::write16(uint16_t d)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
_spi_tran_ext.base.tx_data[0] = d >> 8;
_spi_tran_ext.base.tx_data[1] = d;
_spi_tran_ext.base.length = 16;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeC8D8(uint8_t c, uint8_t d)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.cmd = 0x02;
_spi_tran_ext.base.addr = ((uint32_t)c) << 8;
_spi_tran_ext.base.tx_data[0] = d;
_spi_tran_ext.base.length = 8;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeC8D16(uint8_t c, uint16_t d)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.cmd = 0x02;
_spi_tran_ext.base.addr = ((uint32_t)c) << 8;
_spi_tran_ext.base.tx_data[0] = d >> 8;
_spi_tran_ext.base.tx_data[1] = d;
_spi_tran_ext.base.length = 16;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.cmd = 0x02;
_spi_tran_ext.base.addr = ((uint32_t)c) << 8;
_spi_tran_ext.base.tx_data[0] = d1 >> 8;
_spi_tran_ext.base.tx_data[1] = d1;
_spi_tran_ext.base.tx_data[2] = d2 >> 8;
_spi_tran_ext.base.tx_data[3] = d2;
_spi_tran_ext.base.length = 32;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.cmd = 0x02;
_spi_tran_ext.base.addr = ((uint32_t)c) << 8;
_spi_tran_ext.base.tx_data[0] = d1 >> 8;
_spi_tran_ext.base.tx_data[1] = d1;
_spi_tran_ext.base.tx_data[2] = d2 >> 8;
_spi_tran_ext.base.tx_data[3] = d2;
_spi_tran_ext.base.length = 32;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeC8Bytes(uint8_t c, uint8_t *data, uint32_t len)
{
CS_LOW();
_spi_tran_ext.base.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
_spi_tran_ext.base.cmd = 0x02;
_spi_tran_ext.base.addr = ((uint32_t)c) << 8;
_spi_tran_ext.base.tx_buffer = data;
_spi_tran_ext.base.length = len << 3;
POLL_START();
POLL_END();
CS_HIGH();
}
void Arduino_ESP32QSPI::writeRepeat(uint16_t p, uint32_t len)
{
bool first_send = true;
uint16_t bufLen = (len >= ESP32QSPI_MAX_PIXELS_AT_ONCE) ? ESP32QSPI_MAX_PIXELS_AT_ONCE : len;
int16_t xferLen, l;
uint32_t c32;
MSB_32_16_16_SET(c32, p, p);
l = (bufLen + 1) / 2;
for (uint32_t i = 0; i < l; i++)
{
_buffer32[i] = c32;
}
CS_LOW();
// Issue pixels in blocks from temp buffer
while (len) // While pixels remain
{
xferLen = (bufLen <= len) ? bufLen : len; // How many this pass?
if (first_send)
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
first_send = false;
}
else
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
}
_spi_tran_ext.base.tx_buffer = _buffer16;
_spi_tran_ext.base.length = xferLen << 4;
POLL_START();
POLL_END();
len -= xferLen;
}
CS_HIGH();
}
void Arduino_ESP32QSPI::writePixels(uint16_t *data, uint32_t len)
{
CS_LOW();
uint32_t l, l2;
uint16_t p1, p2;
bool first_send = true;
while (len)
{
l = (len > ESP32QSPI_MAX_PIXELS_AT_ONCE) ? ESP32QSPI_MAX_PIXELS_AT_ONCE : len;
if (first_send)
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
first_send = false;
}
else
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
}
l2 = l >> 1;
for (uint32_t i = 0; i < l2; ++i)
{
p1 = *data++;
p2 = *data++;
MSB_32_16_16_SET(_buffer32[i], p1, p2);
}
if (l & 1)
{
p1 = *data++;
MSB_16_SET(_buffer16[l - 1], p1);
}
_spi_tran_ext.base.tx_buffer = _buffer32;
_spi_tran_ext.base.length = l << 4;
POLL_START();
POLL_END();
len -= l;
}
CS_HIGH();
}
void Arduino_ESP32QSPI::batchOperation(const uint8_t *operations, size_t len)
{
for (size_t i = 0; i < len; ++i)
{
uint8_t l = 0;
switch (operations[i])
{
case BEGIN_WRITE:
beginWrite();
break;
case WRITE_COMMAND_8:
writeCommand(operations[++i]);
break;
case WRITE_COMMAND_16:
_data16.msb = operations[++i];
_data16.lsb = operations[++i];
writeCommand16(_data16.value);
break;
case WRITE_DATA_8:
write(operations[++i]);
break;
case WRITE_DATA_16:
_data16.msb = operations[++i];
_data16.lsb = operations[++i];
write16(_data16.value);
break;
case WRITE_BYTES:
l = operations[++i];
memcpy(_buffer, operations + i + 1, l);
i += l;
writeBytes(_buffer, l);
break;
case WRITE_C8_D8:
l = operations[++i];
writeC8D8(l, operations[++i]);
break;
case WRITE_C8_D16:
l = operations[++i];
_data16.msb = operations[++i];
_data16.lsb = operations[++i];
writeC8D16(l, _data16.value);
break;
case WRITE_C8_BYTES:
{
uint8_t c = operations[++i];
l = operations[++i];
memcpy(_buffer, operations + i + 1, l);
i += l;
writeC8Bytes(c, _buffer, l);
}
break;
case WRITE_C16_D16:
break;
case END_WRITE:
endWrite();
break;
case DELAY:
delay(operations[++i]);
break;
default:
printf("Unknown operation id at %d: %d\n", i, operations[i]);
break;
}
}
}
void Arduino_ESP32QSPI::writeBytes(uint8_t *data, uint32_t len)
{
CS_LOW();
uint32_t l;
bool first_send = true;
while (len)
{
l = (len >= (ESP32QSPI_MAX_PIXELS_AT_ONCE << 1)) ? (ESP32QSPI_MAX_PIXELS_AT_ONCE << 1) : len;
if (first_send)
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
first_send = false;
}
else
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
}
_spi_tran_ext.base.tx_buffer = data;
_spi_tran_ext.base.length = l << 3;
POLL_START();
POLL_END();
len -= l;
data += l;
}
CS_HIGH();
}
void Arduino_ESP32QSPI::write16bitBeRGBBitmapR1(uint16_t *bitmap, int16_t w, int16_t h)
{
if (h > ESP32QSPI_MAX_PIXELS_AT_ONCE)
{
log_e("h > ESP32QSPI_MAX_PIXELS_AT_ONCE, h: %d", h);
}
else
{
CS_LOW();
uint32_t l = h << 4;
bool first_send = true;
uint16_t *p;
uint16_t *origin_offset = bitmap + ((h - 1) * w);
for (int16_t i = 0; i < w; i++)
{
if (first_send)
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
first_send = false;
}
else
{
POLL_END();
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
}
p = origin_offset + i;
for (int16_t j = 0; j < h; j++)
{
_buffer16[j] = *p;
p -= w;
}
_spi_tran_ext.base.tx_buffer = _buffer16;
_spi_tran_ext.base.length = l;
POLL_START();
}
POLL_END();
CS_HIGH();
}
}
void Arduino_ESP32QSPI::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
CS_LOW();
uint32_t l, l2;
uint16_t p1, p2;
bool first_send = true;
while (len)
{
l = (len > ESP32QSPI_MAX_PIXELS_AT_ONCE) ? ESP32QSPI_MAX_PIXELS_AT_ONCE : len;
if (first_send)
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
first_send = false;
}
else
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
}
l2 = l >> 1;
for (uint32_t i = 0; i < l2; ++i)
{
p1 = idx[*data++];
p2 = idx[*data++];
MSB_32_16_16_SET(_buffer32[i], p1, p2);
}
if (l & 1)
{
p1 = idx[*data++];
MSB_16_SET(_buffer16[l - 1], p1);
}
_spi_tran_ext.base.tx_buffer = _buffer32;
_spi_tran_ext.base.length = l << 4;
POLL_START();
POLL_END();
len -= l;
}
CS_HIGH();
}
void Arduino_ESP32QSPI::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
CS_LOW();
uint32_t l;
uint16_t p;
bool first_send = true;
while (len)
{
l = (len > (ESP32QSPI_MAX_PIXELS_AT_ONCE >> 1)) ? (ESP32QSPI_MAX_PIXELS_AT_ONCE >> 1) : len;
if (first_send)
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
first_send = false;
}
else
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
}
for (uint32_t i = 0; i < l; ++i)
{
p = idx[*data++];
MSB_32_16_16_SET(_buffer32[i], p, p);
}
_spi_tran_ext.base.tx_buffer = _buffer32;
_spi_tran_ext.base.length = l << 5;
POLL_START();
POLL_END();
len -= l;
}
CS_HIGH();
}
void Arduino_ESP32QSPI::writeYCbCrPixels(uint8_t *yData, uint8_t *cbData, uint8_t *crData, uint16_t w, uint16_t h)
{
if (w > (ESP32QSPI_MAX_PIXELS_AT_ONCE / 2))
{
Arduino_DataBus::writeYCbCrPixels(yData, cbData, crData, w, h);
}
else
{
bool first_send = true;
int cols = w >> 1;
int rows = h >> 1;
uint8_t *yData2 = yData + w;
uint16_t *dest = _buffer16;
uint16_t *dest2 = dest + w;
uint16_t out_bits = w << 5;
uint8_t pxCb, pxCr;
int16_t pxR, pxG, pxB, pxY;
CS_LOW();
for (int row = 0; row < rows; ++row)
{
for (int col = 0; col < cols; ++col)
{
pxCb = *cbData++;
pxCr = *crData++;
pxR = CR2R16[pxCr];
pxG = -CB2G16[pxCb] - CR2G16[pxCr];
pxB = CB2B16[pxCb];
pxY = Y2I16[*yData++];
*dest++ = CLIPRBE[pxY + pxR] | CLIPGBE[pxY + pxG] | CLIPBBE[pxY + pxB];
pxY = Y2I16[*yData++];
*dest++ = CLIPRBE[pxY + pxR] | CLIPGBE[pxY + pxG] | CLIPBBE[pxY + pxB];
pxY = Y2I16[*yData2++];
*dest2++ = CLIPRBE[pxY + pxR] | CLIPGBE[pxY + pxG] | CLIPBBE[pxY + pxB];
pxY = Y2I16[*yData2++];
*dest2++ = CLIPRBE[pxY + pxR] | CLIPGBE[pxY + pxG] | CLIPBBE[pxY + pxB];
}
yData += w;
yData2 += w;
if (first_send)
{
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO;
_spi_tran_ext.base.cmd = 0x32;
_spi_tran_ext.base.addr = 0x003C00;
first_send = false;
}
else
{
POLL_END();
_spi_tran_ext.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD |
SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
}
if (row & 1)
{
_spi_tran_ext.base.tx_buffer = _2nd_buffer32;
dest = _buffer16;
}
else
{
_spi_tran_ext.base.tx_buffer = _buffer32;
dest = _2nd_buffer16;
}
_spi_tran_ext.base.length = out_bits;
POLL_START();
dest2 = dest + w;
}
POLL_END();
CS_HIGH();
}
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32QSPI::CS_HIGH(void)
{
*_csPortSet = _csPinMask;
}
GFX_INLINE void Arduino_ESP32QSPI::CS_LOW(void)
{
*_csPortClr = _csPinMask;
}
GFX_INLINE void Arduino_ESP32QSPI::POLL_START()
{
spi_device_polling_start(_handle, _spi_tran, portMAX_DELAY);
}
GFX_INLINE void Arduino_ESP32QSPI::POLL_END()
{
spi_device_polling_end(_handle, portMAX_DELAY);
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,89 @@
#pragma once
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#include <driver/spi_master.h>
#ifndef ESP32QSPI_MAX_PIXELS_AT_ONCE
#define ESP32QSPI_MAX_PIXELS_AT_ONCE 1024
#endif
#ifndef ESP32QSPI_FREQUENCY
#define ESP32QSPI_FREQUENCY 40000000
#endif
#ifndef ESP32QSPI_SPI_MODE
#define ESP32QSPI_SPI_MODE SPI_MODE0
#endif
#ifndef ESP32QSPI_SPI_HOST
#define ESP32QSPI_SPI_HOST SPI2_HOST
#endif
#ifndef ESP32QSPI_DMA_CHANNEL
#define ESP32QSPI_DMA_CHANNEL SPI_DMA_CH_AUTO
#endif
class Arduino_ESP32QSPI : public Arduino_DataBus
{
public:
Arduino_ESP32QSPI(
int8_t cs, int8_t sck, int8_t mosi, int8_t miso, int8_t quadwp, int8_t quadhd, bool is_shared_interface = false); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8Bytes(uint8_t c, uint8_t *data, uint32_t len);
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void write16bitBeRGBBitmapR1(uint16_t *bitmap, int16_t w, int16_t h) override;
void batchOperation(const uint8_t *operations, size_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeYCbCrPixels(uint8_t *yData, uint8_t *cbData, uint8_t *crData, uint16_t w, uint16_t h) override;
protected:
private:
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
GFX_INLINE void POLL_START();
GFX_INLINE void POLL_END();
int8_t _cs, _sck, _mosi, _miso, _quadwp, _quadhd;
bool _is_shared_interface;
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
uint32_t _csPinMask; ///< Bitmask for chip select
spi_device_handle_t _handle;
spi_transaction_ext_t _spi_tran_ext;
spi_transaction_t *_spi_tran;
union
{
uint8_t *_buffer;
uint16_t *_buffer16;
uint32_t *_buffer32;
};
union
{
uint8_t *_2nd_buffer;
uint16_t *_2nd_buffer16;
uint32_t *_2nd_buffer32;
};
};
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,159 @@
// ESP_LCD_Panel implementation for esp32s3.
#include "Arduino_ESP32RGBPanel.h"
//#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4) //Modify
Arduino_ESP32RGBPanel::Arduino_ESP32RGBPanel(
int8_t de, int8_t vsync, int8_t hsync, int8_t pclk,
int8_t r0, int8_t r1, int8_t r2, int8_t r3, int8_t r4,
int8_t g0, int8_t g1, int8_t g2, int8_t g3, int8_t g4, int8_t g5,
int8_t b0, int8_t b1, int8_t b2, int8_t b3, int8_t b4,
uint16_t hsync_polarity, uint16_t hsync_front_porch, uint16_t hsync_pulse_width, uint16_t hsync_back_porch,
uint16_t vsync_polarity, uint16_t vsync_front_porch, uint16_t vsync_pulse_width, uint16_t vsync_back_porch,
uint16_t pclk_active_neg, int32_t prefer_speed, bool useBigEndian,
uint16_t de_idle_high, uint16_t pclk_idle_high, size_t bounce_buffer_size_px)
: _de(de), _vsync(vsync), _hsync(hsync), _pclk(pclk),
_r0(r0), _r1(r1), _r2(r2), _r3(r3), _r4(r4),
_g0(g0), _g1(g1), _g2(g2), _g3(g3), _g4(g4), _g5(g5),
_b0(b0), _b1(b1), _b2(b2), _b3(b3), _b4(b4),
_hsync_polarity(hsync_polarity), _hsync_front_porch(hsync_front_porch), _hsync_pulse_width(hsync_pulse_width), _hsync_back_porch(hsync_back_porch),
_vsync_polarity(vsync_polarity), _vsync_front_porch(vsync_front_porch), _vsync_pulse_width(vsync_pulse_width), _vsync_back_porch(vsync_back_porch),
_pclk_active_neg(pclk_active_neg), _prefer_speed(prefer_speed), _useBigEndian(useBigEndian),
_de_idle_high(de_idle_high), _pclk_idle_high(pclk_idle_high), _bounce_buffer_size_px(bounce_buffer_size_px)
{
}
bool Arduino_ESP32RGBPanel::begin(int32_t speed)
{
if (speed == GFX_NOT_DEFINED)
{
#ifdef CONFIG_SPIRAM_MODE_QUAD
_speed = 6000000L;
#else
_speed = 12000000L;
#endif
}
else
{
_speed = speed;
}
return true;
}
uint16_t *Arduino_ESP32RGBPanel::getFrameBuffer(int16_t w, int16_t h)
{
esp_lcd_rgb_panel_config_t panel_config = {
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
.clk_src = LCD_CLK_SRC_PLL160M,
#else
.clk_src = LCD_CLK_SRC_DEFAULT,
#endif
.timings = {
.pclk_hz = (uint32_t)((_prefer_speed == GFX_NOT_DEFINED) ? _speed : _prefer_speed),
.h_res = (uint32_t)w,
.v_res = (uint32_t)h,
.hsync_pulse_width = _hsync_pulse_width,
.hsync_back_porch = _hsync_back_porch,
.hsync_front_porch = _hsync_front_porch,
.vsync_pulse_width = _vsync_pulse_width,
.vsync_back_porch = _vsync_back_porch,
.vsync_front_porch = _vsync_front_porch,
.flags = {
.hsync_idle_low = (uint32_t)((_hsync_polarity == 0) ? 1 : 0),
.vsync_idle_low = (uint32_t)((_vsync_polarity == 0) ? 1 : 0),
.de_idle_high = _de_idle_high,
.pclk_active_neg = _pclk_active_neg,
.pclk_idle_high = _pclk_idle_high,
},
},
.data_width = 16, // RGB565 in parallel mode, thus 16 bits in width
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#else
.bits_per_pixel = 16,
.num_fbs = 1,
.bounce_buffer_size_px = _bounce_buffer_size_px,
#endif
.sram_trans_align = 8,
.psram_trans_align = 64,
.hsync_gpio_num = _hsync,
.vsync_gpio_num = _vsync,
.de_gpio_num = _de,
.pclk_gpio_num = _pclk,
.disp_gpio_num = GPIO_NUM_NC, // -1
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
.data_gpio_nums = {0},
#endif
.flags = {
.disp_active_low = true,
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
.refresh_on_demand = false,
#endif
.fb_in_psram = true, // allocate frame buffer from PSRAM
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
.double_fb = false,
.no_fb = false,
.bb_invalidate_cache = false,
#endif
},
};
if (_useBigEndian)
{
panel_config.data_gpio_nums[0] = _g3;
panel_config.data_gpio_nums[1] = _g4;
panel_config.data_gpio_nums[2] = _g5;
panel_config.data_gpio_nums[3] = _r0;
panel_config.data_gpio_nums[4] = _r1;
panel_config.data_gpio_nums[5] = _r2;
panel_config.data_gpio_nums[6] = _r3;
panel_config.data_gpio_nums[7] = _r4;
panel_config.data_gpio_nums[8] = _b0;
panel_config.data_gpio_nums[9] = _b1;
panel_config.data_gpio_nums[10] = _b2;
panel_config.data_gpio_nums[11] = _b3;
panel_config.data_gpio_nums[12] = _b4;
panel_config.data_gpio_nums[13] = _g0;
panel_config.data_gpio_nums[14] = _g1;
panel_config.data_gpio_nums[15] = _g2;
}
else
{
panel_config.data_gpio_nums[0] = _b0;
panel_config.data_gpio_nums[1] = _b1;
panel_config.data_gpio_nums[2] = _b2;
panel_config.data_gpio_nums[3] = _b3;
panel_config.data_gpio_nums[4] = _b4;
panel_config.data_gpio_nums[5] = _g0;
panel_config.data_gpio_nums[6] = _g1;
panel_config.data_gpio_nums[7] = _g2;
panel_config.data_gpio_nums[8] = _g3;
panel_config.data_gpio_nums[9] = _g4;
panel_config.data_gpio_nums[10] = _g5;
panel_config.data_gpio_nums[11] = _r0;
panel_config.data_gpio_nums[12] = _r1;
panel_config.data_gpio_nums[13] = _r2;
panel_config.data_gpio_nums[14] = _r3;
panel_config.data_gpio_nums[15] = _r4;
}
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &_panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_reset(_panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(_panel_handle));
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
esp_rgb_panel_t *_rgb_panel;
_rgb_panel = __containerof(_panel_handle, esp_rgb_panel_t, base);
return (uint16_t *)_rgb_panel->fb;
#else
void *frame_buffer = nullptr;
ESP_ERROR_CHECK(esp_lcd_rgb_panel_get_frame_buffer(_panel_handle, 1, &frame_buffer));
return ((uint16_t *)frame_buffer);
#endif
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,149 @@
#pragma once
// ESP_LCD_Panel implementation for esp32s3.
// This panel implementation requires a hardware setup with
// * RGB LCD peripheral supported (esps3 for now)
// * Octal PSRAM onboard
// * RGB panel, 16 bit-width, with HSYNC, VSYNC and DE signal
//
// It uses a Single Frame Buffer in PSRAM
//
// See: (ESP32 board version 3.x)
// * https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/lcd/rgb_lcd.html
// * https://github.com/espressif/esp-idf/blob/master/examples/peripherals/lcd/rgb_panel/README.md
//
// The prior implementation (ESP32 board version 2.x) was largely undocumented.
#include "Arduino_DataBus.h"
//#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4) //Modify
#include "esp_lcd_panel_rgb.h"
#include "esp_lcd_panel_ops.h"
//#include "esp32s3/rom/cache.h"
// This function is located in ROM (also see esp_rom/${target}/ld/${target}.rom.ld)
//extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size);
//Modify
// 根据目标芯片选择不同的头文件 Select different header files according to the target chip
#if defined(CONFIG_IDF_TARGET_ESP32S3)
#include "esp32s3/rom/cache.h"
#elif defined(CONFIG_IDF_TARGET_ESP32P4)
#include "esp32p4/rom/cache.h"
#else
#error "Unsupported target chip! Please use ESP32-S3 or ESP32-P4."
#endif
// 根据芯片类型选择正确的函数签名 Select different header files according to the target chip
#if defined(CONFIG_IDF_TARGET_ESP32P4)
// ESP32-P4需要使用带gid和map参数的版本
extern "C" int Cache_WriteBack_Addr_Gid(uint32_t gid, uint32_t map, uint32_t addr, uint32_t size);
// 创建兼容旧版API的包装函数
static inline int Cache_WriteBack_Addr(uint32_t addr, uint32_t size) {
// 使用默认gid=0并同时操作L1 DCache和L2 Cache
return Cache_WriteBack_Addr_Gid(0, CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE, addr, size);
}
#else
// ESP32-S3及其他芯片使用原始API
extern "C" int Cache_WriteBack_Addr(uint32_t addr, uint32_t size);
#endif
//#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
#if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR >5)
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_interface.h"
#include "esp_private/gdma.h"
#include "esp_pm.h"
#include "hal/dma_types.h"
#include "hal/lcd_hal.h"
#include "hal/lcd_ll.h"
// extract from esp-idf esp_lcd_rgb_panel.c
struct esp_rgb_panel_t
{
esp_lcd_panel_t base; // Base class of generic lcd panel
int panel_id; // LCD panel ID
lcd_hal_context_t hal; // Hal layer object
size_t data_width; // Number of data lines (e.g. for RGB565, the data width is 16)
size_t sram_trans_align; // Alignment for framebuffer that allocated in SRAM
size_t psram_trans_align; // Alignment for framebuffer that allocated in PSRAM
int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off"
intr_handle_t intr; // LCD peripheral interrupt handle
esp_pm_lock_handle_t pm_lock; // Power management lock
size_t num_dma_nodes; // Number of DMA descriptors that used to carry the frame buffer
uint8_t *fb; // Frame buffer
size_t fb_size; // Size of frame buffer
int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; // GPIOs used for data lines, we keep these GPIOs for action like "invert_color"
size_t resolution_hz; // Peripheral clock resolution
esp_lcd_rgb_timing_t timings; // RGB timing parameters (e.g. pclk, sync pulse, porch width)
gdma_channel_handle_t dma_chan; // DMA channel handle
esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; // Callback, invoked after frame trans done
void *user_ctx; // Reserved user's data of callback functions
int x_gap; // Extra gap in x coordinate, it's used when calculate the flush window
int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window
struct
{
unsigned int disp_en_level : 1; // The level which can turn on the screen by `disp_gpio_num`
unsigned int stream_mode : 1; // If set, the LCD transfers data continuously, otherwise, it stops refreshing the LCD when transaction done
unsigned int fb_in_psram : 1; // Whether the frame buffer is in PSRAM
} flags;
dma_descriptor_t dma_nodes[]; // DMA descriptor pool of size `num_dma_nodes`
};
#endif // #if (!defined(ESP_ARDUINO_VERSION_MAJOR)) || (ESP_ARDUINO_VERSION_MAJOR < 3)
class Arduino_ESP32RGBPanel
{
public:
Arduino_ESP32RGBPanel(
int8_t de, int8_t vsync, int8_t hsync, int8_t pclk,
int8_t r0, int8_t r1, int8_t r2, int8_t r3, int8_t r4,
int8_t g0, int8_t g1, int8_t g2, int8_t g3, int8_t g4, int8_t g5,
int8_t b0, int8_t b1, int8_t b2, int8_t b3, int8_t b4,
uint16_t hsync_polarity, uint16_t hsync_front_porch, uint16_t hsync_pulse_width, uint16_t hsync_back_porch,
uint16_t vsync_polarity, uint16_t vsync_front_porch, uint16_t vsync_pulse_width, uint16_t vsync_back_porch,
uint16_t pclk_active_neg = 0, int32_t prefer_speed = GFX_NOT_DEFINED, bool useBigEndian = false,
uint16_t de_idle_high = 0, uint16_t pclk_idle_high = 0, size_t bounce_buffer_size_px = 0);
bool begin(int32_t speed = GFX_NOT_DEFINED);
bool isUseBigEndian() {
return _useBigEndian;
}
uint16_t *getFrameBuffer(int16_t w, int16_t h);
protected:
private:
int32_t _speed;
int8_t _de, _vsync, _hsync, _pclk;
int8_t _r0, _r1, _r2, _r3, _r4;
int8_t _g0, _g1, _g2, _g3, _g4, _g5;
int8_t _b0, _b1, _b2, _b3, _b4;
uint16_t _hsync_polarity;
uint16_t _hsync_front_porch;
uint16_t _hsync_pulse_width;
uint16_t _hsync_back_porch;
uint16_t _vsync_polarity;
uint16_t _vsync_front_porch;
uint16_t _vsync_pulse_width;
uint16_t _vsync_back_porch;
uint16_t _pclk_active_neg;
int32_t _prefer_speed;
bool _useBigEndian;
uint16_t _de_idle_high;
uint16_t _pclk_idle_high;
size_t _bounce_buffer_size_px;
esp_lcd_panel_handle_t _panel_handle = NULL;
};
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,314 @@
#include "Arduino_ESP32S2PAR16.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
Arduino_ESP32S2PAR16::Arduino_ESP32S2PAR16(int8_t dc, int8_t cs, int8_t wr, int8_t rd)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd)
{
}
bool Arduino_ESP32S2PAR16::begin(int32_t speed, int8_t dataMode)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
// INIT 16-bit mask
_dataClrMask = 0xFFFF;
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32S2PAR16::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32S2PAR16::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32S2PAR16::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32S2PAR16::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_ESP32S2PAR16::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32S2PAR16::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32S2PAR16::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_ESP32S2PAR16::writeRepeat(uint16_t p, uint32_t len)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = p;
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
void Arduino_ESP32S2PAR16::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
void Arduino_ESP32S2PAR16::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32S2PAR16::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_ESP32S2PAR16::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_ESP32S2PAR16::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR16::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE(*data);
}
}
void Arduino_ESP32S2PAR16::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
WRITE16(idx[*data++]);
}
}
void Arduino_ESP32S2PAR16::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = idx[*data++];
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
GFX_INLINE void Arduino_ESP32S2PAR16::WRITE(uint8_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR16::WRITE16(uint16_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32S2PAR16::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR16::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR16::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32S2PAR16::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,63 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
#ifndef _ARDUINO_ESP32S2PAR16_H_
#define _ARDUINO_ESP32S2PAR16_H_
class Arduino_ESP32S2PAR16 : public Arduino_DataBus
{
public:
Arduino_ESP32S2PAR16(int8_t dc, int8_t cs, int8_t wr, int8_t rd); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet; ///< PORT register SET
PORTreg_t _dataPortClr; ///< PORT register CLEAR
uint32_t _dataClrMask;
};
#endif // _ARDUINO_ESP32S2PAR16_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,311 @@
#include "Arduino_ESP32S2PAR16Q.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
Arduino_ESP32S2PAR16Q::Arduino_ESP32S2PAR16Q(int8_t dc, int8_t cs, int8_t wr, int8_t rd)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd)
{
}
bool Arduino_ESP32S2PAR16Q::begin(int32_t speed, int8_t dataMode)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
// INIT 16-bit mask
_dataClrMask = (1 << _wr) | 0xFFFF;
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32S2PAR16Q::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32S2PAR16Q::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32S2PAR16Q::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32S2PAR16Q::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_ESP32S2PAR16Q::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32S2PAR16Q::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32S2PAR16Q::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_ESP32S2PAR16Q::writeRepeat(uint16_t p, uint32_t len)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = p;
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
void Arduino_ESP32S2PAR16Q::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
void Arduino_ESP32S2PAR16Q::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32S2PAR16Q::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_ESP32S2PAR16Q::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_ESP32S2PAR16Q::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR16Q::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE(*data);
}
}
void Arduino_ESP32S2PAR16Q::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
WRITE16(idx[*data++]);
}
}
void Arduino_ESP32S2PAR16Q::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = idx[*data++];
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
GFX_INLINE void Arduino_ESP32S2PAR16Q::WRITE(uint8_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
*_wrPortSet = _wrPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR16Q::WRITE16(uint16_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32S2PAR16Q::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR16Q::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR16Q::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32S2PAR16Q::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,63 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
#ifndef _ARDUINO_ESP32S2PAR16Q_H_
#define _ARDUINO_ESP32S2PAR16Q_H_
class Arduino_ESP32S2PAR16Q : public Arduino_DataBus
{
public:
Arduino_ESP32S2PAR16Q(int8_t dc, int8_t cs, int8_t wr, int8_t rd); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet; ///< PORT register SET
PORTreg_t _dataPortClr; ///< PORT register CLEAR
uint32_t _dataClrMask;
};
#endif // _ARDUINO_ESP32S2PAR16Q_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,309 @@
#include "Arduino_ESP32S2PAR8.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
Arduino_ESP32S2PAR8::Arduino_ESP32S2PAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd)
{
}
bool Arduino_ESP32S2PAR8::begin(int32_t speed, int8_t dataMode)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
// INIT 8-bit mask
_dataClrMask = 0xFF;
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32S2PAR8::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32S2PAR8::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32S2PAR8::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32S2PAR8::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_ESP32S2PAR8::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32S2PAR8::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32S2PAR8::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR8::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = p;
while (len--)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
else
{
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = _data16.msb;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_dataPortClr = _dataClrMask;
*_dataPortSet = _data16.lsb;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
}
void Arduino_ESP32S2PAR8::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32S2PAR8::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32S2PAR8::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR8::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR8::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_ESP32S2PAR8::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32S2PAR8::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_ESP32S2PAR8::WRITE(uint8_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32S2PAR8::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR8::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR8::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32S2PAR8::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,61 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
#ifndef _ARDUINO_ESP32S2PAR8_H_
#define _ARDUINO_ESP32S2PAR8_H_
class Arduino_ESP32S2PAR8 : public Arduino_DataBus
{
public:
Arduino_ESP32S2PAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet; ///< PORT register SET
PORTreg_t _dataPortClr; ///< PORT register CLEAR
uint32_t _dataClrMask;
};
#endif // _ARDUINO_ESP32S2PAR8_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,309 @@
#include "Arduino_ESP32S2PAR8Q.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
Arduino_ESP32S2PAR8Q::Arduino_ESP32S2PAR8Q(int8_t dc, int8_t cs, int8_t wr, int8_t rd)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd)
{
}
bool Arduino_ESP32S2PAR8Q::begin(int32_t speed, int8_t dataMode)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_dc >= 32)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#endif
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
#if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
if (_wr >= 32)
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#else
_wrPinMask = digitalPinToBitMask(_wr);
_wrPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_wrPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
#endif
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
// INIT 8-bit mask
_dataClrMask = (1 << _wr) | 0xFF;
_dataPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dataPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
*_dataPortClr = _dataClrMask;
return true;
}
void Arduino_ESP32S2PAR8Q::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP32S2PAR8Q::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32S2PAR8Q::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP32S2PAR8Q::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_ESP32S2PAR8Q::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP32S2PAR8Q::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP32S2PAR8Q::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR8Q::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = _data16.msb;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
while (--len)
{
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
*_wrPortClr = _wrPinMask;
*_wrPortSet = _wrPinMask;
}
}
else
{
while (len--)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = _data16.msb;
*_wrPortSet = _wrPinMask;
*_dataPortClr = _dataClrMask;
*_dataPortSet = _data16.lsb;
*_wrPortSet = _wrPinMask;
}
}
}
void Arduino_ESP32S2PAR8Q::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32S2PAR8Q::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP32S2PAR8Q::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR8Q::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_ESP32S2PAR8Q::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_ESP32S2PAR8Q::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_ESP32S2PAR8Q::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_ESP32S2PAR8Q::WRITE(uint8_t d)
{
*_dataPortClr = _dataClrMask;
*_dataPortSet = d;
*_wrPortSet = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP32S2PAR8Q::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR8Q::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_ESP32S2PAR8Q::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_ESP32S2PAR8Q::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

View File

@@ -0,0 +1,61 @@
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
#ifndef _ARDUINO_ESP32S2PAR8Q_H_
#define _ARDUINO_ESP32S2PAR8Q_H_
class Arduino_ESP32S2PAR8Q : public Arduino_DataBus
{
public:
Arduino_ESP32S2PAR8Q(int8_t dc, int8_t cs, int8_t wr, int8_t rd); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
PORTreg_t _dcPortSet; ///< PORT register SET
PORTreg_t _dcPortClr; ///< PORT register CLEAR
uint32_t _dcPinMask; ///< Bitmask
PORTreg_t _csPortSet; ///< PORT register SET
PORTreg_t _csPortClr; ///< PORT register CLEAR
uint32_t _csPinMask; ///< Bitmask
PORTreg_t _wrPortSet; ///< PORT register SET
PORTreg_t _wrPortClr; ///< PORT register CLEAR
uint32_t _wrPinMask; ///< Bitmask
PORTreg_t _dataPortSet; ///< PORT register SET
PORTreg_t _dataPortClr; ///< PORT register CLEAR
uint32_t _dataClrMask;
};
#endif // _ARDUINO_ESP32S2PAR8Q_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,133 @@
#pragma once
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#include "esp32-hal.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_attr.h"
#include "soc/spi_reg.h"
#include "soc/spi_struct.h"
#include "soc/periph_defs.h"
#include "soc/io_mux_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/rtc.h"
#ifndef CONFIG_IDF_TARGET_ESP32C5
#include "hal/clk_gate_ll.h"
#endif
#include "esp32-hal-periman.h"
#include "esp_private/periph_ctrl.h"
#include "esp_system.h"
#include "esp_intr_alloc.h"
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "soc/dport_reg.h"
#include "esp32/rom/ets_sys.h"
#include "esp32/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "soc/dport_reg.h"
#include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "soc/dport_reg.h"
#include "esp32s3/rom/ets_sys.h"
#include "esp32s3/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32C2
#include "esp32c2/rom/ets_sys.h"
#include "esp32c2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/ets_sys.h"
#include "esp32c3/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32C6
#include "esp32c6/rom/ets_sys.h"
#include "esp32c6/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/ets_sys.h"
#include "esp32h2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/ets_sys.h"
#include "esp32p4/rom/gpio.h"
#include "hal/spi_ll.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/ets_sys.h"
#include "esp32c5/rom/gpio.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#ifndef ESP32SPI_MAX_PIXELS_AT_ONCE
#define ESP32SPI_MAX_PIXELS_AT_ONCE 32
#endif
class Arduino_ESP32SPI : public Arduino_DataBus
{
public:
#if CONFIG_IDF_TARGET_ESP32
Arduino_ESP32SPI(int8_t dc = GFX_NOT_DEFINED, int8_t cs = GFX_NOT_DEFINED, int8_t sck = GFX_NOT_DEFINED, int8_t mosi = GFX_NOT_DEFINED, int8_t miso = GFX_NOT_DEFINED, uint8_t spi_num = VSPI, bool is_shared_interface = true); // Constructor
#else
Arduino_ESP32SPI(int8_t dc = GFX_NOT_DEFINED, int8_t cs = GFX_NOT_DEFINED, int8_t sck = GFX_NOT_DEFINED, int8_t mosi = GFX_NOT_DEFINED, int8_t miso = GFX_NOT_DEFINED, uint8_t spi_num = FSPI, bool is_shared_interface = true); // Constructor
#endif
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = SPI_MODE0) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
void flush_data_buf();
GFX_INLINE void WRITE8BIT(uint8_t d);
GFX_INLINE void WRITE9BIT(uint32_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
GFX_INLINE void POLL(uint32_t len);
private:
int8_t _dc, _cs;
int8_t _sck, _mosi, _miso;
uint8_t _spi_num;
bool _is_shared_interface;
uint32_t _div = 0;
PORTreg_t _dcPortSet; ///< PORT register for data/command SET
PORTreg_t _dcPortClr; ///< PORT register for data/command CLEAR
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
uint32_t _dcPinMask; ///< Bitmask for data/command
uint32_t _csPinMask; ///< Bitmask for chip select
spi_t *_spi;
uint8_t _bitOrder = SPI_MSBFIRST;
union
{
uint8_t *_buffer;
uint16_t *_buffer16;
uint32_t *_buffer32;
};
uint16_t _data_buf_bit_idx = 0;
};
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
#pragma once
#include "Arduino_DataBus.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
#include <driver/spi_master.h>
#if (ESP_ARDUINO_VERSION_MAJOR >= 3)
#include <esp_memory_utils.h>
#endif
#ifndef ESP32SPIDMA_MAX_PIXELS_AT_ONCE
#define ESP32SPIDMA_MAX_PIXELS_AT_ONCE 1024
#endif
#ifndef ESP32SPIDMA_DMA_CHANNEL
#define ESP32SPIDMA_DMA_CHANNEL SPI_DMA_CH_AUTO
#endif
class Arduino_ESP32SPIDMA : public Arduino_DataBus
{
public:
#if CONFIG_IDF_TARGET_ESP32
Arduino_ESP32SPIDMA(int8_t dc = GFX_NOT_DEFINED, int8_t cs = GFX_NOT_DEFINED, int8_t sck = GFX_NOT_DEFINED, int8_t mosi = GFX_NOT_DEFINED, int8_t miso = GFX_NOT_DEFINED, uint8_t spi_num = VSPI, bool is_shared_interface = false); // Constructor
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
Arduino_ESP32SPIDMA(int8_t dc = GFX_NOT_DEFINED, int8_t cs = GFX_NOT_DEFINED, int8_t sck = GFX_NOT_DEFINED, int8_t mosi = GFX_NOT_DEFINED, int8_t miso = GFX_NOT_DEFINED, uint8_t spi_num = HSPI, bool is_shared_interface = false); // Constructor
#else
Arduino_ESP32SPIDMA(int8_t dc = GFX_NOT_DEFINED, int8_t cs = GFX_NOT_DEFINED, int8_t sck = GFX_NOT_DEFINED, int8_t mosi = GFX_NOT_DEFINED, int8_t miso = GFX_NOT_DEFINED, uint8_t spi_num = FSPI, bool is_shared_interface = false); // Constructor
#endif
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = SPI_MODE0) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeYCbCrPixels(uint8_t *yData, uint8_t *cbData, uint8_t *crData, uint16_t w, uint16_t h) override;
protected:
void flush_data_buf();
GFX_INLINE void WRITE8BIT(uint8_t d);
GFX_INLINE void WRITE9BIT(uint32_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
GFX_INLINE void POLL_START();
GFX_INLINE void POLL_END();
private:
int8_t _dc, _cs;
int8_t _sck, _mosi, _miso;
uint8_t _spi_num;
bool _is_shared_interface;
uint32_t _div = 0;
PORTreg_t _dcPortSet; ///< PORT register for data/command SET
PORTreg_t _dcPortClr; ///< PORT register for data/command CLEAR
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
uint32_t _dcPinMask; ///< Bitmask for data/command
uint32_t _csPinMask; ///< Bitmask for chip select
spi_device_handle_t _handle;
spi_transaction_t _spi_tran;
uint8_t _bitOrder = SPI_MSBFIRST;
union
{
uint8_t *_buffer;
uint16_t *_buffer16;
uint32_t *_buffer32;
};
union
{
uint8_t *_2nd_buffer;
uint16_t *_2nd_buffer16;
uint32_t *_2nd_buffer32;
};
uint16_t _data_buf_bit_idx = 0;
};
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -0,0 +1,391 @@
/*
* start rewrite from:
* https://github.com/Bodmer/TFT_eSPI.git
*/
#ifdef ESP8266
#include <SPI.h>
#include "Arduino_ESP8266SPI.h"
#define WAIT_SPI_NOT_BUSY while (SPI1CMD & SPIBUSY)
Arduino_ESP8266SPI::Arduino_ESP8266SPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */)
: _dc(dc), _cs(cs)
{
}
bool Arduino_ESP8266SPI::begin(int32_t speed, int8_t dataMode)
{
_speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed;
_dataMode = (dataMode == GFX_NOT_DEFINED) ? SPI_MODE0 : dataMode;
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // Deselect
}
_dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc));
_dcPinMaskSet = digitalPinToBitMask(_dc);
if (_cs != GFX_NOT_DEFINED)
{
_csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs));
_csPinMaskSet = digitalPinToBitMask(_cs);
}
_csPinMaskClr = ~_csPinMaskSet;
_dcPinMaskClr = ~_dcPinMaskSet;
SPI.begin();
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE0;
}
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(_dataMode);
SPI.setFrequency(_speed);
return true;
}
void Arduino_ESP8266SPI::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_ESP8266SPI::endWrite()
{
CS_HIGH();
}
void Arduino_ESP8266SPI::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_ESP8266SPI::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_ESP8266SPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_ESP8266SPI::write(uint8_t d)
{
WRITE(d);
}
void Arduino_ESP8266SPI::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_ESP8266SPI::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
static uint8_t temp[2];
temp[0] = _data16.msb;
temp[1] = _data16.lsb;
SPI.writePattern((uint8_t *)temp, 2, len);
}
void Arduino_ESP8266SPI::writePixels(uint16_t *data, uint32_t len)
{
uint8_t *data8 = (uint8_t *)data;
uint8_t i;
if (len > 31)
{
SPI1U1 = (511 << SPILMOSI);
while (len > 31)
{
i = 0;
while (i < 16)
{
MSB_32_8_ARRAY_SET(twoPixelBuf[i++], data8);
data8 += 4;
}
len -= 32;
// ESP8266 wait time here at 40MHz SPI is ~5.45us
WAIT_SPI_NOT_BUSY;
SPI1W0 = twoPixelBuf[0];
SPI1W1 = twoPixelBuf[1];
SPI1W2 = twoPixelBuf[2];
SPI1W3 = twoPixelBuf[3];
SPI1W4 = twoPixelBuf[4];
SPI1W5 = twoPixelBuf[5];
SPI1W6 = twoPixelBuf[6];
SPI1W7 = twoPixelBuf[7];
SPI1W8 = twoPixelBuf[8];
SPI1W9 = twoPixelBuf[9];
SPI1W10 = twoPixelBuf[10];
SPI1W11 = twoPixelBuf[11];
SPI1W12 = twoPixelBuf[12];
SPI1W13 = twoPixelBuf[13];
SPI1W14 = twoPixelBuf[14];
SPI1W15 = twoPixelBuf[15];
SPI1CMD |= SPIBUSY;
}
}
if (len)
{
uint32_t bits = ((len << 4) - 1); // bits left to shift - 1
i = 0;
len = (len + 1) >> 1;
WAIT_SPI_NOT_BUSY;
SPI1U1 = (bits << SPILMOSI);
while (len--)
{
MSB_32_8_ARRAY_SET(spi1Reg32[i++], data8);
data8 += 4;
}
SPI1CMD |= SPIBUSY;
}
WAIT_SPI_NOT_BUSY;
}
void Arduino_ESP8266SPI::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_ESP8266SPI::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_ESP8266SPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
uint32_t d;
MSB_32_16_16_SET(d, d1, d2);
SPI1U1 = (31 << SPILMOSI);
SPI1W0 = d;
SPI1CMD |= SPIBUSY;
WAIT_SPI_NOT_BUSY;
}
void Arduino_ESP8266SPI::writeBytes(uint8_t *data, uint32_t len)
{
SPI.writeBytes(data, len);
}
void Arduino_ESP8266SPI::writePattern(uint8_t *data, uint8_t len, uint32_t repeat)
{
SPI.writePattern(data, len, repeat);
}
void Arduino_ESP8266SPI::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
uint16_t p1, p2;
uint8_t i;
if (len > 31)
{
SPI1U1 = (511 << SPILMOSI);
while (len > 31)
{
i = 0;
while (i < 16)
{
p1 = idx[*data++];
p2 = idx[*data++];
MSB_32_16_16_SET(twoPixelBuf[i++], p1, p2);
}
len -= 32;
// ESP8266 wait time here at 40MHz SPI is ~5.45us
WAIT_SPI_NOT_BUSY;
SPI1W0 = twoPixelBuf[0];
SPI1W1 = twoPixelBuf[1];
SPI1W2 = twoPixelBuf[2];
SPI1W3 = twoPixelBuf[3];
SPI1W4 = twoPixelBuf[4];
SPI1W5 = twoPixelBuf[5];
SPI1W6 = twoPixelBuf[6];
SPI1W7 = twoPixelBuf[7];
SPI1W8 = twoPixelBuf[8];
SPI1W9 = twoPixelBuf[9];
SPI1W10 = twoPixelBuf[10];
SPI1W11 = twoPixelBuf[11];
SPI1W12 = twoPixelBuf[12];
SPI1W13 = twoPixelBuf[13];
SPI1W14 = twoPixelBuf[14];
SPI1W15 = twoPixelBuf[15];
SPI1CMD |= SPIBUSY;
}
}
if (len)
{
uint32_t bits = ((len << 4) - 1); // bits left to shift - 1
i = 0;
len = (len + 1) >> 1;
WAIT_SPI_NOT_BUSY;
SPI1U1 = (bits << SPILMOSI);
while (len--)
{
p1 = idx[*data++];
p2 = idx[*data++];
MSB_32_16_16_SET(spi1Reg32[i++], p1, p2);
}
SPI1CMD |= SPIBUSY;
}
WAIT_SPI_NOT_BUSY;
}
void Arduino_ESP8266SPI::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
uint16_t p;
uint8_t i;
if (len > 15)
{
SPI1U1 = (511 << SPILMOSI);
while (len > 15)
{
i = 0;
while (i < 16)
{
p = idx[*data++];
MSB_32_16_16_SET(twoPixelBuf[i++], p, p);
}
len -= 16;
// ESP8266 wait time here at 40MHz SPI is ~5.45us
WAIT_SPI_NOT_BUSY;
SPI1W0 = twoPixelBuf[0];
SPI1W1 = twoPixelBuf[1];
SPI1W2 = twoPixelBuf[2];
SPI1W3 = twoPixelBuf[3];
SPI1W4 = twoPixelBuf[4];
SPI1W5 = twoPixelBuf[5];
SPI1W6 = twoPixelBuf[6];
SPI1W7 = twoPixelBuf[7];
SPI1W8 = twoPixelBuf[8];
SPI1W9 = twoPixelBuf[9];
SPI1W10 = twoPixelBuf[10];
SPI1W11 = twoPixelBuf[11];
SPI1W12 = twoPixelBuf[12];
SPI1W13 = twoPixelBuf[13];
SPI1W14 = twoPixelBuf[14];
SPI1W15 = twoPixelBuf[15];
SPI1CMD |= SPIBUSY;
}
}
if (len)
{
uint32_t bits = ((len << 5) - 1); // bits left to shift - 1
i = 0;
WAIT_SPI_NOT_BUSY;
SPI1U1 = (bits << SPILMOSI);
while (len--)
{
p = idx[*data++];
MSB_32_16_16_SET(spi1Reg32[i++], p, p);
}
SPI1CMD |= SPIBUSY;
}
WAIT_SPI_NOT_BUSY;
}
GFX_INLINE void Arduino_ESP8266SPI::WRITE(uint8_t d)
{
SPI1U1 = (7 << SPILMOSI);
SPI1W0 = d;
SPI1CMD |= SPIBUSY;
WAIT_SPI_NOT_BUSY;
}
GFX_INLINE void Arduino_ESP8266SPI::WRITE16(uint16_t d)
{
MSB_16_SET(d, d);
SPI1U1 = (15 << SPILMOSI);
SPI1W0 = d;
SPI1CMD |= SPIBUSY;
WAIT_SPI_NOT_BUSY;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_ESP8266SPI::DC_HIGH(void)
{
*_dcPort |= _dcPinMaskSet;
}
GFX_INLINE void Arduino_ESP8266SPI::DC_LOW(void)
{
*_dcPort &= _dcPinMaskClr;
}
GFX_INLINE void Arduino_ESP8266SPI::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort |= _csPinMaskSet;
}
}
GFX_INLINE void Arduino_ESP8266SPI::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort &= _csPinMaskClr;
}
}
#endif // #ifdef ESP8266

View File

@@ -0,0 +1,60 @@
/*
* start rewrite from:
* https://github.com/Bodmer/TFT_eSPI.git
*/
#ifdef ESP8266
#ifndef _ARDUINO_ESP8266SPI_H_
#define _ARDUINO_ESP8266SPI_H_
#include "Arduino_DataBus.h"
class Arduino_ESP8266SPI : public Arduino_DataBus
{
public:
Arduino_ESP8266SPI(int8_t dc, int8_t cs = GFX_NOT_DEFINED); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePattern(uint8_t *data, uint8_t len, uint32_t repeat) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs;
PORTreg_t _csPort; ///< PORT register for chip select
PORTreg_t _dcPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _csPinMaskSet; ///< Bitmask for chip select SET (OR)
ARDUINOGFX_PORT_t _csPinMaskClr; ///< Bitmask for chip select CLEAR (AND)
ARDUINOGFX_PORT_t _dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
uint32_t twoPixelBuf[16];
volatile uint32_t *spi1Reg32 = (volatile uint32_t *)(0x60000000 + 0x140); // address of SPI1W0
};
#endif // _ARDUINO_ESP8266SPI_H_
#endif // #ifdef ESP8266

View File

@@ -0,0 +1,523 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#include "Arduino_HWSPI.h"
#if defined(SPI_HAS_TRANSACTION)
#define SPI_BEGIN_TRANSACTION() _spi->beginTransaction(mySPISettings)
#define SPI_END_TRANSACTION() _spi->endTransaction()
#else
#define SPI_BEGIN_TRANSACTION() \
{ \
}
#define SPI_END_TRANSACTION() \
{ \
}
#endif
#if defined(SPI_HAS_TRANSACTION)
static SPISettings mySPISettings;
#elif defined(__AVR__) || defined(CORE_TEENSY)
static uint8_t SPCRbackup;
static uint8_t mySPCR;
#endif
#if defined(ESP32)
Arduino_HWSPI::Arduino_HWSPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */, int8_t sck /* = GFX_NOT_DEFINED */, int8_t mosi /* = GFX_NOT_DEFINED */, int8_t miso /* = GFX_NOT_DEFINED */, SPIClass *spi, bool is_shared_interface /* = true */)
: _dc(dc), _cs(cs), _sck(sck), _mosi(mosi), _miso(miso), _spi(spi), _is_shared_interface(is_shared_interface)
{
#else
Arduino_HWSPI::Arduino_HWSPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */, SPIClass *spi, bool is_shared_interface /* = true */)
: _dc(dc), _cs(cs), _spi(spi), _is_shared_interface(is_shared_interface)
{
#endif
}
bool Arduino_HWSPI::begin(int32_t speed, int8_t dataMode)
{
_speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed;
_dataMode = dataMode;
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // Deselect
}
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(ARDUINO_ARCH_NRF52840)
uint32_t pin = digitalPinToPinName((pin_size_t)_dc);
NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin);
_dcPortSet = &reg->OUTSET;
_dcPortClr = &reg->OUTCLR;
_dcPinMask = 1UL << pin;
if (_cs != GFX_NOT_DEFINED)
{
pin = digitalPinToPinName((pin_size_t)_cs);
reg = nrf_gpio_pin_port_decode(&pin);
_csPortSet = &reg->OUTSET;
_csPortClr = &reg->OUTCLR;
_csPinMask = 1UL << pin;
}
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_dc)))->POSR);
_dcPortClr = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_dc)))->PORR);
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_cs)))->POSR);
_csPortClr = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_cs)))->PORR);
}
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)&sio_hw->gpio_set;
_dcPortClr = (PORTreg_t)&sio_hw->gpio_clr;
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)&sio_hw->gpio_set;
_csPortClr = (PORTreg_t)&sio_hw->gpio_clr;
}
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
_dcPinMask = digitalPinToBitMask(_dc);
if (_dc >= 32)
{
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#elif defined(ESP32)
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
#elif defined(CORE_TEENSY)
#if !defined(KINETISK)
_dcPinMask = digitalPinToBitMask(_dc);
#endif
_dcPortSet = portSetRegister(_dc);
_dcPortClr = portClearRegister(_dc);
if (_cs != GFX_NOT_DEFINED)
{
#if !defined(KINETISK)
_csPinMask = digitalPinToBitMask(_cs);
#endif
_csPortSet = portSetRegister(_cs);
_csPortClr = portClearRegister(_cs);
}
#else // !CORE_TEENSY
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = &(PORT->Group[g_APinDescription[_dc].ulPort].OUTSET.reg);
_dcPortClr = &(PORT->Group[g_APinDescription[_dc].ulPort].OUTCLR.reg);
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = &(PORT->Group[g_APinDescription[_cs].ulPort].OUTSET.reg);
_csPortClr = &(PORT->Group[g_APinDescription[_cs].ulPort].OUTCLR.reg);
}
#endif // end !CORE_TEENSY
#else // !HAS_PORT_SET_CLR
_dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc));
_dcPinMaskSet = digitalPinToBitMask(_dc);
_dcPinMaskClr = ~_dcPinMaskSet;
if (_cs != GFX_NOT_DEFINED)
{
_csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs));
_csPinMaskSet = digitalPinToBitMask(_cs);
}
_csPinMaskClr = ~_csPinMaskSet;
#endif // !HAS_PORT_SET_CLR
#endif // USE_FAST_PINIO
#if defined(ESP32)
_spi->begin(_sck, _miso, _mosi);
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE0;
}
mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode);
#elif defined(ESP8266)
_spi->begin();
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE0;
}
mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode);
// Teensy 4.x
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
_spi->begin();
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE0;
}
mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode);
#elif defined(SPI_HAS_TRANSACTION)
_spi->begin();
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE2;
}
mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode);
#elif defined(__AVR__) || defined(CORE_TEENSY)
SPCRbackup = SPCR;
_spi->begin();
_spi->setClockDivider(SPI_CLOCK_DIV2);
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE2;
}
_spi->setDataMode(_dataMode);
mySPCR = SPCR; // save our preferred state
SPCR = SPCRbackup; // then restore
#elif defined(__SAM3X8E__)
_spi->begin();
_spi->setClockDivider(21); // 4MHz
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE2;
}
_spi->setDataMode(_dataMode);
#elif defined(__arm__)
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE2;
}
#endif
return true;
}
void Arduino_HWSPI::beginWrite()
{
if (_is_shared_interface)
{
SPI_BEGIN_TRANSACTION();
}
DC_HIGH();
CS_LOW();
}
void Arduino_HWSPI::endWrite()
{
CS_HIGH();
if (_is_shared_interface)
{
SPI_END_TRANSACTION();
}
}
void Arduino_HWSPI::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_HWSPI::writeCommand16(uint16_t c)
{
DC_LOW();
#if defined(LITTLE_FOOT_PRINT)
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
#else // !defined(LITTLE_FOOT_PRINT)
WRITE16(c);
#endif // !defined(LITTLE_FOOT_PRINT)
DC_HIGH();
}
void Arduino_HWSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_HWSPI::write(uint8_t d)
{
WRITE(d);
}
void Arduino_HWSPI::write16(uint16_t d)
{
#if defined(LITTLE_FOOT_PRINT)
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
#else // !defined(LITTLE_FOOT_PRINT)
WRITE16(d);
#endif // !defined(LITTLE_FOOT_PRINT)
}
void Arduino_HWSPI::writeRepeat(uint16_t p, uint32_t len)
{
#if defined(LITTLE_FOOT_PRINT)
_data16.value = p;
while (len--)
{
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
#elif defined(ESP8266) || defined(CONFIG_ARCH_CHIP_CXD56XX)
MSB_16_SET(p, p);
uint32_t xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE;
for (uint32_t i = 0; i < xferLen; i++)
{
_buffer.v16[i] = p;
}
while (len)
{
xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE;
len -= xferLen;
xferLen += xferLen;
WRITEBUF(_buffer.v8, xferLen);
}
#else // other arch
MSB_16_SET(p, p);
uint32_t xferLen;
while (len)
{
xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE;
for (uint32_t i = 0; i < xferLen; i++)
{
_buffer.v16[i] = p;
}
len -= xferLen;
xferLen += xferLen;
WRITEBUF(_buffer.v8, xferLen);
}
#endif // other arch
}
void Arduino_HWSPI::writeBytes(uint8_t *data, uint32_t len)
{
#if defined(LITTLE_FOOT_PRINT)
while (len--)
{
WRITE(*data++);
}
#else // !defined(LITTLE_FOOT_PRINT)
WRITEBUF(data, len);
#endif // !defined(LITTLE_FOOT_PRINT)
}
void Arduino_HWSPI::writePixels(uint16_t *data, uint32_t len)
{
#if defined(LITTLE_FOOT_PRINT)
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
#else // !defined(LITTLE_FOOT_PRINT)
uint32_t xferLen;
uint8_t *b;
union
{
uint16_t val;
struct
{
uint8_t lsb;
uint8_t msb;
};
} t;
while (len)
{
xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE;
b = _buffer.v8;
for (uint32_t i = 0; i < xferLen; i++)
{
t.val = *data++;
*b++ = t.msb;
*b++ = t.lsb;
}
len -= xferLen;
xferLen += xferLen; // uint16_t to uint8_t, double length
WRITEBUF(_buffer.v8, xferLen);
}
#endif // !defined(LITTLE_FOOT_PRINT)
}
#if !defined(LITTLE_FOOT_PRINT)
void Arduino_HWSPI::writePattern(uint8_t *data, uint8_t len, uint32_t repeat)
{
#if defined(ESP8266) || defined(ESP32)
_spi->writePattern(data, len, repeat);
#else // !(defined(ESP8266) || defined(ESP32))
while (repeat--)
{
WRITEBUF(data, len);
}
#endif // !(defined(ESP8266) || defined(ESP32))
}
#endif // !defined(LITTLE_FOOT_PRINT)
GFX_INLINE void Arduino_HWSPI::WRITE(uint8_t d)
{
#if defined(SPI_HAS_TRANSACTION)
_spi->transfer(d);
#elif defined(__AVR__) || defined(CORE_TEENSY)
SPCRbackup = SPCR;
SPCR = mySPCR;
_spi->transfer(d);
SPCR = SPCRbackup;
#elif defined(__arm__)
_spi->setClockDivider(21); // 4MHz
_spi->setDataMode(_dataMode);
_spi->transfer(d);
#endif
}
#if !defined(LITTLE_FOOT_PRINT)
GFX_INLINE void Arduino_HWSPI::WRITE16(uint16_t d)
{
#if defined(ESP8266) || defined(ESP32)
_spi->write16(d);
#elif defined(SPI_HAS_TRANSACTION)
_spi->transfer16(d);
#elif defined(__AVR__) || defined(CORE_TEENSY)
SPCRbackup = SPCR;
SPCR = mySPCR;
_spi->transfer16(d);
SPCR = SPCRbackup;
#elif defined(__arm__)
_spi->setClockDivider(21); // 4MHz
_spi->setDataMode(_dataMode);
_spi->transfer16(d);
#else
_spi->transfer16(d);
#endif
}
GFX_INLINE void Arduino_HWSPI::WRITEBUF(uint8_t *buf, size_t count)
{
#if defined(ESP8266) || defined(ESP32)
_spi->writeBytes(buf, count);
#elif defined(CONFIG_ARCH_CHIP_CXD56XX)
_spi->send(buf, count);
#else // other arch.
_spi->transfer(buf, count);
#endif // other arch.
}
#endif // !defined(LITTLE_FOOT_PRINT)
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_HWSPI::DC_HIGH(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_dcPortSet = 1;
#else // !KINETISK
*_dcPortSet = _dcPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_dcPort |= _dcPinMaskSet;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_dc, HIGH);
#endif // end !USE_FAST_PINIO
}
GFX_INLINE void Arduino_HWSPI::DC_LOW(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_dcPortClr = 1;
#else // !KINETISK
*_dcPortClr = _dcPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_dcPort &= _dcPinMaskClr;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_dc, LOW);
#endif // end !USE_FAST_PINIO
}
GFX_INLINE void Arduino_HWSPI::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_csPortSet = 1;
#else // !KINETISK
*_csPortSet = _csPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_csPort |= _csPinMaskSet;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_cs, HIGH);
#endif // end !USE_FAST_PINIO
}
}
GFX_INLINE void Arduino_HWSPI::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_csPortClr = 1;
#else // !KINETISK
*_csPortClr = _csPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_csPort &= _csPinMaskClr;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_cs, LOW);
#endif // end !USE_FAST_PINIO
}
}

View File

@@ -0,0 +1,104 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#ifndef _ARDUINO_HWSPI_H_
#define _ARDUINO_HWSPI_H_
#include <SPI.h>
#include "Arduino_DataBus.h"
#if !defined(LITTLE_FOOT_PRINT)
#ifndef SPI_MAX_PIXELS_AT_ONCE
#define SPI_MAX_PIXELS_AT_ONCE 32
#endif
#endif
// HARDWARE CONFIG ---------------------------------------------------------
class Arduino_HWSPI : public Arduino_DataBus
{
public:
#if defined(ESP32)
Arduino_HWSPI(int8_t dc, int8_t cs = GFX_NOT_DEFINED, int8_t sck = GFX_NOT_DEFINED, int8_t mosi = GFX_NOT_DEFINED, int8_t miso = GFX_NOT_DEFINED, SPIClass *spi = &SPI, bool is_shared_interface = true); // Constructor
#elif defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
Arduino_HWSPI(int8_t dc, int8_t cs = GFX_NOT_DEFINED, SPIClass *spi = &LCD_SPI, bool is_shared_interface = true); // Constructor
#elif defined(RTL8722DM) && defined(BOARD_RTL8722DM)
Arduino_HWSPI(int8_t dc, int8_t cs = GFX_NOT_DEFINED, SPIClass *spi = &SPI1, bool is_shared_interface = true); // Constructor
#else
Arduino_HWSPI(int8_t dc, int8_t cs = GFX_NOT_DEFINED, SPIClass *spi = &SPI, bool is_shared_interface = true); // Constructor
#endif
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
#if !defined(LITTLE_FOOT_PRINT)
void writePattern(uint8_t *data, uint8_t len, uint32_t repeat) override;
#endif // !defined(LITTLE_FOOT_PRINT)
private:
GFX_INLINE void WRITE(uint8_t d);
#if !defined(LITTLE_FOOT_PRINT)
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITEBUF(uint8_t *buf, size_t count);
#endif // !defined(LITTLE_FOOT_PRINT)
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs;
#if defined(ESP32)
int8_t _sck, _mosi, _miso;
#endif
SPIClass *_spi;
bool _is_shared_interface;
// CLASS INSTANCE VARIABLES --------------------------------------------
// Here be dragons! There's a big union of three structures here --
// one each for hardware SPI, software (bitbang) SPI, and parallel
// interfaces. This is to save some memory, since a display's connection
// will be only one of these. The order of some things is a little weird
// in an attempt to get values to align and pack better in RAM.
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
PORTreg_t _dcPortSet; ///< PORT register for data/command SET
PORTreg_t _dcPortClr; ///< PORT register for data/command CLEAR
#if !defined(KINETISK)
ARDUINOGFX_PORT_t _csPinMask; ///< Bitmask for chip select
ARDUINOGFX_PORT_t _dcPinMask; ///< Bitmask for data/command
#endif // !KINETISK
#else // !HAS_PORT_SET_CLR
PORTreg_t _csPort; ///< PORT register for chip select
PORTreg_t _dcPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _csPinMaskSet; ///< Bitmask for chip select SET (OR)
ARDUINOGFX_PORT_t _csPinMaskClr; ///< Bitmask for chip select CLEAR (AND)
ARDUINOGFX_PORT_t _dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
#endif // HAS_PORT_SET_CLR
#endif // !defined(USE_FAST_PINIO)
#if !defined(LITTLE_FOOT_PRINT)
union
{
uint8_t v8[SPI_MAX_PIXELS_AT_ONCE * 2] = {0};
uint16_t v16[SPI_MAX_PIXELS_AT_ONCE];
} _buffer;
#endif // !defined(LITTLE_FOOT_PRINT)
};
#endif // _ARDUINO_HWSPI_H_

View File

@@ -0,0 +1,292 @@
/*
* start rewrite from:
* https://github.com/arduino/ArduinoCore-mbed/blob/master/libraries/SPI/SPI.cpp
*/
#ifdef ARDUINO_ARCH_NRF52840
#include "Arduino_NRFXSPI.h"
Arduino_NRFXSPI::Arduino_NRFXSPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */, int8_t sck /* = GFX_NOT_DEFINED */, int8_t mosi /* = GFX_NOT_DEFINED */, int8_t miso /* = GFX_NOT_DEFINED */)
: _dc(dc), _cs(cs), _sck(sck), _mosi(mosi), _miso(miso)
{
}
bool Arduino_NRFXSPI::begin(int32_t speed, int8_t dataMode)
{
_speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed;
_dataMode = (dataMode == GFX_NOT_DEFINED) ? SPI_MODE2 : dataMode;
// init pin mask
uint32_t pin = digitalPinToPinName((pin_size_t)_dc);
NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin);
nrf_gpio_cfg_output(pin);
_dcPortSet = &reg->OUTSET;
_dcPortClr = &reg->OUTCLR;
_dcPinMask = 1UL << pin;
if (_cs != GFX_NOT_DEFINED)
{
pin = digitalPinToPinName((pin_size_t)_cs);
reg = nrf_gpio_pin_port_decode(&pin);
nrf_gpio_cfg_output(pin);
_csPortSet = &reg->OUTSET;
_csPortClr = &reg->OUTCLR;
_csPinMask = 1UL << pin;
}
// init SPI pins
_nrfxSpiConfig.sck_pin = digitalPinToPinName((pin_size_t)_sck);
_nrfxSpiConfig.mosi_pin = digitalPinToPinName((pin_size_t)_mosi);
if (_miso > 0)
{
_nrfxSpiConfig.miso_pin = digitalPinToPinName((pin_size_t)_miso);
}
else
{
_nrfxSpiConfig.miso_pin = NRFX_SPI_PIN_NOT_USED;
}
// init speed
if (_speed >= 8000000)
{
_nrfxSpiConfig.frequency = NRF_SPI_FREQ_8M;
}
else if (_speed >= 4000000)
{
_nrfxSpiConfig.frequency = NRF_SPI_FREQ_4M;
}
else if (_speed >= 2000000)
{
_nrfxSpiConfig.frequency = NRF_SPI_FREQ_2M;
}
else if (_speed >= 1000000)
{
_nrfxSpiConfig.frequency = NRF_SPI_FREQ_1M;
}
else if (_speed >= 500000)
{
_nrfxSpiConfig.frequency = NRF_SPI_FREQ_500K;
}
else if (_speed >= 250000)
{
_nrfxSpiConfig.frequency = NRF_SPI_FREQ_250K;
}
else if (_speed >= 125000)
{
_nrfxSpiConfig.frequency = NRF_SPI_FREQ_125K;
}
// init data mode
if (_dataMode == SPI_MODE1)
{
_nrfxSpiConfig.mode = NRF_SPI_MODE_1;
}
else if (_dataMode == SPI_MODE2)
{
_nrfxSpiConfig.mode = NRF_SPI_MODE_2;
}
else if (_dataMode == SPI_MODE3)
{
_nrfxSpiConfig.mode = NRF_SPI_MODE_3;
}
else
{
_dataMode = SPI_MODE0;
_nrfxSpiConfig.mode = NRF_SPI_MODE_0;
}
// init SPI
nrfx_spi_init(&_nrfxSpi, &_nrfxSpiConfig, NULL, NULL);
return true;
}
void Arduino_NRFXSPI::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_NRFXSPI::endWrite()
{
CS_HIGH();
}
void Arduino_NRFXSPI::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_NRFXSPI::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_NRFXSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_NRFXSPI::write(uint8_t d)
{
WRITE(d);
}
void Arduino_NRFXSPI::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_NRFXSPI::writeRepeat(uint16_t p, uint32_t len)
{
MSB_16_SET(p, p);
uint32_t bufLen = (len < NRFXSPI_MAX_PIXELS_AT_ONCE) ? len : NRFXSPI_MAX_PIXELS_AT_ONCE;
uint32_t xferLen;
for (uint32_t i = 0; i < bufLen; i++)
{
_buffer16[i] = p;
}
while (len)
{
xferLen = (bufLen < len) ? bufLen : len;
WRITEBUF(_buffer, xferLen * 2);
len -= xferLen;
}
}
void Arduino_NRFXSPI::writePixels(uint16_t *data, uint32_t len)
{
uint32_t xferLen;
uint8_t *p;
union
{
uint16_t val;
struct
{
uint8_t lsb;
uint8_t msb;
};
} t;
while (len)
{
xferLen = (len < NRFXSPI_MAX_PIXELS_AT_ONCE) ? len : NRFXSPI_MAX_PIXELS_AT_ONCE;
p = _buffer;
for (uint32_t i = 0; i < xferLen; i++)
{
t.val = *data++;
*p++ = t.msb;
*p++ = t.lsb;
}
len -= xferLen;
xferLen += xferLen; // uint16_t to uint8_t, double length
WRITEBUF(_buffer, xferLen);
}
}
void Arduino_NRFXSPI::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_NRFXSPI::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_NRFXSPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
const nrfx_spi_xfer_desc_t xfer_desc1 = NRFX_SPI_SINGLE_XFER(&c, 1, NULL, 0);
nrfx_spi_xfer(&_nrfxSpi, &xfer_desc1, 0);
DC_HIGH();
uint32_t d;
MSB_32_16_16_SET(d, d1, d2);
const nrfx_spi_xfer_desc_t xfer_desc2 = NRFX_SPI_SINGLE_XFER(&d, 4, NULL, 0);
nrfx_spi_xfer(&_nrfxSpi, &xfer_desc2, 0);
}
void Arduino_NRFXSPI::writeBytes(uint8_t *data, uint32_t len)
{
WRITEBUF(data, len);
}
GFX_INLINE void Arduino_NRFXSPI::WRITE(uint8_t d)
{
const nrfx_spi_xfer_desc_t xfer_desc = NRFX_SPI_SINGLE_XFER(&d, 1, NULL, 0);
nrfx_spi_xfer(&_nrfxSpi, &xfer_desc, 0);
}
GFX_INLINE void Arduino_NRFXSPI::WRITE16(uint16_t d)
{
MSB_16_SET(d, d);
const nrfx_spi_xfer_desc_t xfer_desc = NRFX_SPI_SINGLE_XFER(&d, 2, NULL, 0);
nrfx_spi_xfer(&_nrfxSpi, &xfer_desc, 0);
}
GFX_INLINE void Arduino_NRFXSPI::WRITEBUF(uint8_t *buf, size_t count)
{
const nrfx_spi_xfer_desc_t xfer_desc = NRFX_SPI_SINGLE_XFER(buf, count, NULL, 0);
nrfx_spi_xfer(&_nrfxSpi, &xfer_desc, 0);
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_NRFXSPI::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_NRFXSPI::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_NRFXSPI::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_NRFXSPI::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #ifdef ARDUINO_ARCH_NRF52840

View File

@@ -0,0 +1,71 @@
/*
* start rewrite from:
* https://github.com/arduino/ArduinoCore-mbed/blob/master/libraries/SPI/SPI.cpp
*/
#ifdef ARDUINO_ARCH_NRF52840
#ifndef _ARDUINO_NRFXSPI_H_
#define _ARDUINO_NRFXSPI_H_
#include <SPI.h>
#include "Arduino_DataBus.h"
#ifndef NRFXSPI_MAX_PIXELS_AT_ONCE
#define NRFXSPI_MAX_PIXELS_AT_ONCE 32
#endif
class Arduino_NRFXSPI : public Arduino_DataBus
{
public:
Arduino_NRFXSPI(int8_t dc, int8_t cs = GFX_NOT_DEFINED, int8_t sck = GFX_NOT_DEFINED, int8_t mosi = GFX_NOT_DEFINED, int8_t miso = GFX_NOT_DEFINED); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITEBUF(uint8_t *buf, size_t count);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs;
int8_t _sck, _mosi, _miso;
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
PORTreg_t _dcPortSet; ///< PORT register for data/command SET
PORTreg_t _dcPortClr; ///< PORT register for data/command CLEAR
ARDUINOGFX_PORT_t _csPinMask; ///< Bitmask for chip select
ARDUINOGFX_PORT_t _dcPinMask; ///< Bitmask for data/command
nrfx_spi_config_t _nrfxSpiConfig = NRFX_SPI_DEFAULT_CONFIG;
nrfx_spi_t _nrfxSpi = NRFX_SPI_INSTANCE(0);
union
{
uint8_t _buffer[NRFXSPI_MAX_PIXELS_AT_ONCE * 2] = {0};
uint16_t _buffer16[NRFXSPI_MAX_PIXELS_AT_ONCE];
uint32_t _buffer32[NRFXSPI_MAX_PIXELS_AT_ONCE / 2];
};
};
#endif // _ARDUINO_NRFXSPI_H_
#endif // #ifdef ARDUINO_ARCH_NRF52840

View File

@@ -0,0 +1,256 @@
#if defined(TARGET_RP2040) || defined(PICO_RP2350)
#include "Arduino_RPiPicoPAR16.h"
Arduino_RPiPicoPAR16::Arduino_RPiPicoPAR16(int8_t dc, int8_t cs, int8_t wr, int8_t rd)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd)
{
}
bool Arduino_RPiPicoPAR16::begin(int32_t speed, int8_t dataMode)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
_dcPinMask = digitalPinToBitMask(_dc);
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
_csPinMask = digitalPinToBitMask(_cs);
}
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
_wrPinMask = digitalPinToBitMask(_wr);
_dataClrMask = 0xFFFF | _wrPinMask;
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
sio_hw->gpio_clr = 0xFFFF;
return true;
}
void Arduino_RPiPicoPAR16::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_RPiPicoPAR16::endWrite()
{
CS_HIGH();
}
void Arduino_RPiPicoPAR16::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_RPiPicoPAR16::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_RPiPicoPAR16::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_RPiPicoPAR16::write(uint8_t d)
{
WRITE(d);
}
void Arduino_RPiPicoPAR16::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_RPiPicoPAR16::writeRepeat(uint16_t p, uint32_t len)
{
while (len--)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = p;
sio_hw->gpio_set = _wrPinMask;
}
}
void Arduino_RPiPicoPAR16::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = *data++;
sio_hw->gpio_set = _wrPinMask;
}
}
void Arduino_RPiPicoPAR16::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_RPiPicoPAR16::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_RPiPicoPAR16::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_RPiPicoPAR16::writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_RPiPicoPAR16::writeBytes(uint8_t *data, uint32_t len)
{
while (len > 1)
{
_data16.msb = *data++;
_data16.lsb = *data++;
WRITE16(_data16.value);
len -= 2;
}
if (len)
{
WRITE(*data);
}
}
void Arduino_RPiPicoPAR16::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = idx[*data++];
sio_hw->gpio_set = _wrPinMask;
}
}
void Arduino_RPiPicoPAR16::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = idx[*data++];
sio_hw->gpio_set = _wrPinMask;
sio_hw->gpio_clr = _wrPinMask;
sio_hw->gpio_set = _wrPinMask;
}
}
GFX_INLINE void Arduino_RPiPicoPAR16::WRITE(uint8_t d)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = d;
sio_hw->gpio_set = _wrPinMask;
}
GFX_INLINE void Arduino_RPiPicoPAR16::WRITE16(uint16_t d)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = d;
sio_hw->gpio_set = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_RPiPicoPAR16::DC_HIGH(void)
{
sio_hw->gpio_set = _dcPinMask;
}
GFX_INLINE void Arduino_RPiPicoPAR16::DC_LOW(void)
{
sio_hw->gpio_clr = _dcPinMask;
}
GFX_INLINE void Arduino_RPiPicoPAR16::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
sio_hw->gpio_set = _csPinMask;
}
}
GFX_INLINE void Arduino_RPiPicoPAR16::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
sio_hw->gpio_clr = _csPinMask;
}
}
#endif // #if defined(TARGET_RP2040) || defined(PICO_RP2350)

View File

@@ -0,0 +1,52 @@
#if defined(TARGET_RP2040) || defined(PICO_RP2350)
#ifndef _ARDUINO_RPIPICOPAR16_H_
#define _ARDUINO_RPIPICOPAR16_H_
#include "Arduino_DataBus.h"
class Arduino_RPiPicoPAR16 : public Arduino_DataBus
{
public:
Arduino_RPiPicoPAR16(int8_t dc, int8_t cs, int8_t wr, int8_t rd); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
uint32_t _dcPinMask; ///< Bitmask
uint32_t _csPinMask; ///< Bitmask
uint32_t _wrPinMask; ///< Bitmask
uint32_t _dataClrMask;
};
#endif // _ARDUINO_RPIPICOPAR16_H_
#endif // #if defined(TARGET_RP2040) || defined(PICO_RP2350)

View File

@@ -0,0 +1,240 @@
#if defined(TARGET_RP2040) || defined(PICO_RP2350)
#include "Arduino_RPiPicoPAR8.h"
Arduino_RPiPicoPAR8::Arduino_RPiPicoPAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd)
{
}
bool Arduino_RPiPicoPAR8::begin(int32_t speed, int8_t dataMode)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
_dcPinMask = digitalPinToBitMask(_dc);
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
_csPinMask = digitalPinToBitMask(_cs);
}
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
_wrPinMask = digitalPinToBitMask(_wr);
_dataClrMask = 0xFF | _wrPinMask;
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
sio_hw->gpio_clr = 0xFF;
return true;
}
void Arduino_RPiPicoPAR8::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_RPiPicoPAR8::endWrite()
{
CS_HIGH();
}
void Arduino_RPiPicoPAR8::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_RPiPicoPAR8::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_RPiPicoPAR8::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_RPiPicoPAR8::write(uint8_t d)
{
WRITE(d);
}
void Arduino_RPiPicoPAR8::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_RPiPicoPAR8::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
sio_hw->gpio_clr = 0xFF;
sio_hw->gpio_set = _data16.msb;
while (len--)
{
sio_hw->gpio_clr = _wrPinMask;
sio_hw->gpio_set = _wrPinMask;
sio_hw->gpio_clr = _wrPinMask;
sio_hw->gpio_set = _wrPinMask;
}
}
else
{
while (len--)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = _data16.msb;
sio_hw->gpio_set = _wrPinMask;
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = _data16.lsb;
sio_hw->gpio_set = _wrPinMask;
}
}
}
void Arduino_RPiPicoPAR8::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_RPiPicoPAR8::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_RPiPicoPAR8::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_RPiPicoPAR8::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_RPiPicoPAR8::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_RPiPicoPAR8::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_RPiPicoPAR8::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_RPiPicoPAR8::WRITE(uint8_t d)
{
sio_hw->gpio_clr = _dataClrMask;
sio_hw->gpio_set = d;
sio_hw->gpio_set = _wrPinMask;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_RPiPicoPAR8::DC_HIGH(void)
{
sio_hw->gpio_set = _dcPinMask;
}
GFX_INLINE void Arduino_RPiPicoPAR8::DC_LOW(void)
{
sio_hw->gpio_clr = _dcPinMask;
}
GFX_INLINE void Arduino_RPiPicoPAR8::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
sio_hw->gpio_set = _csPinMask;
}
}
GFX_INLINE void Arduino_RPiPicoPAR8::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
sio_hw->gpio_clr = _csPinMask;
}
}
#endif // #if defined(TARGET_RP2040) || defined(PICO_RP2350)

View File

@@ -0,0 +1,50 @@
#if defined(TARGET_RP2040) || defined(PICO_RP2350)
#ifndef _ARDUINO_RPIPICOPAR8_H_
#define _ARDUINO_RPIPICOPAR8_H_
#include "Arduino_DataBus.h"
class Arduino_RPiPicoPAR8 : public Arduino_DataBus
{
public:
Arduino_RPiPicoPAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
uint32_t _dcPinMask; ///< Bitmask
uint32_t _csPinMask; ///< Bitmask
uint32_t _wrPinMask; ///< Bitmask
uint32_t _dataClrMask;
};
#endif // _ARDUINO_RPIPICOPAR8_H_
#endif // #if defined(TARGET_RP2040) || defined(PICO_RP2350)

View File

@@ -0,0 +1,231 @@
#if defined(TARGET_RP2040) || defined(PICO_RP2350)
#include "Arduino_DataBus.h"
#include "Arduino_RPiPicoSPI.h"
Arduino_RPiPicoSPI::Arduino_RPiPicoSPI(int8_t dc /* = GFX_NOT_DEFINED */, int8_t cs /* = GFX_NOT_DEFINED */, int8_t sck /* = 18 */, int8_t mosi /* = 19 */, int8_t miso /* = 16 */, spi_inst_t *spi /* = spi0 */)
: _dc(dc), _cs(cs), _sck(sck), _mosi(mosi), _miso(miso), _spi(spi)
{
}
bool Arduino_RPiPicoSPI::begin(int32_t speed /* = 0 */, int8_t dataMode /* = GFX_NOT_DEFINED */)
{
// set SPI parameters
_speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed;
_dataMode = (dataMode != GFX_NOT_DEFINED) ? dataMode : SPI_MODE0;
_spis = SPISettings(_speed, _bitOrder, _dataMode);
// set pin mode
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
gpio_set_function(_miso, GPIO_FUNC_SPI);
gpio_set_function(_sck, GPIO_FUNC_SPI);
gpio_set_function(_mosi, GPIO_FUNC_SPI);
// set fastIO variables
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)&sio_hw->gpio_set;
_dcPortClr = (PORTreg_t)&sio_hw->gpio_clr;
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)&sio_hw->gpio_set;
_csPortClr = (PORTreg_t)&sio_hw->gpio_clr;
}
spi_init(_spi, _spis.getClockFreq());
spi_set_format(_spi, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
return true;
}
void Arduino_RPiPicoSPI::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_RPiPicoSPI::endWrite()
{
CS_HIGH();
}
void Arduino_RPiPicoSPI::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_RPiPicoSPI::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_RPiPicoSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_RPiPicoSPI::write(uint8_t d)
{
WRITE(d);
}
void Arduino_RPiPicoSPI::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_RPiPicoSPI::writeRepeat(uint16_t p, uint32_t len)
{
MSB_16_SET(p, p);
uint32_t bufLen = (len < RPIPICOSPI_MAX_PIXELS_AT_ONCE) ? len : RPIPICOSPI_MAX_PIXELS_AT_ONCE;
uint32_t xferLen;
for (uint32_t i = 0; i < bufLen; i++)
{
_buffer16[i] = p;
}
while (len)
{
xferLen = (bufLen < len) ? bufLen : len;
WRITEBUF(_buffer, xferLen * 2);
len -= xferLen;
}
}
void Arduino_RPiPicoSPI::writePixels(uint16_t *data, uint32_t len)
{
uint32_t xferLen;
uint8_t *p;
union
{
uint16_t val;
struct
{
uint8_t lsb;
uint8_t msb;
};
} t;
while (len)
{
xferLen = (len < RPIPICOSPI_MAX_PIXELS_AT_ONCE) ? len : RPIPICOSPI_MAX_PIXELS_AT_ONCE;
p = _buffer;
for (uint32_t i = 0; i < xferLen; i++)
{
t.val = *data++;
*p++ = t.msb;
*p++ = t.lsb;
}
len -= xferLen;
xferLen += xferLen; // uint16_t to uint8_t, double length
WRITEBUF(_buffer, xferLen);
}
}
void Arduino_RPiPicoSPI::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_RPiPicoSPI::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_RPiPicoSPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d1);
WRITE16(d2);
}
void Arduino_RPiPicoSPI::writeBytes(uint8_t *data, uint32_t len)
{
WRITEBUF(data, len);
}
GFX_INLINE void Arduino_RPiPicoSPI::WRITE(uint8_t d)
{
spi_write_blocking(_spi, (const uint8_t *)&d, 1);
}
GFX_INLINE void Arduino_RPiPicoSPI::WRITE16(uint16_t d)
{
MSB_16_SET(d, d);
spi_write_blocking(_spi, (const uint8_t *)&d, 2);
}
GFX_INLINE void Arduino_RPiPicoSPI::WRITEBUF(uint8_t *buf, size_t count)
{
spi_write_blocking(_spi, (const uint8_t *)buf, count);
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_RPiPicoSPI::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_RPiPicoSPI::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_RPiPicoSPI::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_RPiPicoSPI::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #if defined(TARGET_RP2040) || defined(PICO_RP2350)

View File

@@ -0,0 +1,69 @@
#pragma once
#include "Arduino_DataBus.h"
#if defined(TARGET_RP2040) || defined(PICO_RP2350)
#include <api/HardwareSPI.h>
#include <hardware/spi.h>
#ifndef RPIPICOSPI_MAX_PIXELS_AT_ONCE
#define RPIPICOSPI_MAX_PIXELS_AT_ONCE 32
#endif
class Arduino_RPiPicoSPI : public Arduino_DataBus
{
public:
Arduino_RPiPicoSPI(int8_t dc = GFX_NOT_DEFINED, int8_t cs = GFX_NOT_DEFINED, int8_t sck = 18, int8_t mosi = 19, int8_t miso = 16, spi_inst_t *spi = spi0); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITEBUF(uint8_t *buf, size_t count);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs;
int8_t _sck, _mosi, _miso;
int32_t _speed;
PORTreg_t _dcPortSet; ///< PORT register for data/command SET
PORTreg_t _dcPortClr; ///< PORT register for data/command CLEAR
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
uint32_t _dcPinMask; ///< Bitmask for data/command
uint32_t _csPinMask; ///< Bitmask for chip select
spi_inst_t *_spi;
SPISettings _spis;
BitOrder _bitOrder = MSBFIRST;
union
{
uint8_t _buffer[RPIPICOSPI_MAX_PIXELS_AT_ONCE * 2] = {0};
uint16_t _buffer16[RPIPICOSPI_MAX_PIXELS_AT_ONCE];
uint32_t _buffer32[RPIPICOSPI_MAX_PIXELS_AT_ONCE / 2];
};
};
#endif // #if defined(TARGET_RP2040) || defined(PICO_RP2350)

View File

@@ -0,0 +1,347 @@
#ifdef RTL8722DM
#include "Arduino_DataBus.h"
#include "Arduino_RTLPAR8.h"
Arduino_RTLPAR8::Arduino_RTLPAR8(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd),
_d0(d0), _d1(d1), _d2(d2), _d3(d3), _d4(d4), _d5(d5), _d6(d6), _d7(d7)
{
}
bool Arduino_RTLPAR8::begin(int32_t, int8_t)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
_dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc));
_dcPinMaskSet = digitalPinToBitMask(_dc);
_dcPinMaskClr = ~_dcPinMaskSet;
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
_csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs));
_csPinMaskSet = digitalPinToBitMask(_cs);
}
_csPinMaskClr = ~_csPinMaskSet;
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
_wrPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_wr));
_wrPinMaskSet = digitalPinToBitMask(_wr);
_wrPinMaskClr = ~_wrPinMaskSet;
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH);
}
// TODO: check pin in same port
pinMode(_d0, OUTPUT);
digitalWrite(_d0, HIGH);
pinMode(_d1, OUTPUT);
digitalWrite(_d1, HIGH);
pinMode(_d2, OUTPUT);
digitalWrite(_d2, HIGH);
pinMode(_d3, OUTPUT);
digitalWrite(_d3, HIGH);
pinMode(_d4, OUTPUT);
digitalWrite(_d4, HIGH);
pinMode(_d5, OUTPUT);
digitalWrite(_d5, HIGH);
pinMode(_d6, OUTPUT);
digitalWrite(_d6, HIGH);
pinMode(_d7, OUTPUT);
digitalWrite(_d7, HIGH);
// INIT 8-bit mask
_dataPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_d0));
for (int32_t c = 0; c < 256; c++)
{
_xset_mask[c] = 0;
if (c & 0x01)
{
_xset_mask[c] |= digitalPinToBitMask(_d0);
}
if (c & 0x02)
{
_xset_mask[c] |= digitalPinToBitMask(_d1);
}
if (c & 0x04)
{
_xset_mask[c] |= digitalPinToBitMask(_d2);
}
if (c & 0x08)
{
_xset_mask[c] |= digitalPinToBitMask(_d3);
}
if (c & 0x10)
{
_xset_mask[c] |= digitalPinToBitMask(_d4);
}
if (c & 0x20)
{
_xset_mask[c] |= digitalPinToBitMask(_d5);
}
if (c & 0x40)
{
_xset_mask[c] |= digitalPinToBitMask(_d6);
}
if (c & 0x80)
{
_xset_mask[c] |= digitalPinToBitMask(_d7);
}
}
_dataPinMaskClr = ~_xset_mask[255];
return true;
}
void Arduino_RTLPAR8::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_RTLPAR8::endWrite()
{
CS_HIGH();
}
void Arduino_RTLPAR8::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_RTLPAR8::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_RTLPAR8::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_RTLPAR8::write(uint8_t d)
{
WRITE(d);
}
void Arduino_RTLPAR8::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_RTLPAR8::writeRepeat(uint16_t p, uint32_t len)
{
uint32_t dataMaskBase = *_dataPort & _dataPinMaskClr;
uint32_t wrMaskBase = *_wrPort & _wrPinMaskClr;
uint32_t wrMaskSet = wrMaskBase | _wrPinMaskSet;
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
*_dataPort = dataMaskBase | _xset_mask[_data16.msb];
while (len--)
{
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
else
{
uint32_t hiMask = _xset_mask[_data16.msb];
uint32_t loMask = _xset_mask[_data16.lsb];
while (len--)
{
*_dataPort = dataMaskBase | hiMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_dataPort = dataMaskBase | loMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
}
void Arduino_RTLPAR8::writePixels(uint16_t *data, uint32_t len)
{
uint32_t dataMaskBase = *_dataPort & _dataPinMaskClr;
uint32_t wrMaskBase = *_wrPort & _wrPinMaskClr;
uint32_t wrMaskSet = wrMaskBase | _wrPinMaskSet;
while (len--)
{
_data16.value = *(data++);
uint32_t hiMask = _xset_mask[_data16.msb];
uint32_t loMask = _xset_mask[_data16.lsb];
*_dataPort = dataMaskBase | hiMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_dataPort = dataMaskBase | loMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
void Arduino_RTLPAR8::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_RTLPAR8::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_RTLPAR8::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_RTLPAR8::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_RTLPAR8::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
uint32_t dataMaskBase = *_dataPort & _dataPinMaskClr;
uint32_t wrMaskBase = *_wrPort & _wrPinMaskClr;
uint32_t wrMaskSet = wrMaskBase | _wrPinMaskSet;
while (len--)
{
_data16.value = idx[*data++];
*_dataPort = dataMaskBase | _xset_mask[_data16.msb];
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_dataPort = dataMaskBase | _xset_mask[_data16.lsb];
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
void Arduino_RTLPAR8::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
uint32_t dataMaskBase = *_dataPort & _dataPinMaskClr;
uint32_t wrMaskBase = *_wrPort & _wrPinMaskClr;
uint32_t wrMaskSet = wrMaskBase | _wrPinMaskSet;
while (len--)
{
_data16.value = idx[*data++];
uint32_t hiMask = _xset_mask[_data16.msb];
uint32_t loMask = _xset_mask[_data16.lsb];
*_dataPort = dataMaskBase | hiMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_dataPort = dataMaskBase | loMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_dataPort = dataMaskBase | hiMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
*_dataPort = dataMaskBase | loMask;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
GFX_INLINE void Arduino_RTLPAR8::WRITE(uint8_t d)
{
uint32_t dataMaskBase = *_dataPort & _dataPinMaskClr;
uint32_t wrMaskBase = *_wrPort & _wrPinMaskClr;
*_dataPort = dataMaskBase | _xset_mask[d];
*_wrPort = wrMaskBase;
*_wrPort = wrMaskBase | _wrPinMaskSet;
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_RTLPAR8::DC_HIGH(void)
{
*_dcPort |= _dcPinMaskSet;
}
GFX_INLINE void Arduino_RTLPAR8::DC_LOW(void)
{
*_dcPort &= _dcPinMaskClr;
}
GFX_INLINE void Arduino_RTLPAR8::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort |= _csPinMaskSet;
}
}
GFX_INLINE void Arduino_RTLPAR8::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPort &= _csPinMaskClr;
}
}
#endif // #ifdef RTL8722DM

View File

@@ -0,0 +1,66 @@
#ifdef RTL8722DM
#ifndef _ARDUINO_RTLPAR8_H_
#define _ARDUINO_RTLPAR8_H_
#include "Arduino_DataBus.h"
class Arduino_RTLPAR8 : public Arduino_DataBus
{
public:
Arduino_RTLPAR8(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
PORTreg_t _dcPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _csPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _csPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _csPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _wrPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _wrPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _wrPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
PORTreg_t _dataPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _dataPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
// Lookup table for ESP32 parallel bus interface uses 1kbyte RAM,
uint32_t _xset_mask[256];
};
#endif // _ARDUINO_RTLPAR8_H_
#endif // #ifdef RTL8722DM

View File

@@ -0,0 +1,257 @@
#ifdef ARDUINO_ARCH_STM32
#include "Arduino_STM32PAR8.h"
Arduino_STM32PAR8::Arduino_STM32PAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd, GPIO_TypeDef *port)
: _dc(dc), _cs(cs), _wr(wr), _rd(rd), _port(port)
{
}
bool Arduino_STM32PAR8::begin(int32_t, int8_t)
{
set_GPIO_Port_Clock(STM_PORT(_port)); // Enable data port
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
_dcPORT = digitalPinToPort(_dc);
_dcPinMaskSet = digitalPinToBitMask(_dc);
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // Disable chip select
_csPinMaskSet = digitalPinToBitMask(_cs);
_csPORT = digitalPinToPort(_cs);
}
pinMode(_wr, OUTPUT);
digitalWrite(_wr, HIGH); // Set write strobe high (inactive)
_wrPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_wr));
_wrPORT = digitalPinToPort(_wr);
_wrPinMaskSet = digitalPinToBitMask(_wr);
_wrPinMaskClr = ~_wrPinMaskSet;
if (_rd != GFX_NOT_DEFINED)
{
pinMode(_rd, OUTPUT);
digitalWrite(_rd, HIGH); // Disable RD
_rdPinMaskSet = digitalPinToBitMask(_rd);
}
else
{
_rdPinMaskSet = 0;
}
*(portModeRegister(_port)) = 0x33333333; // Set data port to output at max speed
_port->BSRR = 0xFF << 16; // Clear data port
return true;
}
void Arduino_STM32PAR8::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_STM32PAR8::endWrite()
{
CS_HIGH();
}
void Arduino_STM32PAR8::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_STM32PAR8::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_STM32PAR8::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_STM32PAR8::write(uint8_t d)
{
WRITE(d);
}
void Arduino_STM32PAR8::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_STM32PAR8::writeRepeat(uint16_t p, uint32_t len)
{
uint8_t wrMaskBase = *_wrPort & _wrPinMaskClr;
uint8_t wrMaskSet = wrMaskBase | _wrPinMaskSet;
uint32_t wrMASKCLR = _wrPinMaskSet << 16;
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
_port->BSRR = 0xFF << 16;
_port->BSRR = (_data16.msb) & 0xFF;
while (len--)
{
*_wrPort = wrMaskBase; // For some reason in this case it's faster then BSRR
*_wrPort = wrMaskSet;
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
else
{
while (len--)
{
_port->BSRR = 0xFF << 16;
_port->BSRR = (_data16.msb);
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
_port->BSRR = 0xFF << 16;
_port->BSRR = (_data16.lsb);
*_wrPort = wrMaskBase;
*_wrPort = wrMaskSet;
}
}
}
void Arduino_STM32PAR8::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_STM32PAR8::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_STM32PAR8::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_STM32PAR8::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
WRITE(c);
DC_HIGH();
_data16.value = d1;
WRITE(_data16.msb);
WRITE(_data16.lsb);
_data16.value = d2;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_STM32PAR8::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_STM32PAR8::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
void Arduino_STM32PAR8::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
{
while (len--)
{
_data16.value = idx[*data++];
WRITE(_data16.msb);
WRITE(_data16.lsb);
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_STM32PAR8::WRITE(uint8_t d)
{
_port->BSRR = 0xFF << 16;
_port->BSRR = (d)&0xFF;
_wrPORT->BSRR = _wrPinMaskSet << 16; // Set WR LOW
_wrPORT->BSRR = _wrPinMaskSet; // Set WR HIGH
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_STM32PAR8::DC_HIGH(void)
{
_dcPORT->BSRR = _dcPinMaskSet;
}
GFX_INLINE void Arduino_STM32PAR8::DC_LOW(void)
{
_dcPORT->BSRR = _dcPinMaskSet << 16;
}
GFX_INLINE void Arduino_STM32PAR8::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
_csPORT->BSRR = _csPinMaskSet;
}
}
GFX_INLINE void Arduino_STM32PAR8::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
_csPORT->BSRR = _csPinMaskSet << 16;
}
}
#endif // #ifdef ARDUINO_ARCH_STM32

View File

@@ -0,0 +1,57 @@
#ifdef ARDUINO_ARCH_STM32
#ifndef _ARDUINO_STM32PAR8_H_
#define _ARDUINO_STM32PAR8_H_
#include "Arduino_DataBus.h"
class Arduino_STM32PAR8 : public Arduino_DataBus
{
public:
Arduino_STM32PAR8(int8_t dc, int8_t cs, int8_t wr, int8_t rd, GPIO_TypeDef* port); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs, _wr, _rd;
GPIO_TypeDef* _port;
GPIO_TypeDef* _dcPORT;
GPIO_TypeDef* _csPORT;
GPIO_TypeDef* _wrPORT;
GPIO_TypeDef* _rdPORT;
ARDUINOGFX_PORT_t _dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _csPinMaskSet; ///< Bitmask for data/command SET (OR)
PORTreg_t _wrPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _wrPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _wrPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
ARDUINOGFX_PORT_t _rdPinMaskSet; ///< Bitmask for data/command SET (OR)
};
#endif // _ARDUINO_STM32PAR8_H_
#endif // #ifdef ARDUINO_ARCH_STM32

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,220 @@
#ifndef _ARDUINO_SWPAR16_H_
#define _ARDUINO_SWPAR16_H_
#include "Arduino_DataBus.h"
class Arduino_SWPAR16 : public Arduino_DataBus
{
public:
Arduino_SWPAR16(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7,
int8_t d8, int8_t d9, int8_t d10, int8_t d11, int8_t d12, int8_t d13, int8_t d14, int8_t d15); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
#if !defined(LITTLE_FOOT_PRINT)
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeC8D16D16Split(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
#endif // !defined(LITTLE_FOOT_PRINT)
protected:
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITEREPEAT(uint16_t p, uint32_t len);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
GFX_INLINE void WR_HIGH(void);
GFX_INLINE void WR_LOW(void);
GFX_INLINE void D0_HIGH(void);
GFX_INLINE void D0_LOW(void);
GFX_INLINE void D1_HIGH(void);
GFX_INLINE void D1_LOW(void);
GFX_INLINE void D2_HIGH(void);
GFX_INLINE void D2_LOW(void);
GFX_INLINE void D3_HIGH(void);
GFX_INLINE void D3_LOW(void);
GFX_INLINE void D4_HIGH(void);
GFX_INLINE void D4_LOW(void);
GFX_INLINE void D5_HIGH(void);
GFX_INLINE void D5_LOW(void);
GFX_INLINE void D6_HIGH(void);
GFX_INLINE void D6_LOW(void);
GFX_INLINE void D7_HIGH(void);
GFX_INLINE void D7_LOW(void);
GFX_INLINE void D8_HIGH(void);
GFX_INLINE void D8_LOW(void);
GFX_INLINE void D9_HIGH(void);
GFX_INLINE void D9_LOW(void);
GFX_INLINE void D10_HIGH(void);
GFX_INLINE void D10_LOW(void);
GFX_INLINE void D11_HIGH(void);
GFX_INLINE void D11_LOW(void);
GFX_INLINE void D12_HIGH(void);
GFX_INLINE void D12_LOW(void);
GFX_INLINE void D13_HIGH(void);
GFX_INLINE void D13_LOW(void);
GFX_INLINE void D14_HIGH(void);
GFX_INLINE void D14_LOW(void);
GFX_INLINE void D15_HIGH(void);
GFX_INLINE void D15_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
int8_t _d8, _d9, _d10, _d11, _d12, _d13, _d14, _d15;
// CLASS INSTANCE VARIABLES --------------------------------------------
// Here be dragons! There's a big union of three structures here --
// one each for hardware SPI, software (bitbang) SPI, and parallel
// interfaces. This is to save some memory, since a display's connection
// will be only one of these. The order of some things is a little weird
// in an attempt to get values to align and pack better in RAM.
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
PORTreg_t _dcPortSet;
PORTreg_t _dcPortClr;
PORTreg_t _csPortSet;
PORTreg_t _csPortClr;
PORTreg_t _wrPortSet;
PORTreg_t _wrPortClr;
PORTreg_t _d0PortSet;
PORTreg_t _d0PortClr;
PORTreg_t _d1PortSet;
PORTreg_t _d1PortClr;
PORTreg_t _d2PortSet;
PORTreg_t _d2PortClr;
PORTreg_t _d3PortSet;
PORTreg_t _d3PortClr;
PORTreg_t _d4PortSet;
PORTreg_t _d4PortClr;
PORTreg_t _d5PortSet;
PORTreg_t _d5PortClr;
PORTreg_t _d6PortSet;
PORTreg_t _d6PortClr;
PORTreg_t _d7PortSet;
PORTreg_t _d7PortClr;
PORTreg_t _d8PortSet;
PORTreg_t _d8PortClr;
PORTreg_t _d9PortSet;
PORTreg_t _d9PortClr;
PORTreg_t _d10PortSet;
PORTreg_t _d10PortClr;
PORTreg_t _d11PortSet;
PORTreg_t _d11PortClr;
PORTreg_t _d12PortSet;
PORTreg_t _d12PortClr;
PORTreg_t _d13PortSet;
PORTreg_t _d13PortClr;
PORTreg_t _d14PortSet;
PORTreg_t _d14PortClr;
PORTreg_t _d15PortSet;
PORTreg_t _d15PortClr;
#if !defined(KINETISK)
ARDUINOGFX_PORT_t _dcPinMask;
ARDUINOGFX_PORT_t _csPinMask;
ARDUINOGFX_PORT_t _wrPinMask;
ARDUINOGFX_PORT_t _d0PinMask;
ARDUINOGFX_PORT_t _d1PinMask;
ARDUINOGFX_PORT_t _d2PinMask;
ARDUINOGFX_PORT_t _d3PinMask;
ARDUINOGFX_PORT_t _d4PinMask;
ARDUINOGFX_PORT_t _d5PinMask;
ARDUINOGFX_PORT_t _d6PinMask;
ARDUINOGFX_PORT_t _d7PinMask;
ARDUINOGFX_PORT_t _d8PinMask;
ARDUINOGFX_PORT_t _d9PinMask;
ARDUINOGFX_PORT_t _d10PinMask;
ARDUINOGFX_PORT_t _d11PinMask;
ARDUINOGFX_PORT_t _d12PinMask;
ARDUINOGFX_PORT_t _d13PinMask;
ARDUINOGFX_PORT_t _d14PinMask;
ARDUINOGFX_PORT_t _d15PinMask;
#endif // !KINETISK
#else // !HAS_PORT_SET_CLR
PORTreg_t _dcPort;
PORTreg_t _csPort;
PORTreg_t _wrPort;
PORTreg_t _d0Port;
PORTreg_t _d1Port;
PORTreg_t _d2Port;
PORTreg_t _d3Port;
PORTreg_t _d4Port;
PORTreg_t _d5Port;
PORTreg_t _d6Port;
PORTreg_t _d7Port;
PORTreg_t _d8Port;
PORTreg_t _d9Port;
PORTreg_t _d10Port;
PORTreg_t _d11Port;
PORTreg_t _d12Port;
PORTreg_t _d13Port;
PORTreg_t _d14Port;
PORTreg_t _d15Port;
ARDUINOGFX_PORT_t _dcPinMaskSet;
ARDUINOGFX_PORT_t _dcPinMaskClr;
ARDUINOGFX_PORT_t _csPinMaskSet;
ARDUINOGFX_PORT_t _csPinMaskClr;
ARDUINOGFX_PORT_t _wrPinMaskSet;
ARDUINOGFX_PORT_t _wrPinMaskClr;
ARDUINOGFX_PORT_t _rdPinMaskSet;
ARDUINOGFX_PORT_t _rdPinMaskClr;
ARDUINOGFX_PORT_t _d0PinMaskSet;
ARDUINOGFX_PORT_t _d0PinMaskClr;
ARDUINOGFX_PORT_t _d1PinMaskSet;
ARDUINOGFX_PORT_t _d1PinMaskClr;
ARDUINOGFX_PORT_t _d2PinMaskSet;
ARDUINOGFX_PORT_t _d2PinMaskClr;
ARDUINOGFX_PORT_t _d3PinMaskSet;
ARDUINOGFX_PORT_t _d3PinMaskClr;
ARDUINOGFX_PORT_t _d4PinMaskSet;
ARDUINOGFX_PORT_t _d4PinMaskClr;
ARDUINOGFX_PORT_t _d5PinMaskSet;
ARDUINOGFX_PORT_t _d5PinMaskClr;
ARDUINOGFX_PORT_t _d6PinMaskSet;
ARDUINOGFX_PORT_t _d6PinMaskClr;
ARDUINOGFX_PORT_t _d7PinMaskSet;
ARDUINOGFX_PORT_t _d7PinMaskClr;
ARDUINOGFX_PORT_t _d8PinMaskSet;
ARDUINOGFX_PORT_t _d8PinMaskClr;
ARDUINOGFX_PORT_t _d9PinMaskSet;
ARDUINOGFX_PORT_t _d9PinMaskClr;
ARDUINOGFX_PORT_t _d10PinMaskSet;
ARDUINOGFX_PORT_t _d10PinMaskClr;
ARDUINOGFX_PORT_t _d11PinMaskSet;
ARDUINOGFX_PORT_t _d11PinMaskClr;
ARDUINOGFX_PORT_t _d12PinMaskSet;
ARDUINOGFX_PORT_t _d12PinMaskClr;
ARDUINOGFX_PORT_t _d13PinMaskSet;
ARDUINOGFX_PORT_t _d13PinMaskClr;
ARDUINOGFX_PORT_t _d14PinMaskSet;
ARDUINOGFX_PORT_t _d14PinMaskClr;
ARDUINOGFX_PORT_t _d15PinMaskSet;
ARDUINOGFX_PORT_t _d15PinMaskClr;
#endif // HAS_PORT_SET_CLR
#endif // defined(USE_FAST_PINIO)
};
#endif // _ARDUINO_SWPAR16_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,151 @@
#ifndef _ARDUINO_SWPAR8_H_
#define _ARDUINO_SWPAR8_H_
#include "Arduino_DataBus.h"
class Arduino_SWPAR8 : public Arduino_DataBus
{
public:
Arduino_SWPAR8(
int8_t dc, int8_t cs, int8_t wr, int8_t rd,
int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t d6, int8_t d7); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
#if !defined(LITTLE_FOOT_PRINT)
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) override;
void writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) override;
#endif // !defined(LITTLE_FOOT_PRINT)
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITEREPEAT(uint16_t p, uint32_t len);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
GFX_INLINE void WR_HIGH(void);
GFX_INLINE void WR_LOW(void);
GFX_INLINE void D0_HIGH(void);
GFX_INLINE void D0_LOW(void);
GFX_INLINE void D1_HIGH(void);
GFX_INLINE void D1_LOW(void);
GFX_INLINE void D2_HIGH(void);
GFX_INLINE void D2_LOW(void);
GFX_INLINE void D3_HIGH(void);
GFX_INLINE void D3_LOW(void);
GFX_INLINE void D4_HIGH(void);
GFX_INLINE void D4_LOW(void);
GFX_INLINE void D5_HIGH(void);
GFX_INLINE void D5_LOW(void);
GFX_INLINE void D6_HIGH(void);
GFX_INLINE void D6_LOW(void);
GFX_INLINE void D7_HIGH(void);
GFX_INLINE void D7_LOW(void);
int8_t _dc, _cs, _wr, _rd;
int8_t _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7;
// CLASS INSTANCE VARIABLES --------------------------------------------
// Here be dragons! There's a big union of three structures here --
// one each for hardware SPI, software (bitbang) SPI, and parallel
// interfaces. This is to save some memory, since a display's connection
// will be only one of these. The order of some things is a little weird
// in an attempt to get values to align and pack better in RAM.
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
PORTreg_t _dcPortSet;
PORTreg_t _dcPortClr;
PORTreg_t _csPortSet;
PORTreg_t _csPortClr;
PORTreg_t _wrPortSet;
PORTreg_t _wrPortClr;
PORTreg_t _d0PortSet;
PORTreg_t _d0PortClr;
PORTreg_t _d1PortSet;
PORTreg_t _d1PortClr;
PORTreg_t _d2PortSet;
PORTreg_t _d2PortClr;
PORTreg_t _d3PortSet;
PORTreg_t _d3PortClr;
PORTreg_t _d4PortSet;
PORTreg_t _d4PortClr;
PORTreg_t _d5PortSet;
PORTreg_t _d5PortClr;
PORTreg_t _d6PortSet;
PORTreg_t _d6PortClr;
PORTreg_t _d7PortSet;
PORTreg_t _d7PortClr;
#if !defined(KINETISK)
ARDUINOGFX_PORT_t _dcPinMask;
ARDUINOGFX_PORT_t _csPinMask;
ARDUINOGFX_PORT_t _wrPinMask;
ARDUINOGFX_PORT_t _d0PinMask;
ARDUINOGFX_PORT_t _d1PinMask;
ARDUINOGFX_PORT_t _d2PinMask;
ARDUINOGFX_PORT_t _d3PinMask;
ARDUINOGFX_PORT_t _d4PinMask;
ARDUINOGFX_PORT_t _d5PinMask;
ARDUINOGFX_PORT_t _d6PinMask;
ARDUINOGFX_PORT_t _d7PinMask;
#endif // !KINETISK
#else // !HAS_PORT_SET_CLR
PORTreg_t _dcPort;
PORTreg_t _csPort;
PORTreg_t _wrPort;
PORTreg_t _d0Port;
PORTreg_t _d1Port;
PORTreg_t _d2Port;
PORTreg_t _d3Port;
PORTreg_t _d4Port;
PORTreg_t _d5Port;
PORTreg_t _d6Port;
PORTreg_t _d7Port;
ARDUINOGFX_PORT_t _dcPinMaskSet;
ARDUINOGFX_PORT_t _dcPinMaskClr;
ARDUINOGFX_PORT_t _csPinMaskSet;
ARDUINOGFX_PORT_t _csPinMaskClr;
ARDUINOGFX_PORT_t _wrPinMaskSet;
ARDUINOGFX_PORT_t _wrPinMaskClr;
ARDUINOGFX_PORT_t _rdPinMaskSet;
ARDUINOGFX_PORT_t _rdPinMaskClr;
ARDUINOGFX_PORT_t _d0PinMaskSet;
ARDUINOGFX_PORT_t _d0PinMaskClr;
ARDUINOGFX_PORT_t _d1PinMaskSet;
ARDUINOGFX_PORT_t _d1PinMaskClr;
ARDUINOGFX_PORT_t _d2PinMaskSet;
ARDUINOGFX_PORT_t _d2PinMaskClr;
ARDUINOGFX_PORT_t _d3PinMaskSet;
ARDUINOGFX_PORT_t _d3PinMaskClr;
ARDUINOGFX_PORT_t _d4PinMaskSet;
ARDUINOGFX_PORT_t _d4PinMaskClr;
ARDUINOGFX_PORT_t _d5PinMaskSet;
ARDUINOGFX_PORT_t _d5PinMaskClr;
ARDUINOGFX_PORT_t _d6PinMaskSet;
ARDUINOGFX_PORT_t _d6PinMaskClr;
ARDUINOGFX_PORT_t _d7PinMaskSet;
ARDUINOGFX_PORT_t _d7PinMaskClr;
#endif // HAS_PORT_SET_CLR
#endif // defined(USE_FAST_PINIO)
};
#endif // _ARDUINO_SWPAR8_H_

View File

@@ -0,0 +1,737 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#include "Arduino_SWSPI.h"
Arduino_SWSPI::Arduino_SWSPI(int8_t dc, int8_t cs, int8_t sck, int8_t mosi, int8_t miso /* = GFX_NOT_DEFINED */)
: _dc(dc), _cs(cs), _sck(sck), _mosi(mosi), _miso(miso)
{
}
bool Arduino_SWSPI::begin(int32_t, int8_t)
{
if (_dc != GFX_NOT_DEFINED)
{
pinMode(_dc, OUTPUT);
digitalWrite(_dc, HIGH); // Data mode
}
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // Deselect
}
pinMode(_sck, OUTPUT);
digitalWrite(_sck, LOW);
pinMode(_mosi, OUTPUT);
digitalWrite(_mosi, LOW);
if (_miso != GFX_NOT_DEFINED)
{
pinMode(_miso, INPUT);
}
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(ARDUINO_ARCH_NRF52840)
uint32_t pin;
NRF_GPIO_Type *reg;
if (_dc != GFX_NOT_DEFINED)
{
pin = digitalPinToPinName((pin_size_t)_dc);
reg = nrf_gpio_pin_port_decode(&pin);
_dcPinMask = 1UL << pin;
_dcPortSet = &reg->OUTSET;
_dcPortClr = &reg->OUTCLR;
}
if (_cs != GFX_NOT_DEFINED)
{
pin = digitalPinToPinName((pin_size_t)_cs);
NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin);
_csPinMask = 1UL << pin;
_csPortSet = &reg->OUTSET;
_csPortClr = &reg->OUTCLR;
}
pin = digitalPinToPinName((pin_size_t)_sck);
reg = nrf_gpio_pin_port_decode(&pin);
_sckPinMask = 1UL << pin;
_sckPortSet = &reg->OUTSET;
_sckPortClr = &reg->OUTCLR;
pin = digitalPinToPinName((pin_size_t)_mosi);
reg = nrf_gpio_pin_port_decode(&pin);
_mosiPinMask = 1UL << pin;
_mosiPortSet = &reg->OUTSET;
_mosiPortClr = &reg->OUTCLR;
if (_miso != GFX_NOT_DEFINED)
{
pin = digitalPinToPinName((pin_size_t)_miso);
reg = nrf_gpio_pin_port_decode(&pin);
_misoPinMask = 1UL << pin;
_misoPort = &reg->IN;
}
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
if (_dc != GFX_NOT_DEFINED)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_dc)))->POSR);
_dcPortClr = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_dc)))->PORR);
}
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_cs)))->POSR);
_csPortClr = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_cs)))->PORR);
}
_sckPinMask = digitalPinToBitMask(_sck);
_sckPortSet = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_sck)))->POSR);
_sckPortClr = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_sck)))->PORR);
_mosiPinMask = digitalPinToBitMask(_mosi);
_mosiPortSet = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_mosi)))->POSR);
_mosiPortClr = (PORTreg_t) & (((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(digitalPinToPort(_mosi)))->PORR);
if (_miso != GFX_NOT_DEFINED)
{
_misoPinMask = digitalPinToBitMask(_miso);
_misoPort = (PORTreg_t)portInputRegister(digitalPinToPort(_miso));
}
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
if (_dc != GFX_NOT_DEFINED)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)&sio_hw->gpio_set;
_dcPortClr = (PORTreg_t)&sio_hw->gpio_clr;
}
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)&sio_hw->gpio_set;
_csPortClr = (PORTreg_t)&sio_hw->gpio_clr;
}
_sckPinMask = digitalPinToBitMask(_sck);
_sckPortSet = (PORTreg_t)&sio_hw->gpio_set;
_sckPortClr = (PORTreg_t)&sio_hw->gpio_clr;
_mosiPinMask = digitalPinToBitMask(_mosi);
_mosiPortSet = (PORTreg_t)&sio_hw->gpio_set;
_mosiPortClr = (PORTreg_t)&sio_hw->gpio_clr;
if (_miso != GFX_NOT_DEFINED)
{
_misoPinMask = digitalPinToBitMask(_miso);
_misoPort = (PORTreg_t)portInputRegister(digitalPinToPort(_miso));
}
#elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5)
_dcPinMask = digitalPinToBitMask(_dc);
if (_dc >= 32)
{
_dcPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_dc != GFX_NOT_DEFINED)
{
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
_sckPinMask = digitalPinToBitMask(_sck);
_mosiPinMask = digitalPinToBitMask(_mosi);
if (_sck >= 32)
{
_sckPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_sckPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_sckPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_sckPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
if (_mosi >= 32)
{
_mosiPortSet = (PORTreg_t)GPIO_OUT1_W1TS_REG;
_mosiPortClr = (PORTreg_t)GPIO_OUT1_W1TC_REG;
}
else
{
_mosiPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_mosiPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
if (_miso != GFX_NOT_DEFINED)
{
_misoPinMask = digitalPinToBitMask(_miso);
_misoPort = (PORTreg_t)portInputRegister(digitalPinToPort(_miso));
}
#elif defined(ESP32)
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_dcPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_csPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
}
_sckPinMask = digitalPinToBitMask(_sck);
_sckPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_sckPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
_mosiPinMask = digitalPinToBitMask(_mosi);
_mosiPortSet = (PORTreg_t)GPIO_OUT_W1TS_REG;
_mosiPortClr = (PORTreg_t)GPIO_OUT_W1TC_REG;
if (_miso != GFX_NOT_DEFINED)
{
_misoPinMask = digitalPinToBitMask(_miso);
_misoPort = (PORTreg_t)GPIO_IN_REG;
}
#elif defined(CORE_TEENSY)
if (_dc != GFX_NOT_DEFINED)
{
#if !defined(KINETISK)
_dcPinMask = digitalPinToBitMask(_dc);
#endif
_dcPortSet = portSetRegister(_dc);
_dcPortClr = portClearRegister(_dc);
}
if (_cs != GFX_NOT_DEFINED)
{
#if !defined(KINETISK)
_csPinMask = digitalPinToBitMask(_cs);
#endif
_csPortSet = portSetRegister(_cs);
_csPortClr = portClearRegister(_cs);
}
#if !defined(KINETISK)
_sckPinMask = digitalPinToBitMask(_sck);
#endif
_sckPortSet = portSetRegister(_sck);
_sckPortClr = portClearRegister(_sck);
#if !defined(KINETISK)
_mosiPinMask = digitalPinToBitMask(_mosi);
#endif
_mosiPortSet = portSetRegister(_mosi);
_mosiPortClr = portClearRegister(_mosi);
if (_miso != GFX_NOT_DEFINED)
{
#if !defined(KINETISK)
_misoPinMask = digitalPinToBitMask(_miso);
#endif
_misoPort = (PORTreg_t)portInputRegister(digitalPinToPort(_miso));
}
#else // !CORE_TEENSY
if (_dc != GFX_NOT_DEFINED)
{
_dcPinMask = digitalPinToBitMask(_dc);
_dcPortSet = &(PORT->Group[g_APinDescription[_dc].ulPort].OUTSET.reg);
_dcPortClr = &(PORT->Group[g_APinDescription[_dc].ulPort].OUTCLR.reg);
}
if (_cs != GFX_NOT_DEFINED)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = &(PORT->Group[g_APinDescription[_cs].ulPort].OUTSET.reg);
_csPortClr = &(PORT->Group[g_APinDescription[_cs].ulPort].OUTCLR.reg);
}
_sckPinMask = digitalPinToBitMask(_sck);
_sckPortSet = &(PORT->Group[g_APinDescription[_sck].ulPort].OUTSET.reg);
_sckPortClr = &(PORT->Group[g_APinDescription[_sck].ulPort].OUTCLR.reg);
_mosiPinMask = digitalPinToBitMask(_mosi);
_mosiPortSet = &(PORT->Group[g_APinDescription[_mosi].ulPort].OUTSET.reg);
_mosiPortClr = &(PORT->Group[g_APinDescription[_mosi].ulPort].OUTCLR.reg);
if (_miso != GFX_NOT_DEFINED)
{
_misoPinMask = digitalPinToBitMask(_miso);
_misoPort = (PORTreg_t)portInputRegister(digitalPinToPort(_miso));
}
#endif // end !CORE_TEENSY
#else // !HAS_PORT_SET_CLR
if (_dc != GFX_NOT_DEFINED)
{
_dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc));
_dcPinMaskSet = digitalPinToBitMask(_dc);
_dcPinMaskClr = ~_dcPinMaskSet;
}
if (_cs != GFX_NOT_DEFINED)
{
_csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs));
_csPinMaskSet = digitalPinToBitMask(_cs);
_csPinMaskClr = ~_csPinMaskSet;
}
_sckPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_sck));
_sckPinMaskSet = digitalPinToBitMask(_sck);
_sckPinMaskClr = ~_sckPinMaskSet;
_mosiPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_mosi));
_mosiPinMaskSet = digitalPinToBitMask(_mosi);
_mosiPinMaskClr = ~_mosiPinMaskSet;
if (_miso != GFX_NOT_DEFINED)
{
_misoPort = (PORTreg_t)portInputRegister(digitalPinToPort(_miso));
_misoPinMask = digitalPinToBitMask(_miso);
}
#endif // !HAS_PORT_SET_CLR
#endif // USE_FAST_PINIO
return true;
}
void Arduino_SWSPI::beginWrite()
{
if (_dc != GFX_NOT_DEFINED)
{
DC_HIGH();
}
CS_LOW();
}
void Arduino_SWSPI::endWrite()
{
CS_HIGH();
}
void Arduino_SWSPI::writeCommand(uint8_t c)
{
if (_dc == GFX_NOT_DEFINED) // 9-bit SPI
{
WRITE9BITCOMMAND(c);
}
else
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
}
void Arduino_SWSPI::writeCommand16(uint16_t c)
{
if (_dc == GFX_NOT_DEFINED) // 9-bit SPI
{
_data16.value = c;
WRITE9BITCOMMAND(_data16.msb);
WRITE9BITCOMMAND(_data16.lsb);
}
else
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
}
void Arduino_SWSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
if (_dc == GFX_NOT_DEFINED) // 9-bit SPI
{
while (len--)
{
WRITE9BITCOMMAND(*data++);
}
}
else
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
}
void Arduino_SWSPI::write(uint8_t d)
{
if (_dc == GFX_NOT_DEFINED) // 9-bit SPI
{
WRITE9BITDATA(d);
}
else
{
WRITE(d);
}
}
void Arduino_SWSPI::write16(uint16_t d)
{
if (_dc == GFX_NOT_DEFINED) // 9-bit SPI
{
_data16.value = d;
WRITE9BITDATA(_data16.msb);
WRITE9BITDATA(_data16.lsb);
}
else
{
WRITE16(d);
}
}
void Arduino_SWSPI::writeRepeat(uint16_t p, uint32_t len)
{
if (_dc == GFX_NOT_DEFINED) // 9-bit SPI
{
// ESP8266 avoid trigger watchdog
#if defined(ESP8266)
while (len > (ESP8266SAFEBATCHBITSIZE / 9))
{
WRITE9BITREPEAT(p, ESP8266SAFEBATCHBITSIZE / 9);
len -= ESP8266SAFEBATCHBITSIZE / 9;
yield();
}
WRITE9BITREPEAT(p, len);
#else
WRITE9BITREPEAT(p, len);
#endif
}
else
{
#if defined(ESP8266)
while (len > (ESP8266SAFEBATCHBITSIZE / 8))
{
WRITEREPEAT(p, ESP8266SAFEBATCHBITSIZE / 8);
len -= ESP8266SAFEBATCHBITSIZE / 8;
yield();
}
WRITEREPEAT(p, len);
#else
WRITEREPEAT(p, len);
#endif
}
}
void Arduino_SWSPI::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
WRITE16(*data++);
}
}
#if !defined(LITTLE_FOOT_PRINT)
void Arduino_SWSPI::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
#endif // !defined(LITTLE_FOOT_PRINT)
GFX_INLINE void Arduino_SWSPI::WRITE9BITCOMMAND(uint8_t c)
{
// D/C bit, command
SPI_MOSI_LOW();
SPI_SCK_HIGH();
SPI_SCK_LOW();
uint8_t bit = 0x80;
while (bit)
{
if (c & bit)
{
SPI_MOSI_HIGH();
}
else
{
SPI_MOSI_LOW();
}
SPI_SCK_HIGH();
bit >>= 1;
SPI_SCK_LOW();
}
}
GFX_INLINE void Arduino_SWSPI::WRITE9BITDATA(uint8_t d)
{
// D/C bit, data
SPI_MOSI_HIGH();
SPI_SCK_HIGH();
SPI_SCK_LOW();
uint8_t bit = 0x80;
while (bit)
{
if (d & bit)
{
SPI_MOSI_HIGH();
}
else
{
SPI_MOSI_LOW();
}
SPI_SCK_HIGH();
bit >>= 1;
SPI_SCK_LOW();
}
}
GFX_INLINE void Arduino_SWSPI::WRITE(uint8_t d)
{
uint8_t bit = 0x80;
while (bit)
{
if (d & bit)
{
SPI_MOSI_HIGH();
}
else
{
SPI_MOSI_LOW();
}
SPI_SCK_HIGH();
bit >>= 1;
SPI_SCK_LOW();
}
}
GFX_INLINE void Arduino_SWSPI::WRITE16(uint16_t d)
{
uint16_t bit = 0x8000;
while (bit)
{
if (d & bit)
{
SPI_MOSI_HIGH();
}
else
{
SPI_MOSI_LOW();
}
SPI_SCK_HIGH();
bit >>= 1;
SPI_SCK_LOW();
}
}
GFX_INLINE void Arduino_SWSPI::WRITE9BITREPEAT(uint16_t p, uint32_t len)
{
if (p == 0xffff) // no need to set MOSI level while filling white
{
SPI_MOSI_HIGH();
len *= 18; // 9-bit * 2
while (len--)
{
SPI_SCK_HIGH();
SPI_SCK_LOW();
}
}
else
{
_data16.value = p;
while (len--)
{
WRITE9BITDATA(_data16.msb);
WRITE9BITDATA(_data16.lsb);
}
}
}
GFX_INLINE void Arduino_SWSPI::WRITEREPEAT(uint16_t p, uint32_t len)
{
if ((p == 0x0000) || (p == 0xffff)) // no need to set MOSI level while filling black or white
{
if (p)
{
SPI_MOSI_HIGH();
}
else
{
SPI_MOSI_LOW();
}
len *= 16;
while (len--)
{
SPI_SCK_HIGH();
SPI_SCK_LOW();
}
}
else
{
while (len--)
{
WRITE16(p);
}
}
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_SWSPI::DC_HIGH(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_dcPortSet = 1;
#else // !KINETISK
*_dcPortSet = _dcPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_dcPort |= _dcPinMaskSet;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_dc, HIGH);
#endif // end !USE_FAST_PINIO
}
GFX_INLINE void Arduino_SWSPI::DC_LOW(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_dcPortClr = 1;
#else // !KINETISK
*_dcPortClr = _dcPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_dcPort &= _dcPinMaskClr;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_dc, LOW);
#endif // end !USE_FAST_PINIO
}
GFX_INLINE void Arduino_SWSPI::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_csPortSet = 1;
#else // !KINETISK
*_csPortSet = _csPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_csPort |= _csPinMaskSet;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_cs, HIGH);
#endif // end !USE_FAST_PINIO
}
}
GFX_INLINE void Arduino_SWSPI::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_csPortClr = 1;
#else // !KINETISK
*_csPortClr = _csPinMask;
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
*_csPort &= _csPinMaskClr;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_cs, LOW);
#endif // end !USE_FAST_PINIO
}
}
/*!
@brief Set the software (bitbang) SPI MOSI line HIGH.
*/
GFX_INLINE void Arduino_SWSPI::SPI_MOSI_HIGH(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_mosiPortSet = 1;
#else // !KINETISK
*_mosiPortSet = _mosiPinMask;
#endif
#else // !HAS_PORT_SET_CLR
*_mosiPort |= _mosiPinMaskSet;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_mosi, HIGH);
#endif // end !USE_FAST_PINIO
}
/*!
@brief Set the software (bitbang) SPI MOSI line LOW.
*/
GFX_INLINE void Arduino_SWSPI::SPI_MOSI_LOW(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_mosiPortClr = 1;
#else // !KINETISK
*_mosiPortClr = _mosiPinMask;
#endif
#else // !HAS_PORT_SET_CLR
*_mosiPort &= _mosiPinMaskClr;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_mosi, LOW);
#endif // end !USE_FAST_PINIO
}
/*!
@brief Set the software (bitbang) SPI SCK line HIGH.
*/
GFX_INLINE void Arduino_SWSPI::SPI_SCK_HIGH(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_sckPortSet = 1;
#else // !KINETISK
*_sckPortSet = _sckPinMask;
#if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
for (volatile uint8_t i = 0; i < 1; i++)
;
#endif
#endif
#else // !HAS_PORT_SET_CLR
*_sckPort |= _sckPinMaskSet;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_sck, HIGH);
#endif // end !USE_FAST_PINIO
}
/*!
@brief Set the software (bitbang) SPI SCK line LOW.
*/
GFX_INLINE void Arduino_SWSPI::SPI_SCK_LOW(void)
{
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if defined(KINETISK)
*_sckPortClr = 1;
#else // !KINETISK
*_sckPortClr = _sckPinMask;
#if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
for (volatile uint8_t i = 0; i < 1; i++)
;
#endif
#endif
#else // !HAS_PORT_SET_CLR
*_sckPort &= _sckPinMaskClr;
#endif // end !HAS_PORT_SET_CLR
#else // !USE_FAST_PINIO
digitalWrite(_sck, LOW);
#endif // end !USE_FAST_PINIO
}
/*!
@brief Read the state of the software (bitbang) SPI MISO line.
@return true if HIGH, false if LOW.
*/
GFX_INLINE bool Arduino_SWSPI::SPI_MISO_READ(void)
{
#if defined(USE_FAST_PINIO)
#if defined(KINETISK)
return *_misoPort;
#else // !KINETISK
return *_misoPort & _misoPinMask;
#endif // end !KINETISK
#else // !USE_FAST_PINIO
return digitalRead(_miso);
#endif // end !USE_FAST_PINIO
}

View File

@@ -0,0 +1,95 @@
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#ifndef _ARDUINO_SWSPI_H_
#define _ARDUINO_SWSPI_H_
#include "Arduino_DataBus.h"
class Arduino_SWSPI : public Arduino_DataBus
{
public:
Arduino_SWSPI(int8_t dc, int8_t cs, int8_t _sck, int8_t _mosi, int8_t _miso = GFX_NOT_DEFINED); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
#if !defined(LITTLE_FOOT_PRINT)
void writeBytes(uint8_t *data, uint32_t len) override;
#endif // !defined(LITTLE_FOOT_PRINT)
private:
GFX_INLINE void WRITE9BITCOMMAND(uint8_t c);
GFX_INLINE void WRITE9BITDATA(uint8_t d);
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITE9BITREPEAT(uint16_t p, uint32_t len);
GFX_INLINE void WRITEREPEAT(uint16_t p, uint32_t len);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
GFX_INLINE void SPI_MOSI_HIGH(void);
GFX_INLINE void SPI_MOSI_LOW(void);
GFX_INLINE void SPI_SCK_HIGH(void);
GFX_INLINE void SPI_SCK_LOW(void);
GFX_INLINE bool SPI_MISO_READ(void);
int8_t _dc, _cs;
int8_t _sck, _mosi, _miso;
// CLASS INSTANCE VARIABLES --------------------------------------------
// Here be dragons! There's a big union of three structures here --
// one each for hardware SPI, software (bitbang) SPI, and parallel
// interfaces. This is to save some memory, since a display's connection
// will be only one of these. The order of some things is a little weird
// in an attempt to get values to align and pack better in RAM.
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
PORTreg_t _dcPortSet; ///< PORT register for data/command SET
PORTreg_t _dcPortClr; ///< PORT register for data/command CLEAR
PORTreg_t _mosiPortSet; ///< PORT register for MOSI SET
PORTreg_t _mosiPortClr; ///< PORT register for MOSI CLEAR
PORTreg_t _sckPortSet; ///< PORT register for SCK SET
PORTreg_t _sckPortClr; ///< PORT register for SCK CLEAR
#if !defined(KINETISK)
ARDUINOGFX_PORT_t _csPinMask; ///< Bitmask for chip select
ARDUINOGFX_PORT_t _dcPinMask; ///< Bitmask for data/command
ARDUINOGFX_PORT_t _mosiPinMask; ///< Bitmask for MOSI
ARDUINOGFX_PORT_t _sckPinMask; ///< Bitmask for SCK
#endif // !KINETISK
#else // !HAS_PORT_SET_CLR
PORTreg_t _mosiPort; ///< PORT register for MOSI
PORTreg_t _sckPort; ///< PORT register for SCK
PORTreg_t _csPort; ///< PORT register for chip select
PORTreg_t _dcPort; ///< PORT register for data/command
ARDUINOGFX_PORT_t _csPinMaskSet; ///< Bitmask for chip select SET (OR)
ARDUINOGFX_PORT_t _csPinMaskClr; ///< Bitmask for chip select CLEAR (AND)
ARDUINOGFX_PORT_t _dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t _dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
ARDUINOGFX_PORT_t _mosiPinMaskSet; ///< Bitmask for MOSI SET (OR)
ARDUINOGFX_PORT_t _mosiPinMaskClr; ///< Bitmask for MOSI CLEAR (AND)
ARDUINOGFX_PORT_t _sckPinMaskSet; ///< Bitmask for SCK SET (OR bitmask)
ARDUINOGFX_PORT_t _sckPinMaskClr; ///< Bitmask for SCK CLEAR (AND)
#endif // HAS_PORT_SET_CLR
PORTreg_t _misoPort; ///< PORT (PIN) register for MISO
#if !defined(KINETISK)
ARDUINOGFX_PORT_t _misoPinMask; ///< Bitmask for MISO
#endif // !KINETISK
#endif // defined(USE_FAST_PINIO)
};
#endif // _ARDUINO_SWSPI_H_

View File

@@ -0,0 +1,249 @@
#include "Arduino_UNOPAR8.h"
// for MCUFriend UNO kind of shields. -jz-
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
Arduino_UNOPAR8::Arduino_UNOPAR8()
{
}
bool Arduino_UNOPAR8::begin(int32_t, int8_t)
{
pinMode(A2, OUTPUT); // LCD DC
digitalWrite(A2, HIGH); // Data mode
pinMode(A3, OUTPUT); // LCD CS
digitalWrite(A3, HIGH); // Disable chip select
pinMode(A1, OUTPUT); // LCD WR
digitalWrite(A1, HIGH); // Set write strobe high (inactive)
pinMode(A0, OUTPUT); // LCD RD
digitalWrite(A0, HIGH); // Disable RD
pinMode(8, OUTPUT); // LCD D0
pinMode(9, OUTPUT); // LCD D1
pinMode(2, OUTPUT); // LCD D2
pinMode(3, OUTPUT); // LCD D3
pinMode(4, OUTPUT); // LCD D4
pinMode(5, OUTPUT); // LCD D5
pinMode(6, OUTPUT); // LCD D6
pinMode(7, OUTPUT); // LCD D7
return true;
}
void Arduino_UNOPAR8::beginWrite()
{
DC_HIGH();
CS_LOW();
}
void Arduino_UNOPAR8::endWrite()
{
CS_HIGH();
}
void Arduino_UNOPAR8::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_UNOPAR8::writeCommand16(uint16_t c)
{
DC_LOW();
_data16.value = c;
WRITE(_data16.msb);
WRITE(_data16.lsb);
DC_HIGH();
}
void Arduino_UNOPAR8::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_UNOPAR8::write(uint8_t d)
{
WRITE(d);
}
void Arduino_UNOPAR8::write16(uint16_t d)
{
_data16.value = d;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
void Arduino_UNOPAR8::writeRepeat(uint16_t p, uint32_t len)
{
_data16.value = p;
if (_data16.msb == _data16.lsb)
{
#if defined(ARDUINO_AVR_UNO)
WRITE(_data16.msb);
// WR_STB
PORTC &= ~_BV(1);
PORTC |= _BV(1);
while (--len)
{
// WR_STB
PORTC &= ~_BV(1);
PORTC |= _BV(1);
// WR_STB
PORTC &= ~_BV(1);
PORTC |= _BV(1);
}
#elif defined(ARDUINO_AVR_MEGA2560)
WRITE(_data16.msb);
// WR_STB
PORTF &= ~_BV(1);
PORTF |= _BV(1);
while (--len)
{
// WR_STB
PORTF &= ~_BV(1);
PORTF |= _BV(1);
// WR_STB
PORTF &= ~_BV(1);
PORTF |= _BV(1);
}
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
WRITE(_data16.msb);
// WR_STB
R_PORT0->PORR = bit(0);
R_PORT0->POSR = bit(0);
while (--len)
{
// WR_STB
R_PORT0->PORR = bit(0);
R_PORT0->POSR = bit(0);
// WR_STB
R_PORT0->PORR = bit(0);
R_PORT0->POSR = bit(0);
}
#endif
}
else
{
while (len--)
{
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
}
void Arduino_UNOPAR8::writeBytes(uint8_t *data, uint32_t len)
{
while (len--)
{
WRITE(*data++);
}
}
void Arduino_UNOPAR8::writePixels(uint16_t *data, uint32_t len)
{
while (len--)
{
_data16.value = *data++;
WRITE(_data16.msb);
WRITE(_data16.lsb);
}
}
GFX_INLINE void Arduino_UNOPAR8::WRITE(uint8_t d)
{
#if defined(ARDUINO_AVR_UNO)
PORTB = (PORTB & 0xFC) | (d & 0x03); // LCD D0-1
PORTD = (PORTD & 0x03) | (d & 0xFC); // LCD D2-7
// WR_STB
PORTC &= ~_BV(1);
PORTC |= _BV(1);
#elif defined(ARDUINO_AVR_MEGA2560)
PORTH = (PORTH & 0x87) | ((d & 0x03) << 5) | ((d & 0xC0) >> 3); // LCD D0-1, D6-7
PORTE = (PORTE & 0xC7) | ((d & 0x0C) << 2) | ((d & 0x20) >> 2); // LCD D2-3, D5
(d & 0x10) ? PORTG |= _BV(5) : PORTG &= ~_BV(5); // LCD D4
// WR_STB
PORTF &= ~_BV(1);
PORTF |= _BV(1);
#elif defined(ARDUINO_UNOR4_MINIMA)
R_PORT3->PORR = 0x18;
R_PORT3->POSR = (d & 0x01) << 4; // LCD D0
R_PORT3->POSR = (d & 0x02) << 2; // LCD D1
R_PORT1->PORR = 0x00FC;
R_PORT1->POSR = _xset_mask[d >> 2]; // LCD D2-7
// WR_STB
R_PORT0->PORR = bit(0);
R_PORT0->POSR = bit(0);
#elif defined(ARDUINO_UNOR4_WIFI)
R_PORT3->PORR = 0x18;
R_PORT3->POSR = (d & 0x01) << 4; // LCD D0
R_PORT3->POSR = (d & 0x02) << 2; // LCD D1
R_PORT1->PORR = 0x18F0;
R_PORT1->POSR = ((d & 0x3C) << 2) | ((d & 0xC0) << 5); // LCD D2-7
// WR_STB
R_PORT0->PORR = bit(0);
R_PORT0->POSR = bit(0);
#endif
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_UNOPAR8::DC_HIGH(void)
{
#if defined(ARDUINO_AVR_UNO)
PORTC |= _BV(2); // RS_H;
#elif defined(ARDUINO_AVR_MEGA2560)
PORTF |= _BV(2); // RS_H;
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
R_PORT0->POSR = bit(1);
#endif
}
GFX_INLINE void Arduino_UNOPAR8::DC_LOW(void)
{
#if defined(ARDUINO_AVR_UNO)
PORTC &= ~_BV(2); // RS_L;
#elif defined(ARDUINO_AVR_MEGA2560)
PORTF &= ~_BV(2); // RS_L;
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
R_PORT0->PORR = bit(1);
#endif
}
GFX_INLINE void Arduino_UNOPAR8::CS_HIGH(void)
{
#if defined(ARDUINO_AVR_UNO)
PORTC |= _BV(3); // CS_H;
#elif defined(ARDUINO_AVR_MEGA2560)
PORTF |= _BV(3); // CS_H;
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
R_PORT0->POSR = bit(2);
#endif
}
GFX_INLINE void Arduino_UNOPAR8::CS_LOW(void)
{
#if defined(ARDUINO_AVR_UNO)
PORTC &= ~_BV(3); // CS_L;
#elif defined(ARDUINO_AVR_MEGA2560)
PORTF &= ~_BV(3); // CS_L;
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
R_PORT0->PORR = bit(2);
#endif
}
#endif // #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)

View File

@@ -0,0 +1,46 @@
#pragma once
#include "Arduino_DataBus.h"
// for MCUFriend UNO kind of shields. -jz-
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
#if defined(ARDUINO_UNOR4_MINIMA)
static const uint16_t _xset_mask[] = {
// 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
0x0000, 0x0020, 0x0010, 0x0030, 0x0008, 0x0028, 0x0018, 0x0038,
0x0004, 0x0024, 0x0014, 0x0034, 0x000C, 0x002C, 0x001C, 0x003C,
0x0040, 0x0060, 0x0050, 0x0070, 0x0048, 0x0068, 0x0058, 0x0078,
0x0044, 0x0064, 0x0054, 0x0074, 0x004C, 0x006C, 0x005C, 0x007C,
0x0080, 0x00A0, 0x0090, 0x00B0, 0x0088, 0x00A8, 0x0098, 0x00B8,
0x0084, 0x00A4, 0x0094, 0x00B4, 0x008C, 0x00AC, 0x009C, 0x00BC,
0x00C0, 0x00E0, 0x00D0, 0x00F0, 0x00C8, 0x00E8, 0x00D8, 0x00F8,
0x00C4, 0x00E4, 0x00D4, 0x00F4, 0x00CC, 0x00EC, 0x00DC, 0x00FC};
#endif
class Arduino_UNOPAR8 : public Arduino_DataBus
{
public:
Arduino_UNOPAR8(); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
};
#endif // #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)

View File

@@ -0,0 +1,147 @@
// Databus Adapter for the Arduino Wire bus (I2C bus)
#include "Arduino_Wire.h"
Arduino_Wire::
Arduino_Wire(uint8_t i2c_addr, int8_t commandPrefix, int8_t dataPrefix, TwoWire *wire)
: _i2c_addr(i2c_addr), _command_prefix(commandPrefix), _data_prefix(dataPrefix), _wire(wire) {}
bool Arduino_Wire::begin(int32_t speed, int8_t)
{
// printf("Wire::begin _command_prefix=0x%02x _data_prefix=0x%02x.\n", _command_prefix, _data_prefix);
if (speed != GFX_NOT_DEFINED)
{
_speed = speed;
_wire->setClock(_speed);
}
_wire->begin();
// find device
_wire->beginTransmission(_i2c_addr);
if (_wire->endTransmission())
{
// printf("Wire::Device not found.\n");
is_found = false;
}
else
{
is_found = true;
}
return is_found;
}
void Arduino_Wire::beginWrite()
{
// printf("Wire::beginWrite()\n");
if (_speed != GFX_NOT_DEFINED)
{
_wire->setClock(_speed);
}
_wire->beginTransmission(_i2c_addr);
}
void Arduino_Wire::endWrite()
{
// printf("Wire::endWrite()\n");
_wire->endTransmission();
}
void Arduino_Wire::write(uint8_t d)
{
// printf("Wire::write(0x%02x)\n", d);
_wire->write(d);
}
void Arduino_Wire::writeCommand(uint8_t c)
{
// printf("Wire::writeCommand(0x%02x 0x%02x)\n", _command_prefix, c);
_wire->write(_command_prefix);
_wire->write(c);
}
void Arduino_Wire::writeCommand16(uint16_t)
{
// printf("Wire::writeCommand16()\n");
// not implemented.
}
void Arduino_Wire::writeCommandBytes(uint8_t *data, uint32_t len)
{
// printf("Wire::writeCommandBytes(...)\n");
uint16_t bytesOut;
_wire->write(_command_prefix);
bytesOut = 1;
while (len--)
{
if (bytesOut >= TWI_BUFFER_LENGTH)
{
// finish this packet and start a new one.
_wire->endTransmission();
_wire->beginTransmission(_i2c_addr);
_wire->write(_command_prefix);
bytesOut = 1;
}
_wire->write(*data++);
bytesOut++;
}
}
void Arduino_Wire::write16(uint16_t)
{
// printf("Wire::write16()\n");
// not implemented
}
void Arduino_Wire::writeRepeat(uint16_t, uint32_t)
{
// printf("Wire::writeRepeat()\n");
// not implemented
}
void Arduino_Wire::writePixels(uint16_t *, uint32_t)
{
// printf("Wire::writePixels()\n");
// not implemented
}
// write data to the bus using the data prefix
// when len exceeds the TWI_BUFFER_LENGTH then a new transfer protocol is started.
void Arduino_Wire::writeBytes(uint8_t *data, uint32_t len)
{
// printf("Wire::writeBytes(...)\n");
uint16_t bytesOut = 0;
_wire->write(_data_prefix);
bytesOut++;
while (len--)
{
if (bytesOut >= TWI_BUFFER_LENGTH)
{
// finish this packet and start a new one.
_wire->endTransmission();
_wire->beginTransmission(_i2c_addr);
bytesOut = 0;
_wire->write(_data_prefix);
bytesOut++;
}
_wire->write(*data++);
bytesOut++;
}
}
void Arduino_Wire::writeRegister(uint8_t, uint8_t *, size_t)
{
// printf("Wire::writeRegister()\n");
}
uint8_t Arduino_Wire::readRegister(uint8_t, uint8_t *, size_t)
{
// printf("Wire::readRegister()\n");
return 0;
}

View File

@@ -0,0 +1,49 @@
// Databus Adapter for the Arduino Wire bus (I2C bus)
#ifndef _Arduino_Wire_H_
#define _Arduino_Wire_H_
#include "Arduino_DataBus.h"
#include <Wire.h>
#ifndef TWI_BUFFER_LENGTH
#if defined(I2C_BUFFER_LENGTH)
#define TWI_BUFFER_LENGTH I2C_BUFFER_LENGTH
#else
#define TWI_BUFFER_LENGTH 32
#endif
#endif
class Arduino_Wire : public Arduino_DataBus
{
public:
Arduino_Wire(uint8_t i2c_addr, int8_t commandPrefix, int8_t dataPrefix, TwoWire *wire = &Wire);
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
protected:
void writeRegister(uint8_t reg, uint8_t *data, size_t len);
uint8_t readRegister(uint8_t reg, uint8_t *data, size_t len);
uint8_t output_buf = 0;
bool is_found;
uint8_t _i2c_addr;
uint8_t _command_prefix;
uint8_t _data_prefix;
TwoWire *_wire;
int32_t _speed;
private:
};
#endif // _Arduino_Wire_H_

View File

@@ -0,0 +1,255 @@
#include "Arduino_XCA9554SWSPI.h"
// #define XCA9554_DEBUG
Arduino_XCA9554SWSPI::Arduino_XCA9554SWSPI(int8_t rst, int8_t cs, int8_t sck, int8_t mosi, TwoWire *wire, uint8_t i2c_addr)
: _rst(rst), _cs(cs), _sck(sck), _mosi(mosi), _wire(wire), _i2c_addr(i2c_addr)
{
}
bool Arduino_XCA9554SWSPI::begin(int32_t, int8_t)
{
_wire->begin();
_wire->beginTransmission(_i2c_addr);
if (!_wire->endTransmission())
{
// println("Found xCA9554");
is_found = true;
uint8_t d = 0;
writeRegister(XCA9554_INVERSION_PORT_REG, &d, 1); // no invert
d = 0xFF;
writeRegister(XCA9554_CONFIG_PORT_REG, &d, 1); // all input
d = 0x0;
writeRegister(XCA9554_OUTPUT_PORT_REG, &d, 1); // all low
output_buf = 0;
if (_rst != GFX_NOT_DEFINED)
{
this->pinMode(_rst, OUTPUT);
this->digitalWrite(_rst, 0);
delay(10);
this->digitalWrite(_rst, 1);
delay(100);
}
this->pinMode(_cs, OUTPUT);
this->digitalWrite(_cs, 1);
this->pinMode(_sck, OUTPUT);
this->digitalWrite(_sck, 1);
this->pinMode(_mosi, OUTPUT);
this->digitalWrite(_mosi, 1);
}
else
{
// println("xCA9554 not found");
is_found = false;
}
return true;
}
void Arduino_XCA9554SWSPI::beginWrite()
{
this->digitalWrite(_cs, 0);
}
void Arduino_XCA9554SWSPI::endWrite()
{
this->digitalWrite(_cs, 1);
}
void Arduino_XCA9554SWSPI::writeCommand(uint8_t c)
{
bool last_databit = 0;
// D/C bit, command
this->digitalWrite(_mosi, last_databit);
this->digitalWrite(_sck, 0);
this->digitalWrite(_sck, 1);
uint8_t bit = 0x80;
while (bit)
{
if (c & bit)
{
if (last_databit != 1)
{
last_databit = 1;
this->digitalWrite(_mosi, last_databit);
}
}
else
{
if (last_databit != 0)
{
last_databit = 0;
this->digitalWrite(_mosi, last_databit);
}
}
this->digitalWrite(_sck, 0);
bit >>= 1;
this->digitalWrite(_sck, 1);
}
}
void Arduino_XCA9554SWSPI::writeCommand16(uint16_t)
{
}
void Arduino_XCA9554SWSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
}
void Arduino_XCA9554SWSPI::write(uint8_t d)
{
bool last_databit = 1;
// D/C bit, data
this->digitalWrite(_mosi, last_databit);
this->digitalWrite(_sck, 0);
this->digitalWrite(_sck, 1);
uint8_t bit = 0x80;
while (bit)
{
if (d & bit)
{
if (last_databit != 1)
{
last_databit = 1;
this->digitalWrite(_mosi, last_databit);
}
}
else
{
if (last_databit != 0)
{
last_databit = 0;
this->digitalWrite(_mosi, last_databit);
}
}
this->digitalWrite(_sck, 0);
bit >>= 1;
this->digitalWrite(_sck, 1);
}
}
void Arduino_XCA9554SWSPI::write16(uint16_t)
{
// not implemented
}
void Arduino_XCA9554SWSPI::writeRepeat(uint16_t, uint32_t)
{
// not implemented
}
void Arduino_XCA9554SWSPI::writeBytes(uint8_t *, uint32_t)
{
// not implemented
}
void Arduino_XCA9554SWSPI::writePixels(uint16_t *, uint32_t)
{
// not implemented
}
void Arduino_XCA9554SWSPI::writeRegister(uint8_t reg, uint8_t *data, size_t len)
{
#ifdef XCA9554_DEBUG
// printf("Writing to $%02X: ", reg);
#endif
_wire->beginTransmission(_i2c_addr);
_wire->write(reg);
for (size_t i = 0; i < len; i++)
{
_wire->write(data[i]);
#ifdef XCA9554_DEBUG
// printf("0x%02X, ", data[i]);
#endif
}
#ifdef XCA9554_DEBUG
// println();
#endif
_wire->endTransmission();
}
uint8_t Arduino_XCA9554SWSPI::readRegister(uint8_t reg, uint8_t *data, size_t len)
{
_wire->beginTransmission(_i2c_addr);
_wire->write(reg);
#ifdef XCA9554_DEBUG
// printf("Read from $%02X: ", reg);
#endif
_wire->endTransmission();
_wire->requestFrom(_i2c_addr, len);
size_t index = 0;
while (index < len)
{
data[index++] = _wire->read();
#ifdef XCA9554_DEBUG
// printf("0x%02X, ", data[index-1]);
#endif
}
#ifdef XCA9554_DEBUG
// println();
#endif
return 0;
}
void Arduino_XCA9554SWSPI::pinMode(uint8_t pin, uint8_t mode)
{
if (is_found)
{
uint8_t port = 0;
this->readRegister(XCA9554_CONFIG_PORT_REG, &port, 1);
if (mode == OUTPUT)
{
port &= ~(1UL << pin);
}
else
{
port |= (1UL << pin);
}
this->writeRegister(XCA9554_CONFIG_PORT_REG, &port, 1);
}
else
{
// println("xCA9554 not found");
}
}
void Arduino_XCA9554SWSPI::digitalWrite(uint8_t pin, uint8_t val)
{
if (is_found)
{
uint8_t reg_data = output_buf;
reg_data &= ~(1UL << pin);
if (val == HIGH)
{
reg_data |= (1UL << pin);
}
this->writeRegister(XCA9554_OUTPUT_PORT_REG, &reg_data, 1);
output_buf = reg_data;
}
else
{
// println("xCA9554 not found");
}
}
int Arduino_XCA9554SWSPI::digitalRead(uint8_t pin)
{
if (is_found)
{
uint8_t port = 0;
this->readRegister(XCA9554_INPUT_PORT_REG, &port, 1);
// printf("Read 0x%02X\n", port);
return (port & (1UL << pin)) ? HIGH : LOW;
}
else
{
// println("xCA9554 not found");
}
return 0;
}

View File

@@ -0,0 +1,50 @@
#ifndef _ARDUINO_XCA9554SWSPI_H_
#define _ARDUINO_XCA9554SWSPI_H_
#include <Wire.h>
#include "Arduino_DataBus.h"
#define XCA9554_IIC_i2c_addr 0x38
#define XCA9554_INPUT_PORT_REG 0x00
#define XCA9554_OUTPUT_PORT_REG 0x01
#define XCA9554_INVERSION_PORT_REG 0x02
#define XCA9554_CONFIG_PORT_REG 0x03
class Arduino_XCA9554SWSPI : public Arduino_DataBus
{
public:
Arduino_XCA9554SWSPI(int8_t rst, int8_t cs, int8_t sck, int8_t mosi, TwoWire *wire = &Wire, uint8_t i2c_addr = XCA9554_IIC_i2c_addr);
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void pinMode(uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin);
protected:
void writeRegister(uint8_t reg, uint8_t *data, size_t len);
uint8_t readRegister(uint8_t reg, uint8_t *data, size_t len);
uint8_t output_buf = 0;
bool is_found;
int8_t _rst, _cs, _sck, _mosi;
TwoWire *_wire;
uint8_t _i2c_addr;
private:
};
#endif // _ARDUINO_XCA9554SWSPI_H_

View File

@@ -0,0 +1,254 @@
#include "Arduino_XL9535SWSPI.h"
Arduino_XL9535SWSPI::Arduino_XL9535SWSPI(int8_t sda, int8_t scl, int8_t pwd, int8_t cs, int8_t sck, int8_t mosi, TwoWire *wire)
: _sda(sda), _scl(scl), _pwd(pwd), _cs(cs), _sck(sck), _mosi(mosi), _wire(wire)
{
}
bool Arduino_XL9535SWSPI::begin(int32_t, int8_t)
{
_address = XL9535_IIC_ADDRESS;
_wire->beginTransmission(_address);
if (!_wire->endTransmission())
{
// println("Found xl9535");
is_found = true;
this->pinMode8(0, 0xFF, OUTPUT);
if (_pwd != GFX_NOT_DEFINED)
{
// this->pinMode(_pwd, OUTPUT);
this->digitalWrite(_pwd, 1);
}
// this->pinMode(_cs, OUTPUT);
this->digitalWrite(_cs, 1);
// this->pinMode(_sck, OUTPUT);
this->digitalWrite(_sck, 1);
// this->pinMode(_mosi, OUTPUT);
this->digitalWrite(_mosi, 1);
}
else
{
// println("xl9535 not found");
is_found = false;
}
return true;
}
void Arduino_XL9535SWSPI::beginWrite()
{
this->digitalWrite(_cs, 0);
}
void Arduino_XL9535SWSPI::endWrite()
{
this->digitalWrite(_cs, 1);
}
void Arduino_XL9535SWSPI::writeCommand(uint8_t c)
{
// D/C bit, command
this->digitalWrite(_mosi, 0);
this->digitalWrite(_sck, 0);
this->digitalWrite(_sck, 1);
uint8_t bit = 0x80;
while (bit)
{
if (c & bit)
{
this->digitalWrite(_mosi, 1);
}
else
{
this->digitalWrite(_mosi, 0);
}
this->digitalWrite(_sck, 0);
bit >>= 1;
this->digitalWrite(_sck, 1);
}
}
void Arduino_XL9535SWSPI::writeCommand16(uint16_t)
{
}
void Arduino_XL9535SWSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
}
void Arduino_XL9535SWSPI::write(uint8_t d)
{
// D/C bit, data
this->digitalWrite(_mosi, 1);
this->digitalWrite(_sck, 0);
this->digitalWrite(_sck, 1);
uint8_t bit = 0x80;
while (bit)
{
if (d & bit)
{
this->digitalWrite(_mosi, 1);
}
else
{
this->digitalWrite(_mosi, 0);
}
this->digitalWrite(_sck, 0);
bit >>= 1;
this->digitalWrite(_sck, 1);
}
}
void Arduino_XL9535SWSPI::write16(uint16_t)
{
// not implemented
}
void Arduino_XL9535SWSPI::writeRepeat(uint16_t, uint32_t)
{
// not implemented
}
void Arduino_XL9535SWSPI::writeBytes(uint8_t *, uint32_t)
{
// not implemented
}
void Arduino_XL9535SWSPI::writePixels(uint16_t *, uint32_t)
{
// not implemented
}
void Arduino_XL9535SWSPI::writeRegister(uint8_t reg, uint8_t *data, size_t len)
{
_wire->beginTransmission(_address);
_wire->write(reg);
for (size_t i = 0; i < len; i++)
{
_wire->write(data[i]);
}
_wire->endTransmission();
}
uint8_t Arduino_XL9535SWSPI::readRegister(uint8_t reg, uint8_t *data, size_t len)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->endTransmission();
_wire->requestFrom(_address, len);
size_t index = 0;
while (index < len)
data[index++] = _wire->read();
return 0;
}
void Arduino_XL9535SWSPI::pinMode(uint8_t pin, uint8_t mode)
{
if (is_found)
{
uint8_t port = 0;
if (pin > 7)
{
this->readRegister(XL9535_CONFIG_PORT_1_REG, &port, 1);
if (mode == OUTPUT)
{
port = port & (~(1 << (pin - 10)));
}
else
{
port = port | (1 << (pin - 10));
}
this->writeRegister(XL9535_CONFIG_PORT_1_REG, &port, 1);
}
else
{
this->readRegister(XL9535_CONFIG_PORT_0_REG, &port, 1);
if (mode == OUTPUT)
{
port = port & (~(1 << pin));
}
else
{
port = port | (1 << pin);
}
this->writeRegister(XL9535_CONFIG_PORT_0_REG, &port, 1);
}
}
else
{
// println("xl9535 not found");
}
}
void Arduino_XL9535SWSPI::pinMode8(uint8_t port, uint8_t pin, uint8_t mode)
{
if (is_found)
{
uint8_t _pin = (mode != OUTPUT) ? pin : ~pin;
if (port)
{
this->writeRegister(XL9535_CONFIG_PORT_1_REG, &_pin, 1);
}
else
{
this->writeRegister(XL9535_CONFIG_PORT_0_REG, &_pin, 1);
}
}
else
{
// println("xl9535 not found");
}
}
void Arduino_XL9535SWSPI::digitalWrite(uint8_t pin, uint8_t val)
{
if (is_found)
{
uint8_t port = 0;
uint8_t reg_data = 0;
if (pin > 7)
{
this->readRegister(XL9535_OUTPUT_PORT_1_REG, &reg_data, 1);
reg_data = reg_data & (~(1 << (pin - 10)));
port = reg_data | val << (pin - 10);
this->writeRegister(XL9535_OUTPUT_PORT_1_REG, &port, 1);
}
else
{
this->readRegister(XL9535_OUTPUT_PORT_0_REG, &reg_data, 1);
reg_data = reg_data & (~(1 << pin));
port = reg_data | val << pin;
this->writeRegister(XL9535_OUTPUT_PORT_0_REG, &port, 1);
}
}
else
{
// println("xl9535 not found");
}
}
int Arduino_XL9535SWSPI::digitalRead(uint8_t pin)
{
if (is_found)
{
int state = 0;
uint8_t port = 0;
if (pin > 7)
{
this->readRegister(XL9535_INPUT_PORT_1_REG, &port, 1);
state = port & (pin - 10) ? 1 : 0;
}
else
{
this->readRegister(XL9535_INPUT_PORT_0_REG, &port, 1);
state = port & pin ? 1 : 0;
}
return state;
}
else
{
// println("xl9535 not found");
}
return 0;
}

View File

@@ -0,0 +1,55 @@
#ifndef _ARDUINO_XL9535SWSPI_H_
#define _ARDUINO_XL9535SWSPI_H_
#include <Wire.h>
#include "Arduino_DataBus.h"
#define XL9535_IIC_ADDRESS 0X20
#define XL9535_INPUT_PORT_0_REG 0X00
#define XL9535_INPUT_PORT_1_REG 0X01
#define XL9535_OUTPUT_PORT_0_REG 0X02
#define XL9535_OUTPUT_PORT_1_REG 0X03
#define XL9535_INVERSION_PORT_0_REG 0X04
#define XL9535_INVERSION_PORT_1_REG 0X05
#define XL9535_CONFIG_PORT_0_REG 0X06
#define XL9535_CONFIG_PORT_1_REG 0X07
class Arduino_XL9535SWSPI : public Arduino_DataBus
{
public:
Arduino_XL9535SWSPI(int8_t sda, int8_t scl, int8_t pwd, int8_t cs, int8_t sck, int8_t mosi, TwoWire *wire = &Wire);
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void pinMode(uint8_t pin, uint8_t mode);
void pinMode8(uint8_t port, uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin);
protected:
void writeRegister(uint8_t reg, uint8_t *data, size_t len);
uint8_t readRegister(uint8_t reg, uint8_t *data, size_t len);
uint8_t _address;
bool is_found;
int8_t _sda, _scl, _pwd, _cs, _sck, _mosi;
TwoWire *_wire;
private:
};
#endif // _ARDUINO_XL9535SWSPI_H_

View File

@@ -0,0 +1,233 @@
/*
* start rewrite from:
* https://github.com/arduino/ArduinoCore-mbed/blob/master/libraries/SPI/SPI.cpp
*/
#ifdef ARDUINO_ARCH_NRF52840
#include "Arduino_mbedSPI.h"
Arduino_mbedSPI::Arduino_mbedSPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */)
: _dc(dc), _cs(cs)
{
}
bool Arduino_mbedSPI::begin(int32_t speed, int8_t dataMode)
{
_speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed;
_dataMode = (dataMode == GFX_NOT_DEFINED) ? SPI_MODE2 : dataMode;
uint32_t pin = digitalPinToPinName((pin_size_t)_dc);
NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin);
nrf_gpio_cfg_output(pin);
_dcPortSet = &reg->OUTSET;
_dcPortClr = &reg->OUTCLR;
_dcPinMask = 1UL << pin;
if (_cs != GFX_NOT_DEFINED)
{
pin = digitalPinToPinName((pin_size_t)_cs);
reg = nrf_gpio_pin_port_decode(&pin);
nrf_gpio_cfg_output(pin);
_csPortSet = &reg->OUTSET;
_csPortClr = &reg->OUTCLR;
_csPinMask = 1UL << pin;
}
if (_dataMode == GFX_NOT_DEFINED)
{
_dataMode = SPI_MODE0;
}
_dev = new mbed::SPI((PinName)SPI_MOSI, (PinName)SPI_MISO, (PinName)SPI_SCK);
return true;
}
void Arduino_mbedSPI::beginWrite()
{
_dev->lock();
_dev->format(8, _dataMode);
_dev->frequency(_speed);
DC_HIGH();
CS_LOW();
}
void Arduino_mbedSPI::endWrite()
{
CS_HIGH();
_dev->unlock();
}
void Arduino_mbedSPI::writeCommand(uint8_t c)
{
DC_LOW();
WRITE(c);
DC_HIGH();
}
void Arduino_mbedSPI::writeCommand16(uint16_t c)
{
DC_LOW();
WRITE16(c);
DC_HIGH();
}
void Arduino_mbedSPI::writeCommandBytes(uint8_t *data, uint32_t len)
{
DC_LOW();
while (len--)
{
WRITE(*data++);
}
DC_HIGH();
}
void Arduino_mbedSPI::write(uint8_t d)
{
WRITE(d);
}
void Arduino_mbedSPI::write16(uint16_t d)
{
WRITE16(d);
}
void Arduino_mbedSPI::writeRepeat(uint16_t p, uint32_t len)
{
MSB_16_SET(p, p);
uint32_t bufLen = (len < MBEDSPI_MAX_PIXELS_AT_ONCE) ? len : MBEDSPI_MAX_PIXELS_AT_ONCE;
uint32_t xferLen;
for (uint32_t i = 0; i < bufLen; i++)
{
_buffer16[i] = p;
}
while (len)
{
xferLen = (bufLen < len) ? bufLen : len;
WRITEBUF(_buffer, xferLen * 2);
len -= xferLen;
}
}
void Arduino_mbedSPI::writePixels(uint16_t *data, uint32_t len)
{
uint32_t xferLen;
uint8_t *p;
union
{
uint16_t val;
struct
{
uint8_t lsb;
uint8_t msb;
};
} t;
while (len)
{
xferLen = (len < MBEDSPI_MAX_PIXELS_AT_ONCE) ? len : MBEDSPI_MAX_PIXELS_AT_ONCE;
p = _buffer;
for (uint32_t i = 0; i < xferLen; i++)
{
t.val = *data++;
*p++ = t.msb;
*p++ = t.lsb;
}
len -= xferLen;
xferLen += xferLen; // uint16_t to uint8_t, double length
WRITEBUF(_buffer, xferLen);
}
}
void Arduino_mbedSPI::writeC8D8(uint8_t c, uint8_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE(d);
}
void Arduino_mbedSPI::writeC8D16(uint8_t c, uint16_t d)
{
DC_LOW();
WRITE(c);
DC_HIGH();
WRITE16(d);
}
void Arduino_mbedSPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
{
DC_LOW();
_dev->write((const char *)&c, 1, NULL, 0);
DC_HIGH();
uint32_t d;
MSB_32_16_16_SET(d, d1, d2);
_dev->write((const char *)&d, 4, NULL, 0);
}
void Arduino_mbedSPI::writeBytes(uint8_t *data, uint32_t len)
{
WRITEBUF(data, len);
}
GFX_INLINE void Arduino_mbedSPI::WRITE(uint8_t d)
{
_dev->write((const char *)&d, 1, NULL, 0);
}
GFX_INLINE void Arduino_mbedSPI::WRITE16(uint16_t d)
{
MSB_16_SET(d, d);
_dev->write((const char *)&d, 2, NULL, 0);
}
GFX_INLINE void Arduino_mbedSPI::WRITEBUF(uint8_t *buf, size_t count)
{
_dev->write((const char *)buf, count, NULL, 0);
}
/******** low level bit twiddling **********/
GFX_INLINE void Arduino_mbedSPI::DC_HIGH(void)
{
*_dcPortSet = _dcPinMask;
}
GFX_INLINE void Arduino_mbedSPI::DC_LOW(void)
{
*_dcPortClr = _dcPinMask;
}
GFX_INLINE void Arduino_mbedSPI::CS_HIGH(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortSet = _csPinMask;
}
}
GFX_INLINE void Arduino_mbedSPI::CS_LOW(void)
{
if (_cs != GFX_NOT_DEFINED)
{
*_csPortClr = _csPinMask;
}
}
#endif // #ifdef ARDUINO_ARCH_NRF52840

View File

@@ -0,0 +1,72 @@
/*
* start rewrite from:
* https://github.com/arduino/ArduinoCore-mbed/blob/master/libraries/SPI/SPI.cpp
*/
#ifdef ARDUINO_ARCH_NRF52840
#ifndef _ARDUINO_MBEDSPI_H_
#define _ARDUINO_MBEDSPI_H_
#include <SPI.h>
#if !defined(ARDUINO_AS_MBED_LIBRARY)
#include "drivers/SPIMaster.h"
#else
#include "drivers/SPI.h"
#endif
#include "Arduino_DataBus.h"
#ifndef MBEDSPI_MAX_PIXELS_AT_ONCE
#define MBEDSPI_MAX_PIXELS_AT_ONCE 32
#endif
class Arduino_mbedSPI : public Arduino_DataBus
{
public:
Arduino_mbedSPI(int8_t dc, int8_t cs = GFX_NOT_DEFINED); // Constructor
bool begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void writeCommandBytes(uint8_t *data, uint32_t len) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeC8D8(uint8_t c, uint8_t d) override;
void writeC8D16(uint8_t c, uint16_t d) override;
void writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) override;
void writeBytes(uint8_t *data, uint32_t len) override;
private:
GFX_INLINE void WRITE(uint8_t d);
GFX_INLINE void WRITE16(uint16_t d);
GFX_INLINE void WRITEBUF(uint8_t *buf, size_t count);
GFX_INLINE void DC_HIGH(void);
GFX_INLINE void DC_LOW(void);
GFX_INLINE void CS_HIGH(void);
GFX_INLINE void CS_LOW(void);
int8_t _dc, _cs;
mbed::SPI *_dev;
PORTreg_t _csPortSet;
PORTreg_t _csPortClr;
PORTreg_t _dcPortSet;
PORTreg_t _dcPortClr;
ARDUINOGFX_PORT_t _dcPinMask;
ARDUINOGFX_PORT_t _csPinMask;
union
{
uint8_t _buffer[MBEDSPI_MAX_PIXELS_AT_ONCE * 2] = {0};
uint16_t _buffer16[MBEDSPI_MAX_PIXELS_AT_ONCE];
uint32_t _buffer32[MBEDSPI_MAX_PIXELS_AT_ONCE / 2];
};
};
#endif // _ARDUINO_MBEDSPI_H_
#endif // #ifdef ARDUINO_ARCH_NRF52840

View File

@@ -0,0 +1,115 @@
/*
* start rewrite from:
* https://github.com/ananevilya/Arduino-AXS15231B-Library.git
*/
#include "Arduino_AXS15231B.h"
Arduino_AXS15231B::Arduino_AXS15231B(
Arduino_DataBus *bus, int8_t rst, uint8_t r,
bool ips, int16_t w, int16_t h,
uint8_t col_offset1, uint8_t row_offset1, uint8_t col_offset2, uint8_t row_offset2,
const uint8_t *init_operations, size_t init_operations_len)
: Arduino_TFT(bus, rst, r, ips, w, h, col_offset1, row_offset1, col_offset2, row_offset2),
_init_operations(init_operations), _init_operations_len(init_operations_len)
{
}
bool Arduino_AXS15231B::begin(int32_t speed)
{
if (speed == GFX_NOT_DEFINED)
{
speed = 32000000UL; // AXS15231B Maximum supported speed
}
return Arduino_TFT::begin(speed);
}
void Arduino_AXS15231B::writeAddrWindow(int16_t x, int16_t y, uint16_t w, uint16_t h)
{
if ((x != _currentX) || (w != _currentW))
{
_currentX = x;
_currentW = w;
x += _xStart;
_bus->writeC8D16D16(AXS15231B_CASET, x, x + w - 1);
}
if ((y != _currentY) || (h != _currentH))
{
_currentY = y;
_currentH = h;
y += _yStart;
_bus->writeC8D16D16(AXS15231B_RASET, y, y + h - 1);
}
_bus->writeCommand(AXS15231B_RAMWR); // write to RAM
}
/**************************************************************************/
/*!
@brief Set origin of (0,0) and orientation of TFT display
@param m The index for rotation, from 0-3 inclusive
*/
/**************************************************************************/
void Arduino_AXS15231B::setRotation(uint8_t r)
{
Arduino_TFT::setRotation(r);
switch (_rotation)
{
case 1:
r = AXS15231B_MADCTL_MX | AXS15231B_MADCTL_MV | AXS15231B_MADCTL_RGB;
break;
case 2:
r = AXS15231B_MADCTL_MX | AXS15231B_MADCTL_MY | AXS15231B_MADCTL_RGB;
break;
case 3:
r = AXS15231B_MADCTL_MY | AXS15231B_MADCTL_MV | AXS15231B_MADCTL_RGB;
break;
default: // case 0:
r = AXS15231B_MADCTL_RGB;
break;
}
_bus->beginWrite();
_bus->writeC8D8(AXS15231B_MADCTL, r);
_bus->endWrite();
}
void Arduino_AXS15231B::invertDisplay(bool i)
{
_bus->sendCommand((_ips ^ i) ? AXS15231B_INVON : AXS15231B_INVOFF);
}
void Arduino_AXS15231B::displayOn(void)
{
_bus->sendCommand(AXS15231B_SLPOUT);
delay(AXS15231B_SLPOUT_DELAY);
}
void Arduino_AXS15231B::displayOff(void)
{
_bus->sendCommand(AXS15231B_SLPIN);
delay(AXS15231B_SLPIN_DELAY);
}
void Arduino_AXS15231B::tftInit()
{
if (_rst != GFX_NOT_DEFINED)
{
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(100);
digitalWrite(_rst, LOW);
delay(AXS15231B_RST_DELAY);
digitalWrite(_rst, HIGH);
delay(AXS15231B_RST_DELAY);
}
else
{
// Software Rest
_bus->sendCommand(AXS15231B_SWRESET);
delay(AXS15231B_RST_DELAY);
}
_bus->batchOperation(_init_operations, _init_operations_len);
invertDisplay(false);
}

View File

@@ -0,0 +1,814 @@
/*
* start rewrite from:
* https://github.com/ananevilya/Arduino-AXS15231B-Library.git
*/
#pragma once
#include "../Arduino_GFX.h"
#include "../Arduino_TFT.h"
#define AXS15231B_TFTWIDTH 360
#define AXS15231B_TFTHEIGHT 640
#define AXS15231B_RST_DELAY 200 ///< delay ms wait for reset finish
#define AXS15231B_SLPIN_DELAY 200 ///< delay ms wait for sleep in finish
#define AXS15231B_SLPOUT_DELAY 200 ///< delay ms wait for sleep out finish
#define AXS15231B_SWRESET 0x01
#define AXS15231B_SLPIN 0x10
#define AXS15231B_SLPOUT 0x11
#define AXS15231B_INVOFF 0x20
#define AXS15231B_INVON 0x21
#define AXS15231B_DISPOFF 0x28
#define AXS15231B_DISPON 0x29
#define AXS15231B_CASET 0x2A
#define AXS15231B_RASET 0x2B
#define AXS15231B_RAMWR 0x2C
#define AXS15231B_PTLAR 0x30
#define AXS15231B_COLMOD 0x3A
#define AXS15231B_MADCTL 0x36
#define AXS15231B_MADCTL_MY 0x80
#define AXS15231B_MADCTL_MX 0x40
#define AXS15231B_MADCTL_MV 0x20
#define AXS15231B_MADCTL_ML 0x10
#define AXS15231B_MADCTL_RGB 0x00
static const uint8_t axs15231b_180640_init_operations[] = {
BEGIN_WRITE,
WRITE_C8_BYTES, 0xBB, 8,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x5A, 0xA5,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA0, 17,
0xC0, 0x10, 0x00, 0x02, 0x00,
0x00, 0x04, 0x3F, 0x20, 0x05,
0x3F, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA2, 31,
0x30, 0x3C, 0x24, 0x14, 0xD0,
0x20, 0xFF, 0xE0, 0x40, 0x19,
0x80, 0x80, 0x80, 0x20, 0xf9,
0x10, 0x02, 0xff, 0xff, 0xF0,
0x90, 0x01, 0x32, 0xA0, 0x91,
0xE0, 0x20, 0x7F, 0xFF, 0x00,
0x5A,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD0, 30,
0xE0, 0x40, 0x51, 0x24, 0x08,
0x05, 0x10, 0x01, 0x20, 0x15,
0xC2, 0x42, 0x22, 0x22, 0xAA,
0x03, 0x10, 0x12, 0x60, 0x14,
0x1E, 0x51, 0x15, 0x00, 0x8A,
0x20, 0x00, 0x03, 0x3A, 0x12,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA3, 22,
0xA0, 0x06, 0xAA, 0x00, 0x08,
0x02, 0x0A, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x00,
0x55, 0x55,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC1, 30,
0x31, 0x04, 0x02, 0x02, 0x71,
0x05, 0x24, 0x55, 0x02, 0x00,
0x41, 0x00, 0x53, 0xFF, 0xFF,
0xFF, 0x4F, 0x52, 0x00, 0x4F,
0x52, 0x00, 0x45, 0x3B, 0x0B,
0x02, 0x0d, 0x00, 0xFF, 0x40,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC3, 11,
0x00, 0x00, 0x00, 0x50, 0x03,
0x00, 0x00, 0x00, 0x01, 0x80,
0x01,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC4, 29,
0x00, 0x24, 0x33, 0x80, 0x00,
0xea, 0x64, 0x32, 0xC8, 0x64,
0xC8, 0x32, 0x90, 0x90, 0x11,
0x06, 0xDC, 0xFA, 0x00, 0x00,
0x80, 0xFE, 0x10, 0x10, 0x00,
0x0A, 0x0A, 0x44, 0x50,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC5, 23,
0x18, 0x00, 0x00, 0x03, 0xFE,
0x3A, 0x4A, 0x20, 0x30, 0x10,
0x88, 0xDE, 0x0D, 0x08, 0x0F,
0x0F, 0x01, 0x3A, 0x4A, 0x20,
0x10, 0x10, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC6, 20,
0x05, 0x0A, 0x05, 0x0A, 0x00,
0xE0, 0x2E, 0x0B, 0x12, 0x22,
0x12, 0x22, 0x01, 0x03, 0x00,
0x3F, 0x6A, 0x18, 0xC8, 0x22,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC7, 20,
0x50, 0x32, 0x28, 0x00, 0xa2,
0x80, 0x8f, 0x00, 0x80, 0xff,
0x07, 0x11, 0x9c, 0x67, 0xff,
0x24, 0x0c, 0x0d, 0x0e, 0x0f,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC9, 4,
0x33, 0x44, 0x44, 0x01,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xCF, 27,
0x2C, 0x1E, 0x88, 0x58, 0x13,
0x18, 0x56, 0x18, 0x1E, 0x68,
0x88, 0x00, 0x65, 0x09, 0x22,
0xC4, 0x0C, 0x77, 0x22, 0x44,
0xAA, 0x55, 0x08, 0x08, 0x12,
0xA0, 0x08,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD5, 30,
0x40, 0x8E, 0x8D, 0x01, 0x35,
0x04, 0x92, 0x74, 0x04, 0x92,
0x74, 0x04, 0x08, 0x6A, 0x04,
0x46, 0x03, 0x03, 0x03, 0x03,
0x82, 0x01, 0x03, 0x00, 0xE0,
0x51, 0xA1, 0x00, 0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD6, 30,
0x10, 0x32, 0x54, 0x76, 0x98,
0xBA, 0xDC, 0xFE, 0x93, 0x00,
0x01, 0x83, 0x07, 0x07, 0x00,
0x07, 0x07, 0x00, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x00,
0x84, 0x00, 0x20, 0x01, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD7, 19,
0x03, 0x01, 0x0b, 0x09, 0x0f,
0x0d, 0x1E, 0x1F, 0x18, 0x1d,
0x1f, 0x19, 0x40, 0x8E, 0x04,
0x00, 0x20, 0xA0, 0x1F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD8, 12,
0x02, 0x00, 0x0a, 0x08, 0x0e,
0x0c, 0x1E, 0x1F, 0x18, 0x1d,
0x1f, 0x19,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD9, 12,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xDD, 12,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xDF, 8,
0x44, 0x73, 0x4B, 0x69, 0x00,
0x0A, 0x02, 0x90,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE0, 17,
0x3B, 0x28, 0x10, 0x16, 0x0c,
0x06, 0x11, 0x28, 0x5c, 0x21,
0x0D, 0x35, 0x13, 0x2C, 0x33,
0x28, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE1, 17,
0x37, 0x28, 0x10, 0x16, 0x0b,
0x06, 0x11, 0x28, 0x5C, 0x21,
0x0D, 0x35, 0x14, 0x2C, 0x33,
0x28, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE2, 17,
0x3B, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x35, 0x44, 0x32,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE3, 17,
0x37, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x35, 0x44, 0x32,
0x0C, 0x14, 0x14, 0x36, 0x32,
0x2F, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE4, 17,
0x3B, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x39, 0x44, 0x2E,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE5, 17,
0x37, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x39, 0x44, 0x2E,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA4, 16,
0x85, 0x85, 0x95, 0x82, 0xAF,
0xAA, 0xAA, 0x80, 0x10, 0x30,
0x40, 0x40, 0x20, 0xFF, 0x60,
0x30,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA4, 4,
0x85, 0x85, 0x95, 0x85,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xBB, 8,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_D8, 0x11, 0x00,
END_WRITE,
DELAY, AXS15231B_SLPOUT_DELAY,
BEGIN_WRITE,
WRITE_C8_D8, 0x29, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_D8, 0x22, 0x00, // All Pixels off
END_WRITE,
DELAY, 100,
BEGIN_WRITE,
WRITE_C8_BYTES, 0x2C, 4,
0x00, 0x00, 0x00, 0x00,
END_WRITE};
static const uint8_t axs15231b_320480_type1_init_operations[] = {
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA0, 17,
0xC0, 0x10, 0x00, 0x02, 0x00,
0x00, 0x04, 0x3F, 0x20, 0x05,
0x3F, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA2, 31,
0x30, 0x3C, 0x24, 0x14, 0xD0,
0x20, 0xFF, 0xE0, 0x40, 0x19,
0x80, 0x80, 0x80, 0x20, 0xf9,
0x10, 0x02, 0xff, 0xff, 0xF0,
0x90, 0x01, 0x32, 0xA0, 0x91,
0xE0, 0x20, 0x7F, 0xFF, 0x00,
0x5A,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD0, 30,
0xE0, 0x40, 0x51, 0x24, 0x08,
0x05, 0x10, 0x01, 0x20, 0x15,
0xC2, 0x42, 0x22, 0x22, 0xAA,
0x03, 0x10, 0x12, 0x60, 0x14,
0x1E, 0x51, 0x15, 0x00, 0x8A,
0x20, 0x00, 0x03, 0x3A, 0x12,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA3, 22,
0xA0, 0x06, 0xAA, 0x00, 0x08,
0x02, 0x0A, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x00,
0x55, 0x55,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC1, 30,
0x31, 0x04, 0x02, 0x02, 0x71,
0x05, 0x24, 0x55, 0x02, 0x00,
0x41, 0x00, 0x53, 0xFF, 0xFF,
0xFF, 0x4F, 0x52, 0x00, 0x4F,
0x52, 0x00, 0x45, 0x3B, 0x0B,
0x02, 0x0d, 0x00, 0xFF, 0x40,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC3, 11,
0x00, 0x00, 0x00, 0x50, 0x03,
0x00, 0x00, 0x00, 0x01, 0x80,
0x01,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC4, 29,
0x00, 0x24, 0x33, 0x80, 0x00,
0xea, 0x64, 0x32, 0xC8, 0x64,
0xC8, 0x32, 0x90, 0x90, 0x11,
0x06, 0xDC, 0xFA, 0x00, 0x00,
0x80, 0xFE, 0x10, 0x10, 0x00,
0x0A, 0x0A, 0x44, 0x50,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC5, 23,
0x18, 0x00, 0x00, 0x03, 0xFE,
0x3A, 0x4A, 0x20, 0x30, 0x10,
0x88, 0xDE, 0x0D, 0x08, 0x0F,
0x0F, 0x01, 0x3A, 0x4A, 0x20,
0x10, 0x10, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC6, 20,
0x05, 0x0A, 0x05, 0x0A, 0x00,
0xE0, 0x2E, 0x0B, 0x12, 0x22,
0x12, 0x22, 0x01, 0x03, 0x00,
0x3F, 0x6A, 0x18, 0xC8, 0x22,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC7, 20,
0x50, 0x32, 0x28, 0x00, 0xa2,
0x80, 0x8f, 0x00, 0x80, 0xff,
0x07, 0x11, 0x9c, 0x67, 0xff,
0x24, 0x0c, 0x0d, 0x0e, 0x0f,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC9, 4,
0x33, 0x44, 0x44, 0x01,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xCF, 27,
0x2C, 0x1E, 0x88, 0x58, 0x13,
0x18, 0x56, 0x18, 0x1E, 0x68,
0x88, 0x00, 0x65, 0x09, 0x22,
0xC4, 0x0C, 0x77, 0x22, 0x44,
0xAA, 0x55, 0x08, 0x08, 0x12,
0xA0, 0x08,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD5, 30,
0x40, 0x8E, 0x8D, 0x01, 0x35,
0x04, 0x92, 0x74, 0x04, 0x92,
0x74, 0x04, 0x08, 0x6A, 0x04,
0x46, 0x03, 0x03, 0x03, 0x03,
0x82, 0x01, 0x03, 0x00, 0xE0,
0x51, 0xA1, 0x00, 0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD6, 30,
0x10, 0x32, 0x54, 0x76, 0x98,
0xBA, 0xDC, 0xFE, 0x93, 0x00,
0x01, 0x83, 0x07, 0x07, 0x00,
0x07, 0x07, 0x00, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x00,
0x84, 0x00, 0x20, 0x01, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD7, 19,
0x03, 0x01, 0x0b, 0x09, 0x0f,
0x0d, 0x1E, 0x1F, 0x18, 0x1d,
0x1f, 0x19, 0x40, 0x8E, 0x04,
0x00, 0x20, 0xA0, 0x1F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD8, 12,
0x02, 0x00, 0x0a, 0x08, 0x0e,
0x0c, 0x1E, 0x1F, 0x18, 0x1d,
0x1f, 0x19,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD9, 12,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xDD, 12,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xDF, 8,
0x44, 0x73, 0x4B, 0x69, 0x00,
0x0A, 0x02, 0x90,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE0, 17,
0x3B, 0x28, 0x10, 0x16, 0x0c,
0x06, 0x11, 0x28, 0x5c, 0x21,
0x0D, 0x35, 0x13, 0x2C, 0x33,
0x28, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE1, 17,
0x37, 0x28, 0x10, 0x16, 0x0b,
0x06, 0x11, 0x28, 0x5C, 0x21,
0x0D, 0x35, 0x14, 0x2C, 0x33,
0x28, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE2, 17,
0x3B, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x35, 0x44, 0x32,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE3, 17,
0x37, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x35, 0x44, 0x32,
0x0C, 0x14, 0x14, 0x36, 0x32,
0x2F, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE4, 17,
0x3B, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x39, 0x44, 0x2E,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE5, 17,
0x37, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x39, 0x44, 0x2E,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA4, 16,
0x85, 0x85, 0x95, 0x82, 0xAF,
0xAA, 0xAA, 0x80, 0x10, 0x30,
0x40, 0x40, 0x20, 0xFF, 0x60,
0x30,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA4, 4,
0x85, 0x85, 0x95, 0x85,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xBB, 8,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_D8, 0x11, 0x00,
END_WRITE,
DELAY, AXS15231B_SLPOUT_DELAY,
BEGIN_WRITE,
WRITE_C8_D8, 0x29, 0x00,
END_WRITE,
DELAY, 100,
BEGIN_WRITE,
WRITE_C8_BYTES, 0x2C, 4,
0x00, 0x00, 0x00, 0x00,
END_WRITE};
static const uint8_t axs15231b_320480_type2_init_operations[] = {
BEGIN_WRITE,
WRITE_C8_D8, 0x28, 0x00,
END_WRITE,
DELAY, 20,
BEGIN_WRITE,
WRITE_C8_D8, 0x10, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xBB, 8,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x5A, 0xA5,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA0, 17,
0x00, 0x30, 0x00, 0x02, 0x00,
0x00, 0x05, 0x3F, 0x30, 0x05,
0x3F, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA2, 31,
0x30, 0x04, 0x14, 0x50, 0x80,
0x30, 0x85, 0x80, 0xB4, 0x28,
0xFF, 0xFF, 0xFF, 0x20, 0x50,
0x10, 0x02, 0x06, 0x20, 0xD0,
0xC0, 0x01, 0x12, 0xA0, 0x91,
0xC0, 0x20, 0x7F, 0xFF, 0x00,
0x06,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD0, 30,
0x80, 0xb4, 0x21, 0x24, 0x08,
0x05, 0x10, 0x01, 0xf2, 0x02,
0xc2, 0x02, 0x22, 0x22, 0xaa,
0x03, 0x10, 0x12, 0xc0, 0x10,
0x10, 0x40, 0x04, 0x00, 0x30,
0x10, 0x00, 0x03, 0x0d, 0x12,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA3, 22,
0xA0, 0x06, 0xAA, 0x00, 0x08,
0x02, 0x0A, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x00,
0x55, 0x55,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC1, 30,
0x33, 0x04, 0x02, 0x02, 0x71,
0x05, 0x24, 0x55, 0x02, 0x00,
0x01, 0x01, 0x53, 0xff, 0xff,
0xff, 0x4f, 0x52, 0x00, 0x4f,
0x52, 0x00, 0x45, 0x3b, 0x0b,
0x04, 0x0d, 0x00, 0xff, 0x42,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC4, 29,
0x00, 0x24, 0x33, 0x80, 0x66,
0xea, 0x64, 0x32, 0xC8, 0x64,
0xC8, 0x32, 0x90, 0x90, 0x11,
0x06, 0xDC, 0xFA, 0x00, 0x00,
0x80, 0xFE, 0x10, 0x10, 0x00,
0x0A, 0x0A, 0x44, 0x50,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC5, 23,
0x18, 0x00, 0x00, 0x03, 0xFE,
0xe8, 0x3b, 0x20, 0x30, 0x10,
0x88, 0xde, 0x0d, 0x08, 0x0f,
0x0f, 0x01, 0xe8, 0x3b, 0x20,
0x10, 0x10, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC6, 20,
0x05, 0x0A, 0x05, 0x0A, 0x00,
0xE0, 0x2E, 0x0B, 0x12, 0x22,
0x12, 0x22, 0x01, 0x03, 0x00,
0x02, 0x6A, 0x18, 0xC8, 0x22,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC7, 20,
0x50, 0x36, 0x28, 0x00, 0xa2,
0x80, 0x8f, 0x00, 0x80, 0xff,
0x07, 0x11, 0x9c, 0x6f, 0xff,
0x24, 0x0c, 0x0d, 0x0e, 0x0f,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xC9, 4,
0x33, 0x44, 0x44, 0x01,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xCF, 27,
0x2c, 0x1e, 0x88, 0x58, 0x13,
0x18, 0x56, 0x18, 0x1e, 0x68,
0xf7, 0x00, 0x66, 0x0d, 0x22,
0xc4, 0x0c, 0x77, 0x22, 0x44,
0xaa, 0x55, 0x04, 0x04, 0x12,
0xa0, 0x08,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD5, 30,
0x30, 0x30, 0x8a, 0x00, 0x44,
0x04, 0x4a, 0xe5, 0x02, 0x4a,
0xe5, 0x02, 0x04, 0xd9, 0x02,
0x47, 0x03, 0x03, 0x03, 0x03,
0x83, 0x00, 0x00, 0x00, 0x80,
0x52, 0x53, 0x50, 0x50, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD6, 30,
0x10, 0x32, 0x54, 0x76, 0x98,
0xba, 0xdc, 0xfe, 0x34, 0x02,
0x01, 0x83, 0xff, 0x00, 0x20,
0x50, 0x00, 0x30, 0x03, 0x03,
0x50, 0x13, 0x00, 0x00, 0x00,
0x04, 0x50, 0x20, 0x01, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD7, 19,
0x03, 0x01, 0x09, 0x0b, 0x0d,
0x0f, 0x1e, 0x1f, 0x18, 0x1d,
0x1f, 0x19, 0x30, 0x30, 0x04,
0x00, 0x20, 0x20, 0x1f,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xD8, 12,
0x02, 0x00, 0x08, 0x0a, 0x0c,
0x0e, 0x1e, 0x1f, 0x18, 0x1d,
0x1f, 0x19,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xDF, 8,
0x44, 0x33, 0x4b, 0x69, 0x00,
0x0a, 0x02, 0x90,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE0, 17,
0x1f, 0x20, 0x10, 0x17, 0x0d,
0x09, 0x12, 0x2a, 0x44, 0x25,
0x0c, 0x15, 0x13, 0x31, 0x36,
0x2f, 0x02,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE1, 17,
0x3f, 0x20, 0x10, 0x16, 0x0c,
0x08, 0x12, 0x29, 0x43, 0x25,
0x0c, 0x15, 0x13, 0x32, 0x36,
0x2f, 0x27,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE2, 17,
0x3B, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x35, 0x44, 0x32,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE3, 17,
0x37, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x35, 0x44, 0x32,
0x0C, 0x14, 0x14, 0x36, 0x32,
0x2F, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE4, 17,
0x3B, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x39, 0x44, 0x2E,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0D,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xE5, 17,
0x37, 0x07, 0x12, 0x18, 0x0E,
0x0D, 0x17, 0x39, 0x44, 0x2E,
0x0C, 0x14, 0x14, 0x36, 0x3A,
0x2F, 0x0F,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xA4, 16,
0x85, 0x85, 0x95, 0x82, 0xAF,
0xAA, 0xAA, 0x80, 0x10, 0x30,
0x40, 0x40, 0x20, 0xFF, 0x60,
0x30,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_BYTES, 0xBB, 8,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
END_WRITE,
BEGIN_WRITE,
WRITE_COMMAND_8, 0x01,
END_WRITE,
BEGIN_WRITE,
WRITE_C8_D8, 0x28, 0x00,
END_WRITE,
DELAY, 20,
BEGIN_WRITE,
WRITE_C8_D8, 0x10, 0x00,
END_WRITE,
DELAY, 200,
BEGIN_WRITE,
WRITE_C8_D8, 0x11, 0x00,
END_WRITE,
DELAY, 200,
BEGIN_WRITE,
WRITE_C8_D8, 0x29, 0x00,
END_WRITE,
DELAY, 100,
BEGIN_WRITE,
WRITE_C8_BYTES, 0x2C, 4,
0x00, 0x00, 0x00, 0x00,
END_WRITE};
class Arduino_AXS15231B : public Arduino_TFT
{
public:
Arduino_AXS15231B(
Arduino_DataBus *bus, int8_t rst = GFX_NOT_DEFINED, uint8_t r = 0,
bool ips = false, int16_t w = AXS15231B_TFTWIDTH, int16_t h = AXS15231B_TFTHEIGHT,
uint8_t col_offset1 = 0, uint8_t row_offset1 = 0, uint8_t col_offset2 = 0, uint8_t row_offset2 = 0,
const uint8_t *init_operations = axs15231b_180640_init_operations, size_t init_operations_len = sizeof(axs15231b_180640_init_operations));
bool begin(int32_t speed = GFX_NOT_DEFINED) override;
void writeAddrWindow(int16_t x, int16_t y, uint16_t w, uint16_t h) override;
void setRotation(uint8_t r) override;
void invertDisplay(bool) override;
void displayOn() override;
void displayOff() override;
protected:
void tftInit() override;
private:
const uint8_t *_init_operations;
size_t _init_operations_len;
};

Some files were not shown because too many files have changed in this diff Show More