1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-16 11:21:18 +03:00

Merge branch 'Links2004-esp8266' into esp8266

* Links2004-esp8266:
  remove libc still not working!
  SD:  - optimize SPI usage 148% write speed (24kB/s -> 37kB/s) and 127% read speed (121kB/s -> 155kB/s) at 8MHz  - add clock frequency as parameter for begin(csPin, frequency)  - SD @80MHz write: 84kB/s read: 231kB/s
  Adafruit_ILI9341 +7% speed now at 327,45% total
  many speed optimizations in Adafruit_ILI9341 lib (3x times faster)
This commit is contained in:
Ivan Grokhotkov
2015-05-12 19:10:24 +03:00
9 changed files with 652 additions and 366 deletions

View File

@ -175,6 +175,9 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
uint32_t size = 0;
if(str == NULL) {
if(temp == NULL) {
return NULL;
}
start = *temp;
} else {
start = str;
@ -184,6 +187,10 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
return NULL;
}
if(delimiters == NULL) {
return NULL;
}
end = start;
while(1) {
@ -211,7 +218,9 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
}
char* ICACHE_FLASH_ATTR strtok(char * str, const char * delimiters) {
return strtok_r(str, delimiters, NULL);
static char * ret = NULL;
ret = strtok_r(str, delimiters, &ret);
return ret;
}
int strcasecmp(const char * str1, const char * str2) {

View File

@ -36,6 +36,7 @@ typedef union {
SPIClass SPI;
SPIClass::SPIClass() {
useHwCs = false;
}
void SPIClass::begin() {
@ -54,9 +55,26 @@ void SPIClass::end() {
pinMode(SCK, INPUT);
pinMode(MISO, INPUT);
pinMode(MOSI, INPUT);
if(useHwCs) {
pinMode(SS, INPUT);
}
}
void SPIClass::setHwCs(bool use) {
if(use) {
pinMode(SS, SPECIAL); ///< GPIO15
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
} else {
if(useHwCs) {
pinMode(SS, INPUT);
SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
}
}
useHwCs = use;
}
void SPIClass::beginTransaction(SPISettings settings) {
while(SPI1CMD & SPIBUSY) {}
setFrequency(settings._clock);
setBitOrder(settings._bitOrder);
setDataMode(settings._dataMode);
@ -198,13 +216,19 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
SPI1CLK = clockDiv;
}
inline void SPIClass::setDataBits(uint16_t bits) {
const uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
bits--;
SPI1U1 = ((SPI1U1 & mask) | ((bits << SPILMOSI) | (bits << SPILMISO)));
}
uint8_t SPIClass::transfer(uint8_t data) {
while(SPI1CMD & SPIBUSY)
;
while(SPI1CMD & SPIBUSY) {}
// reset to 8Bit mode
setDataBits(8);
SPI1W0 = data;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY)
;
while(SPI1CMD & SPIBUSY) {}
return (uint8_t) (SPI1W0 & 0xff);
}
@ -230,3 +254,177 @@ uint16_t SPIClass::transfer16(uint16_t data) {
return out.val;
}
void SPIClass::write(uint8_t data) {
while(SPI1CMD & SPIBUSY) {}
// reset to 8Bit mode
setDataBits(8);
SPI1W0 = data;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
void SPIClass::write16(uint16_t data) {
write16(data, !(SPI1C & (SPICWBO | SPICRBO)));
}
void SPIClass::write16(uint16_t data, bool msb) {
while(SPI1CMD & SPIBUSY) {}
// Set to 16Bits transfer
setDataBits(16);
if(msb) {
// MSBFIRST Byte first
SPI1W0 = (data >> 8) | (data << 8);
SPI1CMD |= SPIBUSY;
} else {
// LSBFIRST Byte first
SPI1W0 = data;
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
}
void SPIClass::write32(uint32_t data) {
write32(data, !(SPI1C & (SPICWBO | SPICRBO)));
}
void SPIClass::write32(uint32_t data, bool msb) {
while(SPI1CMD & SPIBUSY) {}
// Set to 32Bits transfer
setDataBits(32);
if(msb) {
union {
uint32_t l;
uint8_t b[4];
} data_;
data_.l = data;
// MSBFIRST Byte first
SPI1W0 = (data_.b[3] | (data_.b[2] << 8) | (data_.b[1] << 16) | (data_.b[0] << 24));
SPI1CMD |= SPIBUSY;
} else {
// LSBFIRST Byte first
SPI1W0 = data;
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
}
void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
while(size) {
if(size > 64) {
writeBytes_(data, 64);
size -= 64;
data += 64;
} else {
writeBytes_(data, size);
size = 0;
}
}
}
void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
while(SPI1CMD & SPIBUSY) {}
// Set Bits to transfer
setDataBits(size * 8);
volatile uint32_t * fifoPtr = &SPI1W0;
uint32_t * dataPtr = (uint32_t*) data;
uint8_t dataSize = ((size + 3) / 4);
while(dataSize--) {
*fifoPtr = *dataPtr;
dataPtr++;
fifoPtr++;
}
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
if(size > 64) return; //max Hardware FIFO
uint32_t byte = (size * repeat);
uint8_t r = (64 / size);
while(byte) {
if(byte > 64) {
writePattern_(data, size, r);
byte -= 64;
} else {
writePattern_(data, size, (byte / size));
byte = 0;
}
}
}
void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
uint8_t bytes = (size * repeat);
uint8_t buffer[64];
uint8_t * bufferPtr = &buffer[0];
uint8_t * dataPtr;
uint8_t dataSize = bytes;
for(uint8_t i = 0; i < repeat; i++) {
dataSize = size;
dataPtr = data;
while(dataSize--) {
*bufferPtr = *dataPtr;
dataPtr++;
bufferPtr++;
}
}
writeBytes(&buffer[0], bytes);
}
void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size) {
while(size) {
if(size > 64) {
transferBytes_(out, in, 64);
size -= 64;
if(out) out += 64;
if(in) in += 64;
} else {
transferBytes_(out, in, size);
size = 0;
}
}
}
void SPIClass::transferBytes_(uint8_t * out, uint8_t * in, uint8_t size) {
while(SPI1CMD & SPIBUSY) {}
// Set in/out Bits to transfer
setDataBits(size * 8);
volatile uint32_t * fifoPtr = &SPI1W0;
uint8_t dataSize = ((size + 3) / 4);
if(out) {
uint32_t * dataPtr = (uint32_t*) out;
while(dataSize--) {
*fifoPtr = *dataPtr;
dataPtr++;
fifoPtr++;
}
} else {
// no out data only read fill with dummy data!
while(dataSize--) {
*fifoPtr = 0xFFFFFFFF;
fifoPtr++;
}
}
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
if(in) {
volatile uint8_t * fifoPtr8 = (volatile uint8_t *) &SPI1W0;
dataSize = size;
while(dataSize--) {
*in = *fifoPtr8;
in++;
fifoPtr8++;
}
}
}

View File

@ -64,6 +64,7 @@ public:
SPIClass();
void begin();
void end();
void setHwCs(bool use);
void setBitOrder(uint8_t bitOrder);
void setDataMode(uint8_t dataMode);
void setFrequency(uint32_t freq);
@ -71,7 +72,21 @@ public:
void beginTransaction(SPISettings settings);
uint8_t transfer(uint8_t data);
uint16_t transfer16(uint16_t data);
void write(uint8_t data);
void write16(uint16_t data);
void write16(uint16_t data, bool msb);
void write32(uint32_t data);
void write32(uint32_t data, bool msb);
void writeBytes(uint8_t * data, uint32_t size);
void writePattern(uint8_t * data, uint8_t size, uint32_t repeat);
void transferBytes(uint8_t * out, uint8_t * in, uint32_t size);
void endTransaction(void);
private:
bool useHwCs;
void writeBytes_(uint8_t * data, uint8_t size);
void writePattern_(uint8_t * data, uint8_t size, uint8_t repeat);
void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
inline void setDataBits(uint16_t bits);
};
extern SPIClass SPI;

