refactor: use *SPI everywhere to make consistant for implementations.

Fixes #4663 "in reverse" by making SPI a pointer everywhere, as discussed
in the comments.

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram
2025-02-25 11:09:14 +01:00
committed by Ron Evans
parent cab3834bc9
commit 2bee29959b
31 changed files with 99 additions and 101 deletions
+3 -3
View File
@@ -186,15 +186,15 @@ const (
) )
var ( var (
SPI1 = SPI{ SPI1 = &SPI{
Bus: stm32.SPI2, Bus: stm32.SPI2,
AltFuncSelector: AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
SPI2 = SPI{ SPI2 = &SPI{
Bus: stm32.SPI3, Bus: stm32.SPI3,
AltFuncSelector: AF6_SPI3, AltFuncSelector: AF6_SPI3,
} }
SPI3 = SPI{ SPI3 = &SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
+2 -2
View File
@@ -84,10 +84,10 @@ var (
I2C0 = I2C1 I2C0 = I2C1
// SPI // SPI
SPI0 = SPI{ SPI0 = &SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
} }
SPI1 = &SPI0 SPI1 = SPI0
) )
func init() { func init() {
+2 -2
View File
@@ -6,10 +6,10 @@ import "device/kendryte"
// SPI on the MAix Bit. // SPI on the MAix Bit.
var ( var (
SPI0 = SPI{ SPI0 = &SPI{
Bus: kendryte.SPI0, Bus: kendryte.SPI0,
} }
SPI1 = SPI{ SPI1 = &SPI{
Bus: kendryte.SPI1, Bus: kendryte.SPI1,
} }
) )
+2 -2
View File
@@ -89,11 +89,11 @@ const (
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1. // Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
var ( var (
SPI0 = SPI{ SPI0 = &SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
SPI1 = &SPI0 SPI1 = SPI0
) )
const ( const (
+2 -2
View File
@@ -86,11 +86,11 @@ var (
I2C0 = I2C1 I2C0 = I2C1
// SPI // SPI
SPI0 = SPI{ SPI0 = &SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
AltFuncSelector: 0, AltFuncSelector: 0,
} }
SPI1 = &SPI0 SPI1 = SPI0
) )
func init() { func init() {
+2 -2
View File
@@ -59,11 +59,11 @@ const (
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1. // Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
// TODO: implement SPI2 and SPI3. // TODO: implement SPI2 and SPI3.
var ( var (
SPI0 = SPI{ SPI0 = &SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
SPI1 = &SPI0 SPI1 = SPI0
) )
const ( const (
+2 -2
View File
@@ -86,11 +86,11 @@ const (
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1. // Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
// TODO: implement SPI2 and SPI3. // TODO: implement SPI2 and SPI3.
var ( var (
SPI0 = SPI{ SPI0 = &SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
SPI1 = &SPI0 SPI1 = SPI0
) )
const ( const (
+2 -2
View File
@@ -257,7 +257,7 @@ type SPI struct {
} }
// Configure is intended to setup the SPI interface. // Configure is intended to setup the SPI interface.
func (s SPI) Configure(config SPIConfig) error { func (s *SPI) Configure(config SPIConfig) error {
// This is only here to help catch a bug with the configuration // This is only here to help catch a bug with the configuration
// where a machine missed a value. // where a machine missed a value.
@@ -330,7 +330,7 @@ func (s SPI) Configure(config SPIConfig) error {
} }
// Transfer writes the byte into the register and returns the read content // Transfer writes the byte into the register and returns the read content
func (s SPI) Transfer(b byte) (byte, error) { func (s *SPI) Transfer(b byte) (byte, error) {
s.spdr.Set(uint8(b)) s.spdr.Set(uint8(b))
for !s.spsr.HasBits(s.spsrSPIF) { for !s.spsr.HasBits(s.spsrSPIF) {
+1 -1
View File
@@ -927,7 +927,7 @@ func (pwm PWM) Set(channel uint8, value uint32) {
} }
// SPI configuration // SPI configuration
var SPI0 = SPI{ var SPI0 = &SPI{
spcr: avr.SPCR, spcr: avr.SPCR,
spdr: avr.SPDR, spdr: avr.SPDR,
spsr: avr.SPSR, spsr: avr.SPSR,
+1 -1
View File
@@ -71,7 +71,7 @@ func (p Pin) getPortMask() (*volatile.Register8, uint8) {
} }
// SPI configuration // SPI configuration
var SPI0 = SPI{ var SPI0 = &SPI{
spcr: avr.SPCR, spcr: avr.SPCR,
spsr: avr.SPSR, spsr: avr.SPSR,
spdr: avr.SPDR, spdr: avr.SPDR,
+1 -1
View File
@@ -131,7 +131,7 @@ func (p Pin) getPortMask() (*volatile.Register8, uint8) {
} }
// SPI configuration // SPI configuration
var SPI0 = SPI{ var SPI0 = &SPI{
spcr: avr.SPCR, spcr: avr.SPCR,
spdr: avr.SPDR, spdr: avr.SPDR,
spsr: avr.SPSR, spsr: avr.SPSR,
+1 -1
View File
@@ -25,7 +25,7 @@ var I2C0 = &I2C{
} }
// SPI configuration // SPI configuration
var SPI0 = SPI{ var SPI0 = &SPI{
spcr: avr.SPCR, spcr: avr.SPCR,
spdr: avr.SPDR, spdr: avr.SPDR,
spsr: avr.SPSR, spsr: avr.SPSR,
+2 -2
View File
@@ -60,7 +60,7 @@ var I2C1 = &I2C{
} }
// SPI configuration // SPI configuration
var SPI0 = SPI{ var SPI0 = &SPI{
spcr: avr.SPCR0, spcr: avr.SPCR0,
spdr: avr.SPDR0, spdr: avr.SPDR0,
spsr: avr.SPSR0, spsr: avr.SPSR0,
@@ -82,7 +82,7 @@ var SPI0 = SPI{
cs: PB2, cs: PB2,
} }
var SPI1 = SPI{ var SPI1 = &SPI{
spcr: avr.SPCR1, spcr: avr.SPCR1,
spdr: avr.SPDR1, spdr: avr.SPDR1,
spsr: avr.SPSR1, spsr: avr.SPSR1,
+6 -6
View File
@@ -1224,7 +1224,7 @@ type SPIConfig struct {
} }
// Configure is intended to setup the SPI interface. // Configure is intended to setup the SPI interface.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// Use default pins if not set. // Use default pins if not set.
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 { if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
config.SCK = SPI0_SCK_PIN config.SCK = SPI0_SCK_PIN
@@ -1346,7 +1346,7 @@ func (spi SPI) Configure(config SPIConfig) error {
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
// write data // write data
spi.Bus.DATA.Set(uint32(w)) spi.Bus.DATA.Set(uint32(w))
@@ -1375,7 +1375,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet": // This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
// //
// spi.Tx(nil, rx) // spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
switch { switch {
case w == nil: case w == nil:
// read only, so write zero and read a result. // read only, so write zero and read a result.
@@ -1396,7 +1396,7 @@ func (spi SPI) Tx(w, r []byte) error {
return nil return nil
} }
func (spi SPI) tx(tx []byte) { func (spi *SPI) tx(tx []byte) {
for i := 0; i < len(tx); i++ { for i := 0; i < len(tx); i++ {
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) {
} }
@@ -1411,7 +1411,7 @@ func (spi SPI) tx(tx []byte) {
} }
} }
func (spi SPI) rx(rx []byte) { func (spi *SPI) rx(rx []byte) {
spi.Bus.DATA.Set(0) spi.Bus.DATA.Set(0)
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) {
} }
@@ -1427,7 +1427,7 @@ func (spi SPI) rx(rx []byte) {
rx[len(rx)-1] = byte(spi.Bus.DATA.Get()) rx[len(rx)-1] = byte(spi.Bus.DATA.Get())
} }
func (spi SPI) txrx(tx, rx []byte) { func (spi *SPI) txrx(tx, rx []byte) {
spi.Bus.DATA.Set(uint32(tx[0])) spi.Bus.DATA.Set(uint32(tx[0]))
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) {
} }
+6 -6
View File
@@ -1431,7 +1431,7 @@ type SPIConfig struct {
} }
// Configure is intended to setup the SPI interface. // Configure is intended to setup the SPI interface.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// Use default pins if not set. // Use default pins if not set.
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 { if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
config.SCK = SPI0_SCK_PIN config.SCK = SPI0_SCK_PIN
@@ -1574,7 +1574,7 @@ func (spi SPI) Configure(config SPIConfig) error {
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
// write data // write data
spi.Bus.DATA.Set(uint32(w)) spi.Bus.DATA.Set(uint32(w))
@@ -1603,7 +1603,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet": // This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
// //
// spi.Tx(nil, rx) // spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
switch { switch {
case w == nil: case w == nil:
// read only, so write zero and read a result. // read only, so write zero and read a result.
@@ -1624,7 +1624,7 @@ func (spi SPI) Tx(w, r []byte) error {
return nil return nil
} }
func (spi SPI) tx(tx []byte) { func (spi *SPI) tx(tx []byte) {
for i := 0; i < len(tx); i++ { for i := 0; i < len(tx); i++ {
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
} }
@@ -1639,7 +1639,7 @@ func (spi SPI) tx(tx []byte) {
} }
} }
func (spi SPI) rx(rx []byte) { func (spi *SPI) rx(rx []byte) {
spi.Bus.DATA.Set(0) spi.Bus.DATA.Set(0)
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
} }
@@ -1655,7 +1655,7 @@ func (spi SPI) rx(rx []byte) {
rx[len(rx)-1] = byte(spi.Bus.DATA.Get()) rx[len(rx)-1] = byte(spi.Bus.DATA.Get())
} }
func (spi SPI) txrx(tx, rx []byte) { func (spi *SPI) txrx(tx, rx []byte) {
spi.Bus.DATA.Set(uint32(tx[0])) spi.Bus.DATA.Set(uint32(tx[0]))
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
} }
+3 -3
View File
@@ -354,7 +354,7 @@ type SPIConfig struct {
} }
// Configure and make the SPI peripheral ready to use. // Configure and make the SPI peripheral ready to use.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 4e6 // default to 4MHz config.Frequency = 4e6 // default to 4MHz
} }
@@ -445,7 +445,7 @@ func (spi SPI) Configure(config SPIConfig) error {
// Transfer writes/reads a single byte using the SPI interface. If you need to // Transfer writes/reads a single byte using the SPI interface. If you need to
// transfer larger amounts of data, Tx will be faster. // transfer larger amounts of data, Tx will be faster.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
spi.Bus.MISO_DLEN.Set(7 << esp.SPI_MISO_DLEN_USR_MISO_DBITLEN_Pos) spi.Bus.MISO_DLEN.Set(7 << esp.SPI_MISO_DLEN_USR_MISO_DBITLEN_Pos)
spi.Bus.MOSI_DLEN.Set(7 << esp.SPI_MOSI_DLEN_USR_MOSI_DBITLEN_Pos) spi.Bus.MOSI_DLEN.Set(7 << esp.SPI_MOSI_DLEN_USR_MOSI_DBITLEN_Pos)
@@ -464,7 +464,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// 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.
// This is accomplished by sending zero bits if r is bigger than w or discarding // This is accomplished by sending zero bits if r is bigger than w or discarding
// the incoming data if w is bigger than r. // the incoming data if w is bigger than r.
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
toTransfer := len(w) toTransfer := len(w)
if len(r) > toTransfer { if len(r) > toTransfer {
toTransfer = len(r) toTransfer = len(r)
+3 -3
View File
@@ -114,7 +114,7 @@ func freqToClockDiv(hz uint32) uint32 {
} }
// Configure and make the SPI peripheral ready to use. // Configure and make the SPI peripheral ready to use.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// right now this is only setup to work for the esp32c3 spi2 bus // right now this is only setup to work for the esp32c3 spi2 bus
if spi.Bus != esp.SPI2 { if spi.Bus != esp.SPI2 {
return ErrInvalidSPIBus return ErrInvalidSPIBus
@@ -216,7 +216,7 @@ func (spi SPI) Configure(config SPIConfig) error {
// Transfer writes/reads a single byte using the SPI interface. If you need to // Transfer writes/reads a single byte using the SPI interface. If you need to
// transfer larger amounts of data, Tx will be faster. // transfer larger amounts of data, Tx will be faster.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
spi.Bus.SetMS_DLEN_MS_DATA_BITLEN(7) spi.Bus.SetMS_DLEN_MS_DATA_BITLEN(7)
spi.Bus.SetW0(uint32(w)) spi.Bus.SetW0(uint32(w))
@@ -238,7 +238,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// 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.
// This is accomplished by sending zero bits if r is bigger than w or discarding // This is accomplished by sending zero bits if r is bigger than w or discarding
// the incoming data if w is bigger than r. // the incoming data if w is bigger than r.
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
toTransfer := len(w) toTransfer := len(w)
if len(r) > toTransfer { if len(r) > toTransfer {
toTransfer = len(r) toTransfer = len(r)
+2 -2
View File
@@ -140,7 +140,7 @@ type SPIConfig struct {
} }
// Configure is intended to setup the SPI interface. // Configure is intended to setup the SPI interface.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// Use default pins if not set. // Use default pins if not set.
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 { if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
config.SCK = SPI0_SCK_PIN config.SCK = SPI0_SCK_PIN
@@ -197,7 +197,7 @@ func (spi SPI) Configure(config SPIConfig) error {
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
// wait for tx ready // wait for tx ready
for spi.Bus.TXDATA.HasBits(sifive.QSPI_TXDATA_FULL) { for spi.Bus.TXDATA.HasBits(sifive.QSPI_TXDATA_FULL) {
} }
+3 -3
View File
@@ -60,13 +60,13 @@ type SPIConfig struct {
Mode uint8 Mode uint8
} }
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
spiConfigure(spi.Bus, config.SCK, config.SDO, config.SDI) spiConfigure(spi.Bus, config.SCK, config.SDO, config.SDI)
return nil return nil
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
return spiTransfer(spi.Bus, w), nil return spiTransfer(spi.Bus, w), nil
} }
@@ -87,7 +87,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet": // This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
// //
// spi.Tx(nil, rx) // spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
var wptr, rptr *byte var wptr, rptr *byte
var wlen, rlen int var wlen, rlen int
if len(w) != 0 { if len(w) != 0 {
+2 -2
View File
@@ -8,7 +8,7 @@ package machine
var ( var (
UART0 = hardwareUART0 UART0 = hardwareUART0
UART1 = hardwareUART1 UART1 = hardwareUART1
SPI0 = SPI{0} SPI0 = &SPI{0}
SPI1 = SPI{1} SPI1 = &SPI{1}
I2C0 = &I2C{0} I2C0 = &I2C{0}
) )
+2 -2
View File
@@ -419,7 +419,7 @@ type SPIConfig struct {
// Configure is intended to setup the SPI interface. // Configure is intended to setup the SPI interface.
// Only SPI controller 0 and 1 can be used because SPI2 is a special // Only SPI controller 0 and 1 can be used because SPI2 is a special
// peripheral-mode controller and SPI3 is used for flashing. // peripheral-mode controller and SPI3 is used for flashing.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// Use default pins if not set. // Use default pins if not set.
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 { if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
config.SCK = SPI0_SCK_PIN config.SCK = SPI0_SCK_PIN
@@ -476,7 +476,7 @@ func (spi SPI) Configure(config SPIConfig) error {
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
spi.Bus.SSIENR.Set(0) spi.Bus.SSIENR.Set(0)
// Set transfer-receive mode. // Set transfer-receive mode.
+5 -5
View File
@@ -34,8 +34,8 @@ type SPI struct {
// There are 2 SPI interfaces on the NRF51. // There are 2 SPI interfaces on the NRF51.
var ( var (
SPI0 = SPI{Bus: nrf.SPI0} SPI0 = &SPI{Bus: nrf.SPI0}
SPI1 = SPI{Bus: nrf.SPI1} SPI1 = &SPI{Bus: nrf.SPI1}
) )
// SPIConfig is used to store config info for SPI. // SPIConfig is used to store config info for SPI.
@@ -49,7 +49,7 @@ type SPIConfig struct {
} }
// Configure is intended to setup the SPI interface. // Configure is intended to setup the SPI interface.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// Disable bus to configure it // Disable bus to configure it
spi.Bus.ENABLE.Set(nrf.SPI_ENABLE_ENABLE_Disabled) spi.Bus.ENABLE.Set(nrf.SPI_ENABLE_ENABLE_Disabled)
@@ -122,7 +122,7 @@ func (spi SPI) Configure(config SPIConfig) error {
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
spi.Bus.TXD.Set(uint32(w)) spi.Bus.TXD.Set(uint32(w))
for spi.Bus.EVENTS_READY.Get() == 0 { for spi.Bus.EVENTS_READY.Get() == 0 {
} }
@@ -150,7 +150,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet": // This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
// //
// spi.Tx(nil, rx) // spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
var err error var err error
switch { switch {
+6 -6
View File
@@ -199,9 +199,9 @@ type SPI struct {
// There are 3 SPI interfaces on the NRF528xx. // There are 3 SPI interfaces on the NRF528xx.
var ( var (
SPI0 = SPI{Bus: nrf.SPIM0, buf: new([1]byte)} SPI0 = &SPI{Bus: nrf.SPIM0, buf: new([1]byte)}
SPI1 = SPI{Bus: nrf.SPIM1, buf: new([1]byte)} SPI1 = &SPI{Bus: nrf.SPIM1, buf: new([1]byte)}
SPI2 = SPI{Bus: nrf.SPIM2, buf: new([1]byte)} SPI2 = &SPI{Bus: nrf.SPIM2, buf: new([1]byte)}
) )
// SPIConfig is used to store config info for SPI. // SPIConfig is used to store config info for SPI.
@@ -215,7 +215,7 @@ type SPIConfig struct {
} }
// Configure is intended to set up the SPI interface. // Configure is intended to set up the SPI interface.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// Disable bus to configure it // Disable bus to configure it
spi.Bus.ENABLE.Set(nrf.SPIM_ENABLE_ENABLE_Disabled) spi.Bus.ENABLE.Set(nrf.SPIM_ENABLE_ENABLE_Disabled)
@@ -288,7 +288,7 @@ func (spi SPI) Configure(config SPIConfig) error {
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
buf := spi.buf[:] buf := spi.buf[:]
buf[0] = w buf[0] = w
err := spi.Tx(buf[:], buf[:]) err := spi.Tx(buf[:], buf[:])
@@ -300,7 +300,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// as bytes read. Therefore, if the number of bytes don't match it will be // as bytes read. Therefore, if the number of bytes don't match it will be
// padded until they fit: if len(w) > len(r) the extra bytes received will be // padded until they fit: if len(w) > len(r) the extra bytes received will be
// dropped and if len(w) < len(r) extra 0 bytes will be sent. // dropped and if len(w) < len(r) extra 0 bytes will be sent.
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
// Unfortunately the hardware (on the nrf52832) only supports up to 255 // Unfortunately the hardware (on the nrf52832) only supports up to 255
// bytes in the buffers, so if either w or r is longer than that the // bytes in the buffers, so if either w or r is longer than that the
// transfer needs to be broken up in pieces. // transfer needs to be broken up in pieces.
+19 -21
View File
@@ -10,12 +10,10 @@ import (
// SPI on the RP2040 // SPI on the RP2040
var ( var (
SPI0 = &_SPI0 SPI0 = &SPI{
_SPI0 = SPI{
Bus: rp.SPI0, Bus: rp.SPI0,
} }
SPI1 = &_SPI1 SPI1 = &SPI{
_SPI1 = SPI{
Bus: rp.SPI1, Bus: rp.SPI1,
} }
) )
@@ -73,7 +71,7 @@ type SPI struct {
// //
// This form sends 0xff and puts the result into rx buffer. Useful for reading from SD cards // This form sends 0xff and puts the result into rx buffer. Useful for reading from SD cards
// which require 0xff input on SI. // which require 0xff input on SI.
func (spi SPI) Tx(w, r []byte) (err error) { func (spi *SPI) Tx(w, r []byte) (err error) {
switch { switch {
case w == nil: case w == nil:
// read only, so write zero and read a result. // read only, so write zero and read a result.
@@ -92,7 +90,7 @@ 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) {
for !spi.isWritable() { for !spi.isWritable() {
} }
@@ -103,7 +101,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return uint8(spi.Bus.SSPDR.Get()), nil return uint8(spi.Bus.SSPDR.Get()), nil
} }
func (spi SPI) SetBaudRate(br uint32) error { func (spi *SPI) SetBaudRate(br uint32) error {
const maxBaud uint32 = 66.5 * MHz // max output frequency is 66.5MHz on rp2040. see Note page 527. const maxBaud uint32 = 66.5 * MHz // max output frequency is 66.5MHz on rp2040. see Note page 527.
// Find smallest prescale value which puts output frequency in range of // Find smallest prescale value which puts output frequency in range of
// post-divide. Prescale is an even number from 2 to 254 inclusive. // post-divide. Prescale is an even number from 2 to 254 inclusive.
@@ -129,8 +127,8 @@ func (spi SPI) SetBaudRate(br uint32) error {
return nil return nil
} }
func (spi SPI) GetBaudRate() uint32 { func (spi *SPI) GetBaudRate() uint32 {
const freqin uint32 = 125 * MHz freqin := CPUFrequency()
prescale := spi.Bus.SSPCPSR.Get() prescale := spi.Bus.SSPCPSR.Get()
postdiv := ((spi.Bus.SSPCR0.Get() & rp.SPI0_SSPCR0_SCR_Msk) >> rp.SPI0_SSPCR0_SCR_Pos) + 1 postdiv := ((spi.Bus.SSPCR0.Get() & rp.SPI0_SSPCR0_SCR_Msk) >> rp.SPI0_SSPCR0_SCR_Pos) + 1
return freqin / (prescale * postdiv) return freqin / (prescale * postdiv)
@@ -152,7 +150,7 @@ func (spi SPI) GetBaudRate() uint32 {
// SCK: 10, 14 // SCK: 10, 14
// //
// No pin configuration is needed of SCK, SDO and SDI needed after calling Configure. // No pin configuration is needed of SCK, SDO and SDI needed after calling Configure.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
const defaultBaud uint32 = 4 * MHz const defaultBaud uint32 = 4 * MHz
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 { if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
// set default pins if config zero valued or invalid clock pin supplied. // set default pins if config zero valued or invalid clock pin supplied.
@@ -199,7 +197,7 @@ func (spi SPI) Configure(config SPIConfig) error {
return spi.initSPI(config) return spi.initSPI(config)
} }
func (spi SPI) initSPI(config SPIConfig) (err error) { func (spi *SPI) initSPI(config SPIConfig) (err error) {
spi.reset() spi.reset()
// LSB-first not supported on PL022: // LSB-first not supported on PL022:
if config.LSBFirst { if config.LSBFirst {
@@ -217,7 +215,7 @@ func (spi SPI) initSPI(config SPIConfig) (err error) {
} }
//go:inline //go:inline
func (spi SPI) setFormat(mode uint8) { func (spi *SPI) setFormat(mode uint8) {
cpha := uint32(mode) & 1 cpha := uint32(mode) & 1
cpol := uint32(mode>>1) & 1 cpol := uint32(mode>>1) & 1
spi.Bus.SSPCR0.ReplaceBits( spi.Bus.SSPCR0.ReplaceBits(
@@ -230,7 +228,7 @@ func (spi SPI) setFormat(mode uint8) {
// reset resets SPI and waits until reset is done. // reset resets SPI and waits until reset is done.
// //
//go:inline //go:inline
func (spi SPI) reset() { func (spi *SPI) reset() {
resetVal := spi.deinit() resetVal := spi.deinit()
rp.RESETS.RESET.ClearBits(resetVal) rp.RESETS.RESET.ClearBits(resetVal)
// Wait until reset is done. // Wait until reset is done.
@@ -239,7 +237,7 @@ func (spi SPI) reset() {
} }
//go:inline //go:inline
func (spi SPI) deinit() (resetVal uint32) { func (spi *SPI) deinit() (resetVal uint32) {
switch spi.Bus { switch spi.Bus {
case rp.SPI0: case rp.SPI0:
resetVal = rp.RESETS_RESET_SPI0 resetVal = rp.RESETS_RESET_SPI0
@@ -254,19 +252,19 @@ func (spi SPI) deinit() (resetVal uint32) {
// isWritable returns false if no space is available to write. True if a write is possible // isWritable returns false if no space is available to write. True if a write is possible
// //
//go:inline //go:inline
func (spi SPI) isWritable() bool { func (spi *SPI) isWritable() bool {
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_TNF) return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_TNF)
} }
// isReadable returns true if a read is possible i.e. data is present // isReadable returns true if a read is possible i.e. data is present
// //
//go:inline //go:inline
func (spi SPI) isReadable() bool { func (spi *SPI) isReadable() bool {
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_RNE) return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_RNE)
} }
// PrintRegs prints SPI's peripheral common registries current values // PrintRegs prints SPI's peripheral common registries current values
func (spi SPI) PrintRegs() { func (spi *SPI) PrintRegs() {
cr0 := spi.Bus.SSPCR0.Get() cr0 := spi.Bus.SSPCR0.Get()
cr1 := spi.Bus.SSPCR1.Get() cr1 := spi.Bus.SSPCR1.Get()
dmacr := spi.Bus.SSPDMACR.Get() dmacr := spi.Bus.SSPDMACR.Get()
@@ -282,12 +280,12 @@ func (spi SPI) PrintRegs() {
} }
//go:inline //go:inline
func (spi SPI) isBusy() bool { func (spi *SPI) isBusy() bool {
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_BSY) return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_BSY)
} }
// 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 {
if len(tx) == 0 { if len(tx) == 0 {
// We don't have to do anything. // We don't have to do anything.
// This avoids a panic in &tx[0] when len(tx) == 0. // This avoids a panic in &tx[0] when len(tx) == 0.
@@ -352,7 +350,7 @@ func (spi SPI) tx(tx []byte) error {
// txrepeat is output repeatedly on SO as data is read in from SI. // txrepeat is output repeatedly on SO as data is read in from SI.
// 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 {
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
@@ -375,7 +373,7 @@ 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 {
plen := len(tx) plen := len(tx)
if plen != len(rx) { if plen != len(rx) {
return ErrTxInvalidSliceSize return ErrTxInvalidSliceSize
+2 -2
View File
@@ -21,7 +21,7 @@ type SPIConfig struct {
} }
// Configure is intended to setup the STM32 SPI1 interface. // Configure is intended to setup the STM32 SPI1 interface.
func (spi SPI) Configure(config SPIConfig) error { func (spi *SPI) Configure(config SPIConfig) error {
// -- CONFIGURING THE SPI IN MASTER MODE -- // -- CONFIGURING THE SPI IN MASTER MODE --
// //
@@ -98,7 +98,7 @@ func (spi SPI) Configure(config SPIConfig) error {
} }
// Transfer writes/reads a single byte using the SPI interface. // Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) { func (spi *SPI) Transfer(w byte) (byte, error) {
// 1. Enable the SPI by setting the SPE bit to 1. // 1. Enable the SPI by setting the SPE bit to 1.
// 2. Write the first data item to be transmitted into the SPI_DR register // 2. Write the first data item to be transmitted into the SPI_DR register
+4 -4
View File
@@ -333,16 +333,16 @@ type SPI struct {
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1. // Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
// TODO: implement SPI2 and SPI3. // TODO: implement SPI2 and SPI3.
var ( var (
SPI1 = SPI{Bus: stm32.SPI1} SPI1 = &SPI{Bus: stm32.SPI1}
SPI0 = SPI1 SPI0 = SPI1
) )
func (spi SPI) config8Bits() { func (spi *SPI) config8Bits() {
// no-op on this series // no-op on this series
} }
// Set baud rate for SPI // Set baud rate for SPI
func (spi SPI) getBaudRate(config SPIConfig) uint32 { func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
var conf uint32 var conf uint32
// set frequency dependent on PCLK2 prescaler (div 1) // set frequency dependent on PCLK2 prescaler (div 1)
@@ -368,7 +368,7 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
} }
// Configure SPI pins for input output and clock // Configure SPI pins for input output and clock
func (spi SPI) configurePins(config SPIConfig) { func (spi *SPI) configurePins(config SPIConfig) {
config.SCK.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull}) config.SCK.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
config.SDO.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull}) config.SDO.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
config.SDI.Configure(PinConfig{Mode: PinInputModeFloating}) config.SDI.Configure(PinConfig{Mode: PinInputModeFloating})
+3 -3
View File
@@ -672,17 +672,17 @@ type SPI struct {
AltFuncSelector uint8 AltFuncSelector uint8
} }
func (spi SPI) config8Bits() { func (spi *SPI) config8Bits() {
// no-op on this series // no-op on this series
} }
func (spi SPI) configurePins(config SPIConfig) { func (spi *SPI) configurePins(config SPIConfig) {
config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector) config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector)
config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector) config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector) config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
} }
func (spi SPI) getBaudRate(config SPIConfig) uint32 { func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
var clock uint32 var clock uint32
switch spi.Bus { switch spi.Bus {
case stm32.SPI1: case stm32.SPI1:
+3 -3
View File
@@ -234,12 +234,12 @@ type SPI struct {
AltFuncSelector uint8 AltFuncSelector uint8
} }
func (spi SPI) config8Bits() { func (spi *SPI) config8Bits() {
// no-op on this series // no-op on this series
} }
// Set baud rate for SPI // Set baud rate for SPI
func (spi SPI) getBaudRate(config SPIConfig) uint32 { func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
var conf uint32 var conf uint32
localFrequency := config.Frequency localFrequency := config.Frequency
@@ -289,7 +289,7 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
} }
// Configure SPI pins for input output and clock // Configure SPI pins for input output and clock
func (spi SPI) configurePins(config SPIConfig) { func (spi *SPI) configurePins(config SPIConfig) {
config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector) config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector)
config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector) config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector) config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
+3 -3
View File
@@ -309,14 +309,14 @@ type SPI struct {
AltFuncSelector uint8 AltFuncSelector uint8
} }
func (spi SPI) config8Bits() { func (spi *SPI) config8Bits() {
// Set rx threshold to 8-bits, so RXNE flag is set for 1 byte // Set rx threshold to 8-bits, so RXNE flag is set for 1 byte
// (common STM32 SPI implementation does 8-bit transfers only) // (common STM32 SPI implementation does 8-bit transfers only)
spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH) spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH)
} }
// Set baud rate for SPI // Set baud rate for SPI
func (spi SPI) getBaudRate(config SPIConfig) uint32 { func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
var conf uint32 var conf uint32
// Default // Default
@@ -359,7 +359,7 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
} }
// Configure SPI pins for input output and clock // Configure SPI pins for input output and clock
func (spi SPI) configurePins(config SPIConfig) { func (spi *SPI) configurePins(config SPIConfig) {
config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector) config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector)
config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector) config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector) config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
+3 -3
View File
@@ -235,19 +235,19 @@ type SPI struct {
AltFuncSelector uint8 AltFuncSelector uint8
} }
func (spi SPI) config8Bits() { func (spi *SPI) config8Bits() {
// Set rx threshold to 8-bits, so RXNE flag is set for 1 byte // Set rx threshold to 8-bits, so RXNE flag is set for 1 byte
// (common STM32 SPI implementation does 8-bit transfers only) // (common STM32 SPI implementation does 8-bit transfers only)
spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH) spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH)
} }
func (spi SPI) configurePins(config SPIConfig) { func (spi *SPI) configurePins(config SPIConfig) {
config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector) config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector)
config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector) config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector) config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
} }
func (spi SPI) getBaudRate(config SPIConfig) uint32 { func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
var clock uint32 var clock uint32
// We keep this switch and separate management of SPI Clocks // We keep this switch and separate management of SPI Clocks
+1 -1
View File
@@ -22,7 +22,7 @@ package machine
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet": // This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
// //
// spi.Tx(nil, rx) // spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error { func (spi *SPI) Tx(w, r []byte) error {
var err error var err error
switch { switch {