Commit graph zephyr/drivers/adc/adc_stm32.c
Author SHA1 Message Date
Guillaume Gautier
ebc1228ab4 drivers: adc: stm32: improve error message for common sampling times
For ADCs that use a common register for sampling times, improve the error
message when the common registers are already set and can't accept a new
value.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-07-20 08:35:34 -05:00
Marin Jurjević
c97ff35c75 drivers: adc: stm32: fix resetting PCSEL register
To reset channel preselection register (PCSEL), low-level function
LL_ADC_SetChannelPreselection has been used. This function does not clear
any bit as it uses bitwise OR and can only set the bit. Replace this with
stm32_reg_write() to clear whole register with 0.

Signed-off-by: Marin Jurjević <marinjurjevic@outlook.com>
2026-07-17 11:54:39 -04:00
Marin Jurjević
5be85a76fb drivers: adc: stm32: fix channel preselection setup condition
Channel preselection condition uses bitwise operation on raw
register value to check if channel needs setup. Use BIT(channel_id)
macro to extract relevant bit instead of channel.

Signed-off-by: Marin Jurjević <marinjurjevic@outlook.com>
2026-07-17 11:54:39 -04:00
Fabrice DJIATSA
05e3f0a644 drivers: adc: stm32: skip buffer check in stream mode
In streaming mode the application does not supply a buffer in the
adc_sequence; sample data is written into a buffer allocated from the
RTIO mempool inside the ISR. Skip the sequence buffer size validation
in start_read() when CONFIG_ADC_STREAM is enabled, which otherwise
fails with a spurious -ENOMEM "Provided buffer is too small" error.

Signed-off-by: Fabrice DJIATSA <fabrice.djiatsa-ext@st.com>
2026-06-30 11:54:37 -04:00
Basile GRUNER
6c430754bf stm32: adc: Enable ADC differential on STM32N6 SoC series
Change calibration process to handle differential calibration
Configure channel 10 to differential for Nucleo N657X0-Q and
STM32N6570-DK in `adc_api` test
Pin PA10 (Arduino A2) is shared as positive input for channel 11
and negative input for channel 10, allowing to keep default pin
configuration to test single and differential input.

Signed-off-by: Basile GRUNER <basile.gruner@smile.fr>
2026-06-25 06:17:58 -04:00
Guillaume Gautier
8c39353686 drivers: adc: stm32: fix get channel differential
The LL_ADC_GetChannelSingleDiff function to know whether an ADC channel
is configured as differential or single-ended was not used correctly.
This lead to systematically disabling the ADC to reconfigure it, even if
the configuration was already the correct one.

Instead of returning the mode, LL_ADC_GetChannelSingleDiff returns the
channel if it is configured as differential, or 0 if it is single-ended.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-05-06 19:57:55 +02:00
Guillaume Gautier
725e397e90 drivers: adc: stm32: lock adc during setup
If the channel setup function is called while an ADC conversion is
on-going, it can lead the system to hang indefinitely. Prevent this by
adding a locking mechanism on the setup function, similar to what is
done for the read function.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-05-04 21:57:23 +02:00
Guillaume Gautier
0d55eba1b1 drivers: adc: stm32: fix channel 0 setting on stm32h5
On STM32H5, the bit 0 of the Option register of ADC1 controls the channel 0
switch control. It has to be set if either ADC1 or ADC2 wants to use this
channel. Until now, it was enabled only if ADC1 requested channel 0. This
commit fixes this by setting the option bit if channel 0 is used, with no
consideration of the ADC instance.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-04-22 17:14:38 +02:00
Guillaume Gautier
9e10d4a7ca drivers: adc: stm32: fix preselection register for stm32h72x/73x
STM32H72x/73x ADC have a PCSEL_RES0 register instead of PCSEL for other
series.
Make a special case to prevent a compilation error.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-31 13:54:23 -05:00
Guillaume Gautier
e0d3379c07 drivers: adc: stm32: add stm32c5 adc support
Update STM32 ADC driver for STM32C5 and STM32 HAL2.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-24 09:07:31 -04:00
Guillaume Gautier
22b086de60 drivers: adc: stm32: add an error message if calibration is missing
To prevent missing calibration when adding new series, add an error
message if no calibration is done.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-24 09:05:34 -04:00
Guillaume Gautier
1aeb56e8c0 drivers: adc: stm32: add calibration for stm32u3
Calibration for STM32U3 ADC was missing.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-24 09:05:34 -04:00
Guillaume Gautier
eadb255c75 drivers: adc: use the new injected support property in the driver
Use the new has-injected-support property in the Kconfig instead of
filtering on series directly, and use it also in the driver to return an
error if a specific instance doesn't support injected (this is the case
for STM32U5 where ADC1 and 2 support injected, but not ADC4).

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-23 10:37:18 -04:00
Guillaume Gautier
6d664ea6bf drivers: adc: stm32: do not stop conversion unconditionally
In order to write into some ADC registers, it is necessary to have no
on-going conversions (either regular, injected, or both). Until now, each
time such a write was needed, the ADC was disabled unconditionally,
stopping any potential on-going conversion.

