Skip to content

Commit de017a8

Browse files
committed
Optimize SPI transfers to take one lock and do not return until completed
1 parent 672631d commit de017a8

File tree

3 files changed

+41
-29
lines changed

3 files changed

+41
-29
lines changed

Diff for: cores/esp32/esp32-hal-spi.c

+34-19
Original file line numberDiff line numberDiff line change
@@ -454,17 +454,17 @@ void spiWrite(spi_t * spi, uint32_t *data, uint8_t len)
454454
len = 16;
455455
}
456456
SPI_MUTEX_LOCK();
457-
while(spi->dev->cmd.usr);
458457
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
459-
spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1;
458+
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
460459
for(i=0; i<len; i++) {
461460
spi->dev->data_buf[i] = data[i];
462461
}
463462
spi->dev->cmd.usr = 1;
463+
while(spi->dev->cmd.usr);
464464
SPI_MUTEX_UNLOCK();
465465
}
466466

467-
void spiRead(spi_t * spi, uint32_t *data, uint8_t len)
467+
void spiTransfer(spi_t * spi, uint32_t *data, uint8_t len)
468468
{
469469
if(!spi) {
470470
return;
@@ -474,6 +474,12 @@ void spiRead(spi_t * spi, uint32_t *data, uint8_t len)
474474
len = 16;
475475
}
476476
SPI_MUTEX_LOCK();
477+
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
478+
spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1;
479+
for(i=0; i<len; i++) {
480+
spi->dev->data_buf[i] = data[i];
481+
}
482+
spi->dev->cmd.usr = 1;
477483
while(spi->dev->cmd.usr);
478484
for(i=0; i<len; i++) {
479485
data[i] = spi->dev->data_buf[i];
@@ -487,21 +493,24 @@ void spiWriteByte(spi_t * spi, uint8_t data)
487493
return;
488494
}
489495
SPI_MUTEX_LOCK();
490-
while(spi->dev->cmd.usr);
491496
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
492-
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
497+
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
493498
spi->dev->data_buf[0] = data;
494499
spi->dev->cmd.usr = 1;
500+
while(spi->dev->cmd.usr);
495501
SPI_MUTEX_UNLOCK();
496502
}
497503

498-
uint8_t spiReadByte(spi_t * spi)
504+
uint8_t spiTransferByte(spi_t * spi, uint8_t data)
499505
{
500506
if(!spi) {
501507
return 0;
502508
}
503-
uint8_t data;
504509
SPI_MUTEX_LOCK();
510+
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
511+
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
512+
spi->dev->data_buf[0] = data;
513+
spi->dev->cmd.usr = 1;
505514
while(spi->dev->cmd.usr);
506515
data = spi->dev->data_buf[0] & 0xFF;
507516
SPI_MUTEX_UNLOCK();
@@ -551,21 +560,24 @@ void spiWriteWord(spi_t * spi, uint16_t data)
551560
return;
552561
}
553562
SPI_MUTEX_LOCK();
554-
while(spi->dev->cmd.usr);
555563
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
556-
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
564+
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
557565
spi->dev->data_buf[0] = __spiTranslate16(data, !spi->dev->ctrl.wr_bit_order);
558566
spi->dev->cmd.usr = 1;
567+
while(spi->dev->cmd.usr);
559568
SPI_MUTEX_UNLOCK();
560569
}
561570

562-
uint16_t spiReadWord(spi_t * spi)
571+
uint16_t spiTransferWord(spi_t * spi, uint16_t data)
563572
{
564573
if(!spi) {
565574
return 0;
566575
}
567-
uint16_t data;
568576
SPI_MUTEX_LOCK();
577+
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
578+
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
579+
spi->dev->data_buf[0] = __spiTranslate16(data, !spi->dev->ctrl.wr_bit_order);
580+
spi->dev->cmd.usr = 1;
569581
while(spi->dev->cmd.usr);
570582
data = __spiTranslate16(spi->dev->data_buf[0] & 0xFFFF, !spi->dev->ctrl.rd_bit_order);
571583
SPI_MUTEX_UNLOCK();
@@ -578,21 +590,24 @@ void spiWriteLong(spi_t * spi, uint32_t data)
578590
return;
579591
}
580592
SPI_MUTEX_LOCK();
581-
while(spi->dev->cmd.usr);
582593
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
583-
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
594+
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
584595
spi->dev->data_buf[0] = __spiTranslate32(data, !spi->dev->ctrl.wr_bit_order);
585596
spi->dev->cmd.usr = 1;
597+
while(spi->dev->cmd.usr);
586598
SPI_MUTEX_UNLOCK();
587599
}
588600

