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 Intel Corporation
|
||||||
# Copyright (c) 2019 Endre Karlson
|
# Copyright (c) 2019 Endre Karlson
|
||||||
# Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
|
# Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
|
||||||
|
# Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
config ADC_STM32
|
config ADC_STM32
|
||||||
|
@ -10,3 +11,13 @@ config ADC_STM32
|
||||||
depends on SOC_FAMILY_STM32
|
depends on SOC_FAMILY_STM32
|
||||||
help
|
help
|
||||||
Enable the driver implementation for the stm32xx ADC
|
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 Song Qiang <songqiang1304521@gmail.com>
|
||||||
* Copyright (c) 2019 Endre Karlson
|
* Copyright (c) 2019 Endre Karlson
|
||||||
* Copyright (c) 2020 Teslabs Engineering S.L.
|
* Copyright (c) 2020 Teslabs Engineering S.L.
|
||||||
|
* Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -262,6 +263,10 @@ struct adc_stm32_cfg {
|
||||||
const struct pinctrl_dev_config *pcfg;
|
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,
|
static int check_buffer_size(const struct adc_sequence *sequence,
|
||||||
uint8_t active_channels)
|
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);
|
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,
|
static int adc_stm32_read(const struct device *dev,
|
||||||
|
@ -1048,11 +1053,60 @@ static const struct adc_driver_api api_stm32_driver_api = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define STM32_ADC_INIT(index) \
|
#ifdef CONFIG_ADC_STM32_SHARED_IRQS
|
||||||
\
|
|
||||||
static void adc_stm32_cfg_func_##index(void); \
|
bool adc_stm32_is_irq_active(ADC_TypeDef *adc)
|
||||||
\
|
{
|
||||||
PINCTRL_DT_INST_DEFINE(index); \
|
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 = { \
|
static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \
|
||||||
.base = (ADC_TypeDef *)DT_INST_REG_ADDR(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), \
|
.bus = DT_INST_CLOCKS_CELL(index, bus), \
|
||||||
}, \
|
}, \
|
||||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
|
.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 = { \
|
static struct adc_stm32_data adc_stm32_data_##index = { \
|
||||||
ADC_CONTEXT_INIT_TIMER(adc_stm32_data_##index, ctx), \
|
ADC_CONTEXT_INIT_TIMER(adc_stm32_data_##index, ctx), \
|
||||||
ADC_CONTEXT_INIT_LOCK(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_init, NULL, \
|
||||||
&adc_stm32_data_##index, &adc_stm32_cfg_##index, \
|
&adc_stm32_data_##index, &adc_stm32_cfg_##index, \
|
||||||
POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \
|
POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \
|
||||||
&api_stm32_driver_api); \
|
&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)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(STM32_ADC_INIT)
|
DT_INST_FOREACH_STATUS_OKAY(STM32_ADC_INIT)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017 Linaro Limited
|
* Copyright (c) 2017 Linaro Limited
|
||||||
|
* Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -257,6 +258,26 @@
|
||||||
status = "disabled";
|
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 {
|
dac1: dac@40007400 {
|
||||||
compatible = "st,stm32-dac";
|
compatible = "st,stm32-dac";
|
||||||
reg = <0x40007400 0x400>;
|
reg = <0x40007400 0x400>;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue