mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-16 11:21:18 +03:00
many speed optimizations in Adafruit_ILI9341 lib (3x times faster)
add new SPI function: void write(uint8_t data); void write16(uint16_t data); void write16(uint16_t data, bool msb); void writeBytes(uint8_t * data, uint32_t size); void writePattern(uint8_t * data, uint8_t size, uint32_t repeat); Adafruit_ILI9341: | Benchmark | Old (ms) | New (ms) | Speedup | | ------------------------- | -------- | -------- | ----------- | | Screen fill | 1248369 | 278707 | +347,91% | | Text | 86102 | 53785 | +60,09% | | Lines | 825400 | 536374 | +53,89% | | Horiz/Vert Lines | 101875 | 24653 | +313,24% | | Rectangles (outline) | 65720 | 17295 | +279,99% | | Rectangles (filled) | 2592250 | 579157 | +347,59% | | Circles (filled) | 411475 | 179454 | +129,29% | | Circles (outline) | 360002 | 233584 | +54,12% | | Triangles (outline) | 261772 | 170118 | +53,88% | | Triangles (filled) | 866951 | 246237 | +252,08% | | Rounded rects (outline) | 154131 | 81570 | +88,96% | | Rounded rects (filled) | 2828112 | 660983 | +327,86% | | | | | | | Total | 9802159 | 3061917 | +220,13% |
This commit is contained in:
@ -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);
|
||||
@ -199,12 +217,10 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
|
||||
}
|
||||
|
||||
uint8_t SPIClass::transfer(uint8_t data) {
|
||||
while(SPI1CMD & SPIBUSY)
|
||||
;
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
SPI1W0 = data;
|
||||
SPI1CMD |= SPIBUSY;
|
||||
while(SPI1CMD & SPIBUSY)
|
||||
;
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
return (uint8_t) (SPI1W0 & 0xff);
|
||||
}
|
||||
|
||||
@ -230,3 +246,101 @@ uint16_t SPIClass::transfer16(uint16_t data) {
|
||||
return out.val;
|
||||
}
|
||||
|
||||
void SPIClass::write(uint8_t data) {
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
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
|
||||
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((16 - 1) << SPILMOSI);
|
||||
if(msb) {
|
||||
// MSBFIRST Byte first
|
||||
SPI1W0 = (data >> 8) | (data << 8);
|
||||
SPI1CMD |= SPIBUSY;
|
||||
} else {
|
||||
// LSBFIRST Byte first
|
||||
SPI1W0 = data;
|
||||
SPI1CMD |= SPIBUSY;
|
||||
}
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
// reset to 8Bit mode
|
||||
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1) << SPILMOSI);
|
||||
}
|
||||
|
||||
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
|
||||
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((size * 8 - 1) << SPILMOSI);
|
||||
|
||||
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) {}
|
||||
// reset to 8Bit mode
|
||||
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1) << SPILMOSI);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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,16 @@ 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 writeBytes(uint8_t * data, uint32_t size);
|
||||
void writePattern(uint8_t * data, uint8_t size, uint32_t repeat);
|
||||
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);
|
||||
};
|
||||
|
||||
extern SPIClass SPI;
|
||||
|
Reference in New Issue
Block a user