machine: refactor pin handling to auto-detect pin mode
With this change, it's no longer necessary to set a specific pin mode: it will get autodetected in the Configure() call. Tested on an ItsyBitsy M4 with the mpu6050 example in the drivers repo.
Этот коммит содержится в:
родитель
4c0ebb5b41
коммит
c61657d22d
6 изменённых файлов: 48 добавлений и 27 удалений
|
@ -67,10 +67,10 @@ const (
|
||||||
|
|
||||||
// I2C on the Feather M4.
|
// I2C on the Feather M4.
|
||||||
var (
|
var (
|
||||||
I2C0 = I2C{Bus: sam.SERCOM2_I2CM,
|
I2C0 = I2C{
|
||||||
SDA: SDA_PIN,
|
Bus: sam.SERCOM2_I2CM,
|
||||||
SCL: SCL_PIN,
|
SERCOM: 2,
|
||||||
PinMode: PinSERCOM}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// SPI pins
|
// SPI pins
|
||||||
|
|
|
@ -69,10 +69,10 @@ const (
|
||||||
|
|
||||||
// I2C on the ItsyBitsy M4.
|
// I2C on the ItsyBitsy M4.
|
||||||
var (
|
var (
|
||||||
I2C0 = I2C{Bus: sam.SERCOM2_I2CM,
|
I2C0 = I2C{
|
||||||
SDA: SDA_PIN,
|
Bus: sam.SERCOM2_I2CM,
|
||||||
SCL: SCL_PIN,
|
SERCOM: 2,
|
||||||
PinMode: PinSERCOM}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// SPI pins
|
// SPI pins
|
||||||
|
|
|
@ -77,10 +77,10 @@ const (
|
||||||
|
|
||||||
// I2C on the Metro M4.
|
// I2C on the Metro M4.
|
||||||
var (
|
var (
|
||||||
I2C0 = I2C{Bus: sam.SERCOM5_I2CM,
|
I2C0 = I2C{
|
||||||
SDA: SDA_PIN,
|
Bus: sam.SERCOM5_I2CM,
|
||||||
SCL: SCL_PIN,
|
SERCOM: 5,
|
||||||
PinMode: PinSERCOMAlt}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// SPI pins
|
// SPI pins
|
||||||
|
|
|
@ -105,10 +105,10 @@ const (
|
||||||
|
|
||||||
// I2C on the ItsyBitsy M4.
|
// I2C on the ItsyBitsy M4.
|
||||||
var (
|
var (
|
||||||
I2C0 = I2C{Bus: sam.SERCOM2_I2CM,
|
I2C0 = I2C{
|
||||||
SDA: SDA_PIN,
|
Bus: sam.SERCOM2_I2CM,
|
||||||
SCL: SCL_PIN,
|
SERCOM: 2,
|
||||||
PinMode: PinSERCOM}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// SPI pins
|
// SPI pins
|
||||||
|
|
|
@ -118,10 +118,10 @@ const (
|
||||||
|
|
||||||
// I2C on the PyPortal.
|
// I2C on the PyPortal.
|
||||||
var (
|
var (
|
||||||
I2C0 = I2C{Bus: sam.SERCOM5_I2CM,
|
I2C0 = I2C{
|
||||||
SDA: SDA_PIN,
|
Bus: sam.SERCOM5_I2CM,
|
||||||
SCL: SCL_PIN,
|
SERCOM: 5,
|
||||||
PinMode: PinSERCOMAlt}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// SPI pins
|
// SPI pins
|
||||||
|
|
|
@ -800,9 +800,7 @@ func handleSERCOM0_2() {
|
||||||
// I2C on the SAMD51.
|
// I2C on the SAMD51.
|
||||||
type I2C struct {
|
type I2C struct {
|
||||||
Bus *sam.SERCOM_I2CM_Type
|
Bus *sam.SERCOM_I2CM_Type
|
||||||
SCL Pin
|
SERCOM uint8
|
||||||
SDA Pin
|
|
||||||
PinMode PinMode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// I2CConfig is used to store config info for I2C.
|
// I2CConfig is used to store config info for I2C.
|
||||||
|
@ -835,12 +833,33 @@ const (
|
||||||
const i2cTimeout = 1000
|
const i2cTimeout = 1000
|
||||||
|
|
||||||
// Configure is intended to setup the I2C interface.
|
// Configure is intended to setup the I2C interface.
|
||||||
func (i2c I2C) Configure(config I2CConfig) {
|
func (i2c I2C) Configure(config I2CConfig) error {
|
||||||
// Default I2C bus speed is 100 kHz.
|
// Default I2C bus speed is 100 kHz.
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = TWI_FREQ_100KHZ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use default I2C pins if not set.
|
||||||
|
if config.SDA == 0 && config.SCL == 0 {
|
||||||
|
config.SDA = SDA_PIN
|
||||||
|
config.SCL = SCL_PIN
|
||||||
|
}
|
||||||
|
|
||||||
|
sclPinMode, sclPad, ok := findPinPadMapping(i2c.SERCOM, config.SCL)
|
||||||
|
if !ok || sclPad != 1 {
|
||||||
|
// SCL must be on pad 1, according to section 36.4 of the datasheet.
|
||||||
|
// Note: this is not an exhaustive test for I2C support on the pin: not
|
||||||
|
// all pins support I2C.
|
||||||
|
return ErrInvalidClockPin
|
||||||
|
}
|
||||||
|
sdaPinMode, sdaPad, ok := findPinPadMapping(i2c.SERCOM, config.SDA)
|
||||||
|
if !ok || sdaPad != 0 {
|
||||||
|
// SDA must be on pad 0, according to section 36.4 of the datasheet.
|
||||||
|
// Note: this is not an exhaustive test for I2C support on the pin: not
|
||||||
|
// all pins support I2C.
|
||||||
|
return ErrInvalidDataPin
|
||||||
|
}
|
||||||
|
|
||||||
// reset SERCOM
|
// reset SERCOM
|
||||||
i2c.Bus.CTRLA.SetBits(sam.SERCOM_I2CM_CTRLA_SWRST)
|
i2c.Bus.CTRLA.SetBits(sam.SERCOM_I2CM_CTRLA_SWRST)
|
||||||
for i2c.Bus.CTRLA.HasBits(sam.SERCOM_I2CM_CTRLA_SWRST) ||
|
for i2c.Bus.CTRLA.HasBits(sam.SERCOM_I2CM_CTRLA_SWRST) ||
|
||||||
|
@ -866,8 +885,10 @@ func (i2c I2C) Configure(config I2CConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable pins
|
// enable pins
|
||||||
i2c.SDA.Configure(PinConfig{Mode: i2c.PinMode})
|
config.SDA.Configure(PinConfig{Mode: sdaPinMode})
|
||||||
i2c.SCL.Configure(PinConfig{Mode: i2c.PinMode})
|
config.SCL.Configure(PinConfig{Mode: sclPinMode})
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBaudRate sets the communication speed for the I2C.
|
// SetBaudRate sets the communication speed for the I2C.
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче