drivers: arm: stm32: adc: Added Shared IRQ
Certain stm32 soc's have a single shared irq for all adc channels on those soc's only a single channel is supported. Added a Kconfig that enables a shared irq for stm32f2x, stm32f4x, stm32f7x soc's. The shared IRQ uses a flag to limit the number of interrupts defined to only 1. A shared irq handler is added which determines which ADC instance the interrupt is for, it then calls into the existing interrupt. Signed-off-by: Marius Scholtz <mariuss@ricelectronics.com>
This commit is contained in:
parent
412c051fbf
commit
14e15df00f
3 changed files with 102 additions and 16 deletions
|
@ -3,6 +3,7 @@
|
|||
# Copyright (c) 2019 Intel Corporation
|
||||
# Copyright (c) 2019 Endre Karlson
|
||||
# Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
|
||||
# Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config ADC_STM32
|
||||
|
@ -10,3 +11,13 @@ config ADC_STM32
|
|||
depends on SOC_FAMILY_STM32
|
||||
help
|
||||
Enable the driver implementation for the stm32xx ADC
|
||||
|
||||
if SOC_SERIES_STM32F2X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
|
||||
|
||||
config ADC_STM32_SHARED_IRQS
|
||||
bool "STM32 ADC shared interrupts"
|
||||
default y
|
||||
depends on ADC_STM32
|
||||
help
|
||||
Enable the use of shared interrupts for families that only have a single interrupt for all ADC's
|
||||
endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
|
||||
* Copyright (c) 2019 Endre Karlson
|
||||
* Copyright (c) 2020 Teslabs Engineering S.L.
|
||||
* Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -262,6 +263,10 @@ struct adc_stm32_cfg {
|
|||
const struct pinctrl_dev_config *pcfg;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ADC_STM32_SHARED_IRQS
|
||||
static bool init_irq = true;
|
||||
#endif
|
||||
|
||||
static int check_buffer_size(const struct adc_sequence *sequence,
|
||||
uint8_t active_channels)
|
||||
{
|
||||
|
@ -666,7 +671,7 @@ static void adc_stm32_isr(const struct device *dev)
|
|||
|
||||
adc_context_on_sampling_done(&data->ctx, dev);
|
||||
|
||||
LOG_DBG("ISR triggered.");
|
||||
LOG_DBG("%s ISR triggered.", dev->name);
|
||||
}
|
||||
|
||||
static int adc_stm32_read(const struct device *dev,
|
||||
|
@ -1048,11 +1053,60 @@ static const struct adc_driver_api api_stm32_driver_api = {
|
|||
#endif
|
||||
};
|
||||
|
||||
#define STM32_ADC_INIT(index) \
|
||||
\
|
||||
static void adc_stm32_cfg_func_##index(void); \
|
||||
\
|
||||
PINCTRL_DT_INST_DEFINE(index); \
|
||||
#ifdef CONFIG_ADC_STM32_SHARED_IRQS
|
||||
|
||||
bool adc_stm32_is_irq_active(ADC_TypeDef *adc)
|
||||
{
|
||||
return LL_ADC_IsActiveFlag_EOCS(adc) ||
|
||||
LL_ADC_IsActiveFlag_OVR(adc) ||
|
||||
LL_ADC_IsActiveFlag_JEOS(adc) ||
|
||||
LL_ADC_IsActiveFlag_AWD1(adc);
|
||||
}
|
||||
|
||||
#define HANDLE_IRQS(index) \
|
||||
static const struct device *dev_##index = DEVICE_DT_INST_GET(index); \
|
||||
const struct adc_stm32_cfg *cfg_##index = dev_##index->config; \
|
||||
ADC_TypeDef *adc_##index = (ADC_TypeDef *)(cfg_##index->base); \
|
||||
\
|
||||
if (adc_stm32_is_irq_active(adc_##index)) { \
|
||||
adc_stm32_isr(dev_##index); \
|
||||
}
|
||||
|
||||
static void adc_stm32_shared_irq_handler(void)
|
||||
{
|
||||
DT_INST_FOREACH_STATUS_OKAY(HANDLE_IRQS);
|
||||
}
|
||||
|
||||
static void adc_stm32_irq_init(void)
|
||||
{
|
||||
if (init_irq) {
|
||||
init_irq = false;
|
||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||
DT_INST_IRQ(0, priority),
|
||||
adc_stm32_shared_irq_handler, NULL, 0);
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
}
|
||||
}
|
||||
|
||||
#define ADC_STM32_CONFIG(index) \
|
||||
static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \
|
||||
.base = (ADC_TypeDef *)DT_INST_REG_ADDR(index), \
|
||||
.irq_cfg_func = adc_stm32_irq_init, \
|
||||
.pclken = { \
|
||||
.enr = DT_INST_CLOCKS_CELL(index, bits), \
|
||||
.bus = DT_INST_CLOCKS_CELL(index, bus), \
|
||||
}, \
|
||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
|
||||
};
|
||||
#else
|
||||
#define ADC_STM32_CONFIG(index) \
|
||||
static void adc_stm32_cfg_func_##index(void) \
|
||||
{ \
|
||||
IRQ_CONNECT(DT_INST_IRQN(index), \
|
||||
DT_INST_IRQ(index, priority), \
|
||||
adc_stm32_isr, DEVICE_DT_INST_GET(index), 0); \
|
||||
irq_enable(DT_INST_IRQN(index)); \
|
||||
} \
|
||||
\
|
||||
static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \
|
||||
.base = (ADC_TypeDef *)DT_INST_REG_ADDR(index), \
|
||||
|
@ -1062,7 +1116,15 @@ static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \
|
|||
.bus = DT_INST_CLOCKS_CELL(index, bus), \
|
||||
}, \
|
||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
|
||||
}; \
|
||||
};
|
||||
#endif /* CONFIG_ADC_STM32_SHARED_IRQS */
|
||||
|
||||
#define STM32_ADC_INIT(index) \
|
||||
\
|
||||
PINCTRL_DT_INST_DEFINE(index); \
|
||||
\
|
||||
ADC_STM32_CONFIG(index) \
|
||||
\
|
||||
static struct adc_stm32_data adc_stm32_data_##index = { \
|
||||
ADC_CONTEXT_INIT_TIMER(adc_stm32_data_##index, ctx), \
|
||||
ADC_CONTEXT_INIT_LOCK(adc_stm32_data_##index, ctx), \
|
||||
|
@ -1073,14 +1135,6 @@ DEVICE_DT_INST_DEFINE(index, \
|
|||
&adc_stm32_init, NULL, \
|
||||
&adc_stm32_data_##index, &adc_stm32_cfg_##index, \
|
||||
POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \
|
||||
&api_stm32_driver_api); \
|
||||
\
|
||||
static void adc_stm32_cfg_func_##index(void) \
|
||||
{ \
|
||||
IRQ_CONNECT(DT_INST_IRQN(index), \
|
||||
DT_INST_IRQ(index, priority), \
|
||||
adc_stm32_isr, DEVICE_DT_INST_GET(index), 0); \
|
||||
irq_enable(DT_INST_IRQN(index)); \
|
||||
}
|
||||
&api_stm32_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(STM32_ADC_INIT)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Linaro Limited
|
||||
* Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -257,6 +258,26 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
adc2: adc@40012100 {
|
||||
compatible = "st,stm32-adc";
|
||||
reg = <0x40012100 0x050>;
|
||||
clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00000200>;
|
||||
interrupts = <18 0>;
|
||||
status = "disabled";
|
||||
label = "ADC_2";
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
|
||||
adc3: adc@40012200 {
|
||||
compatible = "st,stm32-adc";
|
||||
reg = <0x40012200 0x050>;
|
||||
clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00000400>;
|
||||
interrupts = <18 0>;
|
||||
status = "disabled";
|
||||
label = "ADC_3";
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
|
||||
dac1: dac@40007400 {
|
||||
compatible = "st,stm32-dac";
|
||||
reg = <0x40007400 0x400>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue