xref: /btstack/port/stm32-l451-miromico-sx1280/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_opamp.c (revision 2fd737d36a1de5d778cacc671d4b4d8c4f3fed82)
1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_opamp.c
4   * @author  MCD Application Team
5   * @brief   OPAMP HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the operational amplifier(s) peripheral:
8   *           + OPAMP configuration
9   *           + OPAMP calibration
10   *          Thanks to
11   *           + Initialization and de-initialization functions
12   *           + IO operation functions
13   *           + Peripheral Control functions
14   *           + Peripheral State functions
15   *
16   @verbatim
17 ================================================================================
18           ##### OPAMP Peripheral Features #####
19 ================================================================================
20 
21   [..] The device integrates 1 or 2 operational amplifiers OPAMP1 & OPAMP2
22 
23        (#) The OPAMP(s) provide(s) several exclusive running modes.
24        (++) 1 OPAMP: STM32L412xx STM32L422xx STM32L431xx STM32L432xx STM32L433xx STM32L442xx STM32L443xx
25        (++) 2 OPAMP: STM32L471xx STM32L475xx STM32L476xx STM32L485xx STM32L486xx
26 
27        (#) The OPAMP(s) provide(s) several exclusive running modes.
28        (++) Standalone mode
29        (++) Programmable Gain Amplifier (PGA) mode (Resistor feedback output)
30        (++) Follower mode
31 
32        (#) All OPAMP (same for all OPAMPs) can operate in
33        (++) Either Low range (VDDA < 2.4V) power supply
34        (++) Or High range (VDDA > 2.4V) power supply
35 
36        (#) Each OPAMP(s) can be configured in normal and low power mode.
37 
38        (#) The OPAMP(s) provide(s) calibration capabilities.
39        (++) Calibration aims at correcting some offset for running mode.
40        (++) The OPAMP uses either factory calibration settings OR user defined
41            calibration (trimming) settings (i.e. trimming mode).
42        (++) The user defined settings can be figured out using self calibration
43            handled by HAL_OPAMP_SelfCalibrate, HAL_OPAMPEx_SelfCalibrateAll
44        (++) HAL_OPAMP_SelfCalibrate:
45        (+++) Runs automatically the calibration.
46        (+++) Enables the user trimming mode
47        (+++) Updates the init structure with trimming values with fresh calibration
48             results.
49             The user may store the calibration results for larger
50             (ex monitoring the trimming as a function of temperature
51             for instance)
52        (+++) HAL_OPAMPEx_SelfCalibrateAll
53             runs calibration of all OPAMPs in parallel to save search time.
54 
55        (#) Running mode: Standalone mode
56        (++) Gain is set externally (gain depends on external loads).
57        (++) Follower mode also possible externally by connecting the inverting input to
58            the output.
59 
60        (#) Running mode: Follower mode
61        (++) No Inverting Input is connected.
62 
63        (#) Running mode: Programmable Gain Amplifier (PGA) mode
64            (Resistor feedback output)
65        (++) The OPAMP(s) output(s) can be internally connected to resistor feedback
66            output.
67        (++) OPAMP gain is either 2, 4, 8 or 16.
68 
69        (#) The OPAMPs inverting input can be selected according to the Reference Manual
70            "OPAMP function description" chapter.
71 
72        (#) The OPAMPs non inverting input can be selected according to the Reference Manual
73            "OPAMP function description" chapter.
74 
75 
76             ##### How to use this driver #####
77 ================================================================================
78   [..]
79 
80     *** Power supply range ***
81     ============================================
82     [..] To run in low power mode:
83 
84       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
85       (++) Select OPAMP_POWERSUPPLY_LOW (VDDA lower than 2.4V)
86       (++) Otherwise select OPAMP_POWERSUPPLY_HIGH (VDDA higher than 2.4V)
87 
88     *** Low / normal power mode ***
89     ============================================
90     [..] To run in low power mode:
91 
92       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
93       (++) Select OPAMP_POWERMODE_LOWPOWER
94       (++) Otherwise select OPAMP_POWERMODE_NORMAL
95 
96     *** Calibration ***
97     ============================================
98     [..] To run the OPAMP calibration self calibration:
99 
100       (#) Start calibration using HAL_OPAMP_SelfCalibrate.
101            Store the calibration results.
102 
103     *** Running mode ***
104     ============================================
105 
106     [..] To use the OPAMP, perform the following steps:
107 
108       (#) Fill in the HAL_OPAMP_MspInit() to
109       (++) Enable the OPAMP Peripheral clock using macro __HAL_RCC_OPAMP_CLK_ENABLE()
110       (++) Configure the OPAMP input AND output in analog mode using
111            HAL_GPIO_Init() to map the OPAMP output to the GPIO pin.
112 
113       (#) Registrate Callbacks
114       (++) The compilation define  USE_HAL_OPAMP_REGISTER_CALLBACKS when set to 1
115            allows the user to configure dynamically the driver callbacks.
116 
117       (++) Use Functions @ref HAL_OPAMP_RegisterCallback() to register a user callback,
118            it allows to register following callbacks:
119       (+++) MspInitCallback         : OPAMP MspInit.
120       (+++) MspDeInitCallback       : OPAMP MspFeInit.
121            This function takes as parameters the HAL peripheral handle, the Callback ID
122            and a pointer to the user callback function.
123 
124       (++) Use function @ref HAL_OPAMP_UnRegisterCallback() to reset a callback to the default
125            weak (surcharged) function. It allows to reset following callbacks:
126       (+++) MspInitCallback         : OPAMP MspInit.
127       (+++) MspDeInitCallback       : OPAMP MspdeInit.
128       (+++) All Callbacks
129 
130       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
131       (++) Select the mode
132       (++) Select the inverting input
133       (++) Select the non-inverting input
134       (++) If PGA mode is enabled, Select if inverting input is connected.
135       (++) Select either factory or user defined trimming mode.
136       (++) If the user-defined trimming mode is enabled, select PMOS & NMOS trimming values
137           (typically values set by HAL_OPAMP_SelfCalibrate function).
138 
139       (#) Enable the OPAMP using HAL_OPAMP_Start() function.
140 
141       (#) Disable the OPAMP using HAL_OPAMP_Stop() function.
142 
143       (#) Lock the OPAMP in running mode using HAL_OPAMP_Lock() function.
144           Caution: On STM32L4, HAL OPAMP lock is software lock only (not
145           hardware lock as on some other STM32 devices)
146 
147       (#) If needed, unlock the OPAMP using HAL_OPAMPEx_Unlock() function.
148 
149     *** Running mode: change of configuration while OPAMP ON  ***
150     ============================================
151     [..] To Re-configure OPAMP when OPAMP is ON (change on the fly)
152       (#) If needed, fill in the HAL_OPAMP_MspInit()
153       (++) This is the case for instance if you wish to use new OPAMP I/O
154 
155       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
156       (++) As in configure case, select first the parameters you wish to modify.
157 
158       (#) Change from low power mode to normal power mode (& vice versa) requires
159           first HAL_OPAMP_DeInit() (force OPAMP OFF) and then HAL_OPAMP_Init().
160           In other words, of OPAMP is ON, HAL_OPAMP_Init can NOT change power mode
161           alone.
162 
163   @endverbatim
164   ******************************************************************************
165 
166       Table 1.  OPAMPs inverting/non-inverting inputs for the STM32L4 devices:
167       +------------------------------------------------------------------------|
168       |                 |         | OPAMP1               | OPAMP2              |
169       |-----------------|---------|----------------------|---------------------|
170       | Inverting Input | VM_SEL  |                      |                     |
171       |                 |         |  IO0-> PA1           | IO0-> PA7           |
172       |                 |         |  LOW LEAKAGE IO (2)  | LOW LEAKAGE IO (2)  |
173       |                 |         |  Not connected       | Not connected       |
174       | (1)             |         |    PGA mode only     |   PGA mode only     |
175       |-----------------|---------|----------------------|---------------------|
176       |  Non Inverting  | VP_SEL  |                      |                     |
177       |                 |         |  IO0-> PA0 (GPIO)    | IO0-> PA6  (GPIO)   |
178       |    Input        |         |  DAC1_OUT1 internal  | DAC1_OUT2 internal  |
179       +------------------------------------------------------------------------|
180        (1): NA in follower mode.
181        (2): Available on some package only (ex. BGA132).
182 
183 
184       Table 2.  OPAMPs outputs for the STM32L4 devices:
185 
186       +-------------------------------------------------------------------------
187       |                 |        | OPAMP1                | OPAMP2              |
188       |-----------------|--------|-----------------------|---------------------|
189       | Output          |  VOUT  |  PA3                  |  PB0                |
190       |                 |        |  & (1) ADC12_IN if    | & (1) ADC12_IN if   |
191       |                 |        |  connected internally | connected internally|
192       |-----------------|--------|-----------------------|---------------------|
193        (1): ADC1 or ADC2 shall select IN15.
194 
195   ******************************************************************************
196   * @attention
197   *
198   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
199   * All rights reserved.</center></h2>
200   *
201   * This software component is licensed by ST under BSD 3-Clause license,
202   * the "License"; You may not use this file except in compliance with the
203   * License. You may obtain a copy of the License at:
204   *                        opensource.org/licenses/BSD-3-Clause
205   *
206   ******************************************************************************
207   */
208 
209 /* Includes ------------------------------------------------------------------*/
210 #include "stm32l4xx_hal.h"
211 
212 /** @addtogroup STM32L4xx_HAL_Driver
213   * @{
214   */
215 
216 /** @defgroup OPAMP OPAMP
217   * @brief OPAMP module driver
218   * @{
219   */
220 
221 #ifdef HAL_OPAMP_MODULE_ENABLED
222 
223 /* Private types -------------------------------------------------------------*/
224 /* Private variables ---------------------------------------------------------*/
225 /* Private constants ---------------------------------------------------------*/
226 /** @addtogroup OPAMP_Private_Constants
227   * @{
228   */
229 
230 /* CSR register reset value */
231 #define OPAMP_CSR_RESET_VALUE             ((uint32_t)0x00000000)
232 
233 #define OPAMP_CSR_RESET_BITS    (OPAMP_CSR_OPAMPxEN | OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE \
234                                | OPAMP_CSR_PGGAIN | OPAMP_CSR_VMSEL | OPAMP_CSR_VPSEL \
235                                | OPAMP_CSR_CALON | OPAMP_CSR_USERTRIM)
236 
237 /* CSR Init masks */
238 #define OPAMP_CSR_INIT_MASK_PGA (OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE| OPAMP_CSR_PGGAIN \
239                                | OPAMP_CSR_VMSEL | OPAMP_CSR_VPSEL | OPAMP_CSR_USERTRIM)
240 
241 #define OPAMP_CSR_INIT_MASK_FOLLOWER (OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE| OPAMP_CSR_VPSEL \
242                                     | OPAMP_CSR_USERTRIM)
243 
244 #define OPAMP_CSR_INIT_MASK_STANDALONE (OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE| OPAMP_CSR_VPSEL \
245                                       | OPAMP_CSR_VMSEL | OPAMP_CSR_USERTRIM)
246 
247 
248 /**
249   * @}
250   */
251 
252 /* Private macros ------------------------------------------------------------*/
253 /* Private functions ---------------------------------------------------------*/
254 /* Exported functions --------------------------------------------------------*/
255 
256 /** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions
257   * @{
258   */
259 
260 /** @defgroup OPAMP_Exported_Functions_Group1 Initialization and de-initialization functions
261  *  @brief    Initialization and Configuration functions
262  *
263 @verbatim
264   ==============================================================================
265               ##### Initialization and de-initialization functions #####
266   ==============================================================================
267 
268 @endverbatim
269   * @{
270   */
271 
272 /**
273   * @brief  Initializes the OPAMP according to the specified
274   *         parameters in the OPAMP_InitTypeDef and initialize the associated handle.
275   * @note   If the selected opamp is locked, initialization can't be performed.
276   *         To unlock the configuration, perform a system reset.
277   * @param  hopamp OPAMP handle
278   * @retval HAL status
279   */
HAL_OPAMP_Init(OPAMP_HandleTypeDef * hopamp)280 HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp)
281 {
282   HAL_StatusTypeDef status = HAL_OK;
283   uint32_t updateotrlpotr;
284 
285   /* Check the OPAMP handle allocation and lock status */
286   /* Init not allowed if calibration is ongoing */
287   if(hopamp == NULL)
288   {
289     return HAL_ERROR;
290   }
291   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
292   {
293     return HAL_ERROR;
294   }
295   else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
296   {
297     return HAL_ERROR;
298   }
299   else
300   {
301     /* Check the parameter */
302     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
303 
304     /* Set OPAMP parameters */
305     assert_param(IS_OPAMP_POWER_SUPPLY_RANGE(hopamp->Init.PowerSupplyRange));
306     assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
307     assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode));
308     assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput));
309 
310     if(hopamp->State == HAL_OPAMP_STATE_RESET)
311     {
312 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
313     if(hopamp->MspInitCallback == NULL)
314     {
315       hopamp->MspInitCallback               = HAL_OPAMP_MspInit;
316     }
317 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
318     }
319 
320     if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE)
321     {
322       assert_param(IS_OPAMP_INVERTING_INPUT_STANDALONE(hopamp->Init.InvertingInput));
323     }
324 
325     if ((hopamp->Init.Mode) == OPAMP_PGA_MODE)
326     {
327       assert_param(IS_OPAMP_INVERTING_INPUT_PGA(hopamp->Init.InvertingInput));
328     }
329 
330     if ((hopamp->Init.Mode) == OPAMP_PGA_MODE)
331     {
332       assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain));
333     }
334 
335     assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming));
336     if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER)
337     {
338       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
339       {
340         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP));
341         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN));
342       }
343     else
344       {
345         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValuePLowPower));
346         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueNLowPower));
347       }
348     }
349 
350     if(hopamp->State == HAL_OPAMP_STATE_RESET)
351     {
352       /* Allocate lock resource and initialize it */
353       hopamp->Lock = HAL_UNLOCKED;
354     }
355 
356 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
357     hopamp->MspInitCallback(hopamp);
358 #else
359     /* Call MSP init function */
360     HAL_OPAMP_MspInit(hopamp);
361 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
362 
363     /* Set operating mode */
364     CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALON);
365 
366     if (hopamp->Init.Mode == OPAMP_PGA_MODE)
367     {
368       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_PGA, \
369                                         hopamp->Init.PowerMode | \
370                                         hopamp->Init.Mode | \
371                                         hopamp->Init.PgaGain | \
372                                         hopamp->Init.InvertingInput    | \
373                                         hopamp->Init.NonInvertingInput | \
374                                         hopamp->Init.UserTrimming);
375     }
376 
377     if (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE)
378     {
379     /* In Follower mode InvertingInput is Not Applicable  */
380     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_FOLLOWER, \
381                                         hopamp->Init.PowerMode | \
382                                         hopamp->Init.Mode | \
383                                         hopamp->Init.NonInvertingInput | \
384                                         hopamp->Init.UserTrimming);
385     }
386 
387     if (hopamp->Init.Mode == OPAMP_STANDALONE_MODE)
388     {
389       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_STANDALONE, \
390                                         hopamp->Init.PowerMode | \
391                                         hopamp->Init.Mode | \
392                                         hopamp->Init.InvertingInput    | \
393                                         hopamp->Init.NonInvertingInput | \
394                                         hopamp->Init.UserTrimming);
395     }
396 
397     if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER)
398     {
399       /* Set power mode and associated calibration parameters */
400       if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
401       {
402         /* OPAMP_POWERMODE_NORMAL */
403         /* Set calibration mode (factory or user) and values for            */
404         /* transistors differential pair high (PMOS) and low (NMOS) for     */
405         /* normal mode.                                                     */
406         updateotrlpotr = (((hopamp->Init.TrimmingValueP) << (OPAMP_INPUT_NONINVERTING)) \
407                          | (hopamp->Init.TrimmingValueN));
408         MODIFY_REG(hopamp->Instance->OTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr);
409       }
410       else
411       {
412         /* OPAMP_POWERMODE_LOWPOWER */
413         /* transistors differential pair high (PMOS) and low (NMOS) for     */
414         /* low power mode.                                                     */
415         updateotrlpotr = (((hopamp->Init.TrimmingValuePLowPower) << (OPAMP_INPUT_NONINVERTING)) \
416                          | (hopamp->Init.TrimmingValueNLowPower));
417         MODIFY_REG(hopamp->Instance->LPOTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr);
418       }
419     }
420 
421     /* Configure the power supply range */
422     /* The OPAMP_CSR_OPARANGE is common configuration for all OPAMPs */
423     /* bit OPAMP1_CSR_OPARANGE is used for both OPAMPs */
424     MODIFY_REG(OPAMP1->CSR, OPAMP1_CSR_OPARANGE, hopamp->Init.PowerSupplyRange);
425 
426     /* Update the OPAMP state*/
427     if (hopamp->State == HAL_OPAMP_STATE_RESET)
428     {
429       /* From RESET state to READY State */
430       hopamp->State = HAL_OPAMP_STATE_READY;
431     }
432     /* else: remain in READY or BUSY state (no update) */
433     return status;
434   }
435 }
436 
437 /**
438   * @brief  DeInitialize the OPAMP peripheral.
439   * @note   Deinitialization can be performed if the OPAMP configuration is locked.
440   *         (the lock is SW in L4)
441   * @param  hopamp OPAMP handle
442   * @retval HAL status
443   */
HAL_OPAMP_DeInit(OPAMP_HandleTypeDef * hopamp)444 HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef *hopamp)
445 {
446   HAL_StatusTypeDef status = HAL_OK;
447 
448   /* Check the OPAMP handle allocation */
449   /* DeInit not allowed if calibration is ongoing */
450   if(hopamp == NULL)
451   {
452     status = HAL_ERROR;
453   }
454   else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
455   {
456     status = HAL_ERROR;
457   }
458   else
459   {
460     /* Check the parameter */
461     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
462 
463     /* Set OPAMP_CSR register to reset value */
464     /* Mind that OPAMP1_CSR_OPARANGE of CSR of OPAMP1 remains unchanged (applies to both OPAMPs) */
465     /* OPAMP shall be disabled first separately */
466     CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
467     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_RESET_BITS, OPAMP_CSR_RESET_VALUE);
468 
469 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
470   if(hopamp->MspDeInitCallback == NULL)
471   {
472     hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
473   }
474   /* DeInit the low level hardware */
475   hopamp->MspDeInitCallback(hopamp);
476 #else
477     /* DeInit the low level hardware: GPIO, CLOCK and NVIC */
478     HAL_OPAMP_MspDeInit(hopamp);
479 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
480     /* Update the OPAMP state*/
481     hopamp->State = HAL_OPAMP_STATE_RESET;
482 
483     /* Process unlocked */
484     __HAL_UNLOCK(hopamp);
485   }
486   return status;
487 }
488 
489 /**
490   * @brief  Initialize the OPAMP MSP.
491   * @param  hopamp OPAMP handle
492   * @retval None
493   */
HAL_OPAMP_MspInit(OPAMP_HandleTypeDef * hopamp)494 __weak void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef *hopamp)
495 {
496   /* Prevent unused argument(s) compilation warning */
497   UNUSED(hopamp);
498 
499   /* NOTE : This function should not be modified, when the callback is needed,
500             the function "HAL_OPAMP_MspInit()" must be implemented in the user file.
501    */
502 }
503 
504 /**
505   * @brief  DeInitialize OPAMP MSP.
506   * @param  hopamp OPAMP handle
507   * @retval None
508   */
HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef * hopamp)509 __weak void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef *hopamp)
510 {
511   /* Prevent unused argument(s) compilation warning */
512   UNUSED(hopamp);
513 
514   /* NOTE : This function should not be modified, when the callback is needed,
515             the function "HAL_OPAMP_MspDeInit()" must be implemented in the user file.
516    */
517 }
518 
519 /**
520   * @}
521   */
522 
523 
524 /** @defgroup OPAMP_Exported_Functions_Group2 IO operation functions
525  *  @brief   IO operation functions
526  *
527 @verbatim
528  ===============================================================================
529                         ##### IO operation functions #####
530  ===============================================================================
531     [..]
532     This subsection provides a set of functions allowing to manage the OPAMP
533     start, stop and calibration actions.
534 
535 @endverbatim
536   * @{
537   */
538 
539 /**
540   * @brief  Start the OPAMP.
541   * @param  hopamp OPAMP handle
542   * @retval HAL status
543   */
544 
HAL_OPAMP_Start(OPAMP_HandleTypeDef * hopamp)545 HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef *hopamp)
546 {
547   HAL_StatusTypeDef status = HAL_OK;
548 
549   /* Check the OPAMP handle allocation */
550   /* Check if OPAMP locked */
551   if(hopamp == NULL)
552   {
553     status = HAL_ERROR;
554   }
555   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
556   {
557     status = HAL_ERROR;
558   }
559   else
560   {
561     /* Check the parameter */
562     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
563 
564     if(hopamp->State == HAL_OPAMP_STATE_READY)
565     {
566       /* Enable the selected opamp */
567       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
568 
569       /* Update the OPAMP state*/
570       /* From HAL_OPAMP_STATE_READY to HAL_OPAMP_STATE_BUSY */
571       hopamp->State = HAL_OPAMP_STATE_BUSY;
572     }
573     else
574     {
575       status = HAL_ERROR;
576     }
577 
578    }
579   return status;
580 }
581 
582 /**
583   * @brief  Stop the OPAMP.
584   * @param  hopamp OPAMP handle
585   * @retval HAL status
586   */
HAL_OPAMP_Stop(OPAMP_HandleTypeDef * hopamp)587 HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef *hopamp)
588 {
589   HAL_StatusTypeDef status = HAL_OK;
590 
591   /* Check the OPAMP handle allocation */
592   /* Check if OPAMP locked */
593   /* Check if OPAMP calibration ongoing */
594   if(hopamp == NULL)
595   {
596     status = HAL_ERROR;
597   }
598   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
599   {
600     status = HAL_ERROR;
601   }
602   else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
603   {
604     status = HAL_ERROR;
605   }
606   else
607   {
608     /* Check the parameter */
609     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
610 
611     if(hopamp->State == HAL_OPAMP_STATE_BUSY)
612     {
613       /* Disable the selected opamp */
614       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
615 
616       /* Update the OPAMP state*/
617       /* From  HAL_OPAMP_STATE_BUSY to HAL_OPAMP_STATE_READY*/
618       hopamp->State = HAL_OPAMP_STATE_READY;
619     }
620     else
621     {
622       status = HAL_ERROR;
623     }
624   }
625   return status;
626 }
627 
628 /**
629   * @brief  Run the self calibration of one OPAMP.
630   * @note   Calibration is performed in the mode specified in OPAMP init
631   *         structure (mode normal or low-power). To perform calibration for
632   *         both modes, repeat this function twice after OPAMP init structure
633   *         accordingly updated.
634   * @note   Calibration runs about 10 ms.
635   * @param  hopamp handle
636   * @retval Updated offset trimming values (PMOS & NMOS), user trimming is enabled
637   * @retval HAL status
638 
639   */
640 
HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef * hopamp)641 HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef *hopamp)
642 {
643 
644   HAL_StatusTypeDef status = HAL_OK;
645 
646   uint32_t trimmingvaluen;
647   uint32_t trimmingvaluep;
648   uint32_t delta;
649   uint32_t opampmode;
650 
651   __IO uint32_t* tmp_opamp_reg_trimming;   /* Selection of register of trimming depending on power mode: OTR or LPOTR */
652 
653   /* Check the OPAMP handle allocation */
654   /* Check if OPAMP locked */
655   if(hopamp == NULL)
656   {
657     status = HAL_ERROR;
658   }
659   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
660   {
661     status = HAL_ERROR;
662   }
663   else
664   {
665     /* Check if OPAMP in calibration mode and calibration not yet enable */
666     if(hopamp->State ==  HAL_OPAMP_STATE_READY)
667     {
668       /* Check the parameter */
669       assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
670       assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
671 
672       /* Save OPAMP mode as in                                       */
673       /* STM32L471xx STM32L475xx STM32L476xx STM32L485xx STM32L486xx */
674       /* the calibration is not working in PGA mode                  */
675       opampmode = READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_OPAMODE);
676 
677       /* Use of standalone mode */
678       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_OPAMODE, OPAMP_STANDALONE_MODE);
679 
680       /*  user trimming values are used for offset calibration */
681       SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_USERTRIM);
682 
683       /* Select trimming settings depending on power mode */
684       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
685       {
686         tmp_opamp_reg_trimming = &hopamp->Instance->OTR;
687       }
688       else
689       {
690         tmp_opamp_reg_trimming = &hopamp->Instance->LPOTR;
691       }
692 
693       /* Enable calibration */
694       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
695 
696       /* 1st calibration - N */
697       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALSEL);
698 
699       /* Enable the selected opamp */
700       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
701 
702       /* Init trimming counter */
703       /* Medium value */
704       trimmingvaluen = 16U;
705       delta = 8U;
706 
707       while (delta != 0U)
708       {
709         /* Set candidate trimming */
710         /* OPAMP_POWERMODE_NORMAL */
711         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
712 
713         /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
714         /* Offset trim time: during calibration, minimum time needed between */
715         /* two steps to have 1 mV accuracy */
716         HAL_Delay(OPAMP_TRIMMING_DELAY);
717 
718         if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U)
719         {
720           /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
721           trimmingvaluen -= delta;
722         }
723         else
724         {
725           /* OPAMP_CSR_CALOUT is LOW try lower trimming */
726           trimmingvaluen += delta;
727         }
728         /* Divide range by 2 to continue dichotomy sweep */
729         delta >>= 1U;
730       }
731 
732       /* Still need to check if right calibration is current value or one step below */
733       /* Indeed the first value that causes the OUTCAL bit to change from 0 to 1  */
734       /* Set candidate trimming */
735       MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
736 
737       /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
738       /* Offset trim time: during calibration, minimum time needed between */
739       /* two steps to have 1 mV accuracy */
740       HAL_Delay(OPAMP_TRIMMING_DELAY);
741 
742       if ((READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT)) == 0U)
743       {
744         /* Trimming value is actually one value more */
745         trimmingvaluen++;
746         /* Set right trimming */
747         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
748       }
749 
750       /* 2nd calibration - P */
751       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALSEL);
752 
753       /* Init trimming counter */
754       /* Medium value */
755       trimmingvaluep = 16U;
756       delta = 8U;
757 
758       while (delta != 0U)
759       {
760         /* Set candidate trimming */
761         /* OPAMP_POWERMODE_NORMAL */
762         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
763 
764         /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
765         /* Offset trim time: during calibration, minimum time needed between */
766         /* two steps to have 1 mV accuracy */
767         HAL_Delay(OPAMP_TRIMMING_DELAY);
768 
769         if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U)
770         {
771           /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
772           trimmingvaluep += delta;
773         }
774         else
775         {
776           /* OPAMP_CSR_CALOUT  is LOW try lower trimming */
777           trimmingvaluep -= delta;
778         }
779 
780         /* Divide range by 2 to continue dichotomy sweep */
781         delta >>= 1U;
782       }
783 
784       /* Still need to check if right calibration is current value or one step below */
785       /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0  */
786       /* Set candidate trimming */
787       MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
788 
789       /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
790       /* Offset trim time: during calibration, minimum time needed between */
791       /* two steps to have 1 mV accuracy */
792       HAL_Delay(OPAMP_TRIMMING_DELAY);
793 
794       if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U)
795       {
796         /* Trimming value is actually one value more */
797         trimmingvaluep++;
798         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
799       }
800 
801       /* Disable the OPAMP */
802       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
803 
804       /* Disable calibration & set normal mode (operating mode) */
805       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
806 
807       /* Self calibration is successful  */
808       /* Store calibration(user trimming) results in init structure. */
809 
810       /* Set user trimming mode */
811       hopamp->Init.UserTrimming = OPAMP_TRIMMING_USER;
812 
813       /* Affect calibration parameters depending on mode normal/low power */
814       if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
815       {
816         /* Write calibration result N */
817         hopamp->Init.TrimmingValueN = trimmingvaluen;
818         /* Write calibration result P */
819         hopamp->Init.TrimmingValueP = trimmingvaluep;
820       }
821       else
822       {
823         /* Write calibration result N */
824         hopamp->Init.TrimmingValueNLowPower = trimmingvaluen;
825         /* Write calibration result P */
826         hopamp->Init.TrimmingValuePLowPower = trimmingvaluep;
827       }
828 
829     /* Restore OPAMP mode after calibration */
830     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_OPAMODE, opampmode);
831     }
832     else
833     {
834       /* OPAMP can not be calibrated from this mode */
835       status = HAL_ERROR;
836     }
837   }
838   return status;
839 }
840 
841 /**
842   * @}
843   */
844 
845 /** @defgroup OPAMP_Exported_Functions_Group3 Peripheral Control functions
846  *  @brief   Peripheral Control functions
847  *
848 @verbatim
849  ===============================================================================
850                       ##### Peripheral Control functions #####
851  ===============================================================================
852     [..]
853     This subsection provides a set of functions allowing to control the OPAMP data
854     transfers.
855 
856 
857 
858 @endverbatim
859   * @{
860   */
861 
862 /**
863   * @brief  Lock the selected OPAMP configuration.
864   * @note   On STM32L4, HAL OPAMP lock is software lock only (in
865   *         contrast of hardware lock available on some other STM32
866   *         devices).
867   * @param  hopamp OPAMP handle
868   * @retval HAL status
869   */
HAL_OPAMP_Lock(OPAMP_HandleTypeDef * hopamp)870 HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef *hopamp)
871 {
872   HAL_StatusTypeDef status = HAL_OK;
873 
874   /* Check the OPAMP handle allocation */
875   /* Check if OPAMP locked */
876   /* OPAMP can be locked when enabled and running in normal mode */
877   /*   It is meaningless otherwise */
878   if(hopamp == NULL)
879   {
880     status = HAL_ERROR;
881   }
882   else if(hopamp->State == HAL_OPAMP_STATE_BUSY)
883   {
884     /* Check the parameter */
885     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
886 
887    /* OPAMP state changed to locked */
888     hopamp->State = HAL_OPAMP_STATE_BUSYLOCKED;
889   }
890   else
891   {
892     status = HAL_ERROR;
893   }
894   return status;
895 }
896 
897 /**
898   * @brief  Return the OPAMP factory trimming value.
899   * @note            On STM32L4 OPAMP, user can retrieve factory trimming if
900   *                  OPAMP has never been set to user trimming before.
901   *                  Therefore, this function must be called when OPAMP init
902   *                  parameter "UserTrimming" is set to trimming factory,
903   *                  and before OPAMP  calibration (function
904   *                  "HAL_OPAMP_SelfCalibrate()").
905   *                  Otherwise, factory trimming value cannot be retrieved and
906   *                  error status is returned.
907   * @param  hopamp : OPAMP handle
908   * @param  trimmingoffset : Trimming offset (P or N)
909   *         This parameter must be a value of @ref OPAMP_FactoryTrimming
910   * @note   Calibration parameter retrieved is corresponding to the mode
911   *         specified in OPAMP init structure (mode normal or low-power).
912   *         To retrieve calibration parameters for both modes, repeat this
913   *         function after OPAMP init structure accordingly updated.
914   * @retval Trimming value (P or N): range: 0->31
915   *         or OPAMP_FACTORYTRIMMING_DUMMY if trimming value is not available
916   *
917   */
918 
HAL_OPAMP_GetTrimOffset(OPAMP_HandleTypeDef * hopamp,uint32_t trimmingoffset)919 HAL_OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset (OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset)
920 {
921   HAL_OPAMP_TrimmingValueTypeDef trimmingvalue;
922   __IO uint32_t* tmp_opamp_reg_trimming;  /* Selection of register of trimming depending on power mode: OTR or LPOTR */
923 
924   /* Check the OPAMP handle allocation */
925   /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
926   if(hopamp == NULL)
927   {
928     return OPAMP_FACTORYTRIMMING_DUMMY;
929   }
930 
931   /* Check the OPAMP handle allocation */
932   /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
933   if(hopamp->State == HAL_OPAMP_STATE_READY)
934   {
935     /* Check the parameter */
936     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
937     assert_param(IS_OPAMP_FACTORYTRIMMING(trimmingoffset));
938     assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
939 
940     /* Check the trimming mode */
941     if (READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_USERTRIM) != 0U)
942     {
943       /* This function must called when OPAMP init parameter "UserTrimming"   */
944       /* is set to trimming factory, and before OPAMP calibration (function   */
945       /* "HAL_OPAMP_SelfCalibrate()").                                        */
946       /* Otherwise, factory trimming value cannot be retrieved and error       */
947       /* status is returned.                                                  */
948       trimmingvalue = OPAMP_FACTORYTRIMMING_DUMMY;
949     }
950     else
951     {
952       /* Select trimming settings depending on power mode */
953       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
954       {
955         tmp_opamp_reg_trimming = &OPAMP->OTR;
956       }
957       else
958       {
959         tmp_opamp_reg_trimming = &OPAMP->LPOTR;
960       }
961 
962       /* Get factory trimming  */
963       if (trimmingoffset == OPAMP_FACTORYTRIMMING_P)
964       {
965         /* OPAMP_FACTORYTRIMMING_P */
966         trimmingvalue = ((*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING;
967       }
968       else
969       {
970         /* OPAMP_FACTORYTRIMMING_N */
971         trimmingvalue = (*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETN;
972       }
973     }
974   }
975   else
976   {
977     return OPAMP_FACTORYTRIMMING_DUMMY;
978   }
979   return trimmingvalue;
980 }
981 
982 /**
983   * @}
984   */
985 
986 
987 /** @defgroup OPAMP_Exported_Functions_Group4 Peripheral State functions
988  *  @brief   Peripheral State functions
989  *
990 @verbatim
991  ===============================================================================
992                       ##### Peripheral State functions #####
993  ===============================================================================
994     [..]
995     This subsection permits to get in run-time the status of the peripheral.
996 
997 @endverbatim
998   * @{
999   */
1000 
1001 /**
1002   * @brief  Return the OPAMP handle state.
1003   * @param  hopamp : OPAMP handle
1004   * @retval HAL state
1005   */
HAL_OPAMP_GetState(OPAMP_HandleTypeDef * hopamp)1006 HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(OPAMP_HandleTypeDef *hopamp)
1007 {
1008   /* Check the OPAMP handle allocation */
1009   if(hopamp == NULL)
1010   {
1011     return HAL_OPAMP_STATE_RESET;
1012   }
1013 
1014   /* Check the parameter */
1015   assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
1016 
1017   /* Return OPAMP handle state */
1018   return hopamp->State;
1019 }
1020 
1021 /**
1022   * @}
1023   */
1024 
1025 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
1026 /**
1027   * @brief  Register a User OPAMP Callback
1028   *         To be used instead of the weak (surcharged) predefined callback
1029   * @param hopamp : OPAMP handle
1030   * @param CallbackID : ID of the callback to be registered
1031   *        This parameter can be one of the following values:
1032   *          @arg @ref HAL_OPAMP_MSPINIT_CB_ID       OPAMP MspInit callback ID
1033   *          @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID     OPAMP MspDeInit callback ID
1034   * @param pCallback : pointer to the Callback function
1035   * @retval status
1036   */
HAL_OPAMP_RegisterCallback(OPAMP_HandleTypeDef * hopamp,HAL_OPAMP_CallbackIDTypeDef CallbackID,pOPAMP_CallbackTypeDef pCallback)1037 HAL_StatusTypeDef HAL_OPAMP_RegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackID, pOPAMP_CallbackTypeDef pCallback)
1038 {
1039   HAL_StatusTypeDef status = HAL_OK;
1040 
1041   if(pCallback == NULL)
1042   {
1043     return HAL_ERROR;
1044   }
1045 
1046   /* Process locked */
1047   __HAL_LOCK(hopamp);
1048 
1049   if(hopamp->State == HAL_OPAMP_STATE_READY)
1050   {
1051     switch (CallbackID)
1052     {
1053     case HAL_OPAMP_MSPINIT_CB_ID :
1054       hopamp->MspInitCallback = pCallback;
1055       break;
1056     case HAL_OPAMP_MSPDEINIT_CB_ID :
1057       hopamp->MspDeInitCallback = pCallback;
1058       break;
1059     default :
1060       /* update return status */
1061       status =  HAL_ERROR;
1062       break;
1063     }
1064   }
1065   else if (hopamp->State == HAL_OPAMP_STATE_RESET)
1066   {
1067     switch (CallbackID)
1068     {
1069     case HAL_OPAMP_MSPINIT_CB_ID :
1070       hopamp->MspInitCallback = pCallback;
1071       break;
1072     case HAL_OPAMP_MSPDEINIT_CB_ID :
1073       hopamp->MspDeInitCallback = pCallback;
1074       break;
1075     default :
1076       /* update return status */
1077       status =  HAL_ERROR;
1078       break;
1079     }
1080   }
1081   else
1082   {
1083     /* update return status */
1084     status =  HAL_ERROR;
1085   }
1086 
1087   /* Release Lock */
1088   __HAL_UNLOCK(hopamp);
1089   return status;
1090 }
1091 
1092 /**
1093   * @brief  Unregister a User OPAMP Callback
1094   *         OPAMP Callback is redirected to the weak (surcharged) predefined callback
1095   * @param hopamp : OPAMP handle
1096   * @param CallbackID : ID of the callback to be unregistered
1097   *        This parameter can be one of the following values:
1098   *          @arg @ref HAL_OPAMP_MSPINIT_CB_ID              OPAMP MSP Init Callback ID
1099   *          @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID            OPAMP MSP DeInit Callback ID
1100   *          @arg @ref HAL_OPAMP_ALL_CB_ID                   OPAMP All Callbacks
1101   * @retval status
1102   */
1103 
HAL_OPAMP_UnRegisterCallback(OPAMP_HandleTypeDef * hopamp,HAL_OPAMP_CallbackIDTypeDef CallbackID)1104 HAL_StatusTypeDef HAL_OPAMP_UnRegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackID)
1105 {
1106   HAL_StatusTypeDef status = HAL_OK;
1107 
1108   /* Process locked */
1109   __HAL_LOCK(hopamp);
1110 
1111   if(hopamp->State == HAL_OPAMP_STATE_READY)
1112   {
1113     switch (CallbackID)
1114     {
1115       case HAL_OPAMP_MSPINIT_CB_ID :
1116       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1117       break;
1118     case HAL_OPAMP_MSPDEINIT_CB_ID :
1119       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1120       break;
1121     case HAL_OPAMP_ALL_CB_ID :
1122       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1123       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1124       break;
1125     default :
1126       /* update return status */
1127       status =  HAL_ERROR;
1128       break;
1129     }
1130   }
1131   else if (hopamp->State == HAL_OPAMP_STATE_RESET)
1132   {
1133     switch (CallbackID)
1134     {
1135     case HAL_OPAMP_MSPINIT_CB_ID :
1136       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1137       break;
1138     case HAL_OPAMP_MSPDEINIT_CB_ID :
1139       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1140       break;
1141     default :
1142       /* update return status */
1143       status =  HAL_ERROR;
1144       break;
1145     }
1146   }
1147   else
1148   {
1149     /* update return status */
1150     status =  HAL_ERROR;
1151   }
1152 
1153   /* Release Lock */
1154   __HAL_UNLOCK(hopamp);
1155   return status;
1156 }
1157 
1158 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
1159 
1160 
1161 /**
1162   * @}
1163   */
1164 
1165   /**
1166   * @}
1167   */
1168 
1169 #endif /* HAL_OPAMP_MODULE_ENABLED */
1170 /**
1171   * @}
1172   */
1173 
1174 /**
1175   * @}
1176   */
1177 
1178 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1179