diff options
author | Patricio Whittingslow <[email protected]> | 2023-02-23 09:26:14 -0300 |
---|---|---|
committer | GitHub <[email protected]> | 2023-02-23 13:26:14 +0100 |
commit | 96b70fd619b9701335a1ae8d827ff1d54bc52330 (patch) | |
tree | 16d6bb380605300a3927ec698cbccb976851e26c | |
parent | 4d0dfbd6fd607eacfd77460e74eadae2ba73215c (diff) | |
download | tinygo-96b70fd619b9701335a1ae8d827ff1d54bc52330.tar.gz tinygo-96b70fd619b9701335a1ae8d827ff1d54bc52330.zip |
rp2040: provide better errors for invalid pins on i2c and spi (#3443)
machine/rp2040: provide better errors for invalid pins on i2c and spi
-rw-r--r-- | src/machine/machine_rp2040_i2c.go | 19 | ||||
-rw-r--r-- | src/machine/machine_rp2040_spi.go | 24 |
2 files changed, 41 insertions, 2 deletions
diff --git a/src/machine/machine_rp2040_i2c.go b/src/machine/machine_rp2040_i2c.go index d49e7f576..2c0c2e6ed 100644 --- a/src/machine/machine_rp2040_i2c.go +++ b/src/machine/machine_rp2040_i2c.go @@ -57,6 +57,8 @@ var ( ErrInvalidTgtAddr = errors.New("invalid target i2c address not in 0..0x80 or is reserved") ErrI2CGeneric = errors.New("i2c error") ErrRP2040I2CDisable = errors.New("i2c rp2040 peripheral timeout in disable") + errInvalidI2CSDA = errors.New("invalid I2C SDA pin") + errInvalidI2CSCL = errors.New("invalid I2C SCL pin") ) // Tx performs a write and then a read transfer placing the result in @@ -90,7 +92,7 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) error { // SCL: 3, 7, 11, 15, 19, 27 func (i2c *I2C) Configure(config I2CConfig) error { const defaultBaud uint32 = 100_000 // 100kHz standard mode - if config.SCL == 0 { + if config.SCL == 0 && config.SDA == 0 { // If config pins are zero valued or clock pin is invalid then we set default values. switch i2c.Bus { case rp.I2C0: @@ -101,6 +103,21 @@ func (i2c *I2C) Configure(config I2CConfig) error { config.SDA = I2C1_SDA_PIN } } + var okSDA, okSCL bool + switch i2c.Bus { + case rp.I2C0: + okSDA = config.SDA%4 == 0 + okSCL = (config.SCL+1)%4 == 0 + case rp.I2C1: + okSDA = (config.SDA+2)%4 == 0 + okSCL = (config.SCL+3)%4 == 0 + } + + if !okSDA { + return errInvalidI2CSDA + } else if !okSCL { + return errInvalidI2CSCL + } if config.Frequency == 0 { config.Frequency = defaultBaud } diff --git a/src/machine/machine_rp2040_spi.go b/src/machine/machine_rp2040_spi.go index fd1b6ab0f..569a452a5 100644 --- a/src/machine/machine_rp2040_spi.go +++ b/src/machine/machine_rp2040_spi.go @@ -40,6 +40,9 @@ var ( ErrLSBNotSupported = errors.New("SPI LSB unsupported on PL022") ErrSPITimeout = errors.New("SPI timeout") ErrSPIBaud = errors.New("SPI baud too low or above 66.5Mhz") + errSPIInvalidSDI = errors.New("invalid SPI SDI pin") + errSPIInvalidSDO = errors.New("invalid SPI SDO pin") + errSPIInvalidSCK = errors.New("invalid SPI SCK pin") ) type SPI struct { @@ -162,7 +165,7 @@ func (spi SPI) GetBaudRate() uint32 { // No pin configuration is needed of SCK, SDO and SDI needed after calling Configure. func (spi SPI) Configure(config SPIConfig) error { const defaultBaud uint32 = 115200 - if config.SCK == 0 { + if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 { // set default pins if config zero valued or invalid clock pin supplied. switch spi.Bus { case rp.SPI0: @@ -175,6 +178,25 @@ func (spi SPI) Configure(config SPIConfig) error { config.SDI = SPI1_SDI_PIN } } + var okSDI, okSDO, okSCK bool + switch spi.Bus { + case rp.SPI0: + okSDI = config.SDI == 0 || config.SDI == 4 || config.SDI == 17 + okSDO = config.SDO == 3 || config.SDO == 7 || config.SDO == 19 + okSCK = config.SCK == 2 || config.SCK == 6 || config.SCK == 18 + case rp.SPI1: + okSDI = config.SDI == 8 || config.SDI == 12 + okSDO = config.SDO == 11 || config.SDO == 15 + okSDO = config.SCK == 10 || config.SCK == 14 + } + + if !okSDI { + return errSPIInvalidSDI + } else if !okSDO { + return errSPIInvalidSDO + } else if !okSCK { + return errSPIInvalidSCK + } if config.DataBits < 4 || config.DataBits > 16 { config.DataBits = 8 } |