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,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