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