With the introduction of the injected mode, this could lead to problems
if for example an injected is configured differently than a running
regular one. In that case it would stop the regular conversion. If the
application is waiting the result before starting another one, it will be
stuck waiting forever.

To avoid cases like this, return an error rather than stopping conversion
and disabling the ADC. This reworks many functions to return an error in
case it was not possible to safely disable the ADC.

It stays possible to force an ADC disable even though a conversion is
running, this is useful at init where we don't want this to fail.

This also creates a dedicated function for the preselection register to
avoid duplication.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-23 10:37:18 -04:00
Guillaume Gautier
a9f59076e0 drivers: adc: stm32: add injected mode support
Add injected mode support for STM32 ADC driver. To avoid potential
conflicts when configuring the ADC registers, some settings (like presel)
are moved into the channel_setup function when injected is enabled.

Also configures an ISR when DMA and injected mode are enabled. The reason
is that DMA is not available for injected sequence, so an ISR is still
necessary in this case.

Factorizes the "start_read_xxx" functions to avoid needless duplication
between sync/async and regular/injected mode.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-23 10:37:18 -04:00
Fabrice DJIATSA
782c47f6bb drivers: adc: stm32: Remove call to LL_ADC_REG_SetContinuousMode
It is unnecessary since it is never set to continuous (and single is the
default value), and causes issues on STM32F1 by starting conversions out
of turn (setting ADON bit while it is already set, without changing
any other bit in the register start a conversion).

Signed-off-by: Fabrice DJIATSA <fabrice.djiatsa-ext@st.com>
2026-03-23 08:48:46 -04:00
Guillaume Gautier
872b423b63 drivers: adc: stm32: add rtio support
Add RTIO support for the STM32 ADC driver to be able to stream data
continuously.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-03-16 12:28:34 +01:00
Mathieu Choplain
a11688fab5 drivers: *: stm32: don't check if clock device is ready
If the clock device (i.e., RCC) failed to initialize, we have bigger
problems than trying to call clock_control_{off,on,configure} on it.
Don't bother checking to save some footprint.

Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
2026-02-13 18:59:16 +00:00
Benedek Kupper
12cd3703eb drivers: adc: stm32: only set CR2/DMA bit once on STM32F1
As reported in #101190, running adc_sequence sample on stm32f103c8 with 8
ADC channels causes all subsequent conversions after the first to be one
channel shifted. This is because writing to CR2 with ADON=1 and no other
changes triggers a conversion (which is why the bug happens on all
but the first sequence). Adding this check will ensure that CR2 is only
written when the DMA bit changes.

