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
 | 
						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
 | 
					// 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.
 | 
					// 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.
 | 
					// 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.
 | 
					// Write a single byte and read a single byte from TX/RX FIFO.
 | 
				
			||||||
func (spi SPI) Transfer(w byte) (byte, error) {
 | 
					func (spi SPI) Transfer(w byte) (byte, error) {
 | 
				
			||||||
	var deadline = ticks() + _SPITimeout
 | 
					 | 
				
			||||||
	for !spi.isWritable() {
 | 
						for !spi.isWritable() {
 | 
				
			||||||
		if ticks() > deadline {
 | 
					 | 
				
			||||||
			return 0, ErrSPITimeout
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spi.Bus.SSPDR.Set(uint32(w))
 | 
						spi.Bus.SSPDR.Set(uint32(w))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for !spi.isReadable() {
 | 
						for !spi.isReadable() {
 | 
				
			||||||
		if ticks() > deadline {
 | 
					 | 
				
			||||||
			return 0, ErrSPITimeout
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return uint8(spi.Bus.SSPDR.Get()), nil
 | 
						return uint8(spi.Bus.SSPDR.Get()), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -298,15 +288,11 @@ func (spi SPI) isBusy() bool {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// tx writes buffer to SPI ignoring Rx.
 | 
					// tx writes buffer to SPI ignoring Rx.
 | 
				
			||||||
func (spi SPI) tx(tx []byte) error {
 | 
					func (spi SPI) tx(tx []byte) error {
 | 
				
			||||||
	var deadline = ticks() + _SPITimeout
 | 
					 | 
				
			||||||
	// Write to TX FIFO whilst ignoring RX, then clean up afterward. When RX
 | 
						// 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
 | 
						// 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.
 | 
						// push-on-full, but continues shifting. Safe if SSPIMSC_RORIM is not set.
 | 
				
			||||||
	for i := range tx {
 | 
						for i := range tx {
 | 
				
			||||||
		for !spi.isWritable() {
 | 
							for !spi.isWritable() {
 | 
				
			||||||
			if ticks() > deadline {
 | 
					 | 
				
			||||||
				return ErrSPITimeout
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		spi.Bus.SSPDR.Set(uint32(tx[i]))
 | 
							spi.Bus.SSPDR.Set(uint32(tx[i]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -316,9 +302,6 @@ func (spi SPI) tx(tx []byte) error {
 | 
				
			||||||
		spi.Bus.SSPDR.Get()
 | 
							spi.Bus.SSPDR.Get()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for spi.isBusy() {
 | 
						for spi.isBusy() {
 | 
				
			||||||
		if ticks() > deadline {
 | 
					 | 
				
			||||||
			return ErrSPITimeout
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for spi.isReadable() {
 | 
						for spi.isReadable() {
 | 
				
			||||||
		spi.Bus.SSPDR.Get()
 | 
							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,
 | 
					// Generally this can be 0, but some devices require a specific value here,
 | 
				
			||||||
// e.g. SD cards expect 0xff
 | 
					// e.g. SD cards expect 0xff
 | 
				
			||||||
func (spi SPI) rx(rx []byte, txrepeat byte) error {
 | 
					func (spi SPI) rx(rx []byte, txrepeat byte) error {
 | 
				
			||||||
	var deadline = ticks() + _SPITimeout
 | 
					 | 
				
			||||||
	plen := len(rx)
 | 
						plen := len(rx)
 | 
				
			||||||
	const fifoDepth = 8 // see txrx
 | 
						const fifoDepth = 8 // see txrx
 | 
				
			||||||
	var rxleft, txleft = plen, plen
 | 
						var rxleft, txleft = plen, plen
 | 
				
			||||||
| 
						 | 
					@ -345,10 +327,7 @@ func (spi SPI) rx(rx []byte, txrepeat byte) error {
 | 
				
			||||||
		if rxleft != 0 && spi.isReadable() {
 | 
							if rxleft != 0 && spi.isReadable() {
 | 
				
			||||||
			rx[plen-rxleft] = uint8(spi.Bus.SSPDR.Get())
 | 
								rx[plen-rxleft] = uint8(spi.Bus.SSPDR.Get())
 | 
				
			||||||
			rxleft--
 | 
								rxleft--
 | 
				
			||||||
			continue // if reading succesfully in rx there is no need to check deadline.
 | 
								continue
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if ticks() > deadline {
 | 
					 | 
				
			||||||
			return ErrSPITimeout
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						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.
 | 
					// 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)
 | 
					// 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 {
 | 
					func (spi SPI) txrx(tx, rx []byte) error {
 | 
				
			||||||
	var deadline = ticks() + _SPITimeout
 | 
					 | 
				
			||||||
	plen := len(tx)
 | 
						plen := len(tx)
 | 
				
			||||||
	if plen != len(rx) {
 | 
						if plen != len(rx) {
 | 
				
			||||||
		return ErrTxInvalidSliceSize
 | 
							return ErrTxInvalidSliceSize
 | 
				
			||||||
| 
						 | 
					@ -366,7 +344,7 @@ func (spi SPI) txrx(tx, rx []byte) error {
 | 
				
			||||||
	// else FIFO will overflow if this code is heavily interrupted.
 | 
						// else FIFO will overflow if this code is heavily interrupted.
 | 
				
			||||||
	const fifoDepth = 8
 | 
						const fifoDepth = 8
 | 
				
			||||||
	var rxleft, txleft = plen, plen
 | 
						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 {
 | 
							if txleft != 0 && spi.isWritable() && rxleft < txleft+fifoDepth {
 | 
				
			||||||
			spi.Bus.SSPDR.Set(uint32(tx[plen-txleft]))
 | 
								spi.Bus.SSPDR.Set(uint32(tx[plen-txleft]))
 | 
				
			||||||
			txleft--
 | 
								txleft--
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче