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