Signed-off-by: Benedek Kupper <kupper.benedek@gmail.com>
2026-01-13 15:21:05 +01:00
Guillaume Gautier
c81e2f70fe drivers: adc: stm32: clean up concat macros
Some internal _CONCAT* macros were used throughout the file. Replace them
with the simple CONCAT macro.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-01-08 11:55:35 +00:00
Guillaume Gautier
717d7e8ee0 drivers: adc: stm32: resolution rework
Rework the way to set the STM32 ADC resolution.
Instead of using special macros in device tree, supported resolutions are
now simply listed as an array.

From this array, the driver defines two tables. The first contains the same
values as the array, the second contains the LL macros for each resolution.
When setting the resolution, the driver checks the value with the first
table, then sets it with the second table.

The two tables are defined for each enabled ADC instance so there are no
conflicts if different ADC have different resolutions.

For STM32H7, this changes the internal values used for 14 and 12-bit
resolutions, from 0b101/110 to 0b001/010 respectively, i.e. it uses the
so-called "legacy" resolutions instead of the "power-optimized" ones.
Note that AN5354 indicates: "The optimized modes have better power
consumption figures. The standard modes have better parameters, but
power consumption is not optimized and is comparable to 16-bit mode."

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2026-01-08 11:55:35 +00:00
Gaetan Perrot
4bec0387c8 drivers: adc: adc_stm32: make set_sequencer void
set_sequencer() never reports errors and always returns 0.
The error check at the call site is therefore dead code.

Make the function void and drop the unused error handling.

Signed-off-by: Gaetan Perrot <gaetan.perrot@spacecubics.com>
2026-01-07 07:45:01 +01:00
Sylvio Alves
f8d2e00a0e includes: remove duplicated entries in zephyr-tree
Remove duplicated #include directives within the same
preprocessor scope across the Zephyr tree.

Duplicates inside different #ifdef branches are preserved
as they may be intentional.

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
2025-12-17 13:57:38 -05:00
Guillaume Gautier
cec2702012 drivers: adc: stm32: fix init issue when 2 adc are enabled
If several ADCs are used and share a common clock property (for example
ADC1/2 prescaler value on STM32U5), none of them should be enabled when
the clock is set.
To that end, make sure to disable ADC at the end of the initialization,
it will be enabled later when necessary anyway.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-12-15 17:10:20 +00:00
Mathieu Choplain
c4d884c7ed drivers: adc: stm32: configure proper DMA burst length
The burst length unit is bytes, not number of transfers. This had not been
an issue since the DMA driver historically ignored the values, but has now
become one since they are used and (most importantly for us) validated.

Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
2025-12-04 05:23:02 -05:00
Etienne Carriere
97fc64e812 drivers: adc: stm32: clean instance init macro indentation
Cleanup indentation in ADC_STM32_INIT() macro.

Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
2025-11-14 15:26:17 +02:00
Etienne Carriere
b0ccb2295f drivers: stm32: use STM32_CLOCK_INFO_BY_NAME() and friends
Use STM32_CLOCK_INFO(), STM32_DT_INST_CLOCK_INFO(),
STM32_CLOCK_INFO_BY_NAME() and STM32_DT_INST_CLOCK_INFO_BY_NAME()
helper macros in STM32 drivers.

Using these macros ensure the clock division factor is properly
populated according to DT information. Prior these changes some
drivers only got the bus and bits position information and missed
the clock division information which is fine only when this division
factor information is 0.

Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
2025-11-14 15:26:17 +02:00
Guillaume Gautier
7c4d42b4fd drivers: adc: stm32: add support for rcc prescaler clock
Some series like F1, F3, N6 and U3 use an ADC prescaler defined in the RCC.
Instead of adding specific properties in the RCC driver, use the secondary
clock system to configure the prescaler.

