diff --git a/boards/saml21-xpro/Makefile.features b/boards/saml21-xpro/Makefile.features index 87ef69414957cbc31bcb4d5f64f63edba4d59a0a..8f680caccf4d0dfd21397bf9acbc33bdfd1aeada 100644 --- a/boards/saml21-xpro/Makefile.features +++ b/boards/saml21-xpro/Makefile.features @@ -3,6 +3,7 @@ FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_cpuid FEATURES_PROVIDED += periph_flashpage FEATURES_PROVIDED += periph_gpio +FEATURES_PROVIDED += periph_i2c FEATURES_PROVIDED += periph_rtc FEATURES_PROVIDED += periph_rtt FEATURES_PROVIDED += periph_spi diff --git a/boards/saml21-xpro/include/periph_conf.h b/boards/saml21-xpro/include/periph_conf.h index 33f41658d97710eb455be91fe01e865a6e507275..2a06a983989f5dfe187ecd88830048bc3b0f24f6 100644 --- a/boards/saml21-xpro/include/periph_conf.h +++ b/boards/saml21-xpro/include/periph_conf.h @@ -96,7 +96,23 @@ static const spi_conf_t spi_config[] = { * @name I2C configuration * @{ */ -#define I2C_NUMOF (0) +#define I2C_NUMOF (1U) +#define I2C_0_EN 1 +#define I2C_1_EN 0 +#define I2C_2_EN 0 +#define I2C_3_EN 0 +#define I2C_IRQ_PRIO 1 + +#define I2C_0_DEV SERCOM2->I2CM +#define I2C_0_IRQ SERCOM2_IRQn +#define I2C_0_ISR isr_sercom2 +/* I2C 0 GCLK */ +#define I2C_0_GCLK_ID SERCOM2_GCLK_ID_CORE +#define I2C_0_GCLK_ID_SLOW SERCOM2_GCLK_ID_SLOW +/* I2C 0 pin configuration */ +#define I2C_0_SDA GPIO_PIN(PA, 8) +#define I2C_0_SCL GPIO_PIN(PA, 9) +#define I2C_0_MUX GPIO_MUX_D /** @} */ /** diff --git a/cpu/sam0_common/periph/i2c.c b/cpu/sam0_common/periph/i2c.c index a58f53cacb9a0b504d9e100befc92ff6223c4cc8..630c7166b17ed946f1994a98cd84231d3164ce8c 100644 --- a/cpu/sam0_common/periph/i2c.c +++ b/cpu/sam0_common/periph/i2c.c @@ -40,6 +40,10 @@ #define BUSSTATE_OWNER SERCOM_I2CM_STATUS_BUSSTATE(2) #define BUSSTATE_BUSY SERCOM_I2CM_STATUS_BUSSTATE(3) +#if CPU_FAM_SAML21 +#define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER SERCOM_I2CM_CTRLA_MODE(5) +#endif + /* static function definitions */ static void _i2c_poweron(SercomI2cm *sercom); static void _i2c_poweroff(SercomI2cm *sercom); @@ -106,9 +110,23 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed) while (I2CSercom->SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_MASK) {} /* Turn on power manager for sercom */ +#if CPU_FAM_SAML21 + /* OK for SERCOM0-4 */ + MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << (sercom_gclk_id - SERCOM0_GCLK_ID_CORE)); +#else PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << (sercom_gclk_id - GCLK_CLKCTRL_ID_SERCOM0_CORE_Val)); +#endif /* I2C using CLK GEN 0 */ +#if CPU_FAM_SAML21 + GCLK->PCHCTRL[sercom_gclk_id].reg = (GCLK_PCHCTRL_CHEN | + GCLK_PCHCTRL_GEN_GCLK0 ); + while (GCLK->SYNCBUSY.bit.GENCTRL) {} + + GCLK->PCHCTRL[sercom_gclk_id_slow].reg = (GCLK_PCHCTRL_CHEN | + GCLK_PCHCTRL_GEN_GCLK0 ); + while (GCLK->SYNCBUSY.bit.GENCTRL) {} +#else GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(sercom_gclk_id)); @@ -118,6 +136,7 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed) GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(sercom_gclk_id_slow)); while (GCLK->STATUS.bit.SYNCBUSY) {} +#endif /* Check if module is enabled. */