From 6eda52a289839c977c78bb84e32ea7bda9b7ae52 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 31 Mar 2023 23:25:24 +0200 Subject: [PATCH] rp2040: remove SPI deadline Removing it improves SPI performance by about 20% for me (updating the display of a Gopher Badge). --- src/machine/machine_rp2040_spi.go | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/machine/machine_rp2040_spi.go b/src/machine/machine_rp2040_spi.go index d21ad1f8..3c67fdbf 100644 --- a/src/machine/machine_rp2040_spi.go +++ b/src/machine/machine_rp2040_spi.go @@ -47,9 +47,6 @@ type SPI struct { Bus *rp.SPI0_Type } -// time to wait on a transaction before dropping. Unit in Microseconds for compatibility with ticks(). -const _SPITimeout = 10 * 1000 // 10 ms - // Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read // interface, there must always be the same number of bytes written as bytes read. // The Tx method knows about this, and offers a few different ways of calling it. @@ -95,19 +92,12 @@ func (spi SPI) Tx(w, r []byte) (err error) { // Write a single byte and read a single byte from TX/RX FIFO. func (spi SPI) Transfer(w byte) (byte, error) { - var deadline = ticks() + _SPITimeout for !spi.isWritable() { - if ticks() > deadline { - return 0, ErrSPITimeout - } } spi.Bus.SSPDR.Set(uint32(w)) for !spi.isReadable() { - if ticks() > deadline { - return 0, ErrSPITimeout - } } return uint8(spi.Bus.SSPDR.Get()), nil } @@ -298,15 +288,11 @@ func (spi SPI) isBusy() bool { // tx writes buffer to SPI ignoring Rx. func (spi SPI) tx(tx []byte) error { - var deadline = ticks() + _SPITimeout // Write to TX FIFO whilst ignoring RX, then clean up afterward. When RX // is full, PL022 inhibits RX pushes, and sets a sticky flag on // push-on-full, but continues shifting. Safe if SSPIMSC_RORIM is not set. for i := range tx { for !spi.isWritable() { - if ticks() > deadline { - return ErrSPITimeout - } } spi.Bus.SSPDR.Set(uint32(tx[i])) } @@ -316,9 +302,6 @@ func (spi SPI) tx(tx []byte) error { spi.Bus.SSPDR.Get() } for spi.isBusy() { - if ticks() > deadline { - return ErrSPITimeout - } } for spi.isReadable() { spi.Bus.SSPDR.Get() @@ -333,7 +316,6 @@ func (spi SPI) tx(tx []byte) error { // Generally this can be 0, but some devices require a specific value here, // e.g. SD cards expect 0xff func (spi SPI) rx(rx []byte, txrepeat byte) error { - var deadline = ticks() + _SPITimeout plen := len(rx) const fifoDepth = 8 // see txrx var rxleft, txleft = plen, plen @@ -345,10 +327,7 @@ func (spi SPI) rx(rx []byte, txrepeat byte) error { if rxleft != 0 && spi.isReadable() { rx[plen-rxleft] = uint8(spi.Bus.SSPDR.Get()) rxleft-- - continue // if reading succesfully in rx there is no need to check deadline. - } - if ticks() > deadline { - return ErrSPITimeout + continue } } return nil @@ -357,7 +336,6 @@ func (spi SPI) rx(rx []byte, txrepeat byte) error { // Write len bytes from src to SPI. Simultaneously read len bytes from SPI to dst. // Note this function is guaranteed to exit in a known amount of time (bits sent * time per bit) func (spi SPI) txrx(tx, rx []byte) error { - var deadline = ticks() + _SPITimeout plen := len(tx) if plen != len(rx) { return ErrTxInvalidSliceSize @@ -366,7 +344,7 @@ func (spi SPI) txrx(tx, rx []byte) error { // else FIFO will overflow if this code is heavily interrupted. const fifoDepth = 8 var rxleft, txleft = plen, plen - for (txleft != 0 || rxleft != 0) && ticks() <= deadline { + for txleft != 0 || rxleft != 0 { if txleft != 0 && spi.isWritable() && rxleft < txleft+fifoDepth { spi.Bus.SSPDR.Set(uint32(tx[plen-txleft])) txleft--