mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-10 22:13:39 +00:00
machine: make I2C usable in the simulator
This fixes/improves a few issues with I2C support:
* Validate I2C pins, so only pins that are supported by the hardware
can be used (similar to how it's done with PWM).
* Add address to Tx API (without it, the simulator can't really
simulate I2C).
* Add frequency when configuring. Not currently used, but might be
useful in the future and adding it now avoids possibly breaking
changes.
This is a breaking change, but since the simulator doesn't support I2C
yet that seems fine to me. (It does in my local changes, but those need
to be cleaned up before I can push them).
This commit is contained in:
committed by
Ron Evans
parent
35adbffa54
commit
f845b469b1
@@ -4,6 +4,8 @@ package machine
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// Dummy machine package that calls out to external functions.
|
||||
@@ -227,7 +229,9 @@ func adcRead(pin Pin) uint16
|
||||
|
||||
// I2C is a generic implementation of the Inter-IC communication protocol.
|
||||
type I2C struct {
|
||||
Bus uint8
|
||||
Bus uint8
|
||||
PinsSCL []Pin
|
||||
PinsSDA []Pin
|
||||
}
|
||||
|
||||
// I2CConfig is used to store config info for I2C.
|
||||
@@ -239,7 +243,21 @@ type I2CConfig struct {
|
||||
|
||||
// Configure is intended to setup the I2C interface.
|
||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||
i2cConfigure(i2c.Bus, config.SCL, config.SDA)
|
||||
if i2c.PinsSCL != nil {
|
||||
matchSCL := slices.Index(i2c.PinsSCL, config.SCL) >= 0
|
||||
matchSDA := slices.Index(i2c.PinsSDA, config.SDA) >= 0
|
||||
if !matchSCL && !matchSDA {
|
||||
return errors.New("i2c: SCL and SDA pins are incorrect for this I2C instance")
|
||||
} else if !matchSCL {
|
||||
return errors.New("i2c: SCL pin is incorrect for this I2C instance")
|
||||
} else if !matchSDA {
|
||||
return errors.New("i2c: SDA pin is incorrect for this I2C instance")
|
||||
}
|
||||
}
|
||||
if config.Frequency == 0 {
|
||||
config.Frequency = 100 * KHz
|
||||
}
|
||||
i2cConfigure(i2c.Bus, config.SCL, config.SDA, config.Frequency)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -261,19 +279,29 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
rptr = &r[0]
|
||||
rlen = len(r)
|
||||
}
|
||||
i2cTransfer(i2c.Bus, wptr, wlen, rptr, rlen)
|
||||
// TODO: do something with the returned error code.
|
||||
return nil
|
||||
errCode := i2cTransfer(i2c.Bus, addr, wptr, wlen, rptr, rlen)
|
||||
switch errCode {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return errI2CNoDevices
|
||||
case 2:
|
||||
return errI2CMultipleDevices
|
||||
case 3:
|
||||
return errI2CWrongAddress
|
||||
default:
|
||||
return errI2CBusError // unknown error code
|
||||
}
|
||||
}
|
||||
|
||||
//export __tinygo_i2c_configure
|
||||
func i2cConfigure(bus uint8, scl Pin, sda Pin)
|
||||
func i2cConfigure(bus uint8, scl Pin, sda Pin, frequency uint32)
|
||||
|
||||
//export __tinygo_i2c_set_baud_rate
|
||||
func i2cSetBaudRate(bus uint8, br uint32)
|
||||
|
||||
//export __tinygo_i2c_transfer
|
||||
func i2cTransfer(bus uint8, w *byte, wlen int, r *byte, rlen int) int
|
||||
func i2cTransfer(bus uint8, addr uint16, w *byte, wlen int, r *byte, rlen int) int
|
||||
|
||||
type UART struct {
|
||||
Bus uint8
|
||||
@@ -336,15 +364,6 @@ var (
|
||||
sercomUSART4 = UART{4}
|
||||
sercomUSART5 = UART{5}
|
||||
|
||||
sercomI2CM0 = &I2C{0}
|
||||
sercomI2CM1 = &I2C{1}
|
||||
sercomI2CM2 = &I2C{2}
|
||||
sercomI2CM3 = &I2C{3}
|
||||
sercomI2CM4 = &I2C{4}
|
||||
sercomI2CM5 = &I2C{5}
|
||||
sercomI2CM6 = &I2C{6}
|
||||
sercomI2CM7 = &I2C{7}
|
||||
|
||||
sercomSPIM0 = &SPI{0}
|
||||
sercomSPIM1 = &SPI{1}
|
||||
sercomSPIM2 = &SPI{2}
|
||||
|
||||
Reference in New Issue
Block a user