/* Attach and start I2C as slave */ int i2c_stm32_slave_register(struct device *dev, struct i2c_slave_config *config) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); struct i2c_stm32_data *data = DEV_DATA(dev); I2C_TypeDef *i2c = cfg->i2c; u32_t bitrate_cfg; int ret; if (!config) { return -EINVAL; } if (data->slave_attached) { return -EBUSY; } if (data->master_active) { return -EBUSY; } bitrate_cfg = _i2c_map_dt_bitrate(cfg->bitrate); ret = i2c_stm32_runtime_configure(dev, bitrate_cfg); if (ret < 0) { SYS_LOG_ERR("i2c: failure initializing"); return ret; } data->slave_cfg = config; LL_I2C_Enable(i2c); LL_I2C_SetOwnAddress1(i2c, config->address << 1, LL_I2C_OWNADDRESS1_7BIT); LL_I2C_EnableOwnAddress1(i2c); data->slave_attached = true; SYS_LOG_DBG("i2c: slave registered"); LL_I2C_EnableIT_ADDR(i2c); return 0; }
static int i2c_stm32_init(struct device *dev) { struct device *clock = device_get_binding(STM32_CLOCK_CONTROL_NAME); const struct i2c_stm32_config *cfg = DEV_CFG(dev); u32_t bitrate_cfg; int ret; struct i2c_stm32_data *data = DEV_DATA(dev); #ifdef CONFIG_I2C_STM32_INTERRUPT k_sem_init(&data->device_sync_sem, 0, UINT_MAX); cfg->irq_config_func(dev); #endif /* * initialize mutex used when multiple transfers * are taking place to guarantee that each one is * atomic and has exclusive access to the I2C bus. */ k_sem_init(&data->bus_mutex, 1, 1); __ASSERT_NO_MSG(clock); if (clock_control_on(clock, (clock_control_subsys_t *) &cfg->pclken) != 0) { LOG_ERR("i2c: failure enabling clock"); return -EIO; } #if defined(CONFIG_SOC_SERIES_STM32F3X) || defined(CONFIG_SOC_SERIES_STM32F0X) /* * STM32F0/3 I2C's independent clock source supports only * HSI and SYSCLK, not APB1. We force I2C clock source to SYSCLK. * I2C2 on STM32F0 uses APB1 clock as I2C clock source */ switch ((u32_t)cfg->i2c) { #ifdef CONFIG_I2C_1 case DT_I2C_1_BASE_ADDRESS: LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_SYSCLK); break; #endif /* CONFIG_I2C_1 */ #if defined(CONFIG_SOC_SERIES_STM32F3X) && defined(CONFIG_I2C_2) case DT_I2C_2_BASE_ADDRESS: LL_RCC_SetI2CClockSource(LL_RCC_I2C2_CLKSOURCE_SYSCLK); break; #endif /* CONFIG_SOC_SERIES_STM32F3X && CONFIG_I2C_2 */ #ifdef CONFIG_I2C_3 case DT_I2C_3_BASE_ADDRESS: LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_SYSCLK); break; #endif /* CONFIG_I2C_3 */ } #endif /* CONFIG_SOC_SERIES_STM32F3X) || CONFIG_SOC_SERIES_STM32F0X */ bitrate_cfg = _i2c_map_dt_bitrate(cfg->bitrate); ret = i2c_stm32_runtime_configure(dev, I2C_MODE_MASTER | bitrate_cfg); if (ret < 0) { LOG_ERR("i2c: failure initializing"); return ret; } return 0; }