The ADC driver now configures the clocks depending on their presence and
their name. Three clocks can be defined:
- the register clock (mandatory for all series)
- the kernel clock (depends on series)
- the prescaler value (depends on series)

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-24 13:24:44 -04:00
Guillaume Gautier
004c613e25 drivers: stm32: replace MODIFY_REG HAL macro by stm32_reg_modify_bits
For all STM32 drivers and SoC, replace the MODIFY_REG macro (defined in
the STM32 HAL) by stm32_reg_modify_bits defined in Zephyr.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-24 08:58:25 -07:00
Guillaume Gautier
73e9749c68 drivers: stm32: replace SET_BIT HAL macro by stm32_reg_set_bits
For all STM32 drivers, replace the SET_BIT macro (defined in
the STM32 HAL) by stm32_reg_set_bits defined in Zephyr.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-24 08:58:25 -07:00
Guillaume Gautier
625e2acda8 drivers: adc: stm32: Rename sequencer and oversampler and fix macro issue
In STM32 ADC binding, rename the possible values of the sequencer and
oversampler properties to use lowercase string, similar to the internal
regulator.

Adapts the driver and the dtsi with the new values.

Fixes a macro issue in the driver. Since the value from the dtsi didn't
start with internal_regulator_, the reconstruction of the defines by
the macro ANY_ADC_INTERNAL_REGULATOR_TYPE_IS was missing this prefix and
the comparison failed. Add a new argument to the IS_EQ_STRING_PROP to be
able to insert such a prefix.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-16 17:11:12 +03:00
Guillaume Gautier
88735a4aa1 drivers: adc: stm32: remove useless check of internal regulator state
Disabling the internal regulator is immediate so there is no need to check
the state of the Enable bit in the register.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-13 11:27:22 -04:00
Guillaume Gautier
67906ce049 drivers: adc: stm32: use the new differential support property
Use the new differential support property instead of relying on the series
name to determine if the ADC supports differential input channels.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-13 11:27:22 -04:00
Guillaume Gautier
7acd045e62 drivers: adc: stm32: use the new channel preselection property
Use the new channel preselection property instead of relying on the series
name to determine if the ADC channels need to be preselecting.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-13 11:27:22 -04:00
Guillaume Gautier
77be4b72eb drivers: adc: stm32: use the new deep powerdown property
Use the new deep powerdown property instead of relying on the series name
to determine if the ADC needs to be be put out or into deep powerdown mode.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-13 11:27:22 -04:00
Guillaume Gautier
7c719cefd5 drivers: adc: stm32: use the new internal regulator property
Use the new internal regulator property instead of relying on series name
to determine if the regulator should be enabled, and how to check that it
is ready.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-13 11:27:22 -04:00
Guillaume Gautier
a0cadb03c7 drivers: adc: stm32: relies on a ll define rather than series names
For managing the CCRDY flag, rely on the presence of the LL constant
LL_ADC_FLAG_CCRDY rather than a list of series.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-10-13 11:27:22 -04:00
Pisit Sawangvonganan
f05f886a70 drivers: adc: remove '&' when assigning adc_xxx_init
Remove address-of operator ('&') when assigning `adc_xxx_init`
function pointer in `DEVICE_DT_INST_DEFINE` and `DEVICE_DT_DEFINE` macro.

This change aims to maintain consistency among the drivers in
`drivers/adc`, ensuring that all function pointer assignments
follow the same pattern.

Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
2025-10-01 08:22:28 +02:00
Khaoula Bidani
18484fb7a2 drivers: adc: stm32: Add unit check for acquisition_time
Add an explicit check to ensure that the acquisition_time
parameter is encoded with the ADC_ACQ_TIME macro and uses
the TICKS unit, as required by the API.
If the unit is not correct, log an error and return -EINVAL.

Signed-off-by: Khaoula Bidani <khaoula.bidani-ext@st.com>
2025-09-23 12:04:29 -04:00
Keith Packard
469d54e227 drivers/adc/adc_stm32: Check both single-ended and differential defines
The stm32u3x header files defines LL_ADC_SINGLE_ENDED but not
LL_ADC_DIFFERENTIAL as the device doesn't support differential mode. The
driver only checked for LL_ADC_SINGLE_ENDED and assumed that when that was
defined, LL_ADC_DIFFERENTIAL would also be defined.

Check for both when figuring out which calibration type will be required.

