summaryrefslogtreecommitdiffstats
path: root/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c')
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c749
1 files changed, 545 insertions, 204 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c
index 9193a2665f..c2b31715c4 100644
--- a/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c
@@ -3,28 +3,32 @@
* @file stm32h7xx_hal_adc.c
* @author MCD Application Team
* @brief This file provides firmware functions to manage the following
- * functionalities of the Analog to Digital Convertor (ADC)
+ * functionalities of the Analog to Digital Converter (ADC)
* peripheral:
- * + Initialization and de-initialization functions
- * ++ Initialization and Configuration of ADC
- * + Operation functions
- * ++ Start, stop, get result of conversions of regular
- * group, using 3 possible modes: polling, interruption or DMA.
- * + Control functions
- * ++ Channels configuration on regular group
- * ++ Analog Watchdog configuration
- * + State functions
- * ++ ADC state machine management
- * ++ Interrupts and flags management
+ * + Peripheral Control functions
+ * + Peripheral State functions
* Other functions (extended functions) are available in file
* "stm32h7xx_hal_adc_ex.c".
*
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
@verbatim
==============================================================================
##### ADC peripheral features #####
==============================================================================
[..]
(+) 16-bit, 14-bit, 12-bit, 10-bit or 8-bit configurable resolution.
+ Note: On devices STM32H72xx and STM32H73xx, these resolution are applicable to instances ADC1 and ADC2.
+ ADC3 is featuring resolutions 12-bit, 10-bit, 8-bit, 6-bit.
(+) Interrupt generation at the end of regular conversion and in case of
analog watchdog or overrun events.
@@ -219,11 +223,11 @@
The compilation flag USE_HAL_ADC_REGISTER_CALLBACKS, when set to 1,
allows the user to configure dynamically the driver callbacks.
- Use Functions @ref HAL_ADC_RegisterCallback()
+ Use Functions HAL_ADC_RegisterCallback()
to register an interrupt callback.
[..]
- Function @ref HAL_ADC_RegisterCallback() allows to register following callbacks:
+ Function HAL_ADC_RegisterCallback() allows to register following callbacks:
(+) ConvCpltCallback : ADC conversion complete callback
(+) ConvHalfCpltCallback : ADC conversion DMA half-transfer callback
(+) LevelOutOfWindowCallback : ADC analog watchdog 1 callback
@@ -239,11 +243,11 @@
and a pointer to the user callback function.
[..]
- Use function @ref HAL_ADC_UnRegisterCallback to reset a callback to the default
+ Use function HAL_ADC_UnRegisterCallback to reset a callback to the default
weak function.
[..]
- @ref HAL_ADC_UnRegisterCallback takes as parameters the HAL peripheral handle,
+ HAL_ADC_UnRegisterCallback takes as parameters the HAL peripheral handle,
and the Callback ID.
This function allows to reset following callbacks:
(+) ConvCpltCallback : ADC conversion complete callback
@@ -259,27 +263,27 @@
(+) MspDeInitCallback : ADC Msp DeInit callback
[..]
- By default, after the @ref HAL_ADC_Init() and when the state is @ref HAL_ADC_STATE_RESET
+ By default, after the HAL_ADC_Init() and when the state is HAL_ADC_STATE_RESET
all callbacks are set to the corresponding weak functions:
- examples @ref HAL_ADC_ConvCpltCallback(), @ref HAL_ADC_ErrorCallback().
+ examples HAL_ADC_ConvCpltCallback(), HAL_ADC_ErrorCallback().
Exception done for MspInit and MspDeInit functions that are
- reset to the legacy weak functions in the @ref HAL_ADC_Init()/ @ref HAL_ADC_DeInit() only when
+ reset to the legacy weak functions in the HAL_ADC_Init()/ HAL_ADC_DeInit() only when
these callbacks are null (not registered beforehand).
[..]
- If MspInit or MspDeInit are not null, the @ref HAL_ADC_Init()/ @ref HAL_ADC_DeInit()
+ If MspInit or MspDeInit are not null, the HAL_ADC_Init()/ HAL_ADC_DeInit()
keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
[..]
- Callbacks can be registered/unregistered in @ref HAL_ADC_STATE_READY state only.
+ Callbacks can be registered/unregistered in HAL_ADC_STATE_READY state only.
Exception done MspInit/MspDeInit functions that can be registered/unregistered
- in @ref HAL_ADC_STATE_READY or @ref HAL_ADC_STATE_RESET state,
+ in HAL_ADC_STATE_READY or HAL_ADC_STATE_RESET state,
thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
[..]
Then, the user first registers the MspInit/MspDeInit user callbacks
- using @ref HAL_ADC_RegisterCallback() before calling @ref HAL_ADC_DeInit()
- or @ref HAL_ADC_Init() function.
+ using HAL_ADC_RegisterCallback() before calling HAL_ADC_DeInit()
+ or HAL_ADC_Init() function.
[..]
When the compilation flag USE_HAL_ADC_REGISTER_CALLBACKS is set to 0 or
@@ -288,17 +292,6 @@
@endverbatim
******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
@@ -329,6 +322,14 @@
ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL)) /*!< ADC_CFGR fields of parameters that can be updated
when no regular conversion is on-going */
+#if defined(ADC_VER_V5_V90)
+#define ADC3_CFGR_FIELDS_1 ((ADC3_CFGR_RES | ADC3_CFGR_ALIGN |\
+ ADC_CFGR_CONT | ADC_CFGR_OVRMOD |\
+ ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM |\
+ ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL)) /*!< ADC_CFGR fields of parameters that can be updated
+ when no regular conversion is on-going */
+#endif
+
#define ADC_CFGR2_FIELDS ((uint32_t)(ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR |\
ADC_CFGR2_OVSS | ADC_CFGR2_TROVS |\
ADC_CFGR2_ROVSM)) /*!< ADC_CFGR2 fields of parameters that can be updated when no conversion
@@ -348,7 +349,7 @@
/* - ADC clock with prescaler 256 */
/* 823 * 256 = 210688 clock cycles max */
/* Unit: cycles of CPU clock. */
-#define ADC_CONVERSION_TIME_MAX_CPU_CYCLES ((uint32_t) 210688) /*!< ADC conversion completion time-out value */
+#define ADC_CONVERSION_TIME_MAX_CPU_CYCLES (210688UL) /*!< ADC conversion completion time-out value */
/**
* @}
@@ -504,7 +505,7 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles, scaling in us split to not */
/* exceed 32 bits register capacity and handle low frequency. */
- wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
+ wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
while (wait_loop_index != 0UL)
{
wait_loop_index--;
@@ -579,26 +580,46 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
/* - discontinuous mode Init.DiscontinuousConvMode */
/* - discontinuous mode channel count Init.NbrOfDiscConversion */
#if defined(ADC_VER_V5_3)
+
+ tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
+ hadc->Init.Overrun |
+ hadc->Init.Resolution |
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode));
+
+#elif defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
+ hadc->Init.Overrun |
+ hadc->Init.DataAlign |
+ ((__LL_ADC12_RESOLUTION_TO_ADC3(hadc->Init.Resolution) & (ADC_CFGR_RES_1 | ADC_CFGR_RES_0)) << 1UL) |
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode));
+ }
+ else
+ {
tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
hadc->Init.Overrun |
hadc->Init.Resolution |
- ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode) );
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode));
+ }
#else
- if((HAL_GetREVID() > REV_ID_Y) && (ADC_RESOLUTION_8B == hadc->Init.Resolution))
+
+ if ((HAL_GetREVID() > REV_ID_Y) && (ADC_RESOLUTION_8B == hadc->Init.Resolution))
{
/* for STM32H7 silicon rev.B and above , ADC_CFGR_RES value for 8bits resolution is : b111 */
tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
hadc->Init.Overrun |
- hadc->Init.Resolution |(ADC_CFGR_RES_1|ADC_CFGR_RES_0) |
- ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode) );
+ hadc->Init.Resolution | (ADC_CFGR_RES_1 | ADC_CFGR_RES_0) |
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode));
}
else
{
+
tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
hadc->Init.Overrun |
hadc->Init.Resolution |
- ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode) );
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode));
}
#endif /* ADC_VER_V5_3 */
@@ -620,8 +641,24 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
);
}
+
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ /* Update Configuration Register CFGR */
+ MODIFY_REG(hadc->Instance->CFGR, ADC3_CFGR_FIELDS_1, tmpCFGR);
+ /* Configuration of sampling mode */
+ MODIFY_REG(hadc->Instance->CFGR2, ADC3_CFGR2_BULB | ADC3_CFGR2_SMPTRIG, hadc->Init.SamplingMode);
+ }
+ else
+ {
+ /* Update Configuration Register CFGR */
+ MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_1, tmpCFGR);
+ }
+#else
/* Update Configuration Register CFGR */
MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_1, tmpCFGR);
+#endif
/* Parameters update conditioned to ADC state: */
/* Parameters that can be updated when ADC is disabled or enabled without */
@@ -635,38 +672,102 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
&& (tmp_adc_is_conversion_on_going_injected == 0UL)
)
{
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ tmpCFGR = (
+ ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) |
+ ADC3_CFGR_DMACONTREQ((uint32_t)hadc->Init.DMAContinuousRequests));
+ }
+ else
+ {
+ tmpCFGR = (
+ ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) |
+ ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.ConversionDataManagement));
+ }
+#else
tmpCFGR = (
- ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) |
- ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.ConversionDataManagement));
+ ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) |
+ ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.ConversionDataManagement));
+#endif
MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_2, tmpCFGR);
if (hadc->Init.OversamplingMode == ENABLE)
{
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ assert_param(IS_ADC_OVERSAMPLING_RATIO_ADC3(hadc->Init.Oversampling.Ratio));
+ }
+ else
+ {
+ assert_param(IS_ADC_OVERSAMPLING_RATIO(hadc->Init.Oversampling.Ratio));
+ }
+#else
assert_param(IS_ADC_OVERSAMPLING_RATIO(hadc->Init.Oversampling.Ratio));
+#endif
assert_param(IS_ADC_RIGHT_BIT_SHIFT(hadc->Init.Oversampling.RightBitShift));
assert_param(IS_ADC_TRIGGERED_OVERSAMPLING_MODE(hadc->Init.Oversampling.TriggeredMode));
assert_param(IS_ADC_REGOVERSAMPLING_MODE(hadc->Init.Oversampling.OversamplingStopReset));
- if ((hadc->Init.ExternalTrigConv == ADC_SOFTWARE_START)
+ if ((hadc->Init.ExternalTrigConv == ADC_SOFTWARE_START)
|| (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE))
{
/* Multi trigger is not applicable to software-triggered conversions */
assert_param((hadc->Init.Oversampling.TriggeredMode == ADC_TRIGGEREDMODE_SINGLE_TRIGGER));
}
- /* Configuration of Oversampler: */
- /* - Oversampling Ratio */
- /* - Right bit shift */
- /* - Left bit shift */
- /* - Triggered mode */
- /* - Oversampling mode (continued/resumed) */
- MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_FIELDS,
- ADC_CFGR2_ROVSE |
- ((hadc->Init.Oversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
- hadc->Init.Oversampling.RightBitShift |
- hadc->Init.Oversampling.TriggeredMode |
- hadc->Init.Oversampling.OversamplingStopReset);
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ /* Configuration of Oversampler: */
+ /* - Oversampling Ratio */
+ /* - Right bit shift */
+ /* - Triggered mode */
+ /* - Oversampling mode (continued/resumed) */
+ MODIFY_REG(hadc->Instance->CFGR2,
+ ADC_CFGR2_OVSR |
+ ADC_CFGR2_OVSS |
+ ADC_CFGR2_TROVS |
+ ADC_CFGR2_ROVSM,
+ ADC_CFGR2_ROVSE |
+ hadc->Init.Oversampling.Ratio |
+ hadc->Init.Oversampling.RightBitShift |
+ hadc->Init.Oversampling.TriggeredMode |
+ hadc->Init.Oversampling.OversamplingStopReset
+ );
+ }
+ else
+ {
+
+ /* Configuration of Oversampler: */
+ /* - Oversampling Ratio */
+ /* - Right bit shift */
+ /* - Left bit shift */
+ /* - Triggered mode */
+ /* - Oversampling mode (continued/resumed) */
+ MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_FIELDS,
+ ADC_CFGR2_ROVSE |
+ ((hadc->Init.Oversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
+ hadc->Init.Oversampling.RightBitShift |
+ hadc->Init.Oversampling.TriggeredMode |
+ hadc->Init.Oversampling.OversamplingStopReset);
+ }
+#else
+ /* Configuration of Oversampler: */
+ /* - Oversampling Ratio */
+ /* - Right bit shift */
+ /* - Left bit shift */
+ /* - Triggered mode */
+ /* - Oversampling mode (continued/resumed) */
+ MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_FIELDS,
+ ADC_CFGR2_ROVSE |
+ ((hadc->Init.Oversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
+ hadc->Init.Oversampling.RightBitShift |
+ hadc->Init.Oversampling.TriggeredMode |
+ hadc->Init.Oversampling.OversamplingStopReset);
+#endif
}
else
@@ -677,9 +778,16 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
/* Set the LeftShift parameter: it is applied to the final result with or without oversampling */
MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_LSHIFT, hadc->Init.LeftBitShift);
-
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance != ADC3)
+ {
+ /* Configure the BOOST Mode */
+ ADC_ConfigureBoostMode(hadc);
+ }
+#else
/* Configure the BOOST Mode */
ADC_ConfigureBoostMode(hadc);
+#endif
}
/* Configuration of regular group sequencer: */
@@ -807,11 +915,11 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc)
/* Reset register CFGR */
CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_AWD1CH | ADC_CFGR_JAUTO | ADC_CFGR_JAWD1EN |
- ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL | ADC_CFGR_JQM |
- ADC_CFGR_JDISCEN | ADC_CFGR_DISCNUM | ADC_CFGR_DISCEN |
- ADC_CFGR_AUTDLY | ADC_CFGR_CONT | ADC_CFGR_OVRMOD |
- ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL |
- ADC_CFGR_RES | ADC_CFGR_DMNGT);
+ ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL | ADC_CFGR_JQM |
+ ADC_CFGR_JDISCEN | ADC_CFGR_DISCNUM | ADC_CFGR_DISCEN |
+ ADC_CFGR_AUTDLY | ADC_CFGR_CONT | ADC_CFGR_OVRMOD |
+ ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL |
+ ADC_CFGR_RES | ADC_CFGR_DMNGT);
SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
/* Reset register CFGR2 */
@@ -826,6 +934,30 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc)
ADC_SMPR2_SMP15 | ADC_SMPR2_SMP14 | ADC_SMPR2_SMP13 |
ADC_SMPR2_SMP12 | ADC_SMPR2_SMP11 | ADC_SMPR2_SMP10);
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ /* Reset register LTR1 and HTR1 */
+ CLEAR_BIT(hadc->Instance->LTR1_TR1, ADC3_TR1_HT1 | ADC3_TR1_LT1);
+ CLEAR_BIT(hadc->Instance->HTR1_TR2, ADC3_TR2_HT2 | ADC3_TR2_LT2);
+
+ /* Reset register LTR3 and HTR3 */
+ CLEAR_BIT(hadc->Instance->RES1_TR3, ADC3_TR3_HT3 | ADC3_TR3_LT3);
+ }
+ else
+ {
+ CLEAR_BIT(hadc->Instance->LTR1_TR1, ADC_LTR_LT);
+ CLEAR_BIT(hadc->Instance->HTR1_TR2, ADC_HTR_HT);
+
+ /* Reset register LTR2 and HTR2*/
+ CLEAR_BIT(hadc->Instance->LTR2_DIFSEL, ADC_LTR_LT);
+ CLEAR_BIT(hadc->Instance->HTR2_CALFACT, ADC_HTR_HT);
+
+ /* Reset register LTR3 and HTR3 */
+ CLEAR_BIT(hadc->Instance->LTR3_RES10, ADC_LTR_LT);
+ CLEAR_BIT(hadc->Instance->HTR3_RES11, ADC_HTR_HT);
+ }
+#else
/* Reset register LTR1 and HTR1 */
CLEAR_BIT(hadc->Instance->LTR1, ADC_LTR_LT);
CLEAR_BIT(hadc->Instance->HTR1, ADC_HTR_HT);
@@ -837,6 +969,8 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc)
/* Reset register LTR3 and HTR3 */
CLEAR_BIT(hadc->Instance->LTR3, ADC_LTR_LT);
CLEAR_BIT(hadc->Instance->HTR3, ADC_HTR_HT);
+#endif /* ADC_VER_V5_V90 */
+
/* Reset register SQR1 */
CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_SQ4 | ADC_SQR1_SQ3 | ADC_SQR1_SQ2 |
@@ -876,12 +1010,30 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc)
/* Reset register AWD3CR */
CLEAR_BIT(hadc->Instance->AWD3CR, ADC_AWD3CR_AWD3CH);
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ /* Reset register DIFSEL */
+ CLEAR_BIT(hadc->Instance->LTR2_DIFSEL, ADC_DIFSEL_DIFSEL);
+
+ /* Reset register CALFACT */
+ CLEAR_BIT(hadc->Instance->HTR2_CALFACT, ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S);
+ }
+ else
+ {
+ /* Reset register DIFSEL */
+ CLEAR_BIT(hadc->Instance->DIFSEL_RES12, ADC_DIFSEL_DIFSEL);
+
+ /* Reset register CALFACT */
+ CLEAR_BIT(hadc->Instance->CALFACT_RES13, ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S);
+ }
+#else
/* Reset register DIFSEL */
CLEAR_BIT(hadc->Instance->DIFSEL, ADC_DIFSEL_DIFSEL);
/* Reset register CALFACT */
CLEAR_BIT(hadc->Instance->CALFACT, ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S);
-
+#endif /* ADC_VER_V5_V90 */
/* ========== Reset common ADC registers ========== */
@@ -897,32 +1049,31 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc)
HAL_ADC_ConfigChannel() or HAL_ADCEx_InjectedConfigChannel() )
*/
ADC_CLEAR_COMMON_CONTROL_REGISTER(hadc);
- }
- /* DeInit the low level hardware.
+ /* ========== Hard reset ADC peripheral ========== */
+ /* Performs a global reset of the entire ADC peripherals instances */
+ /* sharing the same common ADC instance: ADC state is forced to */
+ /* a similar state as after device power-on. */
+ /* Note: A possible implementation is to add RCC bus reset of ADC */
+ /* (for example, using macro */
+ /* __HAL_RCC_ADC..._FORCE_RESET()/..._RELEASE_RESET()/..._CLK_DISABLE()) */
+ /* in function "void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)": */
- For example:
- __HAL_RCC_ADC_FORCE_RESET();
- __HAL_RCC_ADC_RELEASE_RESET();
- __HAL_RCC_ADC_CLK_DISABLE();
-
- Keep in mind that all ADCs use the same clock: disabling
- the clock will reset all ADCs.
-
- */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
- if (hadc->MspDeInitCallback == NULL)
- {
- hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
- }
+ if (hadc->MspDeInitCallback == NULL)
+ {
+ hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
+ }
- /* DeInit the low level hardware: RCC clock, NVIC */
- hadc->MspDeInitCallback(hadc);
+ /* DeInit the low level hardware: RCC clock, NVIC */
+ hadc->MspDeInitCallback(hadc);
#else
- /* DeInit the low level hardware: RCC clock, NVIC */
- HAL_ADC_MspDeInit(hadc);
+ /* DeInit the low level hardware: RCC clock, NVIC */
+ HAL_ADC_MspDeInit(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+ }
+
/* Set ADC error code to none */
ADC_CLEAR_ERRORCODE(hadc);
@@ -1490,13 +1641,17 @@ HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Ti
{
if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
{
- /* Update ADC state machine to timeout */
- SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+ /* New check to avoid false timeout detection in case of preemption */
+ if((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
- return HAL_TIMEOUT;
+ return HAL_TIMEOUT;
+ }
}
}
}
@@ -1601,13 +1756,17 @@ HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef *hadc, uint32_t EventTy
{
if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
{
- /* Update ADC state machine to timeout */
- SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+ /* New check to avoid false timeout detection in case of preemption */
+ if(__HAL_ADC_GET_FLAG(hadc, EventType) == 0UL)
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
- return HAL_TIMEOUT;
+ return HAL_TIMEOUT;
+ }
}
}
}
@@ -2040,7 +2199,21 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, ui
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
/* Enable ADC DMA mode*/
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ LL_ADC_REG_SetDMATransferMode(hadc->Instance, ADC3_CFGR_DMACONTREQ((uint32_t)hadc->Init.DMAContinuousRequests));
+ LL_ADC_EnableDMAReq(hadc->Instance);
+ }
+ else
+ {
+ LL_ADC_REG_SetDataTransferMode(hadc->Instance, ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.ConversionDataManagement));
+ }
+
+#else
LL_ADC_REG_SetDataTransferMode(hadc->Instance, (uint32_t)hadc->Init.ConversionDataManagement);
+#endif
+
/* Start the DMA channel */
tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
@@ -2104,8 +2277,8 @@ HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef *hadc)
/* Disable ADC peripheral if conversions are effectively stopped */
if (tmp_hal_status == HAL_OK)
{
- /* Disable ADC DMA (ADC DMA configuration of continous requests is kept) */
- MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_DMNGT_0 |ADC_CFGR_DMNGT_1, 0UL);
+ /* Disable ADC DMA (ADC DMA configuration of continuous requests is kept) */
+ MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_DMNGT_0 | ADC_CFGR_DMNGT_1, 0UL);
/* Disable the DMA channel (in case of DMA in circular mode or stop */
/* while DMA transfer is on going) */
@@ -2352,44 +2525,46 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc)
/* group having no further conversion upcoming (same conditions as */
/* regular group interruption disabling above), */
/* and if injected scan sequence is completed. */
- if ((tmp_adc_inj_is_trigger_source_sw_start != 0UL) ||
- ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) &&
- ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
- (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL))))
+ if (tmp_adc_inj_is_trigger_source_sw_start != 0UL)
{
- /* If End of Sequence is reached, disable interrupts */
- if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
+ if ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) ||
+ ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
+ (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL)))
{
- /* Particular case if injected contexts queue is enabled: */
- /* when the last context has been fully processed, JSQR is reset */
- /* by the hardware. Even if no injected conversion is planned to come */
- /* (queue empty, triggers are ignored), it can start again */
- /* immediately after setting a new context (JADSTART is still set). */
- /* Therefore, state of HAL ADC injected group is kept to busy. */
- if (READ_BIT(tmp_cfgr, ADC_CFGR_JQM) == 0UL)
+ /* If End of Sequence is reached, disable interrupts */
+ if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
{
- /* Allowed to modify bits ADC_IT_JEOC/ADC_IT_JEOS only if bit */
- /* JADSTART==0 (no conversion on going) */
- if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ /* Particular case if injected contexts queue is enabled: */
+ /* when the last context has been fully processed, JSQR is reset */
+ /* by the hardware. Even if no injected conversion is planned to come */
+ /* (queue empty, triggers are ignored), it can start again */
+ /* immediately after setting a new context (JADSTART is still set). */
+ /* Therefore, state of HAL ADC injected group is kept to busy. */
+ if (READ_BIT(tmp_cfgr, ADC_CFGR_JQM) == 0UL)
{
- /* Disable ADC end of sequence conversion interrupt */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC | ADC_IT_JEOS);
+ /* Allowed to modify bits ADC_IT_JEOC/ADC_IT_JEOS only if bit */
+ /* JADSTART==0 (no conversion on going) */
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* Disable ADC end of sequence conversion interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC | ADC_IT_JEOS);
- /* Set ADC state */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
- if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
}
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
- /* Set ADC error code to ADC peripheral internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ }
}
}
}
@@ -2490,10 +2665,10 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc)
else
{
/* Multimode not set or feature not available or ADC independent */
- if ((hadc->Instance->CFGR & ADC_CFGR_DMNGT) != 0UL)
- {
- overrun_error = 1UL;
- }
+ if ((hadc->Instance->CFGR & ADC_CFGR_DMNGT) != 0UL)
+ {
+ overrun_error = 1UL;
+ }
}
}
@@ -2665,11 +2840,20 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
/* Check offset range according to oversampling setting */
if (hadc->Init.OversamplingMode == ENABLE)
{
- assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset/(hadc->Init.Oversampling.Ratio+1U)));
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset / (hadc->Init.Oversampling.Ratio + 1U)));
}
else
{
- assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset));
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ assert_param(IS_ADC3_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset));
+ }
+ else
+#endif /* ADC_VER_V5_V90 */
+ {
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset));
+ }
}
/* if ROVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is
@@ -2710,8 +2894,17 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
/* - Channel rank */
if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
{
+
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance != ADC3)
+ {
+ /* ADC channels preselection */
+ hadc->Instance->PCSEL_RES0 |= (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfig->Channel) & 0x1FUL));
+ }
+#else
/* ADC channels preselection */
hadc->Instance->PCSEL |= (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfig->Channel) & 0x1FUL));
+#endif /* ADC_VER_V5_V90 */
/* Set ADC group regular sequence: channel on the selected scan sequence rank */
LL_ADC_REG_SetSequencerRanks(hadc->Instance, sConfig->Rank, sConfig->Channel);
@@ -2734,27 +2927,72 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
/* Shift the offset with respect to the selected ADC resolution. */
/* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
- tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, (uint32_t)sConfig->Offset);
-
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ tmpOffsetShifted = ADC3_OFFSET_SHIFT_RESOLUTION(hadc, (uint32_t)sConfig->Offset);
+ }
+ else
+#endif /* ADC_VER_V5_V90 */
+ {
+ tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, (uint32_t)sConfig->Offset);
+ }
+
if (sConfig->OffsetNumber != ADC_OFFSET_NONE)
{
/* Set ADC selected offset number */
LL_ADC_SetOffset(hadc->Instance, sConfig->OffsetNumber, sConfig->Channel, tmpOffsetShifted);
- assert_param(IS_FUNCTIONAL_STATE(sConfig->OffsetSignedSaturation));
- /* Set ADC selected offset signed saturation */
- LL_ADC_SetOffsetSignedSaturation(hadc->Instance, sConfig->OffsetNumber, (sConfig->OffsetSignedSaturation == ENABLE) ? LL_ADC_OFFSET_SIGNED_SATURATION_ENABLE : LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ assert_param(IS_ADC3_OFFSET_SIGN(sConfig->OffsetSign));
+ assert_param(IS_FUNCTIONAL_STATE(sConfig->OffsetSaturation));
+ /* Set ADC selected offset sign & saturation */
+ LL_ADC_SetOffsetSign(hadc->Instance, sConfig->OffsetNumber, sConfig->OffsetSign);
+ LL_ADC_SetOffsetSaturation(hadc->Instance, sConfig->OffsetNumber, (sConfig->OffsetSaturation == ENABLE) ? LL_ADC_OFFSET_SATURATION_ENABLE : LL_ADC_OFFSET_SATURATION_DISABLE);
+ }
+ else
+#endif /* ADC_VER_V5_V90 */
+ {
+ assert_param(IS_FUNCTIONAL_STATE(sConfig->OffsetSignedSaturation));
+ /* Set ADC selected offset signed saturation */
+ LL_ADC_SetOffsetSignedSaturation(hadc->Instance, sConfig->OffsetNumber, (sConfig->OffsetSignedSaturation == ENABLE) ? LL_ADC_OFFSET_SIGNED_SATURATION_ENABLE : LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
- assert_param(IS_FUNCTIONAL_STATE(sConfig->OffsetRightShift));
- /* Set ADC selected offset right shift */
- LL_ADC_SetDataRightShift(hadc->Instance, sConfig->OffsetNumber, (sConfig->OffsetRightShift == ENABLE) ? LL_ADC_OFFSET_RSHIFT_ENABLE : LL_ADC_OFFSET_RSHIFT_DISABLE);
+ assert_param(IS_FUNCTIONAL_STATE(sConfig->OffsetRightShift));
+ /* Set ADC selected offset right shift */
+ LL_ADC_SetDataRightShift(hadc->Instance, sConfig->OffsetNumber, (sConfig->OffsetRightShift == ENABLE) ? LL_ADC_OFFSET_RSHIFT_ENABLE : LL_ADC_OFFSET_RSHIFT_DISABLE);
+ }
}
else
{
- /* Scan OFR1, OFR2, OFR3, OFR4 to check if the selected channel is enabled.
- If this is the case, offset OFRx is disabled since
- sConfig->OffsetNumber = ADC_OFFSET_NONE. */
+ /* Scan OFR1, OFR2, OFR3, OFR4 to check if the selected channel is enabled.
+ If this is the case, offset OFRx is disabled since
+ sConfig->OffsetNumber = ADC_OFFSET_NONE. */
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
+ {
+ LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_1, LL_ADC_OFFSET_DISABLE);
+ }
+ if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
+ {
+ LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_2, LL_ADC_OFFSET_DISABLE);
+ }
+ if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
+ {
+ LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_3, LL_ADC_OFFSET_DISABLE);
+ }
+ if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
+ {
+ LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_4, LL_ADC_OFFSET_DISABLE);
+ }
+ }
+ else
+#endif /* ADC_VER_V5_V90 */
+ {
if (((hadc->Instance->OFR1) & ADC_OFR1_OFFSET1_CH) == ADC_OFR_CHANNEL(sConfig->Channel))
{
CLEAR_BIT(hadc->Instance->OFR1, ADC_OFR1_SSATE);
@@ -2771,7 +3009,9 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
{
CLEAR_BIT(hadc->Instance->OFR4, ADC_OFR4_SSATE);
}
- }
+ }
+
+ }
}
/* Parameters update conditioned to ADC state: */
@@ -2799,7 +3039,7 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
/* Note: these internal measurement paths can be disabled using */
/* HAL_ADC_DeInit(). */
- if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
+ if (__LL_ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
{
/* Configuration of common ADC parameters */
@@ -2822,8 +3062,8 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles, scaling in us split to not */
/* exceed 32 bits register capacity and handle low frequency. */
- wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
- while(wait_loop_index != 0UL)
+ wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
+ while (wait_loop_index != 0UL)
{
wait_loop_index--;
}
@@ -2890,7 +3130,7 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
* The setting of these parameters is conditioned to ADC state.
* For parameters constraints, see comments of structure
* "ADC_AnalogWDGConfTypeDef".
- * @note On this STM32 serie, analog watchdog thresholds cannot be modified
+ * @note On this STM32 series, analog watchdog thresholds cannot be modified
* while ADC conversion is on going.
* @param hadc ADC handle
* @param AnalogWDGConfig Structure of ADC analog watchdog configuration
@@ -2917,19 +3157,42 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDG
assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
}
- /* Verify thresholds range */
- if (hadc->Init.OversamplingMode == ENABLE)
+#if defined(ADC_VER_V5_V90)
+
+ if (hadc->Instance == ADC3)
{
- /* Case of oversampling enabled: thresholds are compared to oversampling
- intermediate computation (after ratio, before shift application) */
- assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
- assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
+ /* Verify thresholds range */
+ if (hadc->Init.OversamplingMode == ENABLE)
+ {
+ /* Case of oversampling enabled: thresholds are compared to oversampling
+ intermediate computation (after ratio, before shift application) */
+ assert_param(IS_ADC3_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
+ assert_param(IS_ADC3_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
+ }
+ else
+ {
+ /* Verify if thresholds are within the selected ADC resolution */
+ assert_param(IS_ADC3_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold));
+ assert_param(IS_ADC3_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold));
+ }
}
else
+#endif /* ADC_VER_V5_V90 */
{
- /* Verify if thresholds are within the selected ADC resolution */
- assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold));
- assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold));
+ /* Verify thresholds range */
+ if (hadc->Init.OversamplingMode == ENABLE)
+ {
+ /* Case of oversampling enabled: thresholds are compared to oversampling
+ intermediate computation (after ratio, before shift application) */
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
+ }
+ else
+ {
+ /* Verify if thresholds are within the selected ADC resolution */
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold));
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold));
+ }
}
/* Process locked */
@@ -2993,8 +3256,25 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDG
tmpAWDLowThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
/* Set the high and low thresholds */
- MODIFY_REG(hadc->Instance->LTR1, ADC_LTR_LT , tmpAWDLowThresholdShifted);
- MODIFY_REG(hadc->Instance->HTR1, ADC_HTR_HT , tmpAWDHighThresholdShifted);
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
+ {
+ MODIFY_REG(hadc->Instance->LTR1_TR1,
+ ADC3_TR1_AWDFILT,
+ AnalogWDGConfig->FilteringConfig);
+ MODIFY_REG(hadc->Instance->LTR1_TR1, ADC3_TR1_LT1, tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->LTR1_TR1, ADC3_TR1_HT1, (tmpAWDHighThresholdShifted << ADC3_TR1_HT1_Pos));
+ }
+ else
+ {
+
+ MODIFY_REG(hadc->Instance->LTR1_TR1, ADC_LTR_LT, tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR1_TR2, ADC_HTR_HT, tmpAWDHighThresholdShifted);
+ }
+#else
+ MODIFY_REG(hadc->Instance->LTR1, ADC_LTR_LT, tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR1, ADC_HTR_HT, tmpAWDHighThresholdShifted);
+#endif
/* Update state, clear previous result related to AWD1 */
CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD1);
@@ -3038,16 +3318,30 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDG
case ADC_ANALOGWATCHDOG_ALL_REG:
case ADC_ANALOGWATCHDOG_ALL_INJEC:
case ADC_ANALOGWATCHDOG_ALL_REGINJEC:
- /* Update AWD by bitfield to keep the possibility to monitor */
- /* several channels by successive calls of this function. */
- if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
{
- SET_BIT(hadc->Instance->AWD2CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, AnalogWDGConfig->WatchdogNumber, LL_ADC_AWD_ALL_CHANNELS_REG_INJ);
+
}
else
{
- SET_BIT(hadc->Instance->AWD3CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+#endif /*ADC_VER_V5_V90*/
+ /* Update AWD by bitfield to keep the possibility to monitor */
+ /* several channels by successive calls of this function. */
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+ {
+ SET_BIT(hadc->Instance->AWD2CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+ }
+ else
+ {
+ SET_BIT(hadc->Instance->AWD3CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+ }
+#if defined(ADC_VER_V5_V90)
}
+#endif /*ADC_VER_V5_V90*/
break;
default: /* ADC_ANALOGWATCHDOG_NONE */
@@ -3060,19 +3354,56 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDG
tmpAWDHighThresholdShifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold);
tmpAWDLowThresholdShifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
- if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+#if defined(ADC_VER_V5_V90)
+ if (hadc->Instance == ADC3)
{
- /* Set ADC analog watchdog thresholds value of both thresholds high and low */
- MODIFY_REG(hadc->Instance->LTR2, ADC_LTR_LT , tmpAWDLowThresholdShifted);
- MODIFY_REG(hadc->Instance->HTR2, ADC_HTR_HT , tmpAWDHighThresholdShifted);
+
+ /* Analog watchdog thresholds configuration */
+ if (AnalogWDGConfig->WatchdogNumber != ADC_ANALOGWATCHDOG_1)
+ {
+ /* Shift the offset with respect to the selected ADC resolution: */
+ /* Thresholds have to be left-aligned on bit 7, the LSB (right bits) */
+ /* are set to 0. */
+ tmpAWDHighThresholdShifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold);
+ tmpAWDLowThresholdShifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
+ }
+
+ /* Set ADC analog watchdog thresholds value of both thresholds high and low */
+ LL_ADC_ConfigAnalogWDThresholds(hadc->Instance, AnalogWDGConfig->WatchdogNumber, tmpAWDHighThresholdShifted, tmpAWDLowThresholdShifted);
+
+
}
else
{
+
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+ {
+ /* Set ADC analog watchdog thresholds value of both thresholds high and low */
+ MODIFY_REG(hadc->Instance->LTR2_DIFSEL, ADC_LTR_LT, tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR2_CALFACT, ADC_HTR_HT, tmpAWDHighThresholdShifted);
+ }
+ else
+ {
+ /* Set ADC analog watchdog thresholds value of both thresholds high and low */
+ MODIFY_REG(hadc->Instance->LTR3_RES10, ADC_LTR_LT, tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR3_RES11, ADC_HTR_HT, tmpAWDHighThresholdShifted);
+ }
+ }
+#else
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+ {
/* Set ADC analog watchdog thresholds value of both thresholds high and low */
- MODIFY_REG(hadc->Instance->LTR3, ADC_LTR_LT , tmpAWDLowThresholdShifted);
- MODIFY_REG(hadc->Instance->HTR3, ADC_HTR_HT , tmpAWDHighThresholdShifted);
+ MODIFY_REG(hadc->Instance->LTR2, ADC_LTR_LT, tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR2, ADC_HTR_HT, tmpAWDHighThresholdShifted);
+ }
+ else
+ {
+ /* Set ADC analog watchdog thresholds value of both thresholds high and low */
+ MODIFY_REG(hadc->Instance->LTR3, ADC_LTR_LT, tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR3, ADC_HTR_HT, tmpAWDHighThresholdShifted);
}
+#endif
if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
{
/* Update state, clear previous result related to AWD2 */
@@ -3318,13 +3649,17 @@ HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef *hadc, uint32_t Conversio
{
if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
{
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+ /* New check to avoid false timeout detection in case of preemption */
+ if((hadc->Instance->CR & tmp_ADC_CR_ADSTART_JADSTART) != 0UL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
- /* Set ADC error code to ADC peripheral internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
- return HAL_ERROR;
+ return HAL_ERROR;
+ }
}
}
@@ -3374,11 +3709,11 @@ HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc)
/* Poll for ADC ready flag raised except case of multimode enabled
and ADC slave selected. */
uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
- if ( (__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
- || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
)
{
- while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
+ while (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
{
/* If ADEN bit is set less than 4 ADC clock cycles after the ADCAL bit
has been cleared (after a calibration), ADEN bit is reset by the
@@ -3388,20 +3723,24 @@ HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc)
4 ADC clock cycle duration */
/* Note: Test of ADC enabled required due to hardware constraint to */
/* not enable ADC if already enabled. */
- if(LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
{
LL_ADC_Enable(hadc->Instance);
}
- if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
+ if ((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
{
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+ /* New check to avoid false timeout detection in case of preemption */
+ if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
- /* Set ADC error code to ADC peripheral internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
- return HAL_ERROR;
+ return HAL_ERROR;
+ }
}
}
}
@@ -3456,13 +3795,17 @@ HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef *hadc)
{
if ((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
{
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+ /* New check to avoid false timeout detection in case of preemption */
+ if ((hadc->Instance->CR & ADC_CR_ADEN) != 0UL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
- /* Set ADC error code to ADC peripheral internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
- return HAL_ERROR;
+ return HAL_ERROR;
+ }
}
}
}
@@ -3598,13 +3941,13 @@ void ADC_DMAError(DMA_HandleTypeDef *hdma)
* @param hadc ADC handle
* @retval None.
*/
-void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
+void ADC_ConfigureBoostMode(ADC_HandleTypeDef *hadc)
{
uint32_t freq;
- if(ADC_IS_SYNCHRONOUS_CLOCK_MODE(hadc))
+ if (ADC_IS_SYNCHRONOUS_CLOCK_MODE(hadc))
{
freq = HAL_RCC_GetHCLKFreq();
- switch(hadc->Init.ClockPrescaler)
+ switch (hadc->Init.ClockPrescaler)
{
case ADC_CLOCK_SYNC_PCLK_DIV1:
case ADC_CLOCK_SYNC_PCLK_DIV2:
@@ -3620,7 +3963,7 @@ void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
else
{
freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC);
- switch(hadc->Init.ClockPrescaler)
+ switch (hadc->Init.ClockPrescaler)
{
case ADC_CLOCK_ASYNC_DIV2:
case ADC_CLOCK_ASYNC_DIV4:
@@ -3632,8 +3975,8 @@ void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
break;
case ADC_CLOCK_ASYNC_DIV16:
freq /= 16UL;
- break;
- case ADC_CLOCK_ASYNC_DIV32:
+ break;
+ case ADC_CLOCK_ASYNC_DIV32:
freq /= 32UL;
break;
case ADC_CLOCK_ASYNC_DIV64:
@@ -3650,18 +3993,17 @@ void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
}
}
-#if defined(ADC_VER_V5_3)
+#if defined(ADC_VER_V5_3) || defined(ADC_VER_V5_V90)
freq /= 2U;
-
if (freq <= 6250000UL)
{
MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, 0UL);
}
- else if(freq <= 12500000UL)
+ else if (freq <= 12500000UL)
{
MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_0);
}
- else if(freq <= 25000000UL)
+ else if (freq <= 25000000UL)
{
MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_1);
}
@@ -3670,9 +4012,9 @@ void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_1 | ADC_CR_BOOST_0);
}
#else
- if(HAL_GetREVID() <= REV_ID_Y) /* STM32H7 silicon Rev.Y */
+ if (HAL_GetREVID() <= REV_ID_Y) /* STM32H7 silicon Rev.Y */
{
- if(freq > 20000000UL)
+ if (freq > 20000000UL)
{
SET_BIT(hadc->Instance->CR, ADC_CR_BOOST_0);
}
@@ -3689,11 +4031,11 @@ void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
{
MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, 0UL);
}
- else if(freq <= 12500000UL)
+ else if (freq <= 12500000UL)
{
MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_0);
}
- else if(freq <= 25000000UL)
+ else if (freq <= 25000000UL)
{
MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_1);
}
@@ -3718,4 +4060,3 @@ void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
* @}
*/
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/