mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-13 13:01:55 +03:00
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
This commit is contained in:
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user