From c61657d22d15e11532d466f530d4734e6ff39331 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 18 Jan 2020 14:12:55 +0100 Subject: [PATCH] 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. --- src/machine/board_feather-m4.go | 8 +++--- src/machine/board_itsybitsy-m4.go | 8 +++--- src/machine/board_metro-m4-airlift.go | 8 +++--- src/machine/board_pybadge.go | 8 +++--- src/machine/board_pyportal.go | 8 +++--- src/machine/machine_atsamd51.go | 35 +++++++++++++++++++++------ 6 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/machine/board_feather-m4.go b/src/machine/board_feather-m4.go index 71ebcdbf..53ad0fae 100644 --- a/src/machine/board_feather-m4.go +++ b/src/machine/board_feather-m4.go @@ -67,10 +67,10 @@ const ( // I2C on the Feather M4. var ( - I2C0 = I2C{Bus: sam.SERCOM2_I2CM, - SDA: SDA_PIN, - SCL: SCL_PIN, - PinMode: PinSERCOM} + I2C0 = I2C{ + Bus: sam.SERCOM2_I2CM, + SERCOM: 2, + } ) // SPI pins diff --git a/src/machine/board_itsybitsy-m4.go b/src/machine/board_itsybitsy-m4.go index 8483de24..13612f52 100644 --- a/src/machine/board_itsybitsy-m4.go +++ b/src/machine/board_itsybitsy-m4.go @@ -69,10 +69,10 @@ const ( // I2C on the ItsyBitsy M4. var ( - I2C0 = I2C{Bus: sam.SERCOM2_I2CM, - SDA: SDA_PIN, - SCL: SCL_PIN, - PinMode: PinSERCOM} + I2C0 = I2C{ + Bus: sam.SERCOM2_I2CM, + SERCOM: 2, + } ) // SPI pins diff --git a/src/machine/board_metro-m4-airlift.go b/src/machine/board_metro-m4-airlift.go index 09042ac3..49373214 100644 --- a/src/machine/board_metro-m4-airlift.go +++ b/src/machine/board_metro-m4-airlift.go @@ -77,10 +77,10 @@ const ( // I2C on the Metro M4. var ( - I2C0 = I2C{Bus: sam.SERCOM5_I2CM, - SDA: SDA_PIN, - SCL: SCL_PIN, - PinMode: PinSERCOMAlt} + I2C0 = I2C{ + Bus: sam.SERCOM5_I2CM, + SERCOM: 5, + } ) // SPI pins diff --git a/src/machine/board_pybadge.go b/src/machine/board_pybadge.go index 8c134d5c..1d8c30f5 100644 --- a/src/machine/board_pybadge.go +++ b/src/machine/board_pybadge.go @@ -105,10 +105,10 @@ const ( // I2C on the ItsyBitsy M4. var ( - I2C0 = I2C{Bus: sam.SERCOM2_I2CM, - SDA: SDA_PIN, - SCL: SCL_PIN, - PinMode: PinSERCOM} + I2C0 = I2C{ + Bus: sam.SERCOM2_I2CM, + SERCOM: 2, + } ) // SPI pins diff --git a/src/machine/board_pyportal.go b/src/machine/board_pyportal.go index ad3ba7fd..6b48f0d3 100644 --- a/src/machine/board_pyportal.go +++ b/src/machine/board_pyportal.go @@ -118,10 +118,10 @@ const ( // I2C on the PyPortal. var ( - I2C0 = I2C{Bus: sam.SERCOM5_I2CM, - SDA: SDA_PIN, - SCL: SCL_PIN, - PinMode: PinSERCOMAlt} + I2C0 = I2C{ + Bus: sam.SERCOM5_I2CM, + SERCOM: 5, + } ) // SPI pins diff --git a/src/machine/machine_atsamd51.go b/src/machine/machine_atsamd51.go index 22a93e41..d61e9aa4 100644 --- a/src/machine/machine_atsamd51.go +++ b/src/machine/machine_atsamd51.go @@ -799,10 +799,8 @@ func handleSERCOM0_2() { // I2C on the SAMD51. type I2C struct { - Bus *sam.SERCOM_I2CM_Type - SCL Pin - SDA Pin - PinMode PinMode + Bus *sam.SERCOM_I2CM_Type + SERCOM uint8 } // I2CConfig is used to store config info for I2C. @@ -835,12 +833,33 @@ const ( const i2cTimeout = 1000 // 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. if config.Frequency == 0 { 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 i2c.Bus.CTRLA.SetBits(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 - i2c.SDA.Configure(PinConfig{Mode: i2c.PinMode}) - i2c.SCL.Configure(PinConfig{Mode: i2c.PinMode}) + config.SDA.Configure(PinConfig{Mode: sdaPinMode}) + config.SCL.Configure(PinConfig{Mode: sclPinMode}) + + return nil } // SetBaudRate sets the communication speed for the I2C.