i2c: stm32_ll: add support for STM32F0 with combined irq

The STM32F0 has only a single IRQ line, add a combined IRQ handler.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
This commit is contained in:
Neil Armstrong 2017-11-30 11:02:38 +01:00 committed by Kumar Gala
commit 59d33b5f27
4 changed files with 47 additions and 6 deletions

View file

@ -114,14 +114,14 @@ config I2C_STM32_V1
driver also supports the F2 and L1 series.
config I2C_STM32_V2
bool "STM32 V2 Driver (F3/L4X)"
bool "STM32 V2 Driver (F0/F3/L4X)"
depends on SOC_FAMILY_STM32
depends on SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X
depends on SOC_SERIES_STM32F0X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X
select HAS_DTS_I2C
default n
help
Enable I2C support on the STM32 F3 and L4X family of processors. This
driver also supports the F0, F7 and L0 series.
Enable I2C support on the STM32 F0, F3 and L4X family of processors.
This driver also supports the F7 and L0 series.
config I2C_STM32_INTERRUPT
bool "STM32 MCU I2C Interrupt Support"
@ -130,6 +130,11 @@ config I2C_STM32_INTERRUPT
help
Enable Interrupt support for the I2C Driver
config I2C_STM32_COMBINED_INTERRUPT
bool
depends on I2C_STM32_INTERRUPT
default y if SOC_SERIES_STM32F0X
config I2C_BITBANG
bool
default n

View file

@ -142,6 +142,7 @@ static int i2c_stm32_init(struct device *dev)
/*
* 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) {
@ -151,11 +152,11 @@ static int i2c_stm32_init(struct device *dev)
break;
#endif /* CONFIG_I2C_1 */
#ifdef CONFIG_I2C_2
#if defined(CONFIG_SOC_SERIES_STM32F3X) && defined(CONFIG_I2C_2)
case CONFIG_I2C_2_BASE_ADDRESS:
LL_RCC_SetI2CClockSource(LL_RCC_I2C2_CLKSOURCE_SYSCLK);
break;
#endif /* CONFIG_I2C_2 */
#endif /* CONFIG_SOC_SERIES_STM32F3X && CONFIG_I2C_2 */
#ifdef CONFIG_I2C_3
case CONFIG_I2C_3_BASE_ADDRESS:
@ -204,6 +205,11 @@ DEVICE_AND_API_INIT(i2c_stm32_1, CONFIG_I2C_1_NAME, &i2c_stm32_init,
#ifdef CONFIG_I2C_STM32_INTERRUPT
static void i2c_stm32_irq_config_func_1(struct device *dev)
{
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
IRQ_CONNECT(CONFIG_I2C_1_COMBINED_IRQ, CONFIG_I2C_1_COMBINED_IRQ_PRI,
stm32_i2c_combined_isr, DEVICE_GET(i2c_stm32_1), 0);
irq_enable(CONFIG_I2C_1_COMBINED_IRQ);
#else
IRQ_CONNECT(CONFIG_I2C_1_EVENT_IRQ, CONFIG_I2C_1_EVENT_IRQ_PRI,
stm32_i2c_event_isr, DEVICE_GET(i2c_stm32_1), 0);
irq_enable(CONFIG_I2C_1_EVENT_IRQ);
@ -211,6 +217,7 @@ static void i2c_stm32_irq_config_func_1(struct device *dev)
IRQ_CONNECT(CONFIG_I2C_1_ERROR_IRQ, CONFIG_I2C_1_ERROR_IRQ_PRI,
stm32_i2c_error_isr, DEVICE_GET(i2c_stm32_1), 0);
irq_enable(CONFIG_I2C_1_ERROR_IRQ);
#endif
}
#endif
@ -244,6 +251,11 @@ DEVICE_AND_API_INIT(i2c_stm32_2, CONFIG_I2C_2_NAME, &i2c_stm32_init,
#ifdef CONFIG_I2C_STM32_INTERRUPT
static void i2c_stm32_irq_config_func_2(struct device *dev)
{
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
IRQ_CONNECT(CONFIG_I2C_2_COMBINED_IRQ, CONFIG_I2C_2_COMBINED_IRQ_PRI,
stm32_i2c_combined_isr, DEVICE_GET(i2c_stm32_2), 0);
irq_enable(CONFIG_I2C_2_COMBINED_IRQ);
#else
IRQ_CONNECT(CONFIG_I2C_2_EVENT_IRQ, CONFIG_I2C_2_EVENT_IRQ_PRI,
stm32_i2c_event_isr, DEVICE_GET(i2c_stm32_2), 0);
irq_enable(CONFIG_I2C_2_EVENT_IRQ);
@ -251,6 +263,7 @@ static void i2c_stm32_irq_config_func_2(struct device *dev)
IRQ_CONNECT(CONFIG_I2C_2_ERROR_IRQ, CONFIG_I2C_2_ERROR_IRQ_PRI,
stm32_i2c_error_isr, DEVICE_GET(i2c_stm32_2), 0);
irq_enable(CONFIG_I2C_2_ERROR_IRQ);
#endif
}
#endif

View file

@ -50,6 +50,9 @@ s32_t stm32_i2c_configure_timing(struct device *dev, u32_t clk);
void stm32_i2c_event_isr(void *arg);
void stm32_i2c_error_isr(void *arg);
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
void stm32_i2c_combined_isr(void *arg);
#endif
#define DEV_DATA(dev) ((struct i2c_stm32_data * const)(dev)->driver_data)
#define DEV_CFG(dev) \

View file

@ -120,6 +120,7 @@ error:
k_sem_give(&data->device_sync_sem);
}
#ifndef CONFIG_I2C_STM32_COMBINED_INTERRUPT
void stm32_i2c_error_isr(void *arg)
{
const struct i2c_stm32_config *cfg = DEV_CFG((struct device *)arg);
@ -135,6 +136,25 @@ void stm32_i2c_error_isr(void *arg)
k_sem_give(&data->device_sync_sem);
}
#endif
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
void stm32_i2c_combined_isr(void *arg)
{
const struct i2c_stm32_config *cfg = DEV_CFG((struct device *)arg);
struct i2c_stm32_data *data = DEV_DATA((struct device *)arg);
I2C_TypeDef *i2c = cfg->i2c;
if (LL_I2C_IsActiveFlag_NACK(i2c)) {
LL_I2C_ClearFlag_NACK(i2c);
data->current.is_nack = 1;
k_sem_give(&data->device_sync_sem);
} else {
stm32_i2c_event_isr(arg);
}
}
#endif
int stm32_i2c_msg_write(struct device *dev, struct i2c_msg *msg,
u8_t *next_msg_flags, uint16_t slave)