1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-13 13:01:55 +03:00
- 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
This commit is contained in:
Markus Sattler
2015-05-10 17:34:16 +02:00
parent 539aa19305
commit 27f45a205a
5 changed files with 135 additions and 20 deletions

View File

@ -216,8 +216,16 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
SPI1CLK = clockDiv;
}
inline void SPIClass::setDataBits(uint16_t bits) {
const uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
bits--;
SPI1U1 = ((SPI1U1 & mask) | ((bits << SPILMOSI) | (bits << SPILMISO)));
}
uint8_t SPIClass::transfer(uint8_t data) {
while(SPI1CMD & SPIBUSY) {}
// reset to 8Bit mode
setDataBits(8);
SPI1W0 = data;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
@ -248,19 +256,21 @@ uint16_t SPIClass::transfer16(uint16_t data) {
void SPIClass::write(uint8_t data) {
while(SPI1CMD & SPIBUSY) {}
// reset to 8Bit mode
setDataBits(8);
SPI1W0 = data;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
void SPIClass::write16(uint16_t data) {
write16(data, (SPI1C & (SPICWBO | SPICRBO)));
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);
setDataBits(16);
if(msb) {
// MSBFIRST Byte first
SPI1W0 = (data >> 8) | (data << 8);
@ -271,8 +281,31 @@ void SPIClass::write16(uint16_t data, bool msb) {
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
// reset to 8Bit mode
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1) << SPILMOSI);
}
void SPIClass::write32(uint32_t data) {
write32(data, !(SPI1C & (SPICWBO | SPICRBO)));
}
void SPIClass::write32(uint32_t data, bool msb) {
while(SPI1CMD & SPIBUSY) {}
// Set to 32Bits transfer
setDataBits(32);
if(msb) {
union {
uint32_t l;
uint8_t b[4];
} data_;
data_.l = data;
// MSBFIRST Byte first
SPI1W0 = (data_.b[3] | (data_.b[2] << 8) | (data_.b[1] << 16) | (data_.b[0] << 24));
SPI1CMD |= SPIBUSY;
} else {
// LSBFIRST Byte first
SPI1W0 = data;
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
}
void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
@ -291,7 +324,7 @@ void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
while(SPI1CMD & SPIBUSY) {}
// Set Bits to transfer
SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((size * 8 - 1) << SPILMOSI);
setDataBits(size * 8);
volatile uint32_t * fifoPtr = &SPI1W0;
uint32_t * dataPtr = (uint32_t*) data;
@ -305,8 +338,6 @@ void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
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) {
@ -344,3 +375,56 @@ void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
writeBytes(&buffer[0], bytes);
}
void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size) {
while(size) {
if(size > 64) {
transferBytes_(out, in, 64);
size -= 64;
if(out) out += 64;
if(in) in += 64;
} else {
transferBytes_(out, in, size);
size = 0;
}
}
}
void SPIClass::transferBytes_(uint8_t * out, uint8_t * in, uint8_t size) {
while(SPI1CMD & SPIBUSY) {}
// Set in/out Bits to transfer
setDataBits(size * 8);
volatile uint32_t * fifoPtr = &SPI1W0;
uint8_t dataSize = ((size + 3) / 4);
if(out) {
uint32_t * dataPtr = (uint32_t*) out;
while(dataSize--) {
*fifoPtr = *dataPtr;
dataPtr++;
fifoPtr++;
}
} else {
// no out data only read fill with dummy data!
while(dataSize--) {
*fifoPtr = 0xFFFFFFFF;
fifoPtr++;
}
}
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
if(in) {
volatile uint8_t * fifoPtr8 = (volatile uint8_t *) &SPI1W0;
dataSize = size;
while(dataSize--) {
*in = *fifoPtr8;
in++;
fifoPtr8++;
}
}
}