rp2040: remove SPI deadline
Removing it improves SPI performance by about 20% for me (updating the display of a Gopher Badge).
Этот коммит содержится в:
родитель
8badf79af9
коммит
6eda52a289
1 изменённых файлов: 2 добавлений и 24 удалений
|
@ -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--
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче