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