snapshot
This commit is contained in:
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
1055
libraries/GFX_Library_for_Arduino/src/databus/Arduino_ESP32LCD8.cpp
Normal file
1055
libraries/GFX_Library_for_Arduino/src/databus/Arduino_ESP32LCD8.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
1167
libraries/GFX_Library_for_Arduino/src/databus/Arduino_ESP32SPI.cpp
Normal file
1167
libraries/GFX_Library_for_Arduino/src/databus/Arduino_ESP32SPI.cpp
Normal file
File diff suppressed because it is too large
Load Diff
133
libraries/GFX_Library_for_Arduino/src/databus/Arduino_ESP32SPI.h
Normal file
133
libraries/GFX_Library_for_Arduino/src/databus/Arduino_ESP32SPI.h
Normal 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
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
523
libraries/GFX_Library_for_Arduino/src/databus/Arduino_HWSPI.cpp
Normal file
523
libraries/GFX_Library_for_Arduino/src/databus/Arduino_HWSPI.cpp
Normal 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 = ®->OUTSET;
|
||||
_dcPortClr = ®->OUTCLR;
|
||||
_dcPinMask = 1UL << pin;
|
||||
if (_cs != GFX_NOT_DEFINED)
|
||||
{
|
||||
pin = digitalPinToPinName((pin_size_t)_cs);
|
||||
reg = nrf_gpio_pin_port_decode(&pin);
|
||||
_csPortSet = ®->OUTSET;
|
||||
_csPortClr = ®->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
|
||||
}
|
||||
}
|
||||
104
libraries/GFX_Library_for_Arduino/src/databus/Arduino_HWSPI.h
Normal file
104
libraries/GFX_Library_for_Arduino/src/databus/Arduino_HWSPI.h
Normal 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_
|
||||
@@ -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 = ®->OUTSET;
|
||||
_dcPortClr = ®->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 = ®->OUTSET;
|
||||
_csPortClr = ®->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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
1823
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR16.cpp
Normal file
1823
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR16.cpp
Normal file
File diff suppressed because it is too large
Load Diff
220
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR16.h
Normal file
220
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR16.h
Normal 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_
|
||||
1117
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR8.cpp
Normal file
1117
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR8.cpp
Normal file
File diff suppressed because it is too large
Load Diff
151
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR8.h
Normal file
151
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWPAR8.h
Normal 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_
|
||||
737
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWSPI.cpp
Normal file
737
libraries/GFX_Library_for_Arduino/src/databus/Arduino_SWSPI.cpp
Normal 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 = ®->OUTSET;
|
||||
_dcPortClr = ®->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 = ®->OUTSET;
|
||||
_csPortClr = ®->OUTCLR;
|
||||
}
|
||||
pin = digitalPinToPinName((pin_size_t)_sck);
|
||||
reg = nrf_gpio_pin_port_decode(&pin);
|
||||
_sckPinMask = 1UL << pin;
|
||||
_sckPortSet = ®->OUTSET;
|
||||
_sckPortClr = ®->OUTCLR;
|
||||
pin = digitalPinToPinName((pin_size_t)_mosi);
|
||||
reg = nrf_gpio_pin_port_decode(&pin);
|
||||
_mosiPinMask = 1UL << pin;
|
||||
_mosiPortSet = ®->OUTSET;
|
||||
_mosiPortClr = ®->OUTCLR;
|
||||
if (_miso != GFX_NOT_DEFINED)
|
||||
{
|
||||
pin = digitalPinToPinName((pin_size_t)_miso);
|
||||
reg = nrf_gpio_pin_port_decode(&pin);
|
||||
_misoPinMask = 1UL << pin;
|
||||
_misoPort = ®->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
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
147
libraries/GFX_Library_for_Arduino/src/databus/Arduino_Wire.cpp
Normal file
147
libraries/GFX_Library_for_Arduino/src/databus/Arduino_Wire.cpp
Normal 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;
|
||||
}
|
||||
49
libraries/GFX_Library_for_Arduino/src/databus/Arduino_Wire.h
Normal file
49
libraries/GFX_Library_for_Arduino/src/databus/Arduino_Wire.h
Normal 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_
|
||||
@@ -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, ®_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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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, ®_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, ®_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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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 = ®->OUTSET;
|
||||
_dcPortClr = ®->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 = ®->OUTSET;
|
||||
_csPortClr = ®->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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user