mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
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:
@@ -186,15 +186,15 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
SPI1 = SPI{
|
||||
SPI1 = &SPI{
|
||||
Bus: stm32.SPI2,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
SPI2 = SPI{
|
||||
SPI2 = &SPI{
|
||||
Bus: stm32.SPI3,
|
||||
AltFuncSelector: AF6_SPI3,
|
||||
}
|
||||
SPI3 = SPI{
|
||||
SPI3 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
|
||||
@@ -84,10 +84,10 @@ var (
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
SPI1 = SPI0
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -6,10 +6,10 @@ import "device/kendryte"
|
||||
|
||||
// SPI on the MAix Bit.
|
||||
var (
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: kendryte.SPI0,
|
||||
}
|
||||
SPI1 = SPI{
|
||||
SPI1 = &SPI{
|
||||
Bus: kendryte.SPI1,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -89,11 +89,11 @@ const (
|
||||
|
||||
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
|
||||
var (
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
SPI1 = SPI0
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -86,11 +86,11 @@ var (
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: 0,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
SPI1 = SPI0
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -59,11 +59,11 @@ const (
|
||||
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
|
||||
// TODO: implement SPI2 and SPI3.
|
||||
var (
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
SPI1 = SPI0
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -86,11 +86,11 @@ const (
|
||||
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
|
||||
// TODO: implement SPI2 and SPI3.
|
||||
var (
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
SPI1 = SPI0
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -257,7 +257,7 @@ type SPI struct {
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
func (s SPI) Transfer(b byte) (byte, error) {
|
||||
func (s *SPI) Transfer(b byte) (byte, error) {
|
||||
s.spdr.Set(uint8(b))
|
||||
|
||||
for !s.spsr.HasBits(s.spsrSPIF) {
|
||||
|
||||
@@ -927,7 +927,7 @@ func (pwm PWM) Set(channel uint8, value uint32) {
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
var SPI0 = &SPI{
|
||||
spcr: avr.SPCR,
|
||||
spdr: avr.SPDR,
|
||||
spsr: avr.SPSR,
|
||||
|
||||
@@ -71,7 +71,7 @@ func (p Pin) getPortMask() (*volatile.Register8, uint8) {
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
var SPI0 = &SPI{
|
||||
spcr: avr.SPCR,
|
||||
spsr: avr.SPSR,
|
||||
spdr: avr.SPDR,
|
||||
|
||||
@@ -131,7 +131,7 @@ func (p Pin) getPortMask() (*volatile.Register8, uint8) {
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
var SPI0 = &SPI{
|
||||
spcr: avr.SPCR,
|
||||
spdr: avr.SPDR,
|
||||
spsr: avr.SPSR,
|
||||
|
||||
@@ -25,7 +25,7 @@ var I2C0 = &I2C{
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
var SPI0 = &SPI{
|
||||
spcr: avr.SPCR,
|
||||
spdr: avr.SPDR,
|
||||
spsr: avr.SPSR,
|
||||
|
||||
@@ -60,7 +60,7 @@ var I2C1 = &I2C{
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
var SPI0 = &SPI{
|
||||
spcr: avr.SPCR0,
|
||||
spdr: avr.SPDR0,
|
||||
spsr: avr.SPSR0,
|
||||
@@ -82,7 +82,7 @@ var SPI0 = SPI{
|
||||
cs: PB2,
|
||||
}
|
||||
|
||||
var SPI1 = SPI{
|
||||
var SPI1 = &SPI{
|
||||
spcr: avr.SPCR1,
|
||||
spdr: avr.SPDR1,
|
||||
spsr: avr.SPSR1,
|
||||
|
||||
@@ -1224,7 +1224,7 @@ type SPIConfig struct {
|
||||
}
|
||||
|
||||
// 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.
|
||||
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
|
||||
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.
|
||||
func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
func (spi *SPI) Transfer(w byte) (byte, error) {
|
||||
// write data
|
||||
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":
|
||||
//
|
||||
// spi.Tx(nil, rx)
|
||||
func (spi SPI) Tx(w, r []byte) error {
|
||||
func (spi *SPI) Tx(w, r []byte) error {
|
||||
switch {
|
||||
case w == nil:
|
||||
// read only, so write zero and read a result.
|
||||
@@ -1396,7 +1396,7 @@ func (spi SPI) Tx(w, r []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (spi SPI) tx(tx []byte) {
|
||||
func (spi *SPI) tx(tx []byte) {
|
||||
for i := 0; i < len(tx); i++ {
|
||||
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)
|
||||
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())
|
||||
}
|
||||
|
||||
func (spi SPI) txrx(tx, rx []byte) {
|
||||
func (spi *SPI) txrx(tx, rx []byte) {
|
||||
spi.Bus.DATA.Set(uint32(tx[0]))
|
||||
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) {
|
||||
}
|
||||
|
||||
@@ -1431,7 +1431,7 @@ type SPIConfig struct {
|
||||
}
|
||||
|
||||
// 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.
|
||||
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
|
||||
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.
|
||||
func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
func (spi *SPI) Transfer(w byte) (byte, error) {
|
||||
// write data
|
||||
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":
|
||||
//
|
||||
// spi.Tx(nil, rx)
|
||||
func (spi SPI) Tx(w, r []byte) error {
|
||||
func (spi *SPI) Tx(w, r []byte) error {
|
||||
switch {
|
||||
case w == nil:
|
||||
// read only, so write zero and read a result.
|
||||
@@ -1624,7 +1624,7 @@ func (spi SPI) Tx(w, r []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (spi SPI) tx(tx []byte) {
|
||||
func (spi *SPI) tx(tx []byte) {
|
||||
for i := 0; i < len(tx); i++ {
|
||||
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)
|
||||
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())
|
||||
}
|
||||
|
||||
func (spi SPI) txrx(tx, rx []byte) {
|
||||
func (spi *SPI) txrx(tx, rx []byte) {
|
||||
spi.Bus.DATA.Set(uint32(tx[0]))
|
||||
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ type SPIConfig struct {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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 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.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.
|
||||
// This is accomplished by sending zero bits if r is bigger than w or discarding
|
||||
// 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)
|
||||
if len(r) > toTransfer {
|
||||
toTransfer = len(r)
|
||||
|
||||
@@ -114,7 +114,7 @@ func freqToClockDiv(hz uint32) uint32 {
|
||||
}
|
||||
|
||||
// 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
|
||||
if spi.Bus != esp.SPI2 {
|
||||
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 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.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.
|
||||
// This is accomplished by sending zero bits if r is bigger than w or discarding
|
||||
// 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)
|
||||
if len(r) > toTransfer {
|
||||
toTransfer = len(r)
|
||||
|
||||
@@ -140,7 +140,7 @@ type SPIConfig struct {
|
||||
}
|
||||
|
||||
// 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.
|
||||
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
|
||||
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.
|
||||
func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
func (spi *SPI) Transfer(w byte) (byte, error) {
|
||||
// wait for tx ready
|
||||
for spi.Bus.TXDATA.HasBits(sifive.QSPI_TXDATA_FULL) {
|
||||
}
|
||||
|
||||
@@ -60,13 +60,13 @@ type SPIConfig struct {
|
||||
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)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -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":
|
||||
//
|
||||
// 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 wlen, rlen int
|
||||
if len(w) != 0 {
|
||||
|
||||
@@ -8,7 +8,7 @@ package machine
|
||||
var (
|
||||
UART0 = hardwareUART0
|
||||
UART1 = hardwareUART1
|
||||
SPI0 = SPI{0}
|
||||
SPI1 = SPI{1}
|
||||
SPI0 = &SPI{0}
|
||||
SPI1 = &SPI{1}
|
||||
I2C0 = &I2C{0}
|
||||
)
|
||||
|
||||
@@ -419,7 +419,7 @@ type SPIConfig struct {
|
||||
// Configure is intended to setup the SPI interface.
|
||||
// Only SPI controller 0 and 1 can be used because SPI2 is a special
|
||||
// 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.
|
||||
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
|
||||
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.
|
||||
func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
func (spi *SPI) Transfer(w byte) (byte, error) {
|
||||
spi.Bus.SSIENR.Set(0)
|
||||
|
||||
// Set transfer-receive mode.
|
||||
|
||||
@@ -34,8 +34,8 @@ type SPI struct {
|
||||
|
||||
// There are 2 SPI interfaces on the NRF51.
|
||||
var (
|
||||
SPI0 = SPI{Bus: nrf.SPI0}
|
||||
SPI1 = SPI{Bus: nrf.SPI1}
|
||||
SPI0 = &SPI{Bus: nrf.SPI0}
|
||||
SPI1 = &SPI{Bus: nrf.SPI1}
|
||||
)
|
||||
|
||||
// SPIConfig is used to store config info for SPI.
|
||||
@@ -49,7 +49,7 @@ type SPIConfig struct {
|
||||
}
|
||||
|
||||
// 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
|
||||
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.
|
||||
func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
func (spi *SPI) Transfer(w byte) (byte, error) {
|
||||
spi.Bus.TXD.Set(uint32(w))
|
||||
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":
|
||||
//
|
||||
// spi.Tx(nil, rx)
|
||||
func (spi SPI) Tx(w, r []byte) error {
|
||||
func (spi *SPI) Tx(w, r []byte) error {
|
||||
var err error
|
||||
|
||||
switch {
|
||||
|
||||
@@ -199,9 +199,9 @@ type SPI struct {
|
||||
|
||||
// There are 3 SPI interfaces on the NRF528xx.
|
||||
var (
|
||||
SPI0 = SPI{Bus: nrf.SPIM0, buf: new([1]byte)}
|
||||
SPI1 = SPI{Bus: nrf.SPIM1, buf: new([1]byte)}
|
||||
SPI2 = SPI{Bus: nrf.SPIM2, buf: new([1]byte)}
|
||||
SPI0 = &SPI{Bus: nrf.SPIM0, buf: new([1]byte)}
|
||||
SPI1 = &SPI{Bus: nrf.SPIM1, buf: new([1]byte)}
|
||||
SPI2 = &SPI{Bus: nrf.SPIM2, buf: new([1]byte)}
|
||||
)
|
||||
|
||||
// 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.
|
||||
func (spi SPI) Configure(config SPIConfig) error {
|
||||
func (spi *SPI) Configure(config SPIConfig) error {
|
||||
// Disable bus to configure it
|
||||
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.
|
||||
func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
func (spi *SPI) Transfer(w byte) (byte, error) {
|
||||
buf := spi.buf[:]
|
||||
buf[0] = w
|
||||
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
|
||||
// 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.
|
||||
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
|
||||
// bytes in the buffers, so if either w or r is longer than that the
|
||||
// transfer needs to be broken up in pieces.
|
||||
|
||||
@@ -10,12 +10,10 @@ import (
|
||||
|
||||
// SPI on the RP2040
|
||||
var (
|
||||
SPI0 = &_SPI0
|
||||
_SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: rp.SPI0,
|
||||
}
|
||||
SPI1 = &_SPI1
|
||||
_SPI1 = SPI{
|
||||
SPI1 = &SPI{
|
||||
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
|
||||
// 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 {
|
||||
case w == nil:
|
||||
// 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.
|
||||
func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
func (spi *SPI) Transfer(w byte) (byte, error) {
|
||||
for !spi.isWritable() {
|
||||
}
|
||||
|
||||
@@ -103,7 +101,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
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.
|
||||
// Find smallest prescale value which puts output frequency in range of
|
||||
// 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
|
||||
}
|
||||
|
||||
func (spi SPI) GetBaudRate() uint32 {
|
||||
const freqin uint32 = 125 * MHz
|
||||
func (spi *SPI) GetBaudRate() uint32 {
|
||||
freqin := CPUFrequency()
|
||||
prescale := spi.Bus.SSPCPSR.Get()
|
||||
postdiv := ((spi.Bus.SSPCR0.Get() & rp.SPI0_SSPCR0_SCR_Msk) >> rp.SPI0_SSPCR0_SCR_Pos) + 1
|
||||
return freqin / (prescale * postdiv)
|
||||
@@ -152,7 +150,7 @@ func (spi SPI) GetBaudRate() uint32 {
|
||||
// SCK: 10, 14
|
||||
//
|
||||
// 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
|
||||
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (spi SPI) initSPI(config SPIConfig) (err error) {
|
||||
func (spi *SPI) initSPI(config SPIConfig) (err error) {
|
||||
spi.reset()
|
||||
// LSB-first not supported on PL022:
|
||||
if config.LSBFirst {
|
||||
@@ -217,7 +215,7 @@ func (spi SPI) initSPI(config SPIConfig) (err error) {
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (spi SPI) setFormat(mode uint8) {
|
||||
func (spi *SPI) setFormat(mode uint8) {
|
||||
cpha := uint32(mode) & 1
|
||||
cpol := uint32(mode>>1) & 1
|
||||
spi.Bus.SSPCR0.ReplaceBits(
|
||||
@@ -230,7 +228,7 @@ func (spi SPI) setFormat(mode uint8) {
|
||||
// reset resets SPI and waits until reset is done.
|
||||
//
|
||||
//go:inline
|
||||
func (spi SPI) reset() {
|
||||
func (spi *SPI) reset() {
|
||||
resetVal := spi.deinit()
|
||||
rp.RESETS.RESET.ClearBits(resetVal)
|
||||
// Wait until reset is done.
|
||||
@@ -239,7 +237,7 @@ func (spi SPI) reset() {
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (spi SPI) deinit() (resetVal uint32) {
|
||||
func (spi *SPI) deinit() (resetVal uint32) {
|
||||
switch spi.Bus {
|
||||
case rp.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
|
||||
//
|
||||
//go:inline
|
||||
func (spi SPI) isWritable() bool {
|
||||
func (spi *SPI) isWritable() bool {
|
||||
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_TNF)
|
||||
}
|
||||
|
||||
// isReadable returns true if a read is possible i.e. data is present
|
||||
//
|
||||
//go:inline
|
||||
func (spi SPI) isReadable() bool {
|
||||
func (spi *SPI) isReadable() bool {
|
||||
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_RNE)
|
||||
}
|
||||
|
||||
// PrintRegs prints SPI's peripheral common registries current values
|
||||
func (spi SPI) PrintRegs() {
|
||||
func (spi *SPI) PrintRegs() {
|
||||
cr0 := spi.Bus.SSPCR0.Get()
|
||||
cr1 := spi.Bus.SSPCR1.Get()
|
||||
dmacr := spi.Bus.SSPDMACR.Get()
|
||||
@@ -282,12 +280,12 @@ func (spi SPI) PrintRegs() {
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (spi SPI) isBusy() bool {
|
||||
func (spi *SPI) isBusy() bool {
|
||||
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_BSY)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// We don't have to do anything.
|
||||
// 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.
|
||||
// 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 {
|
||||
func (spi *SPI) rx(rx []byte, txrepeat byte) error {
|
||||
plen := len(rx)
|
||||
const fifoDepth = 8 // see txrx
|
||||
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.
|
||||
// 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)
|
||||
if plen != len(rx) {
|
||||
return ErrTxInvalidSliceSize
|
||||
|
||||
@@ -21,7 +21,7 @@ type SPIConfig struct {
|
||||
}
|
||||
|
||||
// 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 --
|
||||
//
|
||||
@@ -98,7 +98,7 @@ func (spi SPI) Configure(config SPIConfig) error {
|
||||
}
|
||||
|
||||
// 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.
|
||||
// 2. Write the first data item to be transmitted into the SPI_DR register
|
||||
|
||||
@@ -333,16 +333,16 @@ type SPI struct {
|
||||
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
|
||||
// TODO: implement SPI2 and SPI3.
|
||||
var (
|
||||
SPI1 = SPI{Bus: stm32.SPI1}
|
||||
SPI1 = &SPI{Bus: stm32.SPI1}
|
||||
SPI0 = SPI1
|
||||
)
|
||||
|
||||
func (spi SPI) config8Bits() {
|
||||
func (spi *SPI) config8Bits() {
|
||||
// no-op on this series
|
||||
}
|
||||
|
||||
// Set baud rate for SPI
|
||||
func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
var conf uint32
|
||||
|
||||
// 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
|
||||
func (spi SPI) configurePins(config SPIConfig) {
|
||||
func (spi *SPI) configurePins(config SPIConfig) {
|
||||
config.SCK.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
|
||||
config.SDO.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
|
||||
config.SDI.Configure(PinConfig{Mode: PinInputModeFloating})
|
||||
|
||||
@@ -672,17 +672,17 @@ type SPI struct {
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (spi SPI) config8Bits() {
|
||||
func (spi *SPI) config8Bits() {
|
||||
// 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.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, 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
|
||||
switch spi.Bus {
|
||||
case stm32.SPI1:
|
||||
|
||||
@@ -234,12 +234,12 @@ type SPI struct {
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (spi SPI) config8Bits() {
|
||||
func (spi *SPI) config8Bits() {
|
||||
// no-op on this series
|
||||
}
|
||||
|
||||
// Set baud rate for SPI
|
||||
func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
var conf uint32
|
||||
|
||||
localFrequency := config.Frequency
|
||||
@@ -289,7 +289,7 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
}
|
||||
|
||||
// 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.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
|
||||
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
|
||||
|
||||
@@ -309,14 +309,14 @@ type SPI struct {
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (spi SPI) config8Bits() {
|
||||
func (spi *SPI) config8Bits() {
|
||||
// Set rx threshold to 8-bits, so RXNE flag is set for 1 byte
|
||||
// (common STM32 SPI implementation does 8-bit transfers only)
|
||||
spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH)
|
||||
}
|
||||
|
||||
// Set baud rate for SPI
|
||||
func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
func (spi *SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
var conf uint32
|
||||
|
||||
// Default
|
||||
@@ -359,7 +359,7 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
}
|
||||
|
||||
// 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.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
|
||||
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
|
||||
|
||||
@@ -235,19 +235,19 @@ type SPI struct {
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (spi SPI) config8Bits() {
|
||||
func (spi *SPI) config8Bits() {
|
||||
// Set rx threshold to 8-bits, so RXNE flag is set for 1 byte
|
||||
// (common STM32 SPI implementation does 8-bit transfers only)
|
||||
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.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, 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
|
||||
|
||||
// We keep this switch and separate management of SPI Clocks
|
||||
|
||||
@@ -22,7 +22,7 @@ package machine
|
||||
// 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 {
|
||||
func (spi *SPI) Tx(w, r []byte) error {
|
||||
var err error
|
||||
|
||||
switch {
|
||||
|
||||
Reference in New Issue
Block a user