589-
uint32_t spiReadLong(spi_t * spi)
601+
uint32_t spiTransferLong(spi_t * spi, uint32_t data)
590602
{
591603
if(!spi) {
592604
return 0;
593605
}
594-
uint32_t data;
595606
SPI_MUTEX_LOCK();
607+
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
608+
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
609+
spi->dev->data_buf[0] = __spiTranslate32(data, !spi->dev->ctrl.wr_bit_order);
610+
spi->dev->cmd.usr = 1;
596611
while(spi->dev->cmd.usr);
597612
data = __spiTranslate32(spi->dev->data_buf[0], !spi->dev->ctrl.rd_bit_order);
598613
SPI_MUTEX_UNLOCK();
@@ -612,7 +627,6 @@ void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
612627
uint32_t mask = (((uint64_t)1 << bits) - 1) & 0xFFFFFFFF;
613628

614629
SPI_MUTEX_LOCK();
615-
while(spi->dev->cmd.usr);
616630
spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
617631
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
618632
if(bytes == 1) {
@@ -626,8 +640,9 @@ void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
626640
}
627641
spi->dev->cmd.usr = 1;
628642

643+
while(spi->dev->cmd.usr);
644+
629645
if(out) {
630-
while(spi->dev->cmd.usr);
631646
if(bytes == 1) {
632647
*out = spi->dev->data_buf[0] & mask;
633648
} else if(bytes == 2) {
@@ -663,7 +678,6 @@ void __spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t byt
663678
memset(bytesBuf, 0xFF, bytes);
664679
}
665680

666-
while(spi->dev->cmd.usr);
667681
spi->dev->mosi_dlen.usr_mosi_dbitlen = ((bytes * 8) - 1);
668682
spi->dev->miso_dlen.usr_miso_dbitlen = ((bytes * 8) - 1);
669683

@@ -673,8 +687,9 @@ void __spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t byt
673687

674688
spi->dev->cmd.usr = 1;
675689

690+
while(spi->dev->cmd.usr);
691+
676692
if(out) {
677-
while(spi->dev->cmd.usr);
678693
for(i=0; i<words; i++) {
679694
wordsBuf[i] = spi->dev->data_buf[i];//copy spi fifo to buffer
680695
}

Diff for: cores/esp32/esp32-hal-spi.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ void spiWriteByte(spi_t * spi, uint8_t data);
9898
void spiWriteWord(spi_t * spi, uint16_t data);
9999
void spiWriteLong(spi_t * spi, uint32_t data);
100100

101-
void spiRead(spi_t * spi, uint32_t *out, uint8_t len);
102-
uint8_t spiReadByte(spi_t * spi);
103-
uint16_t spiReadWord(spi_t * spi);
104-
uint32_t spiReadLong(spi_t * spi);
101+
void spiTransfer(spi_t * spi, uint32_t *out, uint8_t len);
102+
uint8_t spiTransferByte(spi_t * spi, uint8_t data);
103+
uint16_t spiTransferWord(spi_t * spi, uint16_t data);
104+
uint32_t spiTransferLong(spi_t * spi, uint32_t data);
105105

106106
void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits);
107107
void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size);

Diff for: libraries/SPI/src/SPI.cpp

+3-6
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,7 @@ void SPIClass::write(uint8_t data)
128128

129129
uint8_t SPIClass::transfer(uint8_t data)
130130
{
131-
spiWriteByte(_spi, data);
132-
return spiReadByte(_spi);
131+
return spiTransferByte(_spi, data);
133132
}
134133

135134
void SPIClass::write16(uint16_t data)
@@ -139,8 +138,7 @@ void SPIClass::write16(uint16_t data)
139138

140139
uint16_t SPIClass::transfer16(uint16_t data)
141140
{
142-
spiWriteWord(_spi, data);
143-
return spiReadWord(_spi);
141+
return spiTransferWord(_spi, data);
144142
}
145143

146144
void SPIClass::write32(uint32_t data)
@@ -150,8 +148,7 @@ void SPIClass::write32(uint32_t data)
150148

151149
uint32_t SPIClass::transfer32(uint32_t data)
152150
{
153-
spiWriteLong(_spi, data);
154-
return spiReadLong(_spi);
151+
return spiTransferLong(_spi, data);
155152
}
156153

157154
void SPIClass::transferBits(uint32_t data, uint32_t * out, uint8_t bits)

0 commit comments

Comments
 (0)