View File

@ -23,7 +23,7 @@ compiler.S.flags=-c -g -x assembler-with-cpp -MMD
compiler.c.elf.ldscript=eagle.app.v6.ld
compiler.c.elf.flags=-nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-T{compiler.c.elf.ldscript}"
compiler.c.elf.cmd=xtensa-lx106-elf-gcc
compiler.c.elf.libs=-lm -lc -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig
compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig
compiler.cpp.cmd=xtensa-lx106-elf-g++
compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD

View File

@ -11,6 +11,8 @@
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
Modified 09 May 2015 by Markus Sattler - rewrite the code add ESP8266 support and many optimizations now 220% fastet (320% total)
****************************************************/
#include "Adafruit_ILI9341.h"
@ -24,6 +26,16 @@
#include "wiring_private.h"
#include <SPI.h>
#ifdef ESP8266
#define hwSPI true
#endif
#define writeCmdDataTmp(cmd, ...) { \
const uint8_t tmp##cmd##_[] = { __VA_ARGS__ }; \
writeCmdData(cmd, (uint8_t *) &tmp##cmd##_[0], sizeof(tmp##cmd##_)); \
}
#ifndef ESP8266
// Constructor when using software SPI. All output pins are configurable.
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi,
@ -40,15 +52,40 @@ Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi,
// Constructor when using hardware SPI. Faster, but must use SPI pins
// specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.)
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
_cs = cs;
#if defined(ILI9341_USE_HW_CS) || defined(ILI9341_USE_NO_CS)
Adafruit_ILI9341::Adafruit_ILI9341(int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
_dc = dc;
_rst = rst;
hwSPI = true;
#ifndef ESP8266
#ifdef ESP8266
_dcMask = digitalPinToBitMask(_dc);
_rstMask = digitalPinToBitMask(_rst);
#else
_mosi = _sclk = 0;
#endif
}
#else
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
_cs = cs;
_dc = dc;
_rst = rst;
#ifdef ESP8266
_csMask = digitalPinToBitMask(_cs);
_dcMask = digitalPinToBitMask(_dc);
_rstMask = digitalPinToBitMask(_rst);
#else
hwSPI = true;
_mosi = _sclk = 0;
#endif
}
#endif
#ifdef ESP8266
void Adafruit_ILI9341::spiwrite16(uint16_t c) {
SPI.write16(c, true);
}
#endif
void Adafruit_ILI9341::spiwrite(uint8_t c) {
@ -63,7 +100,7 @@ void Adafruit_ILI9341::spiwrite(uint8_t c) {
while(!(SPSR & _BV(SPIF)));
SPCR = backupSPCR;
#elif defined(TEENSYDUINO) || defined(ESP8266)
SPI.transfer(c);
SPI.write(c);
#elif defined (__arm__)
SPI.setClockDivider(11); // 8-ish MHz (full! speed!)
SPI.setBitOrder(MSBFIRST);
@ -90,73 +127,143 @@ void Adafruit_ILI9341::spiwrite(uint8_t c) {
#endif
}
void Adafruit_ILI9341::spiwriteBytes(uint8_t * data, uint8_t size) {
#ifdef ESP8266
SPI.writeBytes(data, size);
#else
while(size--) {
spiwrite(*data);
data++;
}
#endif
}
void Adafruit_ILI9341::writecommand(uint8_t c) {
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, LOW);
void Adafruit_ILI9341::spiwritePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
#ifdef ESP8266
SPI.writePattern(data, size, repeat);
#else
uint8_t * ptr;
uint8_t i;
while(repeat--) {
ptr = data;
i = size;
while(i--) {
spiwrite(*ptr);
ptr++;
}
}
#endif
}
inline void Adafruit_ILI9341::spiCsLow(void) {
#ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOC = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
#else
*dcport &= ~dcpinmask;
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
//digitalWrite(_sclk, LOW);
*csport &= ~cspinmask;
#if !defined(ILI9341_USE_HW_CS) && !defined(ILI9341_USE_NO_CS)
GPOC = _csMask;
#endif
#endif
spiwrite(c);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
*csport &= ~cspinmask;
#endif
#endif
}
void Adafruit_ILI9341::writedata(uint8_t c) {
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
#else
*dcport |= dcpinmask;
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
//digitalWrite(_sclk, LOW);
*csport &= ~cspinmask;
#endif
#endif
spiwrite(c);
#ifdef USE_DIGITAL_WRITE
inline void Adafruit_ILI9341::spiCsHigh(void) {
#ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#if !defined(ILI9341_USE_HW_CS) && !defined(ILI9341_USE_NO_CS)
GPOS = _csMask;
#endif
#else
*csport |= cspinmask;
*csport |= cspinmask;
#endif
#endif
}
inline void Adafruit_ILI9341::spiDcLow(void){
#ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_dc, LOW);
#else
#ifdef ESP8266
#ifndef USE_HW_CS
GPOC = _dcMask;
#endif
#else
*dcport &= ~dcpinmask;
#endif
#endif
}
inline void Adafruit_ILI9341::spiDcHigh(void) {
#ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
#else
#ifdef ESP8266
GPOS = _dcMask;
#else
*dcport |= dcpinmask;
#endif
#endif
}
void Adafruit_ILI9341::writecommand(uint8_t c) {
spiDcLow();
spiCsLow();
spiwrite(c);
spiCsHigh();
}
void Adafruit_ILI9341::writedata(uint8_t c) {
spiDcHigh();
spiCsLow();
spiwrite(c);
spiCsHigh();
}
void Adafruit_ILI9341::writedata(uint8_t * data, uint8_t size) {
spiDcHigh();
spiCsLow();
spiwriteBytes(data, size);
spiCsHigh();
}
void Adafruit_ILI9341::writeCmdData(uint8_t cmd, uint8_t * data, uint8_t size) {
spiDcLow();
spiCsLow();
spiwrite(cmd);
spiDcHigh();
spiwriteBytes(data, size);
spiCsHigh();
}
// If the SPI library has transaction support, these functions
// establish settings and protect from interference from other
// libraries. Otherwise, they simply do nothing.
#ifdef SPI_HAS_TRANSACTION
#ifdef ESP8266
SPISettings spiSettings = SPISettings(F_CPU, MSBFIRST, SPI_MODE0);
#else
SPISettings spiSettings = SPISettings(8000000, MSBFIRST, SPI_MODE0);
#endif
static inline void spi_begin(void) __attribute__((always_inline));
static inline void spi_begin(void) {
#ifdef ESP8266
SPI.beginTransaction(SPISettings(80000000, MSBFIRST, SPI_MODE0));
#else
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
#endif
SPI.beginTransaction(spiSettings);
}
static inline void spi_end(void) __attribute__((always_inline));
static inline void spi_end(void) {
@ -202,15 +309,17 @@ void Adafruit_ILI9341::commandList(uint8_t *addr) {
void Adafruit_ILI9341::begin(void) {
if (_rst > 0) {
if (_rst > NOT_A_PIN) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, LOW);
}
pinMode(_dc, OUTPUT);
#ifndef USE_HW_CS
pinMode(_cs, OUTPUT);
#endif
#ifndef ESP8266
#ifndef USE_DIGITAL_WRITE
#ifndef ILI9341_USE_DIGITAL_WRITE
csport = portOutputRegister(digitalPinToPort(_cs));
cspinmask = digitalPinToBitMask(_cs);
dcport = portOutputRegister(digitalPinToPort(_dc));
@ -236,6 +345,9 @@ void Adafruit_ILI9341::begin(void) {
SPI.setDataMode(SPI_MODE0);
#elif defined (ESP8266)
SPI.begin();
#ifdef USE_HW_CS
SPI.setHwCs(true);
#endif
#endif
#ifndef ESP8266
} else {
@ -251,7 +363,7 @@ void Adafruit_ILI9341::begin(void) {
}
#endif
// toggle RST low to reset
if (_rst > 0) {
if (_rst > NOT_A_PIN) {
digitalWrite(_rst, HIGH);
delay(5);
digitalWrite(_rst, LOW);
@ -275,108 +387,47 @@ void Adafruit_ILI9341::begin(void) {
//if(cmdList) commandList(cmdList);
if (hwSPI) spi_begin();
writecommand(0xEF);
writedata(0x03);
writedata(0x80);
writedata(0x02);
writecommand(0xCF);
writedata(0x00);
writedata(0XC1);
writedata(0X30);
writeCmdDataTmp(0xEF, 0x03, 0x80, 0x02);
writeCmdDataTmp(0xCF, 0x00, 0XC1, 0X30);
writeCmdDataTmp(0xED, 0x64, 0x03, 0X12, 0X81);
writeCmdDataTmp(0xE8, 0x85, 0x00, 0x78);
writeCmdDataTmp(0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02);
writeCmdDataTmp(0xF7, 0x20);
writeCmdDataTmp(0xEA, 0x00, 0x00);
writecommand(0xED);
writedata(0x64);
writedata(0x03);
writedata(0X12);
writedata(0X81);
writecommand(0xE8);
writedata(0x85);
writedata(0x00);
writedata(0x78);
//Powercontrol
//VRH[5:0]
writeCmdDataTmp(ILI9341_PWCTR1, 0x23);
writecommand(0xCB);
writedata(0x39);
writedata(0x2C);
writedata(0x00);
writedata(0x34);
writedata(0x02);
writecommand(0xF7);
writedata(0x20);
//Powercontrol
//SAP[2:0];BT[3:0]
writeCmdDataTmp(ILI9341_PWCTR2, 0x10);
writecommand(0xEA);
writedata(0x00);
writedata(0x00);
writecommand(ILI9341_PWCTR1); //Power control
writedata(0x23); //VRH[5:0]
writecommand(ILI9341_PWCTR2); //Power control
writedata(0x10); //SAP[2:0];BT[3:0]
writecommand(ILI9341_VMCTR1); //VCM control
writedata(0x3e); //<2F>Աȶȵ<C8B6><C8B5><EFBFBD>
writedata(0x28);
//VCMcontrol
writeCmdDataTmp(ILI9341_VMCTR1, 0x3e, 0x28);
//VCMcontrol2
writeCmdDataTmp(ILI9341_VMCTR2, 0x86);
//MemoryAccessControl
writeCmdDataTmp(ILI9341_MADCTL, 0x48);
writeCmdDataTmp(ILI9341_PIXFMT, 0x55);
writeCmdDataTmp(ILI9341_FRMCTR1, 0x00, 0x18);
//DisplayFunctionControl
writeCmdDataTmp(ILI9341_DFUNCTR, 0x08, 0x82, 0x27);
//3GammaFunctionDisable
writeCmdDataTmp(0xF2, 0x00);
writecommand(ILI9341_VMCTR2); //VCM control2
writedata(0x86); //--
writecommand(ILI9341_MADCTL); // Memory Access Control
writedata(0x48);
writecommand(ILI9341_PIXFMT);
writedata(0x55);
//Gammacurveselected
writeCmdDataTmp(ILI9341_GAMMASET, 0x01);
writecommand(ILI9341_FRMCTR1);
writedata(0x00);
writedata(0x18);
writecommand(ILI9341_DFUNCTR); // Display Function Control
writedata(0x08);
writedata(0x82);
writedata(0x27);
writecommand(0xF2); // 3Gamma Function Disable
writedata(0x00);
writecommand(ILI9341_GAMMASET); //Gamma curve selected
writedata(0x01);
writecommand(ILI9341_GMCTRP1); //Set Gamma
writedata(0x0F);
writedata(0x31);
writedata(0x2B);
writedata(0x0C);
writedata(0x0E);
writedata(0x08);
writedata(0x4E);
writedata(0xF1);
writedata(0x37);
writedata(0x07);
writedata(0x10);
writedata(0x03);
writedata(0x0E);
writedata(0x09);
writedata(0x00);
writecommand(ILI9341_GMCTRN1); //Set Gamma
writedata(0x00);
writedata(0x0E);
writedata(0x14);
writedata(0x03);
writedata(0x11);
writedata(0x07);
writedata(0x31);
writedata(0xC1);
writedata(0x48);
writedata(0x08);
writedata(0x0F);
writedata(0x0C);
writedata(0x31);
writedata(0x36);
writedata(0x0F);
//SetGamma
writeCmdDataTmp(ILI9341_GMCTRP1, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00);
writeCmdDataTmp(ILI9341_GMCTRN1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F);
writecommand(ILI9341_SLPOUT); //Exit Sleep
if (hwSPI) spi_end();
@ -387,217 +438,161 @@ void Adafruit_ILI9341::begin(void) {
}
void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
spiCsLow();
setAddrWindow_(x0, y0, x1, y1);
spiCsHigh();
}
void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,
uint16_t y1) {
void Adafruit_ILI9341::setAddrWindow_(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
writecommand(ILI9341_CASET); // Column addr set
writedata(x0 >> 8);
writedata(x0 & 0xFF); // XSTART
writedata(x1 >> 8);
writedata(x1 & 0xFF); // XEND
uint8_t buffC[] = { (uint8_t) (x0 >> 8), (uint8_t) x0, (uint8_t) (x1 >> 8), (uint8_t) x1 };
uint8_t buffP[] = { (uint8_t) (y0 >> 8), (uint8_t) y0, (uint8_t) (y1 >> 8), (uint8_t) y1 };
writecommand(ILI9341_PASET); // Row addr set
writedata(y0>>8);
writedata(y0); // YSTART
writedata(y1>>8);
writedata(y1); // YEND
spiDcLow();
spiwrite(ILI9341_CASET);
spiDcHigh();
spiwriteBytes(&buffC[0], sizeof(buffC));
spiDcLow();
spiwrite(ILI9341_PASET);
spiDcHigh();
spiwriteBytes(&buffP[0], sizeof(buffP));
spiDcLow();
spiwrite(ILI9341_RAMWR);
spiDcHigh();
writecommand(ILI9341_RAMWR); // write to RAM
}
void Adafruit_ILI9341::pushColor(uint16_t color) {
if (hwSPI) spi_begin();
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
spiDcHigh();
spiCsLow();
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
spiwrite16(color);
#else
*dcport |= dcpinmask;
*csport &= ~cspinmask;
#endif
#endif
spiwrite(color >> 8);
spiwrite(color);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
spiCsHigh();
if (hwSPI) spi_end();
}
void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color) {
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) {
return;
}
if(hwSPI) {
spi_begin();
}
spiCsLow();
setAddrWindow_(x, y, x + 1, y + 1);
if (hwSPI) spi_begin();
setAddrWindow(x,y,x+1,y+1);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
spiwrite16(color);
#else
*dcport |= dcpinmask;
*csport &= ~cspinmask;
#endif
spiwrite(color >> 8);
spiwrite(color);
#endif
spiwrite(color >> 8);
spiwrite(color);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
spiCsHigh();
if(hwSPI) {
spi_end();
}
}
void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
if((y + h - 1) >= _height) h = _height - y;
if((y+h-1) >= _height)
h = _height-y;
if(hwSPI) {
spi_begin();
}
if (hwSPI) spi_begin();
setAddrWindow(x, y, x, y+h-1);
spiCsLow();
uint8_t hi = color >> 8, lo = color;
setAddrWindow_(x, y, x, (y + h - 1));
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
#else
*dcport |= dcpinmask;
*csport &= ~cspinmask;
#endif
#endif
uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
spiwritePattern(&colorBin[0], 2, h);
while (h--) {
spiwrite(hi);
spiwrite(lo);
}
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
spiCsHigh();
if(hwSPI) {
spi_end();
}
}
void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
if((x+w-1) >= _width) w = _width-x;
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
if((x+w-1) >= _width) w = _width-x;
if (hwSPI) spi_begin();
setAddrWindow(x, y, x+w-1, y);
if(hwSPI) {
spi_begin();
}
uint8_t hi = color >> 8, lo = color;
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
#else
*dcport |= dcpinmask;
*csport &= ~cspinmask;
#endif
#endif
while (w--) {
spiwrite(hi);
spiwrite(lo);
}
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
spiDcHigh();
spiCsLow();
setAddrWindow_(x, y, (x + w - 1), y);
uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
spiwritePattern(&colorBin[0], 2, w);
spiCsHigh();
if(hwSPI) {
spi_end();
}
}
void Adafruit_ILI9341::fillScreen(uint16_t color) {
fillRect(0, 0, _width, _height, color);
fillRect(0, 0, _width, _height, color);
}
// fill a rectangle
void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color) {
void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
// rudimentary clipping (drawChar w/big text requires this)
if((x >= _width) || (y >= _height)) return;
if((x + w - 1) >= _width) w = _width - x;
if((y + h - 1) >= _height) h = _height - y;
// rudimentary clipping (drawChar w/big text requires this)
if((x >= _width) || (y >= _height))
return;
if((x + w - 1) >= _width)
w = _width - x;
if((y + h - 1) >= _height)
h = _height - y;
if (hwSPI) spi_begin();
setAddrWindow(x, y, x+w-1, y+h-1);
uint8_t hi = color >> 8, lo = color;
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
#else
*dcport |= dcpinmask;
*csport &= ~cspinmask;
#endif
#endif
for(y=h; y>0; y--) {
for(x=w; x>0; x--) {
spiwrite(hi);
spiwrite(lo);
if(hwSPI) {
spi_begin();
}
spiCsLow();
setAddrWindow_(x, y, x + w - 1, y + h - 1);
uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
spiwritePattern(&colorBin[0], 2, (w * h));
spiCsHigh();
if(hwSPI) {
spi_end();
}
}
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
}
@ -675,9 +670,7 @@ uint8_t Adafruit_ILI9341::spiread(void) {
SPI.setDataMode(SPI_MODE0);
r = SPI.transfer(0x00);
#else
spi_begin();
r = SPI.transfer(0x00);
spi_end();
#endif
} else {
#ifndef ESP8266
@ -695,40 +688,40 @@ uint8_t Adafruit_ILI9341::spiread(void) {
return r;
}
uint8_t Adafruit_ILI9341::readdata(void) {
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
uint8_t r = spiread();
digitalWrite(_cs, HIGH);
return r;
uint8_t Adafruit_ILI9341::readdata(void) {
if(hwSPI) spi_begin();
spiCsLow();
spiDcLow();
uint8_t r = spiread();
spiCsHigh();
if(hwSPI) spi_end();
return r;
}
uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) {
if (hwSPI) spi_begin();
digitalWrite(_dc, LOW); // command
digitalWrite(_cs, LOW);
spiwrite(0xD9); // woo sekret command?
digitalWrite(_dc, HIGH); // data
spiwrite(0x10 + index);
digitalWrite(_cs, HIGH);
if(hwSPI) spi_begin();
spiCsLow();
spiDcLow();
spiwrite(0xD9); // woo sekret command?
spiDcHigh();
spiwrite(0x10 + index);
digitalWrite(_dc, LOW);
#ifndef ESP8266
digitalWrite(_sclk, LOW);
digitalWrite(_sclk, LOW);
#endif
digitalWrite(_cs, LOW);
spiwrite(c);
digitalWrite(_dc, HIGH);
uint8_t r = spiread();
digitalWrite(_cs, HIGH);
if (hwSPI) spi_end();
return r;
spiDcLow();
spiwrite(c);
spiDcHigh();
uint8_t r = spiread();
spiCsHigh();
if(hwSPI) spi_end();
return r;
}
/*

View File

@ -110,7 +110,12 @@
#define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
#define ILI9341_PINK 0xF81F
//#define USE_DIGITAL_WRITE
//#define ILI9341_USE_DIGITAL_WRITE
//#define ILI9341_USE_NO_CS
#ifdef ESP8266
//not working
//#define ILI9341_USE_HW_CS
#endif
class Adafruit_ILI9341 : public Adafruit_GFX {
@ -119,8 +124,11 @@ class Adafruit_ILI9341 : public Adafruit_GFX {
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
int8_t _RST, int8_t _MISO);
#endif
#if defined(USE_HW_CS) || defined(USE_NO_CS)
Adafruit_ILI9341(int8_t _DC, int8_t _RST = -1);
#else
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1);
#endif
void begin(void),
setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1),
pushColor(uint16_t color),
@ -134,25 +142,51 @@ class Adafruit_ILI9341 : public Adafruit_GFX {
invertDisplay(boolean i);
uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
/* These are not for current use, 8-bit protocol only! */
uint8_t readdata(void),
readcommand8(uint8_t reg, uint8_t index = 0);
/*
uint16_t readcommand16(uint8_t);
uint32_t readcommand32(uint8_t);
void dummyclock(void);
*/
void commandList(uint8_t *addr);
void spiwrite(uint8_t),
writecommand(uint8_t c),
writedata(uint8_t d),
commandList(uint8_t *addr);
uint8_t spiread(void);
/* These are not for current use, 8-bit protocol only! */
uint8_t readdata(void),
readcommand8(uint8_t reg, uint8_t index = 0);
/*
uint16_t readcommand16(uint8_t);
uint32_t readcommand32(uint8_t);
void dummyclock(void);
*/
void writecommand(uint8_t c);
void writedata(uint8_t d);
void writedata(uint8_t * data, uint8_t size);
void writeCmdData(uint8_t cmd, uint8_t * data, uint8_t size);
private:
uint8_t tabcolor;
uint8_t spiread(void);
#ifdef ESP8266
inline void spiwrite(uint8_t data);
inline void spiwrite16(uint16_t data);
inline void spiwriteBytes(uint8_t * data, uint8_t size);
inline void spiwritePattern(uint8_t * data, uint8_t size, uint32_t repeat);
inline void setAddrWindow_(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
#else
void spiwrite(uint8_t);
void spiwrite16(uint16_t data);
void spiwriteBytes(uint8_t * data, uint8_t size);
void spiwritePattern(uint8_t * data, uint8_t size, uint8_t repeat);
void setAddrWindow_(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
#endif
inline void spiCsHigh(void);
inline void spiCsLow(void);
inline void spiDcHigh(void);
inline void spiDcLow(void);
uint8_t tabcolor;
#ifndef ESP8266
boolean hwSPI;
#endif
#if defined (__AVR__) || defined(TEENSYDUINO)
uint8_t mySPCR;
volatile uint8_t *mosiport, *clkport, *dcport, *rsport, *csport;
@ -163,7 +197,12 @@ class Adafruit_ILI9341 : public Adafruit_GFX {
uint32_t _cs, _dc, _rst, _mosi, _miso, _sclk;
uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask;
#elif defined (ESP8266)
uint32_t _cs, _dc, _rst;
#ifndef USE_HW_CS
int8_t _cs;
uint32_t _csMask;
#endif
int8_t _dc, _rst;
uint32_t _dcMask, _rstMask;
#endif
};

View File

@ -345,8 +345,6 @@ boolean SDClass::begin(uint8_t csPin, uint32_t speed) {
root.openRoot(volume);
}
// this little helper is used to traverse paths
SdFile SDClass::getParentDir(const char *filepath, int *index) {
// get parent directory

View File

@ -66,7 +66,7 @@ public:
// This needs to be called to set up the connection to the SD card
// before other methods are used.
boolean begin(uint8_t csPin = SD_CHIP_SELECT_PIN, uint32_t speed = SPI_HALF_SPEED);
// Open the specified file/directory with the supplied mode (e.g. read or
// write, etc). Returns a File object for interacting with the file.
// Note that currently only one file can be open at a time.

View File

@ -33,9 +33,13 @@ static void spiSend(uint8_t b) {
SPDR = b;
while (!(SPSR & (1 << SPIF)))
;
#else
#ifdef ESP8266
SPI.write(b);
#else
SPI.transfer(b);
#endif
#endif
}
/** Receive a byte from the card */
static uint8_t spiRec(void) {
@ -116,8 +120,14 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
// send command
spiSend(cmd | 0x40);
#ifdef ESP8266
// send argument
SPI.write32(arg, true);
#else
// send argument
for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
#endif
// send CRC
uint8_t crc = 0xFF;
@ -424,7 +434,14 @@ uint8_t Sd2Card::readData(uint32_t block,
dst[n] = SPDR;
#else // OPTIMIZE_HARDWARE_SPI
#ifdef ESP8266
// skip data before offset
SPI.transferBytes(NULL, NULL, offset_);
// transfer data
SPI.transferBytes(NULL, dst, count);
#else
// skip data before offset
for (;offset_ < offset; offset_++) {
spiRec();
@ -433,6 +450,7 @@ uint8_t Sd2Card::readData(uint32_t block,
for (uint16_t i = 0; i < count; i++) {
dst[i] = spiRec();
}
#endif
#endif // OPTIMIZE_HARDWARE_SPI
offset_ += count;
@ -463,7 +481,11 @@ void Sd2Card::readEnd(void) {
while (!(SPSR & (1 << SPIF)))
;
#else // OPTIMIZE_HARDWARE_SPI
#ifdef ESP8266
SPI.transferBytes(NULL, NULL, (514-offset_));
#else
while (offset_++ < 514) spiRec();
#endif
#endif // OPTIMIZE_HARDWARE_SPI
chipSelectHigh();
inBlock_ = 0;
@ -479,7 +501,11 @@ uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
}
if (!waitStartBlock()) goto fail;
// transfer data
#ifdef ESP8266
SPI.transferBytes(NULL, dst, 16);
#else
for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
#endif
spiRec(); // get first crc byte
spiRec(); // get second crc byte
chipSelectHigh();
@ -646,13 +672,21 @@ uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
#else // OPTIMIZE_HARDWARE_SPI
spiSend(token);
#ifdef ESP8266
// send argument
SPI.writeBytes((uint8_t *)src, 512);
#else
for (uint16_t i = 0; i < 512; i++) {
spiSend(src[i]);
}
#endif
#endif // OPTIMIZE_HARDWARE_SPI
#ifdef ESP8266
SPI.write16(0xFFFF, true);
#else
spiSend(0xff); // dummy crc
spiSend(0xff); // dummy crc
#endif
status_ = spiRec();
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
error(SD_CARD_ERROR_WRITE);