Skip to content

Commit 2d37fb6

Browse files
committed
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% |
1 parent 86e4786 commit 2d37fb6

File tree

4 files changed

+365
-187
lines changed

4 files changed

+365
-187
lines changed

hardware/esp8266com/esp8266/libraries/SPI/SPI.cpp

Lines changed: 118 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef union {
3636
SPIClass SPI;
3737

3838
SPIClass::SPIClass() {
39+
useHwCs = false;
3940
}
4041

4142
void SPIClass::begin() {
@@ -54,9 +55,26 @@ void SPIClass::end() {
5455
pinMode(SCK, INPUT);
5556
pinMode(MISO, INPUT);
5657
pinMode(MOSI, INPUT);
58+
if(useHwCs) {
59+
pinMode(SS, INPUT);
60+
}
61+
}
62+
63+
void SPIClass::setHwCs(bool use) {
64+
if(use) {
65+
pinMode(SS, SPECIAL); ///< GPIO15
66+
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
67+
} else {
68+
if(useHwCs) {
69+
pinMode(SS, INPUT);
70+
SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
71+
}
72+
}
73+
useHwCs = use;
5774
}
5875

5976
void SPIClass::beginTransaction(SPISettings settings) {
77+
while(SPI1CMD & SPIBUSY) {}
6078
setFrequency(settings._clock);
6179
setBitOrder(settings._bitOrder);
6280
setDataMode(settings._dataMode);
@@ -199,12 +217,10 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
199217
}
200218

201219
uint8_t SPIClass::transfer(uint8_t data) {
202-
while(SPI1CMD & SPIBUSY)
203-
;
220+
while(SPI1CMD & SPIBUSY) {}
204221
SPI1W0 = data;
205222
SPI1CMD |= SPIBUSY;
206-
while(SPI1CMD & SPIBUSY)
207-
;
223+
while(SPI1CMD & SPIBUSY) {}
208224
return (uint8_t) (SPI1W0 & 0xff);
209225
}
210226

@@ -230,3 +246,101 @@ uint16_t SPIClass::transfer16(uint16_t data) {
230246
return out.val;
231247
}
232248

249+
void SPIClass::write(uint8_t data) {
250+
while(SPI1CMD & SPIBUSY) {}
251+
SPI1W0 = data;
252+
SPI1CMD |= SPIBUSY;
253+
while(SPI1CMD & SPIBUSY) {}
254+
}
255+
256+
void SPIClass::write16(uint16_t data) {
257+
write16(data, (SPI1C & (SPICWBO | SPICRBO)));
258+
}
259+
260+
void SPIClass::write16(uint16_t data, bool msb) {
261+
while(SPI1CMD & SPIBUSY) {}
262+
// Set to 16Bits transfer
263+
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((16 - 1) << SPILMOSI);
264+
if(msb) {
265+
// MSBFIRST Byte first
266+
SPI1W0 = (data >> 8) | (data << 8);
267+
SPI1CMD |= SPIBUSY;
268+
} else {
269+
// LSBFIRST Byte first
270+
SPI1W0 = data;
271+
SPI1CMD |= SPIBUSY;
272+
}
273+
while(SPI1CMD & SPIBUSY) {}
274+
// reset to 8Bit mode
275+
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1) << SPILMOSI);
276+
}
277+
278+
void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
279+
while(size) {
280+
if(size > 64) {
281+
writeBytes_(data, 64);
282+
size -= 64;
283+
data += 64;
284+
} else {
285+
writeBytes_(data, size);
286+
size = 0;
287+
}
288+
}
289+
}
290+
291+
void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
292+
while(SPI1CMD & SPIBUSY) {}
293+
// Set Bits to transfer
294+
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((size * 8 - 1) << SPILMOSI);
295+
296+
volatile uint32_t * fifoPtr = &SPI1W0;
297+
uint32_t * dataPtr = (uint32_t*) data;
298+
uint8_t dataSize = ((size + 3) / 4);
299+
300+
while(dataSize--) {
301+
*fifoPtr = *dataPtr;
302+
dataPtr++;
303+
fifoPtr++;
304+
}
305+
306+
SPI1CMD |= SPIBUSY;
307+
while(SPI1CMD & SPIBUSY) {}
308+
// reset to 8Bit mode
309+
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1) << SPILMOSI);
310+
}
311+
312+
void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
313+
if(size > 64) return; //max Hardware FIFO
314+
315+
uint32_t byte = (size * repeat);
316+
uint8_t r = (64 / size);
317+
318+
while(byte) {
319+
if(byte > 64) {
320+
writePattern_(data, size, r);
321+
byte -= 64;
322+
} else {
323+
writePattern_(data, size, (byte / size));
324+
byte = 0;
325+
}
326+
}
327+
}
328+
329+
void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
330+
uint8_t bytes = (size * repeat);
331+
uint8_t buffer[64];
332+
uint8_t * bufferPtr = &buffer[0];
333+
uint8_t * dataPtr;
334+
uint8_t dataSize = bytes;
335+
for(uint8_t i = 0; i < repeat; i++) {
336+
dataSize = size;
337+
dataPtr = data;
338+
while(dataSize--) {
339+
*bufferPtr = *dataPtr;
340+
dataPtr++;
341+
bufferPtr++;
342+
}
343+
}
344+
345+
writeBytes(&buffer[0], bytes);
346+
}

hardware/esp8266com/esp8266/libraries/SPI/SPI.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,24 @@ class SPIClass {
6464
SPIClass();
6565
void begin();
6666
void end();
67+
void setHwCs(bool use);
6768
void setBitOrder(uint8_t bitOrder);
6869
void setDataMode(uint8_t dataMode);
6970
void setFrequency(uint32_t freq);
7071
void setClockDivider(uint32_t clockDiv);
7172
void beginTransaction(SPISettings settings);
7273
uint8_t transfer(uint8_t data);
7374
uint16_t transfer16(uint16_t data);
75+
void write(uint8_t data);
76+
void write16(uint16_t data);
77+
void write16(uint16_t data, bool msb);
78+
void writeBytes(uint8_t * data, uint32_t size);
79+
void writePattern(uint8_t * data, uint8_t size, uint32_t repeat);
7480
void endTransaction(void);
81+
private:
82+
bool useHwCs;
83+
void writeBytes_(uint8_t * data, uint8_t size);
84+
void writePattern_(uint8_t * data, uint8_t size, uint8_t repeat);
7585
};
7686

7787
extern SPIClass SPI;

0 commit comments

Comments
 (0)