Skip to content

Commit ddef215

Browse files
committed
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)
2 parents eb6baec + 635275c commit ddef215

File tree

9 files changed

+642
-356
lines changed

9 files changed

+642
-356
lines changed

hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
175175
uint32_t size = 0;
176176

177177
if(str == NULL) {
178+
if(temp == NULL) {
179+
return NULL;
180+
}
178181
start = *temp;
179182
} else {
180183
start = str;
@@ -184,6 +187,10 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
184187
return NULL;
185188
}
186189

190+
if(delimiters == NULL) {
191+
return NULL;
192+
}
193+
187194
end = start;
188195

189196
while(1) {
@@ -211,7 +218,9 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
211218
}
212219

213220
char* ICACHE_FLASH_ATTR strtok(char * str, const char * delimiters) {
214-
return strtok_r(str, delimiters, NULL);
221+
static char * ret = NULL;
222+
ret = strtok_r(str, delimiters, &ret);
223+
return ret;
215224
}
216225

217226
int strcasecmp(const char * str1, const char * str2) {

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

+202-4
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);
@@ -198,13 +216,19 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
198216
SPI1CLK = clockDiv;
199217
}
200218

219+
inline void SPIClass::setDataBits(uint16_t bits) {
220+
const uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
221+
bits--;
222+
SPI1U1 = ((SPI1U1 & mask) | ((bits << SPILMOSI) | (bits << SPILMISO)));
223+
}
224+
201225
uint8_t SPIClass::transfer(uint8_t data) {
202-
while(SPI1CMD & SPIBUSY)
203-
;
226+
while(SPI1CMD & SPIBUSY) {}
227+
// reset to 8Bit mode
228+
setDataBits(8);
204229
SPI1W0 = data;
205230
SPI1CMD |= SPIBUSY;
206-
while(SPI1CMD & SPIBUSY)
207-
;
231+
while(SPI1CMD & SPIBUSY) {}
208232
return (uint8_t) (SPI1W0 & 0xff);
209233
}
210234

@@ -230,3 +254,177 @@ uint16_t SPIClass::transfer16(uint16_t data) {
230254
return out.val;
231255
}
232256

