Skip to content

Commit 934434d

Browse files
committed
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 SPI add functions: - void write32(uint32_t data); - void write32(uint32_t data, bool msb); - void transferBytes(uint8_t * out, uint8_t * in, uint32_t size); Adafruit_ILI9341: - code clean
1 parent 25c79fb commit 934434d

File tree

7 files changed

+248
-182
lines changed

7 files changed

+248
-182
lines changed

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

+91-7
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,16 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
216216
SPI1CLK = clockDiv;
217217
}
218218

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+
219225
uint8_t SPIClass::transfer(uint8_t data) {
220226
while(SPI1CMD & SPIBUSY) {}
227+
// reset to 8Bit mode
228+
setDataBits(8);
221229
SPI1W0 = data;
222230
SPI1CMD |= SPIBUSY;
223231
while(SPI1CMD & SPIBUSY) {}
@@ -248,19 +256,21 @@ uint16_t SPIClass::transfer16(uint16_t data) {
248256

249257
void SPIClass::write(uint8_t data) {
250258
while(SPI1CMD & SPIBUSY) {}
259+
// reset to 8Bit mode
260+
setDataBits(8);
251261
SPI1W0 = data;
252262
SPI1CMD |= SPIBUSY;
253263
while(SPI1CMD & SPIBUSY) {}
254264
}
255265

256266
void SPIClass::write16(uint16_t data) {
257-
write16(data, (SPI1C & (SPICWBO | SPICRBO)));
267+
write16(data, !(SPI1C & (SPICWBO | SPICRBO)));
258268
}
259269

260270
void SPIClass::write16(uint16_t data, bool msb) {
261271
while(SPI1CMD & SPIBUSY) {}
262272
// Set to 16Bits transfer
263-
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((16 - 1) << SPILMOSI);
273+
setDataBits(16);
264274
if(msb) {
265275
// MSBFIRST Byte first
266276
SPI1W0 = (data >> 8) | (data << 8);
@@ -271,8 +281,31 @@ void SPIClass::write16(uint16_t data, bool msb) {
271281
SPI1CMD |= SPIBUSY;
272282
}
273283
while(SPI1CMD & SPIBUSY) {}
274-
// reset to 8Bit mode
275-
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1) << SPILMOSI);
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) {}
276309
}
277310

278311
void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
@@ -291,7 +324,7 @@ void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
291324
void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
292325
while(SPI1CMD & SPIBUSY) {}
293326
// Set Bits to transfer
294-
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((size * 8 - 1) << SPILMOSI);
327+
setDataBits(size * 8);
295328

296329
volatile uint32_t * fifoPtr = &SPI1W0;
297330
uint32_t * dataPtr = (uint32_t*) data;
@@ -305,8 +338,6 @@ void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
305338

306339
SPI1CMD |= SPIBUSY;
307340
while(SPI1CMD & SPIBUSY) {}
308-
// reset to 8Bit mode
309-
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1) << SPILMOSI);
310341
}
311342

312343
void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
@@ -344,3 +375,56 @@ void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
344375

345376
writeBytes(&buffer[0], bytes);
346377
}
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

+5
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,18 @@ class SPIClass {
7575
void write(uint8_t data);
7676
void write16(uint16_t data);
7777
void write16(uint16_t data, bool msb);
78+
void write32(uint32_t data);
79+
void write32(uint32_t data, bool msb);
7880
void writeBytes(uint8_t * data, uint32_t size);
7981
void writePattern(uint8_t * data, uint8_t size, uint32_t repeat);
82+
void transferBytes(uint8_t * out, uint8_t * in, uint32_t size);
8083
void endTransaction(void);
8184
private:
8285
bool useHwCs;
8386
void writeBytes_(uint8_t * data, uint8_t size);
8487
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);
8590
};
8691

8792
extern SPIClass SPI;

0 commit comments

Comments
 (0)