Very minor SPI speedup

This commit is contained in:
Scott Lahteine 2019-02-20 04:00:49 -06:00
parent 422dd6666e
commit 758c6c9464
3 changed files with 47 additions and 60 deletions

View file

@ -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__

View file

@ -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,7 +777,6 @@
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);
} }
@ -783,7 +784,6 @@
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]);
} }

View file

@ -81,16 +81,14 @@
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]);
} }
@ -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
@ -196,8 +193,7 @@
// 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) {