Signed-off-by: Keith Packard <keithp@keithp.com>
2025-08-18 22:01:08 +02:00
Matt Rodgers
56621fa1de drivers: adc: stm32: add support for differential mode
Differential mode support consists of:
- If differential mode is supported by the underlying hardware AND at
  least one differential channel is enabled in the devicetree for this
  ADC instance, then perform a differential mode calibration in addition
  to the usual single ended calibration during initialisation.
- Set channels to the appropriate differential or single ended mode
  during channel setup.

Currently the N6 series is not supported even though the underlying
hardware supports differential mode, due to complications in the
calibration procedure.

Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
Co-authored-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-07-21 07:25:30 -04:00
Khaoula Bidani
f568b0d68a drivers: adc: update adc driver to integrate stm32u3
add u3 config_soc conditions in adc driver to handle
news peripherals.

Signed-off-by: Khaoula Bidani <khaoula.bidani-ext@st.com>
2025-06-19 22:27:35 -07:00
Henrik Lindblom
24b4ce189f drivers: stm32: dma: fix external dcache support
Several drivers checked for the presense and availability of data cache
through Kconfig symbol. This is supported according to the current
documentation, but the symbol DCACHE masks two types of cache devices: arch
and external caches. The latter is present on some Cortex-M33 chips, like
the STM32U5xx. The external dcache is bypassed when accessing internal
SRAM and only used for external memories.

In commit a2dd232410 ("drivers: adc: stm32: dma support") the rationale
for gating dcache for adc_stm32 behind STM32H7X is only hinted at, but
reason seems to be that it was the only SOC the change was tested on. The
SOC configures DCACHE=y so it is most likely safe to swap the SOC gate for
DCACHE.

The DCACHE ifdefs are now hidden inside the shared stm32_buf_in_nocache()
implementation.

Signed-off-by: Henrik Lindblom <henrik.lindblom@vaisala.com>
2025-06-06 10:19:58 +02:00
John Bason Mitchell
28c2521926 drivers: adc: disabling timer after DMA eror
The ADC timer should be disabled however the read is finished.

Signed-off-by: John Bason Mitchell <johnbasonmitchell@gmail.com>
2025-04-30 10:55:17 +01:00
Etienne Carriere
bec3a6fc98 drivers: adc: stm32: support DMA when CONFIG_MEM_ATTR=n
Allow STM32 ADC driver to operate with DMA support even when
CONFIG_MEM_ATTR is disabled which happen when CONFIG_ARM_MPU is
intentionally disabled despite the CPU supports MPU.

By the way, remove some #ifdef directive on header files inclusion
that add noise in the header file inclusion section without any
benefit. Also remove inclusion of zephyr/arch/cache.h that is not
needed at all.

Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
2025-04-02 12:54:50 +02:00
Jeppe Odgaard
3a8dddcdad drivers: adc: stm32: use __maybe_unused
Replace conditional `ARG_UNUSED` with `__maybe_unused`. This is recommended
by coding style:
https://kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation

Signed-off-by: Jeppe Odgaard <jeppe.odgaard@prevas.dk>
2025-02-28 14:53:17 +01:00
Guillaume Gautier
a0761d6353 drivers: adc: stm32: configure data size for stm32n6
On STM32N6, the register holding the data is 32 bits and DMA must operate
in word transfer to work properly. So we change the type of the buffer in
which we store the ADC data from uint16_t to uint32_t for N6.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-02-14 10:48:35 +01:00
Guillaume Gautier
a28381f459 drivers: adc: stm32: enable analog supply in dedicated function
Move code to enable the analog supply in a dedicated function.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-02-14 10:48:35 +01:00
Guillaume Gautier
9ee33e990e drivers: adc: stm32: add support for stm32n6 adc
Add support for STM32N6 ADC in the STM32 ADC driver.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2025-02-14 10:48:35 +01:00
Guillaume Gautier
2460e894e4 drivers: adc: stm32: remove unused cast
config->base is already defined as ADC_TypeDef so no there is no need to
cast it as such. Remove all occurrences throughout the file.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
2024-12-18 15:32:35 +01:00