nrf: improve SPI write-only speed, by making use of double buffering
The SPI peripheral in the nrf chips support double buffering, which makes it possible to keep sending continuously. This change introduces double buffering on the nrf chips, which should improve SPI performance. Tested on the pca10040 (nrf52832).
Этот коммит содержится в:
родитель
869d2c4524
коммит
d2856bd6bd
2 изменённых файлов: 74 добавлений и 1 удалений
|
@ -5,6 +5,12 @@ package machine
|
|||
import (
|
||||
"device/arm"
|
||||
"device/nrf"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrTxSlicesRequired = errors.New("SPI Tx requires a write or read slice, or both")
|
||||
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
|
||||
)
|
||||
|
||||
type PinMode uint8
|
||||
|
@ -322,3 +328,70 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
|||
// TODO: handle SPI errors
|
||||
return byte(r), nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
||||
// Note that the tx and rx buffers must be the same size:
|
||||
//
|
||||
// spi.Tx(tx, rx)
|
||||
//
|
||||
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
||||
// until all the bytes in the command packet have been received:
|
||||
//
|
||||
// spi.Tx(tx, nil)
|
||||
//
|
||||
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
||||
//
|
||||
// spi.Tx(nil, rx)
|
||||
//
|
||||
func (spi SPI) Tx(w, r []byte) error {
|
||||
if w == nil && r == nil {
|
||||
return ErrTxSlicesRequired
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
switch {
|
||||
case len(w) == 0:
|
||||
// read only, so write zero and read a result.
|
||||
for i := range r {
|
||||
r[i], err = spi.Transfer(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case len(r) == 0:
|
||||
// write only
|
||||
spi.Bus.TXD.Set(uint32(w[0]))
|
||||
w = w[1:]
|
||||
for _, b := range w {
|
||||
spi.Bus.TXD.Set(uint32(b))
|
||||
for spi.Bus.EVENTS_READY.Get() == 0 {
|
||||
}
|
||||
_ = spi.Bus.RXD.Get()
|
||||
spi.Bus.EVENTS_READY.Set(0)
|
||||
}
|
||||
for spi.Bus.EVENTS_READY.Get() == 0 {
|
||||
}
|
||||
_ = spi.Bus.RXD.Get()
|
||||
spi.Bus.EVENTS_READY.Set(0)
|
||||
|
||||
default:
|
||||
// write/read
|
||||
if len(w) != len(r) {
|
||||
return ErrTxInvalidSliceSize
|
||||
}
|
||||
|
||||
for i, b := range w {
|
||||
r[i], err = spi.Transfer(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build nrf sam stm32,!stm32f407
|
||||
// +build sam stm32,!stm32f407
|
||||
|
||||
package machine
|
||||
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче