diff --git a/Pixels.h b/Pixels.h index 047abd7..f5f52e5 100755 --- a/Pixels.h +++ b/Pixels.h @@ -78,6 +78,20 @@ #define regtype volatile uint32_t #define regsize uint32_t +#elif defined(ESP8266) + #include "Arduino.h" + #include + #define cbi(reg, bitmask) GPOC = bitmask + #define sbi(reg, bitmask) GPOS = bitmask + #define pulse_high(reg, bitmask) sbi(reg, bitmask); cbi(reg, bitmask); + #define pulse_low(reg, bitmask) cbi(reg, bitmask); sbi(reg, bitmask); + + #define cport(port, data) port &= data + #define sport(port, data) port |= data + + #define regtype volatile uint32_t + #define regsize uint32_t + #else #define PROGMEM @@ -117,7 +131,11 @@ #define ipart(X) ((int16_t)(X)) -#define round(X) ((uint16_t)(((double)(X))+0.5)) + +#ifndef ESP8266 + #define round(X) ((uint16_t)(((double)(X))+0.5)) +#endif + #define fpart(X) (((double)(X))-(double)ipart(X)) #define rfpart(X) (1.0-fpart(X)) diff --git a/Pixels_ILI9341.h b/Pixels_ILI9341.h index 24d577d..a6ef0e7 100644 --- a/Pixels_ILI9341.h +++ b/Pixels_ILI9341.h @@ -43,7 +43,13 @@ class Pixels : public PixelsBase { protected: void deviceWriteData(uint8_t high, uint8_t low) { - writeData(high, low); + + #if defined(ESP8266) && defined(PIXELS_SPIHW_H) + int16_t data = (high<<8) | low; //convert back to 16bit + writeData16(data); + #else + writeData(high, low); + #endif } void setRegion(int16_t x1, int16_t y1, int16_t x2, int16_t y2); @@ -135,7 +141,7 @@ void Pixels::init() { writeData(0x08); writeData(0x82); writeData(0x27); -/* + writeCmd(0xF2); // 3Gamma Function Disable writeData(0x00); @@ -175,7 +181,7 @@ void Pixels::init() { writeData(0x31); writeData(0x36); writeData(0x0F); -*/ + writeCmd(0x11); //Exit Sleep delay(120); @@ -188,8 +194,13 @@ void Pixels::init() { void Pixels::scrollCmd() { chipSelect(); writeCmd(0x37); - writeData(highByte(currentScroll)); - writeData(lowByte(currentScroll)); + + #if defined(ESP8266) && defined(PIXELS_SPIHW_H) + writeData16(currentScroll); + #else + writeData(highByte(currentScroll)); + writeData(lowByte(currentScroll)); + #endif chipDeselect(); } @@ -205,34 +216,42 @@ void Pixels::quickFill (int color, int16_t x1, int16_t y1, int16_t x2, int16_t y registerSelect(); - uint8_t lo = lowByte(color); - uint8_t hi = highByte(color); - - for (int16_t i = 0; i < counter / 20; i++) { - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - writeData(hi);writeData(lo); - } - for (int32_t i = 0; i < counter % 20; i++) { - writeData(hi);writeData(lo); - } + #if defined(ESP8266) && defined(PIXELS_SPIHW_H) + + uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color }; + writeDataPattern(&colorBin[0], 2, counter); + + #else + + uint8_t lo = lowByte(color); + uint8_t hi = highByte(color); + + for (int16_t i = 0; i < counter / 20; i++) { + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + writeData(hi);writeData(lo); + } + for (int32_t i = 0; i < counter % 20; i++) { + writeData(hi);writeData(lo); + } + #endif chipDeselect(); } @@ -273,16 +292,31 @@ void Pixels::setRegion(int16_t x1, int16_t y1, int16_t x2, int16_t y2) { } } - writeCmd(0x2a); - writeData(x1>>8); - writeData(x1); - writeData(x2>>8); - writeData(x2); - writeCmd(0x2b); - writeData(y1>>8); - writeData(y1); - writeData(y2>>8); - writeData(y2); - writeCmd(0x2c); + #if defined(ESP8266) && defined(PIXELS_SPIHW_H) + + uint8_t buffC[] = { (uint8_t) (x1 >> 8), (uint8_t) x1, (uint8_t) (x2 >> 8), (uint8_t) x2 }; + uint8_t buffP[] = { (uint8_t) (y1 >> 8), (uint8_t) y1, (uint8_t) (y2 >> 8), (uint8_t) y2 }; + + writeCmd(0x2a); + writeDataBytes(&buffC[0], sizeof(buffC)); + writeCmd(0x2b); + writeDataBytes(&buffP[0], sizeof(buffP)); + writeCmd(0x2c); + + #else + + writeCmd(0x2a); + writeData(x1>>8); + writeData(x1); + writeData(x2>>8); + writeData(x2); + writeCmd(0x2b); + writeData(y1>>8); + writeData(y1); + writeData(y2>>8); + writeData(y2); + writeCmd(0x2c); + + #endif } #endif diff --git a/Pixels_SPIhw.h b/Pixels_SPIhw.h index 9fb4bca..0d52aaf 100644 --- a/Pixels_SPIhw.h +++ b/Pixels_SPIhw.h @@ -20,6 +20,10 @@ #include "Pixels.h" +#if defined(ESP8266) + #include +#endif + #ifdef PIXELS_MAIN #error Pixels_SPIhw.h must be included before Pixels_.h #endif @@ -27,25 +31,29 @@ #ifndef PIXELS_SPIHW_H #define PIXELS_SPIHW_H -#define SPI_CLOCK_DIV4 0x00 -#define SPI_CLOCK_DIV16 0x01 -#define SPI_CLOCK_DIV64 0x02 -#define SPI_CLOCK_DIV128 0x03 -#define SPI_CLOCK_DIV2 0x04 -#define SPI_CLOCK_DIV8 0x05 -#define SPI_CLOCK_DIV32 0x06 -#define SPI_CLOCK_DIV64 0x07 +#ifndef ESP8266 + #define SPI_CLOCK_DIV4 0x00 + #define SPI_CLOCK_DIV16 0x01 + #define SPI_CLOCK_DIV64 0x02 + #define SPI_CLOCK_DIV128 0x03 + #define SPI_CLOCK_DIV2 0x04 + #define SPI_CLOCK_DIV8 0x05 + #define SPI_CLOCK_DIV32 0x06 + #define SPI_CLOCK_DIV64 0x07 + + #define SPI_MODE0 0x00 + #define SPI_MODE1 0x04 + #define SPI_MODE2 0x08 + #define SPI_MODE3 0x0C -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x04 -#define SPI_MODE2 0x08 -#define SPI_MODE3 0x0C + #define SPI(X) SPDR=X;while(!(SPSR&_BV(SPIF))) + +#endif #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR -#define SPI(X) SPDR=X;while(!(SPSR&_BV(SPIF))) class SPIhw { private: @@ -66,6 +74,7 @@ class SPIhw { void endSPI(); bool eightBit; + bool hwCS; protected: void reset() { @@ -77,6 +86,9 @@ class SPIhw { void writeCmd(uint8_t b); __attribute__((noinline)) void writeData(uint8_t data); // noinline saves 4-5kb sketch code in the case. An impact to performance is to be learned. + void writeData16(uint16_t data); + void writeDataBytes(uint8_t * data, uint32_t size); + void writeDataPattern(uint8_t * data,uint8_t size, uint32_t repeat); void writeData(uint8_t hi, uint8_t lo) { writeData(hi); @@ -98,6 +110,9 @@ class SPIhw { void setSPIBitOrder(uint8_t bitOrder); void setSPIDataMode(uint8_t mode); void setSPIClockDivider(uint8_t rate); + void setHwCs(bool useHwCs) { + hwCS = useHwCs; + } // void setSPIEightBit(bool bits) { // eightBit = bits; // } @@ -117,6 +132,7 @@ class SPIhw { pinRST = rst; pinWR = wr; eightBit = wr != 255; + hwCS = true; } /** @@ -150,13 +166,40 @@ void SPIhw::initInterface() { reset(); - setSPIBitOrder(MSBFIRST); - setSPIDataMode(SPI_MODE3); - // setSPIClockDivider(SPI_CLOCK_DIV64); - beginSPI(); + #if defined(ESP8266) + + SPI.setClockDivider(SPI_CLOCK_DIV4); + //setSPIClockDivider(SPI_CLOCK_DIV16); + setSPIBitOrder(MSBFIRST); + setSPIDataMode(SPI_MODE0); + + beginSPI(); + + + #else + + setSPIBitOrder(MSBFIRST); + setSPIDataMode(SPI_MODE3); + // setSPIClockDivider(SPI_CLOCK_DIV64); + beginSPI(); + + #endif } void SPIhw::writeCmd(uint8_t cmd) { + +#if defined(ESP8266) + if (eightBit) { + cbi(GPOC,bitmaskWR); //wr low + } + if (hwCS){ + SPI.write(cmd); + } else { + cbi(GPOC,bitmaskCS); //cs low + SPI.write(cmd); + sbi(GPOS,bitmaskCS); //cs high + } +#else if ( eightBit ) { *registerWR &= ~bitmaskWR; } else { @@ -167,18 +210,31 @@ void SPIhw::writeCmd(uint8_t cmd) { sbi(registerSCL, bitmaskSCL); // Pull SPI SCK low SPCR |= _BV(SPE); // Enable SPI again } - -#if defined(TEENSYDUINO) + #if defined(TEENSYDUINO) SPI0_SR = SPI_SR_TCF; SPI0_PUSHR = cmd; while (!(SPI0_SR & SPI_SR_TCF)) ; // wait -#else + #else SPDR = cmd; while (!(SPSR & _BV(SPIF))); -#endif + #endif +#endif } void SPIhw::writeData(uint8_t data) { + + #if defined(ESP8266) + if (eightBit) { + sbi(GPOS,bitmaskWR); + } + if (hwCS){ + SPI.write(data); + } else { + cbi(GPOC,bitmaskCS); //cs low + SPI.write(data); + sbi(GPOS,bitmaskCS); //cs high + } + #else if ( eightBit ) { *registerWR |= bitmaskWR; } else { @@ -190,60 +246,131 @@ void SPIhw::writeData(uint8_t data) { SPCR |= _BV(SPE); // Enable SPI again } -#if defined(TEENSYDUINO) - SPI0_SR = SPI_SR_TCF; - SPI0_PUSHR = data; - while (!(SPI0_SR & SPI_SR_TCF)) ; // wait -#else - SPDR = data; - while (!(SPSR & _BV(SPIF))); + #if defined(TEENSYDUINO) + SPI0_SR = SPI_SR_TCF; + SPI0_PUSHR = data; + while (!(SPI0_SR & SPI_SR_TCF)) ; // wait + #else + SPDR = data; + while (!(SPSR & _BV(SPIF))); + #endif #endif } -void SPIhw::beginSPI() { - cbi(registerSCL, bitmaskSCL); - cbi(registerSDA, bitmaskSDA); - digitalWrite(pinCS, HIGH); - - // Warning: if the SS pin ever becomes a LOW INPUT then SPI - // automatically switches to Slave, so the data direction of - // the SS pin MUST be kept as OUTPUT. - - SPCR |= _BV(MSTR); - SPCR |= _BV(SPE); - -#if defined(TEENSYDUINO) - uint32_t ctar = SPI_CTAR_FMSZ(7) | - SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0) | SPI_CTAR_DBR; - - SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); - SPI0_CTAR0 = ctar; - SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8); - SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F); -#else - DDRB = DDRB | B00000001; // PB0 as OUTPUT - PORTB = PORTB | B00000001; // PB0 as HIGH +#if defined(ESP8266) +void SPIhw::writeData16(uint16_t data) { + if (eightBit) { + sbi(GPOS,bitmaskWR); + } + if (hwCS){ + SPI.write16(data, true); + } else { + cbi(GPOC,bitmaskCS); //cs low + SPI.write16(data, true); + sbi(GPOS,bitmaskCS); //cs high + } +} #endif + +#if defined(ESP8266) +void SPIhw::writeDataBytes(uint8_t * data, uint32_t size) { + if (eightBit) { + sbi(GPOS,bitmaskWR); + } + if (hwCS){ + SPI.writeBytes(data, size); + } else { + cbi(GPOC,bitmaskCS); //cs low + SPI.writeBytes(data, size); + sbi(GPOS,bitmaskCS); //cs high + } + } +#endif + +#if defined(ESP8266) +void SPIhw::writeDataPattern(uint8_t * data, uint8_t size, uint32_t repeat) { + if (eightBit) { + sbi(GPOS,bitmaskWR); + } + if (hwCS){ + SPI.writePattern(data, size, repeat); + } else { + cbi(GPOC,bitmaskCS); //cs low + SPI.writePattern(data, size, repeat); + sbi(GPOS,bitmaskCS); //cs high + } +} +#endif + +void SPIhw::beginSPI() { + + + #if defined(ESP8266) + SPI.setHwCs(hwCS); + SPI.begin(); + #else + + cbi(registerSCL, bitmaskSCL); + cbi(registerSDA, bitmaskSDA); + digitalWrite(pinCS, HIGH); + // Warning: if the SS pin ever becomes a LOW INPUT then SPI + // automatically switches to Slave, so the data direction of + // the SS pin MUST be kept as OUTPUT. + + SPCR |= _BV(MSTR); + SPCR |= _BV(SPE); + + #if defined(TEENSYDUINO) + uint32_t ctar = SPI_CTAR_FMSZ(7) | + SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0) | SPI_CTAR_DBR; + + SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); + SPI0_CTAR0 = ctar; + SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8); + SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F); + #else + DDRB = DDRB | B00000001; // PB0 as OUTPUT + PORTB = PORTB | B00000001; // PB0 as HIGH + #endif + #endif } void SPIhw::endSPI() { - SPCR &= ~_BV(SPE); + #if defined(ESP8266) + SPI.end(); + #else + SPCR &= ~_BV(SPE); + #endif } void SPIhw::setSPIBitOrder(uint8_t bitOrder) { - if(bitOrder == LSBFIRST) { - SPCR |= _BV(DORD); - } else { - SPCR &= ~(_BV(DORD)); - } + + #if defined(ESP8266) + SPI.setBitOrder(bitOrder); + #else + + if(bitOrder == LSBFIRST) { + SPCR |= _BV(DORD); + } else { + SPCR &= ~(_BV(DORD)); + } + #endif } void SPIhw::setSPIDataMode(uint8_t mode) { - SPCR = (SPCR & ~SPI_MODE_MASK) | mode; + #if defined(ESP8266) + SPI.setDataMode(mode); + #else + SPCR = (SPCR & ~SPI_MODE_MASK) | mode; + #endif } void SPIhw::setSPIClockDivider(uint8_t rate) { - SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK); - SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK); + #if defined(ESP8266) + SPI.setClockDivider(rate); + #else + SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK); + SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK); + #endif } #endif diff --git a/Pixels_SPIsw.h b/Pixels_SPIsw.h index d1987f1..788d866 100644 --- a/Pixels_SPIsw.h +++ b/Pixels_SPIsw.h @@ -131,20 +131,20 @@ void SPIsw::busWrite(uint8_t data) { uint8_t c = 8; do { if (data & 0x80) { - *registerSDA |= bitmaskSDA; + sbi(registerSDA,bitmaskSDA); } else { - *registerSDA &= ~bitmaskSDA; + cbi(registerSDA,bitmaskSDA); } data = data<<1; - *registerSCL &= ~bitmaskSCL; + cbi(registerSCL,bitmaskSCL); asm ("nop"); - *registerSCL |= bitmaskSCL; + sbi(registerSCL,bitmaskSCL); } while (--c > 0); } void SPIsw::writeCmd(uint8_t cmd) { if ( eightBit ) { - *registerWR &= ~bitmaskWR; + cbi(registerWR,bitmaskWR); } else { cbi(registerSDA, bitmaskSDA); cbi(registerSCL, bitmaskSCL); // Pull SPI SCK high @@ -155,7 +155,7 @@ void SPIsw::writeCmd(uint8_t cmd) { void SPIsw::writeData(uint8_t data) { if ( eightBit ) { - *registerWR |= bitmaskWR; + sbi(registerWR,bitmaskWR); } else { sbi(registerSDA, bitmaskSDA); cbi(registerSCL, bitmaskSCL); // Pull SPI SCK high diff --git a/examples/PixelsTest/PixelsTest.ino b/examples/PixelsTest/PixelsTest.ino index 96180e4..e9f21f7 100644 --- a/examples/PixelsTest/PixelsTest.ino +++ b/examples/PixelsTest/PixelsTest.ino @@ -1,21 +1,28 @@ -#include -#include // optional (a removal does not impact fonts antialiasing) -#include +//#include +//#include // optional (a removal does not impact fonts antialiasing) +//#include -Pixels pxs(240, 400); +//Pixels pxs(240, 400); -//#include -//#include -//#include +#include +#include +#include -//Pixels pxs(240, 320); +Pixels pxs(240, 320); extern prog_uchar Eurostile13a[494] PROGMEM; extern prog_uchar Verdana8[637] PROGMEM; +#define TFT_CLK D5 +#define TFT_MOSI D7 +#define TFT_DC D4 +#define TFT_CS D1 +#define TFT_RST D2 + void setup() { pxs.init(); + pxs.setSpiPins(TFT_CLK,TFT_MOSI,TFT_CS,TFT_RST,TFT_DC); int delayCounter = 0; long start = millis(); int orientation = pxs.getOrientation();