mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-18 23:03:34 +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 SPI;
|
||||||
|
|
||||||
SPIClass::SPIClass() {
|
SPIClass::SPIClass() {
|
||||||
|
useHwCs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::begin() {
|
void SPIClass::begin() {
|
||||||
@ -54,9 +55,26 @@ void SPIClass::end() {
|
|||||||
pinMode(SCK, INPUT);
|
pinMode(SCK, INPUT);
|
||||||
pinMode(MISO, INPUT);
|
pinMode(MISO, INPUT);
|
||||||
pinMode(MOSI, 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) {
|
void SPIClass::beginTransaction(SPISettings settings) {
|
||||||
|
while(SPI1CMD & SPIBUSY) {}
|
||||||
setFrequency(settings._clock);
|
setFrequency(settings._clock);
|
||||||
setBitOrder(settings._bitOrder);
|
setBitOrder(settings._bitOrder);
|
||||||
setDataMode(settings._dataMode);
|
setDataMode(settings._dataMode);
|
||||||
@ -199,12 +217,10 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SPIClass::transfer(uint8_t data) {
|
uint8_t SPIClass::transfer(uint8_t data) {
|
||||||
while(SPI1CMD & SPIBUSY)
|
while(SPI1CMD & SPIBUSY) {}
|
||||||
;
|
|
||||||
SPI1W0 = data;
|
SPI1W0 = data;
|
||||||
SPI1CMD |= SPIBUSY;
|
SPI1CMD |= SPIBUSY;
|
||||||
while(SPI1CMD & SPIBUSY)
|
while(SPI1CMD & SPIBUSY) {}
|
||||||
;
|
|
||||||
return (uint8_t) (SPI1W0 & 0xff);
|
return (uint8_t) (SPI1W0 & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,3 +246,101 @@ uint16_t SPIClass::transfer16(uint16_t data) {
|
|||||||
return out.val;
|
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();
|
SPIClass();
|
||||||
void begin();
|
void begin();
|
||||||
void end();
|
void end();
|
||||||
|
void setHwCs(bool use);
|
||||||
void setBitOrder(uint8_t bitOrder);
|
void setBitOrder(uint8_t bitOrder);
|
||||||
void setDataMode(uint8_t dataMode);
|
void setDataMode(uint8_t dataMode);
|
||||||
void setFrequency(uint32_t freq);
|
void setFrequency(uint32_t freq);
|
||||||
@ -71,7 +72,16 @@ public:
|
|||||||
void beginTransaction(SPISettings settings);
|
void beginTransaction(SPISettings settings);
|
||||||
uint8_t transfer(uint8_t data);
|
uint8_t transfer(uint8_t data);
|
||||||
uint16_t transfer16(uint16_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);
|
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;
|
extern SPIClass SPI;
|
||||||
|
Reference in New Issue
Block a user