1 /**
2 ******************************************************************************
3 * @file stm32l1xx_hal_opamp.c
4 * @author MCD Application Team
5 * @brief OPAMP HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the operational amplifier(s) peripheral:
8 * + OPAMP configuration
9 * + OPAMP calibration
10 * Thanks to
11 * + Initialization and de-initialization functions
12 * + IO operation functions
13 * + Peripheral Control functions
14 * + Peripheral State functions
15 *
16 @verbatim
17 ================================================================================
18 ##### OPAMP Peripheral Features #####
19 ================================================================================
20 [..] The device integrates up to 3 operational amplifiers OPAMP1, OPAMP2,
21 OPAMP3 (OPAMP3 availability depends on device category)
22
23 (#) The OPAMP(s) provide(s) several exclusive running modes.
24 (++) Standalone mode
25 (++) Follower mode
26
27 (#) All OPAMP (same for all OPAMPs) can operate in
28 (++) Either Low range (VDDA < 2.4V) power supply
29 (++) Or High range (VDDA > 2.4V) power supply
30
31 (#) Each OPAMP(s) can be configured in normal and low power mode.
32
33 (#) The OPAMP(s) provide(s) calibration capabilities.
34 (++) Calibration aims at correcting some offset for running mode.
35 (++) The OPAMP uses either factory calibration settings OR user defined
36 calibration (trimming) settings (i.e. trimming mode).
37 (++) The user defined settings can be figured out using self calibration
38 handled by HAL_OPAMP_SelfCalibrate, HAL_OPAMPEx_SelfCalibrateAll
39 (++) HAL_OPAMP_SelfCalibrate:
40 (+++) Runs automatically the calibration in 2 steps: for transistors
41 differential pair high (PMOS) or low (NMOS)
42 (+++) Enables the user trimming mode
43 (+++) Updates the init structure with trimming values with fresh calibration
44 results.
45 The user may store the calibration results for larger
46 (ex monitoring the trimming as a function of temperature
47 for instance)
48 (+++) For devices having several OPAMPs, HAL_OPAMPEx_SelfCalibrateAll
49 runs calibration of all OPAMPs in parallel to save search time.
50
51 (#) Running mode: Standalone mode
52 (++) Gain is set externally (gain depends on external loads).
53 (++) Follower mode also possible externally by connecting the inverting input to
54 the output.
55
56 (#) Running mode: Follower mode
57 (++) No Inverting Input is connected.
58 (++) The OPAMP(s) output(s) are internally connected to inverting input.
59
60 ##### How to use this driver #####
61 ================================================================================
62 [..]
63
64 *** Power supply range ***
65 ============================================
66 [..] To run in low power mode:
67
68 (#) Configure the OPAMP using HAL_OPAMP_Init() function:
69 (++) Select OPAMP_POWERSUPPLY_LOW (VDDA lower than 2.4V)
70 (++) Otherwise select OPAMP_POWERSUPPLY_HIGH (VDDA higher than 2.4V)
71
72 *** Low / normal power mode ***
73 ============================================
74 [..] To run in low power mode:
75
76 (#) Configure the OPAMP using HAL_OPAMP_Init() function:
77 (++) Select OPAMP_POWERMODE_LOWPOWER
78 (++) Otherwise select OPAMP_POWERMODE_NORMAL
79
80 *** Calibration ***
81 ============================================
82 [..] To run the OPAMP calibration self calibration:
83
84 (#) Start calibration using HAL_OPAMP_SelfCalibrate.
85 Store the calibration results.
86
87 *** Running mode ***
88 ============================================
89
90 [..] To use the OPAMP, perform the following steps:
91
92 (#) Fill in the HAL_OPAMP_MspInit() to
93 (++) Enable the OPAMP Peripheral clock using macro __HAL_RCC_OPAMP_CLK_ENABLE()
94 (++) Configure the OPAMP input AND output in analog mode using
95 HAL_GPIO_Init() to map the OPAMP output to the GPIO pin.
96
97 (#) Registrate Callbacks
98 (++) The compilation define USE_HAL_OPAMP_REGISTER_CALLBACKS when set to 1
99 allows the user to configure dynamically the driver callbacks.
100
101 (++) Use Functions @ref HAL_OPAMP_RegisterCallback() to register a user callback,
102 it allows to register following callbacks:
103 (+++) MspInitCallback : OPAMP MspInit.
104 (+++) MspDeInitCallback : OPAMP MspFeInit.
105 This function takes as parameters the HAL peripheral handle, the Callback ID
106 and a pointer to the user callback function.
107
108 (++) Use function @ref HAL_OPAMP_UnRegisterCallback() to reset a callback to the default
109 weak (surcharged) function. It allows to reset following callbacks:
110 (+++) MspInitCallback : OPAMP MspInit.
111 (+++) MspDeInitCallback : OPAMP MspdeInit.
112 (+++) All Callbacks
113
114 (#) Configure the OPAMP using HAL_OPAMP_Init() function:
115 (++) Select the mode
116 (++) Select the inverting input
117 (++) Select the non-inverting input
118 (++) Select either factory or user defined trimming mode.
119 (++) If the user-defined trimming mode is enabled, select PMOS & NMOS trimming values
120 (typically values set by HAL_OPAMP_SelfCalibrate function).
121
122 (#) Enable the OPAMP using HAL_OPAMP_Start() function.
123
124 (#) Disable the OPAMP using HAL_OPAMP_Stop() function.
125
126 (#) Lock the OPAMP in running mode using HAL_OPAMP_Lock() function.
127 Caution: On STM32L1, HAL OPAMP lock is software lock only (not
128 hardware lock as on some other STM32 devices)
129
130 (#) If needed, unlock the OPAMP using HAL_OPAMPEx_Unlock() function.
131
132 *** Running mode: change of configuration while OPAMP ON ***
133 ============================================
134 [..] To Re-configure OPAMP when OPAMP is ON (change on the fly)
135 (#) If needed, fill in the HAL_OPAMP_MspInit()
136 (++) This is the case for instance if you wish to use new OPAMP I/O
137
138 (#) Configure the OPAMP using HAL_OPAMP_Init() function:
139 (++) As in configure case, select first the parameters you wish to modify.
140
141 (#) Change from low power mode to normal power mode (& vice versa) requires
142 first HAL_OPAMP_DeInit() (force OPAMP OFF) and then HAL_OPAMP_Init().
143 In other words, of OPAMP is ON, HAL_OPAMP_Init can NOT change power mode
144 alone.
145
146 @endverbatim
147 ******************************************************************************
148 * @attention
149 *
150 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
151 * All rights reserved.</center></h2>
152 *
153 * This software component is licensed by ST under BSD 3-Clause license,
154 * the "License"; You may not use this file except in compliance with the
155 * License. You may obtain a copy of the License at:
156 * opensource.org/licenses/BSD-3-Clause
157 *
158 ******************************************************************************
159 */
160
161 /*
162 Additionnal remark:
163 The OPAMPs inverting input can be selected among the list shown by table below.
164 The OPAMPs non inverting input can be selected among the list shown by table below.
165
166 Table 1. OPAMPs inverting/non-inverting inputs for STM32L1 devices:
167 +--------------------------------------------------------------------------+
168 | | HAL param | OPAMP1 | OPAMP2 | OPAMP3(4) |
169 | | name | | | |
170 |----------------|------------|--------------|--------------|--------------|
171 | Inverting | VM0 | PA2 | PA7 | PC2 |
172 | input (1) | VM1 | VINM pin (2) | VINM pin (2) | VINM pin (2) |
173 |----------------|------------|--------------|--------------|--------------|
174 | Non Inverting | VP0 | PA1 | PA6 | PC1 |
175 | input | DAC_CH1 (3)| DAC_CH1 | DAC_CH1 | --- |
176 | | DAC_CH2 (3)| --- | DAC_CH2 | DAC_CH2 |
177 +--------------------------------------------------------------------------+
178 (1): NA in follower mode.
179 (2): OPAMP input OPAMPx_VINM are dedicated OPAMP pins, their availability
180 depends on device package.
181 (3): DAC channels 1 and 2 are connected internally to OPAMP. Nevertheless,
182 I/O pins connected to DAC can still be used as DAC output (pins PA4
183 and PA5).
184 (4): OPAMP3 availability depends on device category.
185
186 Table 2. OPAMPs outputs for STM32L1 devices:
187 +--------------------------------------------------------+
188 | | OPAMP1 | OPAMP2 | OPAMP3(4) |
189 |-----------------|------------|------------|------------|
190 | Output | PA3 | PB0 | PC3 |
191 +--------------------------------------------------------+
192 (4) : OPAMP3 availability depends on device category
193 */
194
195 /* Includes ------------------------------------------------------------------*/
196 #include "stm32l1xx_hal.h"
197
198 /** @addtogroup STM32L1xx_HAL_Driver
199 * @{
200 */
201
202 /** @defgroup OPAMP OPAMP
203 * @brief OPAMP module driver
204 * @{
205 */
206
207 #ifdef HAL_OPAMP_MODULE_ENABLED
208
209 #if defined (STM32L151xCA) || defined (STM32L151xD) || defined (STM32L152xCA) || defined (STM32L152xD) || defined (STM32L162xCA) || defined (STM32L162xD) || defined (STM32L151xE) || defined (STM32L151xDX) || defined (STM32L152xE) || defined (STM32L152xDX) || defined (STM32L162xE) || defined (STM32L162xDX) || defined (STM32L162xC) || defined (STM32L152xC) || defined (STM32L151xC)
210
211 /* Private typedef -----------------------------------------------------------*/
212 /* Private define ------------------------------------------------------------*/
213 /* Private macro -------------------------------------------------------------*/
214 /* Private variables ---------------------------------------------------------*/
215 /* Private constants ---------------------------------------------------------*/
216 /* Private function prototypes -----------------------------------------------*/
217 /* Private functions ---------------------------------------------------------*/
218 /* Exported functions --------------------------------------------------------*/
219
220 /** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions
221 * @{
222 */
223
224 /** @defgroup OPAMP_Exported_Functions_Group1 Initialization and de-initialization functions
225 * @brief Initialization and Configuration functions
226 *
227 @verbatim
228 ==============================================================================
229 ##### Initialization and de-initialization functions #####
230 ==============================================================================
231 [..] This section provides functions allowing to:
232
233 @endverbatim
234 * @{
235 */
236
237 /**
238 * @brief Initializes the OPAMP according to the specified
239 * parameters in the OPAMP_InitTypeDef and create the associated handle.
240 * @note If the selected opamp is locked, initialization can't be performed.
241 * To unlock the configuration, perform a system reset.
242 * @param hopamp OPAMP handle
243 * @retval HAL status
244 */
HAL_OPAMP_Init(OPAMP_HandleTypeDef * hopamp)245 HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef* hopamp)
246 {
247 HAL_StatusTypeDef status = HAL_OK;
248 uint32_t tmp_csr; /* Temporary variable to update register CSR, except bits ANAWSSELx, S7SEL2, OPA_RANGE, OPAxCALOUT */
249
250 /* Check the OPAMP handle allocation and lock status */
251 /* Init not allowed if calibration is ongoing */
252 if(hopamp == NULL)
253 {
254 return HAL_ERROR;
255 }
256 else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
257 {
258 return HAL_ERROR;
259 }
260 else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
261 {
262 return HAL_ERROR;
263 }
264 else
265 {
266 /* Check the parameter */
267 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
268
269 /* Set OPAMP parameters */
270 assert_param(IS_OPAMP_POWER_SUPPLY_RANGE(hopamp->Init.PowerSupplyRange));
271 assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
272 assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode));
273 assert_param(IS_OPAMP_NONINVERTING_INPUT_CHECK_INSTANCE(hopamp, hopamp->Init.NonInvertingInput));
274 assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming));
275
276 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
277 if(hopamp->State == HAL_OPAMP_STATE_RESET)
278 {
279 if(hopamp->MspInitCallback == NULL)
280 {
281 hopamp->MspInitCallback = HAL_OPAMP_MspInit;
282 }
283 }
284 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
285
286 if (hopamp->Init.Mode != OPAMP_FOLLOWER_MODE)
287 {
288 assert_param(IS_OPAMP_INVERTING_INPUT(hopamp->Init.InvertingInput));
289 }
290
291 if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER)
292 {
293 if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
294 {
295 assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP));
296 assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN));
297 }
298 else
299 {
300 assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValuePLowPower));
301 assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueNLowPower));
302 }
303 }
304
305 if(hopamp->State == HAL_OPAMP_STATE_RESET)
306 {
307 /* Allocate lock resource and initialize it */
308 hopamp->Lock = HAL_UNLOCKED;
309 }
310
311 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
312 hopamp->MspInitCallback(hopamp);
313 #else
314 /* Call MSP init function */
315 HAL_OPAMP_MspInit(hopamp);
316 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
317
318 /* Set OPAMP parameters */
319 /* - Set internal switches in function of: */
320 /* - OPAMP selected mode: standalone or follower. */
321 /* - Non-inverting input connection */
322 /* - Inverting input connection */
323 /* - Set power supply range */
324 /* - Set power mode and associated calibration parameters */
325
326 /* Get OPAMP CSR register into temporary variable */
327 /* Note: OPAMP register CSR is written directly, independently of OPAMP */
328 /* instance, because all OPAMP settings are dispatched in the same */
329 /* register. */
330 /* Settings of bits for each OPAMP instances are managed case by */
331 /* case using macro (OPAMP_CSR_S3SELX(), OPAMP_CSR_ANAWSELX(), ...) */
332 tmp_csr = OPAMP->CSR;
333
334 /* Open all switches on non-inverting input, inverting input and output */
335 /* feedback. */
336 CLEAR_BIT(tmp_csr, OPAMP_CSR_ALL_SWITCHES(hopamp));
337
338 /* Set internal switches in function of OPAMP mode selected: standalone */
339 /* or follower. */
340 /* If follower mode is selected, feedback switch S3 is closed and */
341 /* inverting inputs switches are let opened. */
342 /* If standalone mode is selected, feedback switch S3 is let opened and */
343 /* the selected inverting inputs switch is closed. */
344 if (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE)
345 {
346 /* Follower mode: Close switches S3 and SanB */
347 SET_BIT(tmp_csr, OPAMP_CSR_S3SELX(hopamp));
348 }
349 else
350 {
351 /* Set internal switches in function of inverting input selected: */
352 /* Close switch to connect OPAMP inverting input to the selected */
353 /* input: dedicated IO pin or alternative IO pin available on some */
354 /* device packages. */
355 if (hopamp->Init.InvertingInput == OPAMP_INVERTINGINPUT_IO0)
356 {
357 /* Close switch to connect OPAMP non-inverting input to */
358 /* dedicated IO pin low-leakage. */
359 SET_BIT(tmp_csr, OPAMP_CSR_S4SELX(hopamp));
360 }
361 else
362 {
363 /* Close switch to connect OPAMP inverting input to alternative */
364 /* IO pin available on some device packages. */
365 SET_BIT(tmp_csr, OPAMP_CSR_ANAWSELX(hopamp));
366 }
367 }
368
369 /* Set internal switches in function of non-inverting input selected: */
370 /* Close switch to connect OPAMP non-inverting input to the selected */
371 /* input: dedicated IO pin or DAC channel. */
372 if (hopamp->Init.NonInvertingInput == OPAMP_NONINVERTINGINPUT_IO0)
373 {
374 /* Close switch to connect OPAMP non-inverting input to */
375 /* dedicated IO pin low-leakage. */
376 SET_BIT(tmp_csr, OPAMP_CSR_S5SELX(hopamp));
377 }
378 else if (hopamp->Init.NonInvertingInput == OPAMP_NONINVERTINGINPUT_DAC_CH1)
379 {
380
381 /* Particular case for connection to DAC channel 1: */
382 /* OPAMP_NONINVERTINGINPUT_DAC_CH1 available on OPAMP1 and OPAMP2 only */
383 /* (OPAMP3 availability depends on device category). */
384 if ((hopamp->Instance == OPAMP1) || (hopamp->Instance == OPAMP2))
385 {
386 /* Close switch to connect OPAMP non-inverting input to */
387 /* DAC channel 1. */
388 SET_BIT(tmp_csr, OPAMP_CSR_S6SELX(hopamp));
389 }
390 else
391 {
392 /* Set HAL status to error if another OPAMP instance as OPAMP1 or */
393 /* OPAMP2 is intended to be connected to DAC channel 2. */
394 status = HAL_ERROR;
395 }
396 }
397 else /* if (hopamp->Init.NonInvertingInput == */
398 /* OPAMP_NONINVERTINGINPUT_DAC_CH2 ) */
399 {
400 /* Particular case for connection to DAC channel 2: */
401 /* OPAMP_NONINVERTINGINPUT_DAC_CH2 available on OPAMP2 and OPAMP3 only */
402 /* (OPAMP3 availability depends on device category). */
403 if (hopamp->Instance == OPAMP2)
404 {
405 /* Close switch to connect OPAMP non-inverting input to */
406 /* DAC channel 2. */
407 SET_BIT(tmp_csr, OPAMP_CSR_S7SEL2);
408 }
409 /* If OPAMP3 is selected (if available) */
410 else if (hopamp->Instance != OPAMP1)
411 {
412 /* Close switch to connect OPAMP non-inverting input to */
413 /* DAC channel 2. */
414 SET_BIT(tmp_csr, OPAMP_CSR_S6SELX(hopamp));
415 }
416 else
417 {
418 /* Set HAL status to error if another OPAMP instance as OPAMP2 or */
419 /* OPAMP3 (if available) is intended to be connected to DAC channel 2.*/
420 status = HAL_ERROR;
421 }
422 }
423
424 /* Continue OPAMP configuration if settings of switches are correct */
425 if (status != HAL_ERROR)
426 {
427 /* Set power mode and associated calibration parameters */
428 if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
429 {
430 /* Set normal mode */
431 CLEAR_BIT(tmp_csr, OPAMP_CSR_OPAXLPM(hopamp));
432
433 if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER)
434 {
435 /* Set calibration mode (factory or user) and values for */
436 /* transistors differential pair high (PMOS) and low (NMOS) for */
437 /* normal mode. */
438 MODIFY_REG(OPAMP->OTR, OPAMP_OTR_OT_USER |
439 OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, OPAMP_TRIM_VALUE_MASK) |
440 OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, OPAMP_TRIM_VALUE_MASK) ,
441 hopamp->Init.UserTrimming |
442 OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, hopamp->Init.TrimmingValueN) |
443 OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, hopamp->Init.TrimmingValueP) );
444 }
445 else
446 {
447 /* Set calibration mode to factory */
448 CLEAR_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER);
449 }
450
451 }
452 else
453 {
454 /* Set low power mode */
455 SET_BIT(tmp_csr, OPAMP_CSR_OPAXLPM(hopamp));
456
457 if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER)
458 {
459 /* Set calibration mode to user trimming */
460 SET_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER);
461
462 /* Set values for transistors differential pair high (PMOS) and low */
463 /* (NMOS) for low power mode. */
464 MODIFY_REG(OPAMP->LPOTR, OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, OPAMP_TRIM_VALUE_MASK) |
465 OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, OPAMP_TRIM_VALUE_MASK) ,
466 OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, hopamp->Init.TrimmingValueNLowPower) |
467 OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, hopamp->Init.TrimmingValuePLowPower) );
468 }
469 else
470 {
471 /* Set calibration mode to factory trimming */
472 CLEAR_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER);
473 }
474
475 }
476
477
478 /* Configure the power supply range */
479 MODIFY_REG(tmp_csr, OPAMP_CSR_AOP_RANGE,
480 hopamp->Init.PowerSupplyRange);
481
482 /* Set OPAMP CSR register from temporary variable */
483 /* This allows to apply all changes on one time, in case of update on */
484 /* the fly with OPAMP previously set and running: */
485 /* - to avoid hazardous transient switches settings (risk of short */
486 /* circuit) */
487 /* - to avoid interruption of input signal */
488 OPAMP->CSR = tmp_csr;
489
490
491 /* Update the OPAMP state */
492 /* If coming from state reset: Update from state RESET to state READY */
493 if (hopamp->State == HAL_OPAMP_STATE_RESET)
494 {
495 hopamp->State = HAL_OPAMP_STATE_READY;
496 }
497 /* else: OPAMP state remains READY or BUSY state (no update) */
498 }
499 }
500
501 return status;
502 }
503
504 /**
505 * @brief DeInitializes the OPAMP peripheral
506 * @note Deinitialization can be performed if the OPAMP configuration is locked.
507 * (the OPAMP lock is SW in STM32L1)
508 * @param hopamp OPAMP handle
509 * @retval HAL status
510 */
HAL_OPAMP_DeInit(OPAMP_HandleTypeDef * hopamp)511 HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef* hopamp)
512 {
513 HAL_StatusTypeDef status = HAL_OK;
514
515 /* Check the OPAMP handle allocation */
516 /* DeInit not allowed if calibration is ongoing */
517 if(hopamp == NULL)
518 {
519 status = HAL_ERROR;
520 }
521 else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
522 {
523 status = HAL_ERROR;
524 }
525 else
526 {
527 /* Check the parameter */
528 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
529
530 /* Disable the selected opamp */
531 SET_BIT (OPAMP->CSR, OPAMP_CSR_OPAXPD(hopamp));
532
533 /* Open all switches on non-inverting input, inverting input and output */
534 /* feedback. */
535 /* Note: OPAMP register CSR is written directly, independently of OPAMP */
536 /* instance, because all OPAMP settings are dispatched in the same */
537 /* register. */
538 /* Settings of bits for each OPAMP instances are managed case by */
539 /* case using macro (OPAMP_CSR_S3SELX(), OPAMP_CSR_ANAWSELX(), ...) */
540 CLEAR_BIT(OPAMP->CSR, OPAMP_CSR_ALL_SWITCHES(hopamp));
541
542 /* Note: Registers and bits shared with other OPAMP instances are kept */
543 /* unchanged, to not impact other OPAMP while operating on the */
544 /* selected OPAMP. */
545 /* Unchanged: bit OPAMP_OTR_OT_USER (parameter "UserTrimming") */
546 /* bit OPAMP_CSR_AOP_RANGE (parameter "PowerSupplyRange")*/
547
548 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
549 if(hopamp->MspDeInitCallback == NULL)
550 {
551 hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
552 }
553 /* DeInit the low level hardware */
554 hopamp->MspDeInitCallback(hopamp);
555 #else
556 /* DeInit the low level hardware: GPIO, CLOCK and NVIC */
557 HAL_OPAMP_MspDeInit(hopamp);
558 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
559
560 /* Update the OPAMP state*/
561 hopamp->State = HAL_OPAMP_STATE_RESET;
562 }
563
564 /* Process unlocked */
565 __HAL_UNLOCK(hopamp);
566
567 return status;
568 }
569
570 /**
571 * @brief Initialize the OPAMP MSP.
572 * @param hopamp OPAMP handle
573 * @retval None
574 */
HAL_OPAMP_MspInit(OPAMP_HandleTypeDef * hopamp)575 __weak void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef* hopamp)
576 {
577 /* Prevent unused argument(s) compilation warning */
578 UNUSED(hopamp);
579
580 /* NOTE : This function should not be modified, when the callback is needed,
581 the function "HAL_OPAMP_MspInit()" must be implemented in the user file.
582 */
583 }
584
585 /**
586 * @brief DeInitialize OPAMP MSP.
587 * @param hopamp OPAMP handle
588 * @retval None
589 */
HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef * hopamp)590 __weak void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef* hopamp)
591 {
592 /* Prevent unused argument(s) compilation warning */
593 UNUSED(hopamp);
594
595 /* NOTE : This function should not be modified, when the callback is needed,
596 the function "HAL_OPAMP_MspDeInit()" must be implemented in the user file.
597 */
598 }
599
600 /**
601 * @}
602 */
603
604
605 /** @defgroup OPAMP_Exported_Functions_Group2 IO operation functions
606 * @brief IO operation functions
607 *
608 @verbatim
609 ===============================================================================
610 ##### IO operation functions #####
611 ===============================================================================
612 [..]
613 This subsection provides a set of functions allowing to manage the OPAMP
614 start, stop and calibration actions.
615
616 @endverbatim
617 * @{
618 */
619
620 /**
621 * @brief Start the OPAMP.
622 * @param hopamp OPAMP handle
623 * @retval HAL status
624 */
625
HAL_OPAMP_Start(OPAMP_HandleTypeDef * hopamp)626 HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef* hopamp)
627 {
628 HAL_StatusTypeDef status = HAL_OK;
629
630 /* Check the OPAMP handle allocation */
631 /* Check if OPAMP locked */
632 if(hopamp == NULL)
633 {
634 status = HAL_ERROR;
635 }
636 else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
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_READY)
646 {
647 /* Enable the selected opamp */
648 CLEAR_BIT (OPAMP->CSR, OPAMP_CSR_OPAXPD(hopamp));
649
650 /* Update the OPAMP state */
651 /* From HAL_OPAMP_STATE_READY to HAL_OPAMP_STATE_BUSY */
652 hopamp->State = HAL_OPAMP_STATE_BUSY;
653 }
654 else
655 {
656 status = HAL_ERROR;
657 }
658
659 }
660 return status;
661 }
662
663 /**
664 * @brief Stop the OPAMP.
665 * @param hopamp OPAMP handle
666 * @retval HAL status
667 */
HAL_OPAMP_Stop(OPAMP_HandleTypeDef * hopamp)668 HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef* hopamp)
669 {
670 HAL_StatusTypeDef status = HAL_OK;
671
672 /* Check the OPAMP handle allocation */
673 /* Check if OPAMP locked */
674 /* Check if OPAMP calibration ongoing */
675 if(hopamp == NULL)
676 {
677 status = HAL_ERROR;
678 }
679 else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
680 {
681 status = HAL_ERROR;
682 }
683 else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
684 {
685 status = HAL_ERROR;
686 }
687 else
688 {
689 /* Check the parameter */
690 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
691
692 if(hopamp->State == HAL_OPAMP_STATE_BUSY)
693 {
694 /* Disable the selected opamp */
695 SET_BIT (OPAMP->CSR, OPAMP_CSR_OPAXPD(hopamp));
696
697 /* Update the OPAMP state*/
698 /* From HAL_OPAMP_STATE_BUSY to HAL_OPAMP_STATE_READY*/
699 hopamp->State = HAL_OPAMP_STATE_READY;
700 }
701 else
702 {
703 status = HAL_ERROR;
704 }
705 }
706 return status;
707 }
708
709 /**
710 * @brief Run the self calibration of one OPAMP.
711 * @note Trimming values (PMOS & NMOS) are updated and user trimming is
712 * enabled if calibration is succesful.
713 * @note Calibration is performed in the mode specified in OPAMP init
714 * structure (mode normal or low-power). To perform calibration for
715 * both modes, repeat this function twice after OPAMP init structure
716 * accordingly updated.
717 * @note Calibration runs about 10 ms.
718 * @param hopamp handle
719 * @retval Updated offset trimming values (PMOS & NMOS), user trimming is enabled
720 * @retval HAL status
721 */
HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef * hopamp)722 HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef* hopamp)
723 {
724 HAL_StatusTypeDef status = HAL_OK;
725
726 uint32_t* opamp_trimmingvalue;
727 uint32_t opamp_trimmingvaluen = 0;
728 uint32_t opamp_trimmingvaluep = 0;
729
730 uint32_t trimming_diff_pair; /* Selection of differential transistors pair high or low */
731
732 __IO uint32_t* tmp_opamp_reg_trimming; /* Selection of register of trimming depending on power mode: OTR or LPOTR */
733 uint32_t tmp_opamp_otr_otuser; /* Selection of bit OPAMP_OTR_OT_USER depending on trimming register pointed: OTR or LPOTR */
734
735 uint32_t tmp_Opaxcalout_DefaultSate; /* Bit OPAMP_CSR_OPAXCALOUT default state when trimming value is 00000b. Used to detect the bit toggling */
736
737 uint32_t tmp_OpaxSwitchesContextBackup;
738
739 uint8_t trimming_diff_pair_iteration_count; /* For calibration loop algorithm: to repeat the calibration loop for both differential transistors pair high and low */
740 uint8_t delta; /* For calibration loop algorithm: Variable for dichotomy steps value */
741 uint8_t final_step_check = 0x0U; /* For calibration loop algorithm: Flag for additional check of last trimming step */
742
743 /* Check the OPAMP handle allocation */
744 /* Check if OPAMP locked */
745 if(hopamp == NULL)
746 {
747 status = HAL_ERROR;
748 }
749 else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
750 {
751 status = HAL_ERROR;
752 }
753 else
754 {
755
756 /* Check if OPAMP in calibration mode and calibration not yet enable */
757 if(hopamp->State == HAL_OPAMP_STATE_READY)
758 {
759 /* Check the parameter */
760 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
761 assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
762
763 /* Update OPAMP state */
764 hopamp->State = HAL_OPAMP_STATE_CALIBBUSY;
765
766 /* Backup of switches configuration to restore it at the end of the */
767 /* calibration. */
768 tmp_OpaxSwitchesContextBackup = READ_BIT(OPAMP->CSR, OPAMP_CSR_ALL_SWITCHES(hopamp));
769
770 /* Open all switches on non-inverting input, inverting input and output */
771 /* feedback. */
772 CLEAR_BIT(OPAMP->CSR, OPAMP_CSR_ALL_SWITCHES(hopamp));
773
774 /* Set calibration mode to user programmed trimming values */
775 SET_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER);
776
777
778 /* Select trimming settings depending on power mode */
779 if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
780 {
781 tmp_opamp_otr_otuser = OPAMP_OTR_OT_USER;
782 tmp_opamp_reg_trimming = &OPAMP->OTR;
783 }
784 else
785 {
786 tmp_opamp_otr_otuser = 0x00000000U;
787 tmp_opamp_reg_trimming = &OPAMP->LPOTR;
788 }
789
790
791 /* Enable the selected opamp */
792 CLEAR_BIT (OPAMP->CSR, OPAMP_CSR_OPAXPD(hopamp));
793
794 /* Perform trimming for both differential transistors pair high and low */
795 for (trimming_diff_pair_iteration_count = 0U; trimming_diff_pair_iteration_count <=1U; trimming_diff_pair_iteration_count++)
796 {
797 if (trimming_diff_pair_iteration_count == 0U)
798 {
799 /* Calibration of transistors differential pair high (NMOS) */
800 trimming_diff_pair = OPAMP_FACTORYTRIMMING_N;
801 opamp_trimmingvalue = &opamp_trimmingvaluen;
802
803 /* Set bit OPAMP_CSR_OPAXCALOUT default state when trimming value */
804 /* is 00000b. Used to detect the bit toggling during trimming. */
805 tmp_Opaxcalout_DefaultSate = 0U;
806
807 /* Enable calibration for N differential pair */
808 MODIFY_REG(OPAMP->CSR, OPAMP_CSR_OPAXCAL_L(hopamp),
809 OPAMP_CSR_OPAXCAL_H(hopamp) );
810 }
811 else /* (trimming_diff_pair_iteration_count == 1) */
812 {
813 /* Calibration of transistors differential pair low (PMOS) */
814 trimming_diff_pair = OPAMP_FACTORYTRIMMING_P;
815 opamp_trimmingvalue = &opamp_trimmingvaluep;
816
817 /* Set bit OPAMP_CSR_OPAXCALOUT default state when trimming value */
818 /* is 00000b. Used to detect the bit toggling during trimming. */
819 tmp_Opaxcalout_DefaultSate = OPAMP_CSR_OPAXCALOUT(hopamp);
820
821 /* Enable calibration for P differential pair */
822 MODIFY_REG(OPAMP->CSR, OPAMP_CSR_OPAXCAL_H(hopamp),
823 OPAMP_CSR_OPAXCAL_L(hopamp) );
824 }
825
826
827 /* Perform calibration parameter search by dichotomy sweep */
828 /* - Delta initial value 16: for 5 dichotomy steps: 16 for the */
829 /* initial range, then successive delta sweeps (8, 4, 2, 1). */
830 /* can extend the search range to +/- 15 units. */
831 /* - Trimming initial value 15: search range will go from 0 to 30 */
832 /* (Trimming value 31 is forbidden). */
833 /* Note: After dichotomy sweep, the trimming result is determined. */
834 /* However, the final trimming step is deduced from previous */
835 /* trimming steps tested but is not effectively tested. */
836 /* An additional test step (using variable "final_step_check") */
837 /* allow to Test the final trimming step. */
838 *opamp_trimmingvalue = 15U;
839 delta = 16U;
840
841 while ((delta != 0U) || (final_step_check == 1U))
842 {
843 /* Set candidate trimming */
844 MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OFFSET_TRIM_SET(hopamp, trimming_diff_pair, OPAMP_TRIM_VALUE_MASK) ,
845 OPAMP_OFFSET_TRIM_SET(hopamp, trimming_diff_pair, *opamp_trimmingvalue) | tmp_opamp_otr_otuser);
846
847 /* Offset trimming time: during calibration, minimum time needed */
848 /* between two steps to have 1 mV accuracy. */
849 HAL_Delay(OPAMP_TRIMMING_DELAY);
850
851 /* Set flag for additional check of last trimming step equal to */
852 /* dichotomy step before its division by 2 (equivalent to previous */
853 /* value of dichotomy step). */
854 final_step_check = delta;
855
856 /* Divide range by 2 to continue dichotomy sweep */
857 delta >>= 1;
858
859 /* Set trimming values for next iteration in function of trimming */
860 /* result toggle (versus initial state). */
861 /* Note: on the last trimming loop, delta is equal to 0 and */
862 /* therefore has no effect. */
863 if (READ_BIT(OPAMP->CSR, OPAMP_CSR_OPAXCALOUT(hopamp)) != tmp_Opaxcalout_DefaultSate)
864 {
865 /* If calibration output is has toggled, try lower trimming */
866 *opamp_trimmingvalue -= delta;
867 }
868 else
869 {
870 /* If calibration output is has not toggled, try higher trimming */
871 *opamp_trimmingvalue += delta;
872 }
873
874 }
875
876 /* Check trimming result of the selected step and perform final fine */
877 /* trimming. */
878 /* - If calibration output is has toggled: the current step is */
879 /* already optimized. */
880 /* - If calibration output is has not toggled: the current step can */
881 /* be optimized by incrementing it of one step. */
882 if (READ_BIT(OPAMP->CSR, OPAMP_CSR_OPAXCALOUT(hopamp)) == tmp_Opaxcalout_DefaultSate)
883 {
884 *opamp_trimmingvalue += 1U;
885
886 /* Set final fine trimming */
887 MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OFFSET_TRIM_SET(hopamp, trimming_diff_pair, OPAMP_TRIM_VALUE_MASK) ,
888 OPAMP_OFFSET_TRIM_SET(hopamp, trimming_diff_pair, *opamp_trimmingvalue) | tmp_opamp_otr_otuser);
889 }
890
891 }
892
893
894 /* Disable calibration for P and N differential pairs */
895 /* Disable the selected opamp */
896 CLEAR_BIT (OPAMP->CSR, (OPAMP_CSR_OPAXCAL_H(hopamp) |
897 OPAMP_CSR_OPAXCAL_L(hopamp) |
898 OPAMP_CSR_OPAXPD(hopamp)) );
899
900 /* Backup of switches configuration to restore it at the end of the */
901 /* calibration. */
902 SET_BIT(OPAMP->CSR, tmp_OpaxSwitchesContextBackup);
903
904 /* Self calibration is successful */
905 /* Store calibration (user trimming) results in init structure. */
906
907 /* Set user trimming mode */
908 hopamp->Init.UserTrimming = OPAMP_TRIMMING_USER;
909
910 /* Check on unsupported value */
911 if(opamp_trimmingvaluep == 0x1FU) /* 0x1F is not functional */
912 {
913 opamp_trimmingvaluep = 30U;
914 }
915
916 if(opamp_trimmingvaluen == 0x1FU) /* 0x1F is not functional */
917 {
918 opamp_trimmingvaluen = 30U;
919 }
920
921 /* Affect calibration parameters depending on mode normal/low power */
922 if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
923 {
924 /* Write calibration result N */
925 hopamp->Init.TrimmingValueN = opamp_trimmingvaluen;
926 /* Write calibration result P */
927 hopamp->Init.TrimmingValueP = opamp_trimmingvaluep;
928 }
929 else
930 {
931 /* Write calibration result N */
932 hopamp->Init.TrimmingValueNLowPower = opamp_trimmingvaluen;
933 /* Write calibration result P */
934 hopamp->Init.TrimmingValuePLowPower = opamp_trimmingvaluep;
935 }
936
937 /* Update OPAMP state */
938 hopamp->State = HAL_OPAMP_STATE_READY;
939
940 }
941
942 else
943 {
944 /* OPAMP can not be calibrated from this mode */
945 status = HAL_ERROR;
946 }
947 }
948
949 return status;
950
951 }
952
953 /**
954 * @}
955 */
956
957 /**
958 * @}
959 */
960
961 /** @defgroup OPAMP_Exported_Functions_Group3 Peripheral Control functions
962 * @brief Peripheral Control functions
963 *
964 @verbatim
965 ===============================================================================
966 ##### Peripheral Control functions #####
967 ===============================================================================
968 [..]
969 This subsection provides a set of functions allowing to control the OPAMP data
970 transfers.
971
972
973
974 @endverbatim
975 * @{
976 */
977
978 /**
979 * @brief Lock the selected opamp configuration.
980 * Caution: On STM32L1, HAL OPAMP lock is software lock only
981 * (not hardware lock as available on some other STM32 devices)
982 * @param hopamp OPAMP handle
983 * @retval HAL status
984 */
HAL_OPAMP_Lock(OPAMP_HandleTypeDef * hopamp)985 HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef* hopamp)
986 {
987 HAL_StatusTypeDef status = HAL_OK;
988
989 /* Check the OPAMP handle allocation */
990 /* Check if OPAMP locked */
991 /* OPAMP can be locked when enabled and running in normal mode */
992 /* It is meaningless otherwise */
993 if(hopamp == NULL)
994 {
995 status = HAL_ERROR;
996 }
997 else if(hopamp->State == HAL_OPAMP_STATE_BUSY)
998 {
999 /* Check the parameter */
1000 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
1001
1002 /* OPAMP state changed to locked */
1003 hopamp->State = HAL_OPAMP_STATE_BUSYLOCKED;
1004 }
1005 else
1006 {
1007 status = HAL_ERROR;
1008 }
1009 return status;
1010 }
1011
1012 /**
1013 * @brief Return the OPAMP factory trimming value
1014 * Caution: On STM32L1 OPAMP, user can retrieve factory trimming if
1015 * OPAMP has never been set to user trimming before.
1016 * Therefore, this fonction must be called when OPAMP init
1017 * parameter "UserTrimming" is set to trimming factory,
1018 * and before OPAMP calibration (function
1019 * "HAL_OPAMP_SelfCalibrate()").
1020 * Otherwise, factory triming value cannot be retrieved and
1021 * error status is returned.
1022 * @param hopamp OPAMP handle
1023 * @param trimmingoffset Trimming offset (P or N)
1024 * This parameter must be a value of @ref OPAMP_FactoryTrimming
1025 * @note Calibration parameter retrieved is corresponding to the mode
1026 * specified in OPAMP init structure (mode normal or low-power).
1027 * To retrieve calibration parameters for both modes, repeat this
1028 * function after OPAMP init structure accordingly updated.
1029 * @retval Trimming value (P or N) range: 0->31
1030 * or OPAMP_FACTORYTRIMMING_DUMMY if trimming value is not available
1031 *
1032 */
HAL_OPAMP_GetTrimOffset(OPAMP_HandleTypeDef * hopamp,uint32_t trimmingoffset)1033 HAL_OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset (OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset)
1034 {
1035 HAL_OPAMP_TrimmingValueTypeDef trimmingvalue;
1036 __IO uint32_t* tmp_opamp_reg_trimming; /* Selection of register of trimming depending on power mode: OTR or LPOTR */
1037
1038 /* Check the OPAMP handle allocation */
1039 /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
1040 if(hopamp == NULL)
1041 {
1042 return OPAMP_FACTORYTRIMMING_DUMMY;
1043 }
1044
1045 /* Check the OPAMP handle allocation */
1046 /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
1047 if(hopamp->State == HAL_OPAMP_STATE_READY)
1048 {
1049 /* Check the parameter */
1050 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
1051 assert_param(IS_OPAMP_FACTORYTRIMMING(trimmingoffset));
1052 assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
1053
1054 /* Check the trimming mode */
1055 if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER)
1056 {
1057 /* This fonction must called when OPAMP init parameter "UserTrimming" */
1058 /* is set to trimming factory, and before OPAMP calibration (function */
1059 /* "HAL_OPAMP_SelfCalibrate()"). */
1060 /* Otherwise, factory triming value cannot be retrieved and error */
1061 /* status is returned. */
1062 trimmingvalue = OPAMP_FACTORYTRIMMING_DUMMY;
1063 }
1064 else
1065 {
1066 /* Select trimming settings depending on power mode */
1067 if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
1068 {
1069 tmp_opamp_reg_trimming = &OPAMP->OTR;
1070 }
1071 else
1072 {
1073 tmp_opamp_reg_trimming = &OPAMP->LPOTR;
1074 }
1075
1076 /* Get factory trimming */
1077 trimmingvalue = ((*tmp_opamp_reg_trimming >> OPAMP_OFFSET_TRIM_BITSPOSITION(hopamp, trimmingoffset)) & OPAMP_TRIM_VALUE_MASK);
1078 }
1079 }
1080 else
1081 {
1082 return OPAMP_FACTORYTRIMMING_DUMMY;
1083 }
1084 return trimmingvalue;
1085 }
1086
1087 /**
1088 * @}
1089 */
1090
1091
1092 /** @defgroup OPAMP_Exported_Functions_Group4 Peripheral State functions
1093 * @brief Peripheral State functions
1094 *
1095 @verbatim
1096 ===============================================================================
1097 ##### Peripheral State functions #####
1098 ===============================================================================
1099 [..]
1100 This subsection permits to get in run-time the status of the peripheral.
1101
1102 @endverbatim
1103 * @{
1104 */
1105
1106 /**
1107 * @brief Return the OPAMP handle state.
1108 * @param hopamp OPAMP handle
1109 * @retval HAL state
1110 */
HAL_OPAMP_GetState(OPAMP_HandleTypeDef * hopamp)1111 HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(OPAMP_HandleTypeDef* hopamp)
1112 {
1113 /* Check the OPAMP handle allocation */
1114 if(hopamp == NULL)
1115 {
1116 return HAL_OPAMP_STATE_RESET;
1117 }
1118
1119 /* Check the parameter */
1120 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
1121
1122 return hopamp->State;
1123 }
1124
1125 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
1126 /**
1127 * @brief Register a User OPAMP Callback
1128 * To be used instead of the weak (surcharged) predefined callback
1129 * @param hopamp OPAMP handle
1130 * @param CallbackID ID of the callback to be registered
1131 * This parameter can be one of the following values:
1132 * @arg @ref HAL_OPAMP_MSPINIT_CB_ID OPAMP MspInit callback ID
1133 * @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID OPAMP MspDeInit callback ID
1134 * @param pCallback pointer to the Callback function
1135 * @retval status
1136 */
HAL_OPAMP_RegisterCallback(OPAMP_HandleTypeDef * hopamp,HAL_OPAMP_CallbackIDTypeDef CallbackID,pOPAMP_CallbackTypeDef pCallback)1137 HAL_StatusTypeDef HAL_OPAMP_RegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackID, pOPAMP_CallbackTypeDef pCallback)
1138 {
1139 HAL_StatusTypeDef status = HAL_OK;
1140
1141 if(pCallback == NULL)
1142 {
1143 return HAL_ERROR;
1144 }
1145
1146 /* Process locked */
1147 __HAL_LOCK(hopamp);
1148
1149 if(hopamp->State == HAL_OPAMP_STATE_READY)
1150 {
1151 switch (CallbackID)
1152 {
1153 case HAL_OPAMP_MSPINIT_CB_ID :
1154 hopamp->MspInitCallback = pCallback;
1155 break;
1156 case HAL_OPAMP_MSPDEINIT_CB_ID :
1157 hopamp->MspDeInitCallback = pCallback;
1158 break;
1159 default :
1160 /* Update the error code */
1161 // hopamp->ErrorCode |= HAL_OPAMP_ERROR_INVALID_CALLBACK;
1162 /* update return status */
1163 status = HAL_ERROR;
1164 break;
1165 }
1166 }
1167 else if (hopamp->State == HAL_OPAMP_STATE_RESET)
1168 {
1169 switch (CallbackID)
1170 {
1171 case HAL_OPAMP_MSPINIT_CB_ID :
1172 hopamp->MspInitCallback = pCallback;
1173 break;
1174 case HAL_OPAMP_MSPDEINIT_CB_ID :
1175 hopamp->MspDeInitCallback = pCallback;
1176 break;
1177 default :
1178 /* Update the error code */
1179 // hopamp->ErrorCode |= HAL_OPAMP_ERROR_INVALID_CALLBACK;
1180 /* update return status */
1181 status = HAL_ERROR;
1182 break;
1183 }
1184 }
1185 else
1186 {
1187 /* update return status */
1188 status = HAL_ERROR;
1189 }
1190
1191 /* Release Lock */
1192 __HAL_UNLOCK(hopamp);
1193 return status;
1194 }
1195
1196 /**
1197 * @brief Unregister a User OPAMP Callback
1198 * OPAMP Callback is redirected to the weak (surcharged) predefined callback
1199 * @param hopamp OPAMP handle
1200 * @param CallbackID ID of the callback to be unregistered
1201 * This parameter can be one of the following values:
1202 * @arg @ref HAL_OPAMP_MSPINIT_CB_ID OPAMP MSP Init Callback ID
1203 * @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID OPAMP MSP DeInit Callback ID
1204 * @arg @ref HAL_OPAMP_ALL_CB_ID OPAMP All Callbacks
1205 * @retval status
1206 */
1207
HAL_OPAMP_UnRegisterCallback(OPAMP_HandleTypeDef * hopamp,HAL_OPAMP_CallbackIDTypeDef CallbackID)1208 HAL_StatusTypeDef HAL_OPAMP_UnRegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackID)
1209 {
1210 HAL_StatusTypeDef status = HAL_OK;
1211
1212 /* Process locked */
1213 __HAL_LOCK(hopamp);
1214
1215 if(hopamp->State == HAL_OPAMP_STATE_READY)
1216 {
1217 switch (CallbackID)
1218 {
1219 case HAL_OPAMP_MSPINIT_CB_ID :
1220 hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1221 break;
1222 case HAL_OPAMP_MSPDEINIT_CB_ID :
1223 hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1224 break;
1225 case HAL_OPAMP_ALL_CB_ID :
1226 hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1227 hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1228 break;
1229 default :
1230 /* update return status */
1231 status = HAL_ERROR;
1232 break;
1233 }
1234 }
1235 else if (hopamp->State == HAL_OPAMP_STATE_RESET)
1236 {
1237 switch (CallbackID)
1238 {
1239 case HAL_OPAMP_MSPINIT_CB_ID :
1240 hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1241 break;
1242 case HAL_OPAMP_MSPDEINIT_CB_ID :
1243 hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1244 break;
1245 default :
1246 /* update return status */
1247 status = HAL_ERROR;
1248 break;
1249 }
1250 }
1251 else
1252 {
1253 /* update return status */
1254 status = HAL_ERROR;
1255 }
1256
1257 /* Release Lock */
1258 __HAL_UNLOCK(hopamp);
1259 return status;
1260 }
1261
1262 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
1263 /**
1264 * @}
1265 */
1266
1267 /**
1268 * @}
1269 */
1270
1271 #endif /* STM32L151xCA || STM32L151xD || STM32L152xCA || STM32L152xD || STM32L162xCA || STM32L162xD || STM32L151xE || STM32L151xDX || STM32L152xE || STM32L152xDX || STM32L162xE || STM32L162xDX || STM32L162xC || STM32L152xC || STM32L151xC */
1272
1273 #endif /* HAL_OPAMP_MODULE_ENABLED */
1274 /**
1275 * @}
1276 */
1277
1278 /**
1279 * @}
1280 */
1281
1282 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1283