Browse Source

rp2040: remove SPI deadline

Removing it improves SPI performance by about 20% for me (updating the
display of a Gopher Badge).
pull/3634/head
Ayke van Laethem 2 years ago
committed by Ron Evans
parent
commit
6eda52a289
  1. 26
      src/machine/machine_rp2040_spi.go

26
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--

Loading…
Cancel
Save