257+
void SPIClass::write(uint8_t data) {
258+
while(SPI1CMD & SPIBUSY) {}
259+
// reset to 8Bit mode
260+
setDataBits(8);
261+
SPI1W0 = data;
262+
SPI1CMD |= SPIBUSY;
263+
while(SPI1CMD & SPIBUSY) {}
264+
}
265+
266+
void SPIClass::write16(uint16_t data) {
267+
write16(data, !(SPI1C & (SPICWBO | SPICRBO)));
268+
}
269+
270+
void SPIClass::write16(uint16_t data, bool msb) {
271+
while(SPI1CMD & SPIBUSY) {}
272+
// Set to 16Bits transfer
273+
setDataBits(16);
274+
if(msb) {
275+
// MSBFIRST Byte first
276+
SPI1W0 = (data >> 8) | (data << 8);
277+
SPI1CMD |= SPIBUSY;
278+
} else {
279+
// LSBFIRST Byte first
280+
SPI1W0 = data;
281+
SPI1CMD |= SPIBUSY;
282+
}
283+
while(SPI1CMD & SPIBUSY) {}
284+
}
285+
286+
void SPIClass::write32(uint32_t data) {
287+
write32(data, !(SPI1C & (SPICWBO | SPICRBO)));
288+
}
289+
290+
void SPIClass::write32(uint32_t data, bool msb) {
291+
while(SPI1CMD & SPIBUSY) {}
292+
// Set to 32Bits transfer
293+
setDataBits(32);
294+
if(msb) {
295+
union {
296+
uint32_t l;
297+
uint8_t b[4];
298+
} data_;
299+
data_.l = data;
300+
// MSBFIRST Byte first
301+
SPI1W0 = (data_.b[3] | (data_.b[2] << 8) | (data_.b[1] << 16) | (data_.b[0] << 24));
302+
SPI1CMD |= SPIBUSY;
303+
} else {
304+
// LSBFIRST Byte first
305+
SPI1W0 = data;
306+
SPI1CMD |= SPIBUSY;
307+
}
308+
while(SPI1CMD & SPIBUSY) {}
309+
}
310+
311+
void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
312+
while(size) {
313+
if(size > 64) {
314+
writeBytes_(data, 64);
315+
size -= 64;
316+
data += 64;
317+
} else {
318+
writeBytes_(data, size);
319+
size = 0;
320+
}
321+
}
322+
}
323+
324+
void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
325+
while(SPI1CMD & SPIBUSY) {}
326+
// Set Bits to transfer
327+
setDataBits(size * 8);
328+
329+
volatile uint32_t * fifoPtr = &SPI1W0;
330+
uint32_t * dataPtr = (uint32_t*) data;
331+
uint8_t dataSize = ((size + 3) / 4);
332+
333+
while(dataSize--) {
334+
*fifoPtr = *dataPtr;
335+
dataPtr++;
336+
fifoPtr++;
337+
}
338+
339+
SPI1CMD |= SPIBUSY;
340+
while(SPI1CMD & SPIBUSY) {}
341+
}
342+
343+
void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
344+
if(size > 64) return; //max Hardware FIFO
345+
346+
uint32_t byte = (size * repeat);
347+
uint8_t r = (64 / size);
348+
349+
while(byte) {
350+
if(byte > 64) {
351+
writePattern_(data, size, r);
352+
byte -= 64;
353+
} else {
354+
writePattern_(data, size, (byte / size));
355+
byte = 0;
356+
}
357+
}
358+
}
359+
360+
void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
361+
uint8_t bytes = (size * repeat);
362+
uint8_t buffer[64];
363+
uint8_t * bufferPtr = &buffer[0];
364+
uint8_t * dataPtr;
365+
uint8_t dataSize = bytes;
366+
for(uint8_t i = 0; i < repeat; i++) {
367+
dataSize = size;
368+
dataPtr = data;
369+
while(dataSize--) {
370+
*bufferPtr = *dataPtr;
371+
dataPtr++;
372+
bufferPtr++;
373+
}
374+
}
375+
376+
writeBytes(&buffer[0], bytes);
377+
}
378+
379+
void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size) {
380+
while(size) {
381+
if(size > 64) {
382+
transferBytes_(out, in, 64);
383+
size -= 64;
384+
if(out) out += 64;
385+
if(in) in += 64;
386+
} else {
387+
transferBytes_(out, in, size);
388+
size = 0;
389+
}
390+
}
391+
}
392+
393+
void SPIClass::transferBytes_(uint8_t * out, uint8_t * in, uint8_t size) {
394+
while(SPI1CMD & SPIBUSY) {}
395+
// Set in/out Bits to transfer
396+
397+
setDataBits(size * 8);
398+
399+
volatile uint32_t * fifoPtr = &SPI1W0;
400+
uint8_t dataSize = ((size + 3) / 4);
401+
402+
if(out) {
403+
uint32_t * dataPtr = (uint32_t*) out;
404+
while(dataSize--) {
405+
*fifoPtr = *dataPtr;
406+
dataPtr++;
407+
fifoPtr++;
408+
}
409+
} else {
410+
// no out data only read fill with dummy data!
411+
while(dataSize--) {
412+
*fifoPtr = 0xFFFFFFFF;
413+
fifoPtr++;
414+
}
415+
}
416+
417+
SPI1CMD |= SPIBUSY;
418+
while(SPI1CMD & SPIBUSY) {}
419+
420+
if(in) {
421+
volatile uint8_t * fifoPtr8 = (volatile uint8_t *) &SPI1W0;
422+
dataSize = size;
423+
while(dataSize--) {
424+
*in = *fifoPtr8;
425+
in++;
426+
fifoPtr8++;
427+
}
428+
}
429+
}
430+

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

+15
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,29 @@ 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 write32(uint32_t data);
79+
void write32(uint32_t data, bool msb);
80+
void writeBytes(uint8_t * data, uint32_t size);
81+
void writePattern(uint8_t * data, uint8_t size, uint32_t repeat);
82+
void transferBytes(uint8_t * out, uint8_t * in, uint32_t size);
7483
void endTransaction(void);
84+
private:
85+
bool useHwCs;
86+
void writeBytes_(uint8_t * data, uint8_t size);
87+
void writePattern_(uint8_t * data, uint8_t size, uint8_t repeat);
88+
void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
89+
inline void setDataBits(uint16_t bits);
7590
};
7691

7792
extern SPIClass SPI;

hardware/esp8266com/esp8266/platform.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ compiler.S.flags=-c -g -x assembler-with-cpp -MMD
2323
compiler.c.elf.ldscript=eagle.app.v6.ld
2424
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}"
2525
compiler.c.elf.cmd=xtensa-lx106-elf-gcc
26-
compiler.c.elf.libs=-lm -lc -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig
26+
compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig
2727

2828
compiler.cpp.cmd=xtensa-lx106-elf-g++
2929
compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD

0 commit comments

Comments
 (0)