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.
Этот коммит содержится в:
Ayke van Laethem 2020-01-18 14:12:55 +01:00 коммит произвёл Ron Evans
родитель 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.