Very minor SPI speedup
This commit is contained in:
parent
422dd6666e
commit
758c6c9464
3 changed files with 47 additions and 60 deletions
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description: HAL for AVR - SPI functions
|
* Description: HAL for AVR - SPI functions
|
||||||
*
|
|
||||||
* For __AVR__
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
|
@ -68,10 +66,12 @@ void spiBegin (void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#if DISABLED(SOFTWARE_SPI)
|
#if DISABLED(SOFTWARE_SPI)
|
||||||
// functions for hardware SPI
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
// Hardware SPI
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// make sure SPCR rate is in expected bits
|
// make sure SPCR rate is in expected bits
|
||||||
#if (SPR0 != 0 || SPR1 != 1)
|
#if (SPR0 != 0 || SPR1 != 1)
|
||||||
#error "unexpected SPCR bits"
|
#error "unexpected SPCR bits"
|
||||||
|
@ -95,14 +95,13 @@ void spiBegin (void) {
|
||||||
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
|
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** SPI receive a byte */
|
/** SPI receive a byte */
|
||||||
uint8_t spiRec(void) {
|
uint8_t spiRec(void) {
|
||||||
SPDR = 0xFF;
|
SPDR = 0xFF;
|
||||||
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
||||||
return SPDR;
|
return SPDR;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** SPI read data */
|
/** SPI read data */
|
||||||
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
if (nbyte-- == 0) return;
|
if (nbyte-- == 0) return;
|
||||||
|
@ -115,13 +114,13 @@ void spiBegin (void) {
|
||||||
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
||||||
buf[nbyte] = SPDR;
|
buf[nbyte] = SPDR;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** SPI send a byte */
|
/** SPI send a byte */
|
||||||
void spiSend(uint8_t b) {
|
void spiSend(uint8_t b) {
|
||||||
SPDR = b;
|
SPDR = b;
|
||||||
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** SPI send block */
|
/** SPI send block */
|
||||||
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
SPDR = token;
|
SPDR = token;
|
||||||
|
@ -191,25 +190,21 @@ void spiBegin (void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
#else
|
||||||
#else // SOFTWARE_SPI
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** nop to tune soft SPI timing */
|
/** nop to tune soft SPI timing */
|
||||||
#define nop asm volatile ("\tnop\n")
|
#define nop asm volatile ("\tnop\n")
|
||||||
|
|
||||||
/** Set SPI rate */
|
/** Set SPI rate */
|
||||||
void spiInit(uint8_t spiRate) {
|
void spiInit(uint8_t spiRate) {
|
||||||
// nothing to do
|
UNUSED(spiRate); // nothing to do
|
||||||
UNUSED(spiRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Begin SPI transaction, set clock, bit order, data mode */
|
/** Begin SPI transaction, set clock, bit order, data mode */
|
||||||
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
|
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
|
||||||
// nothing to do
|
UNUSED(spiBeginTransaction); // nothing to do
|
||||||
UNUSED(spiBeginTransaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** Soft SPI receive byte */
|
/** Soft SPI receive byte */
|
||||||
uint8_t spiRec() {
|
uint8_t spiRec() {
|
||||||
uint8_t data = 0;
|
uint8_t data = 0;
|
||||||
|
@ -221,8 +216,7 @@ void spiBegin (void) {
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
WRITE(SCK_PIN, HIGH);
|
WRITE(SCK_PIN, HIGH);
|
||||||
|
|
||||||
// adjust so SCK is nice
|
nop; // adjust so SCK is nice
|
||||||
nop;
|
|
||||||
nop;
|
nop;
|
||||||
|
|
||||||
data <<= 1;
|
data <<= 1;
|
||||||
|
@ -231,48 +225,45 @@ void spiBegin (void) {
|
||||||
|
|
||||||
WRITE(SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
}
|
}
|
||||||
// enable interrupts
|
|
||||||
sei();
|
sei();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** Soft SPI read data */
|
/** Soft SPI read data */
|
||||||
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
for (uint16_t i = 0; i < nbyte; i++)
|
for (uint16_t i = 0; i < nbyte; i++)
|
||||||
buf[i] = spiRec();
|
buf[i] = spiRec();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** Soft SPI send byte */
|
/** Soft SPI send byte */
|
||||||
void spiSend(uint8_t data) {
|
void spiSend(uint8_t data) {
|
||||||
// no interrupts during byte send - about 8µs
|
// no interrupts during byte send - about 8µs
|
||||||
cli();
|
cli();
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
WRITE(SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
|
|
||||||
WRITE(MOSI_PIN, data & 0x80);
|
WRITE(MOSI_PIN, data & 0x80);
|
||||||
|
|
||||||
data <<= 1;
|
data <<= 1;
|
||||||
|
|
||||||
WRITE(SCK_PIN, HIGH);
|
WRITE(SCK_PIN, HIGH);
|
||||||
}
|
}
|
||||||
// hold SCK high for a few ns
|
|
||||||
nop;
|
nop; // hold SCK high for a few ns
|
||||||
nop;
|
nop;
|
||||||
nop;
|
nop;
|
||||||
nop;
|
nop;
|
||||||
|
|
||||||
WRITE(SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
// enable interrupts
|
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** Soft SPI send block */
|
/** Soft SPI send block */
|
||||||
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
spiSend(token);
|
spiSend(token);
|
||||||
for (uint16_t i = 0; i < 512; i++)
|
for (uint16_t i = 0; i < 512; i++)
|
||||||
spiSend(buf[i]);
|
spiSend(buf[i]);
|
||||||
}
|
}
|
||||||
#endif // SOFTWARE_SPI
|
|
||||||
|
|
||||||
|
#endif // SOFTWARE_SPI
|
||||||
|
|
||||||
#endif // __AVR__
|
#endif // __AVR__
|
||||||
|
|
|
@ -656,8 +656,8 @@
|
||||||
|
|
||||||
// Read from SPI into buffer
|
// Read from SPI into buffer
|
||||||
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
if (nbyte-- == 0) return;
|
if (!nbyte) return;
|
||||||
|
--nbyte;
|
||||||
for (int i = 0; i < nbyte; i++) {
|
for (int i = 0; i < nbyte; i++) {
|
||||||
//WHILE_TX(0);
|
//WHILE_TX(0);
|
||||||
SPI0->SPI_TDR = 0x000000FF | SPI_PCS(SPI_CHAN);
|
SPI0->SPI_TDR = 0x000000FF | SPI_PCS(SPI_CHAN);
|
||||||
|
@ -669,7 +669,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write single byte to SPI
|
// Write single byte to SPI
|
||||||
void spiSend(byte b) {
|
void spiSend(const byte b) {
|
||||||
// write byte with address and end transmission flag
|
// write byte with address and end transmission flag
|
||||||
SPI0->SPI_TDR = (uint32_t)b | SPI_PCS(SPI_CHAN) | SPI_TDR_LASTXFER;
|
SPI0->SPI_TDR = (uint32_t)b | SPI_PCS(SPI_CHAN) | SPI_TDR_LASTXFER;
|
||||||
WHILE_TX(0);
|
WHILE_TX(0);
|
||||||
|
@ -678,16 +678,17 @@
|
||||||
//DELAY_US(1U);
|
//DELAY_US(1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(const uint8_t* buf, size_t n) {
|
void spiSend(const uint8_t* buf, size_t nbyte) {
|
||||||
if (n == 0) return;
|
if (!nbyte) return;
|
||||||
for (size_t i = 0; i < n - 1; i++) {
|
--nbyte;
|
||||||
|
for (size_t i = 0; i < nbyte; i++) {
|
||||||
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(SPI_CHAN);
|
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(SPI_CHAN);
|
||||||
WHILE_TX(0);
|
WHILE_TX(0);
|
||||||
WHILE_RX(0);
|
WHILE_RX(0);
|
||||||
SPI0->SPI_RDR;
|
SPI0->SPI_RDR;
|
||||||
//DELAY_US(1U);
|
//DELAY_US(1U);
|
||||||
}
|
}
|
||||||
spiSend(buf[n - 1]);
|
spiSend(buf[nbyte]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint32_t chan, byte b) {
|
void spiSend(uint32_t chan, byte b) {
|
||||||
|
@ -698,15 +699,16 @@
|
||||||
FLUSH_RX();
|
FLUSH_RX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
|
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
|
||||||
if (n == 0) return;
|
if (!nbyte) return;
|
||||||
for (int i = 0; i < (int)n - 1; i++) {
|
--nbyte;
|
||||||
|
for (size_t i = 0; i < nbyte; i++) {
|
||||||
WHILE_TX(0);
|
WHILE_TX(0);
|
||||||
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(chan);
|
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(chan);
|
||||||
WHILE_RX(0);
|
WHILE_RX(0);
|
||||||
FLUSH_RX();
|
FLUSH_RX();
|
||||||
}
|
}
|
||||||
spiSend(chan, buf[n - 1]);
|
spiSend(chan, buf[nbyte]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write from buffer to SPI
|
// Write from buffer to SPI
|
||||||
|
@ -775,17 +777,15 @@
|
||||||
uint8_t spiRec() { return (uint8_t)spiTransfer(0xFF); }
|
uint8_t spiRec() { return (uint8_t)spiTransfer(0xFF); }
|
||||||
|
|
||||||
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
if (nbyte)
|
for (int i = 0; i < nbyte; i++)
|
||||||
for (int i = 0; i < nbyte; i++)
|
buf[i] = spiTransfer(0xFF);
|
||||||
buf[i] = spiTransfer(0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint8_t data) { spiTransfer(data); }
|
void spiSend(uint8_t data) { spiTransfer(data); }
|
||||||
|
|
||||||
void spiSend(const uint8_t* buf, size_t nbyte) {
|
void spiSend(const uint8_t* buf, size_t nbyte) {
|
||||||
if (nbyte)
|
for (uint16_t i = 0; i < nbyte; i++)
|
||||||
for (uint16_t i = 0; i < nbyte; i++)
|
spiTransfer(buf[i]);
|
||||||
spiTransfer(buf[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
|
|
|
@ -81,17 +81,15 @@
|
||||||
uint8_t spiRec() { return spiTransfer(0xFF); }
|
uint8_t spiRec() { return spiTransfer(0xFF); }
|
||||||
|
|
||||||
void spiRead(uint8_t*buf, uint16_t nbyte) {
|
void spiRead(uint8_t*buf, uint16_t nbyte) {
|
||||||
if (nbyte)
|
for (int i = 0; i < nbyte; i++)
|
||||||
for (int i = 0; i < nbyte; i++)
|
buf[i] = spiTransfer(0xFF);
|
||||||
buf[i] = spiTransfer(0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint8_t b) { (void)spiTransfer(b); }
|
void spiSend(uint8_t b) { (void)spiTransfer(b); }
|
||||||
|
|
||||||
void spiSend(const uint8_t* buf, size_t n) {
|
void spiSend(const uint8_t* buf, size_t nbyte) {
|
||||||
if (n)
|
for (uint16_t i = 0; i < nbyte; i++)
|
||||||
for (uint16_t i = 0; i < n; i++)
|
(void)spiTransfer(buf[i]);
|
||||||
(void)spiTransfer(buf[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
|
@ -178,15 +176,14 @@
|
||||||
|
|
||||||
void spiSend(uint8_t b) { doio(b); }
|
void spiSend(uint8_t b) { doio(b); }
|
||||||
|
|
||||||
void spiSend(const uint8_t* buf, size_t n) {
|
void spiSend(const uint8_t* buf, size_t nbyte) {
|
||||||
if (n)
|
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
|
||||||
for (uint16_t i = 0; i < n; i++) doio(buf[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint32_t chan, byte b) {
|
void spiSend(uint32_t chan, byte b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
|
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read single byte from SPI
|
// Read single byte from SPI
|
||||||
|
@ -195,9 +192,8 @@
|
||||||
uint8_t spiRec(uint32_t chan) { return 0; }
|
uint8_t spiRec(uint32_t chan) { return 0; }
|
||||||
|
|
||||||
// Read from SPI into buffer
|
// Read from SPI into buffer
|
||||||
void spiRead(uint8_t*buf, uint16_t nbyte) {
|
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
||||||
if (nbyte)
|
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
|
||||||
for (int i = 0; i < nbyte; i++) buf[i] = doio(0xff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t spiTransfer(uint8_t b) {
|
static uint8_t spiTransfer(uint8_t b) {
|
||||||
|
|
Reference in a new issue