2 ******************************************************************************
3 * @file stm32l1xx_hal_opamp_ex.c
4 * @author MCD Application Team
6 * @date 5-September-2014
7 * @brief Extended OPAMP HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the Power Controller (OPAMP) peripheral:
11 * + Extended Initialization and de-initialization functions
12 * + Extended Peripheral Control functions
15 ******************************************************************************
18 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
20 * Redistribution and use in source and binary forms, with or without modification,
21 * are permitted provided that the following conditions are met:
22 * 1. Redistributions of source code must retain the above copyright notice,
23 * this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright notice,
25 * this list of conditions and the following disclaimer in the documentation
26 * and/or other materials provided with the distribution.
27 * 3. Neither the name of STMicroelectronics nor the names of its contributors
28 * may be used to endorse or promote products derived from this software
29 * without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ******************************************************************************
45 /* Includes ------------------------------------------------------------------*/
46 #include "stm32l1xx_hal.h"
48 /** @addtogroup STM32L1xx_HAL_Driver
52 /** @defgroup OPAMPEx OPAMPEx
53 * @brief OPAMP Extended HAL module driver.
57 #ifdef HAL_OPAMP_MODULE_ENABLED
59 #if defined (STM32L151xCA) || defined (STM32L151xD) || defined (STM32L152xCA) || defined (STM32L152xD) || defined (STM32L162xCA) || defined (STM32L162xD) || defined (STM32L151xE) || defined (STM32L152xE) || defined (STM32L162xE) || defined (STM32L162xC) || defined (STM32L152xC) || defined (STM32L151xC)
61 /* Private typedef -----------------------------------------------------------*/
62 /* Private define ------------------------------------------------------------*/
63 /* Private macro -------------------------------------------------------------*/
64 /* Private variables ---------------------------------------------------------*/
65 /* Private function prototypes -----------------------------------------------*/
66 /* Private functions ---------------------------------------------------------*/
68 /** @addtogroup OPAMPEx_Exported_Functions OPAMPEx Exported Functions
72 /** @addtogroup OPAMPEx_Exported_Functions_Group1
73 * @brief Extended operation functions
76 ===============================================================================
77 ##### Extended IO operation functions #####
78 ===============================================================================
80 (+) OPAMP Self calibration.
86 #if defined (STM32L151xD) || defined (STM32L152xD) || defined (STM32L162xD)
88 /* 3 OPAMPS available */
89 /* 3 OPAMPS can be calibrated in parallel */
92 * @brief Run the self calibration of the 3 OPAMPs in parallel.
93 * @note Trimming values (PMOS & NMOS) are updated and user trimming is
94 * enabled is calibration is succesful.
95 * @note Calibration is performed in the mode specified in OPAMP init
96 * structure (mode normal or low-power). To perform calibration for
97 * both modes, repeat this function twice after OPAMP init structure
98 * accordingly updated.
99 * @note Calibration runs about 10 ms (5 dichotmy steps, repeated for P
100 * and N transistors: 10 steps with 1 ms for each step).
101 * @param hopamp1 handle
102 * @param hopamp2 handle
103 * @param hopamp3 handle
106 HAL_StatusTypeDef HAL_OPAMPEx_SelfCalibrateAll(OPAMP_HandleTypeDef *hopamp1, OPAMP_HandleTypeDef *hopamp2, OPAMP_HandleTypeDef *hopamp3)
108 HAL_StatusTypeDef status = HAL_OK;
110 uint32_t* opamp1_trimmingvalue = 0;
111 uint32_t opamp1_trimmingvaluen = 0;
112 uint32_t opamp1_trimmingvaluep = 0;
114 uint32_t* opamp2_trimmingvalue = 0;
115 uint32_t opamp2_trimmingvaluen = 0;
116 uint32_t opamp2_trimmingvaluep = 0;
118 uint32_t* opamp3_trimmingvalue = 0;
119 uint32_t opamp3_trimmingvaluen = 0;
120 uint32_t opamp3_trimmingvaluep = 0;
122 uint32_t trimming_diff_pair = 0; /* Selection of differential transistors pair high or low */
124 __IO uint32_t* tmp_opamp1_reg_trimming; /* Selection of register of trimming depending on power mode: OTR or LPOTR */
125 __IO uint32_t* tmp_opamp2_reg_trimming;
126 __IO uint32_t* tmp_opamp3_reg_trimming;
127 uint32_t tmp_opamp1_otr_otuser = 0; /* Selection of bit OPAMP_OTR_OT_USER depending on trimming register pointed: OTR or LPOTR */
128 uint32_t tmp_opamp2_otr_otuser = 0;
129 uint32_t tmp_opamp3_otr_otuser = 0;
131 uint32_t tmp_Opa1calout_DefaultSate = 0; /* Bit OPAMP_CSR_OPA1CALOUT default state when trimming value is 00000b. Used to detect the bit toggling */
132 uint32_t tmp_Opa2calout_DefaultSate = 0; /* Bit OPAMP_CSR_OPA2CALOUT default state when trimming value is 00000b. Used to detect the bit toggling */
133 uint32_t tmp_Opa3calout_DefaultSate = 0; /* Bit OPAMP_CSR_OPA3CALOUT default state when trimming value is 00000b. Used to detect the bit toggling */
135 uint32_t tmp_OpaxSwitchesContextBackup = 0;
137 uint8_t trimming_diff_pair_iteration_count = 0;
141 /* Check the OPAMP handle allocation */
142 /* Check if OPAMP locked */
143 if((hopamp1 == HAL_NULL) || (hopamp1->State == HAL_OPAMP_STATE_BUSYLOCKED) ||
144 (hopamp2 == HAL_NULL) || (hopamp2->State == HAL_OPAMP_STATE_BUSYLOCKED) ||
145 (hopamp3 == HAL_NULL) || (hopamp3->State == HAL_OPAMP_STATE_BUSYLOCKED) )
152 /* Check if OPAMP in calibration mode and calibration not yet enable */
153 if((hopamp1->State == HAL_OPAMP_STATE_READY) &&
154 (hopamp2->State == HAL_OPAMP_STATE_READY) &&
155 (hopamp3->State == HAL_OPAMP_STATE_READY) )
157 /* Check the parameter */
158 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp1->Instance));
159 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp2->Instance));
160 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp3->Instance));
161 assert_param(IS_OPAMP_POWERMODE(hopamp1->Init.PowerMode));
162 assert_param(IS_OPAMP_POWERMODE(hopamp2->Init.PowerMode));
163 assert_param(IS_OPAMP_POWERMODE(hopamp3->Init.PowerMode));
165 /* Update OPAMP state */
166 hopamp1->State = HAL_OPAMP_STATE_CALIBBUSY;
167 hopamp2->State = HAL_OPAMP_STATE_CALIBBUSY;
168 hopamp3->State = HAL_OPAMP_STATE_CALIBBUSY;
170 /* Backup of switches configuration to restore it at the end of the */
172 tmp_OpaxSwitchesContextBackup = READ_BIT(OPAMP->CSR, OPAMP_CSR_ALL_SWITCHES_ALL_OPAMPS);
174 /* Open all switches on non-inverting input, inverting input and output */
176 CLEAR_BIT(OPAMP->CSR, OPAMP_CSR_ALL_SWITCHES_ALL_OPAMPS);
178 /* Set calibration mode to user programmed trimming values */
179 SET_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER);
181 /* Select trimming settings depending on power mode */
182 if (hopamp1->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
184 tmp_opamp1_otr_otuser = OPAMP_OTR_OT_USER;
185 tmp_opamp1_reg_trimming = &OPAMP->OTR;
189 tmp_opamp1_otr_otuser = 0x00000000;
190 tmp_opamp1_reg_trimming = &OPAMP->LPOTR;
193 if (hopamp2->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
195 tmp_opamp2_otr_otuser = OPAMP_OTR_OT_USER;
196 tmp_opamp2_reg_trimming = &OPAMP->OTR;
200 tmp_opamp2_otr_otuser = 0x00000000;
201 tmp_opamp2_reg_trimming = &OPAMP->LPOTR;
204 if (hopamp3->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
206 tmp_opamp3_otr_otuser = OPAMP_OTR_OT_USER;
207 tmp_opamp3_reg_trimming = &OPAMP->OTR;
211 tmp_opamp3_otr_otuser = 0x00000000;
212 tmp_opamp3_reg_trimming = &OPAMP->LPOTR;
215 /* Enable the selected opamp */
216 CLEAR_BIT (OPAMP->CSR, OPAMP_CSR_OPAXPD_ALL);
218 /* Perform trimming for both differential transistors pair high and low */
219 for (trimming_diff_pair_iteration_count = 0; trimming_diff_pair_iteration_count <=1; trimming_diff_pair_iteration_count++)
221 if (trimming_diff_pair_iteration_count == 0)
223 /* Calibration of transistors differential pair high (NMOS) */
224 trimming_diff_pair = OPAMP_FACTORYTRIMMING_N;
225 opamp1_trimmingvalue = &opamp1_trimmingvaluen;
226 opamp2_trimmingvalue = &opamp2_trimmingvaluen;
227 opamp3_trimmingvalue = &opamp3_trimmingvaluen;
229 /* Set bit OPAMP_CSR_OPAXCALOUT default state when trimming value */
230 /* is 00000b. Used to detect the bit toggling during trimming. */
231 tmp_Opa1calout_DefaultSate = RESET;
232 tmp_Opa2calout_DefaultSate = RESET;
233 tmp_Opa3calout_DefaultSate = RESET;
235 /* Enable calibration for N differential pair */
236 MODIFY_REG(OPAMP->CSR, OPAMP_CSR_OPAXCAL_L_ALL,
237 OPAMP_CSR_OPAXCAL_H_ALL);
239 else /* (trimming_diff_pair_iteration_count == 1) */
241 /* Calibration of transistors differential pair low (PMOS) */
242 trimming_diff_pair = OPAMP_FACTORYTRIMMING_P;
243 opamp1_trimmingvalue = &opamp1_trimmingvaluep;
244 opamp2_trimmingvalue = &opamp2_trimmingvaluep;
245 opamp3_trimmingvalue = &opamp3_trimmingvaluep;
247 /* Set bit OPAMP_CSR_OPAXCALOUT default state when trimming value */
248 /* is 00000b. Used to detect the bit toggling during trimming. */
249 tmp_Opa1calout_DefaultSate = __OPAMP_CSR_OPAXCALOUT(hopamp1);
250 tmp_Opa2calout_DefaultSate = __OPAMP_CSR_OPAXCALOUT(hopamp2);
251 tmp_Opa3calout_DefaultSate = __OPAMP_CSR_OPAXCALOUT(hopamp3);
253 /* Enable calibration for P differential pair */
254 MODIFY_REG(OPAMP->CSR, OPAMP_CSR_OPAXCAL_H_ALL,
255 OPAMP_CSR_OPAXCAL_L_ALL);
259 /* Perform calibration parameter search by dichotomy sweep */
260 /* - Delta initial value 16: for 5 dichotomy steps: 16 for the */
261 /* initial range, then successive delta sweeps (8, 4, 2, 1). */
262 /* can extend the search range to +/- 15 units. */
263 /* - Trimming initial value 15: search range will go from 0 to 30 */
264 /* (Trimming value 31 is forbidden). */
265 *opamp1_trimmingvalue = 15;
266 *opamp2_trimmingvalue = 15;
267 *opamp3_trimmingvalue = 15;
272 /* Set candidate trimming */
274 MODIFY_REG(*tmp_opamp1_reg_trimming, __OPAMP_OFFSET_TRIM_SET(hopamp1, trimming_diff_pair, OPAMP_TRIM_VALUE_MASK) ,
275 __OPAMP_OFFSET_TRIM_SET(hopamp1, trimming_diff_pair, *opamp1_trimmingvalue) | tmp_opamp1_otr_otuser);
277 MODIFY_REG(*tmp_opamp2_reg_trimming, __OPAMP_OFFSET_TRIM_SET(hopamp2, trimming_diff_pair, OPAMP_TRIM_VALUE_MASK) ,
278 __OPAMP_OFFSET_TRIM_SET(hopamp2, trimming_diff_pair, *opamp2_trimmingvalue) | tmp_opamp2_otr_otuser);
280 MODIFY_REG(*tmp_opamp3_reg_trimming, __OPAMP_OFFSET_TRIM_SET(hopamp3, trimming_diff_pair, OPAMP_TRIM_VALUE_MASK) ,
281 __OPAMP_OFFSET_TRIM_SET(hopamp3, trimming_diff_pair, *opamp3_trimmingvalue) | tmp_opamp3_otr_otuser);
284 /* Offset trimming time: during calibration, minimum time needed */
285 /* between two steps to have 1 mV accuracy. */
286 HAL_Delay(OPAMP_TRIMMING_DELAY);
288 /* Divide range by 2 to continue dichotomy sweep */
291 /* Set trimming values for next iteration in function of trimming */
292 /* result toggle (versus initial state). */
293 /* Trimming values update with dichotomy delta of previous */
295 if (READ_BIT(OPAMP->CSR, __OPAMP_CSR_OPAXCALOUT(hopamp1)) != tmp_Opa1calout_DefaultSate)
297 /* If calibration output is has toggled, try lower trimming */
298 *opamp1_trimmingvalue -= delta;
302 /* If calibration output is has not toggled, try higher trimming */
303 *opamp1_trimmingvalue += delta;
306 /* Set trimming values for next iteration in function of trimming */
307 /* result toggle (versus initial state). */
308 /* Trimming values update with dichotomy delta of previous */
310 if (READ_BIT(OPAMP->CSR, __OPAMP_CSR_OPAXCALOUT(hopamp2)) != tmp_Opa2calout_DefaultSate)
312 /* If calibration output is has toggled, try lower trimming */
313 *opamp2_trimmingvalue -= delta;
317 /* If calibration output is has not toggled, try higher trimming */
318 *opamp2_trimmingvalue += delta;
321 /* Set trimming values for next iteration in function of trimming */
322 /* result toggle (versus initial state). */
323 /* Trimming values update with dichotomy delta of previous */
325 if (READ_BIT(OPAMP->CSR, __OPAMP_CSR_OPAXCALOUT(hopamp3)) != tmp_Opa3calout_DefaultSate)
327 /* If calibration output is has toggled, try lower trimming */
328 *opamp3_trimmingvalue -= delta;
332 /* If calibration output is has not toggled, try higher trimming */
333 *opamp3_trimmingvalue += delta;
340 /* Disable calibration for P and N differential pairs */
341 /* Disable the selected opamp */
342 CLEAR_BIT (OPAMP->CSR, (OPAMP_CSR_OPAXCAL_H_ALL |
343 OPAMP_CSR_OPAXCAL_L_ALL |
344 OPAMP_CSR_OPAXPD_ALL ));
346 /* Backup of switches configuration to restore it at the end of the */
348 SET_BIT(OPAMP->CSR, tmp_OpaxSwitchesContextBackup);
350 /* Self calibration is successful */
351 /* Store calibration (user trimming) results in init structure. */
353 /* Set user trimming mode */
354 hopamp1->Init.UserTrimming = OPAMP_TRIMMING_USER;
355 hopamp2->Init.UserTrimming = OPAMP_TRIMMING_USER;
356 hopamp3->Init.UserTrimming = OPAMP_TRIMMING_USER;
358 /* Affect calibration parameters depending on mode normal/low power */
359 if (hopamp1->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
361 /* Write calibration result N */
362 hopamp1->Init.TrimmingValueN = opamp1_trimmingvaluen;
363 /* Write calibration result P */
364 hopamp1->Init.TrimmingValueP = opamp1_trimmingvaluep;
368 /* Write calibration result N */
369 hopamp1->Init.TrimmingValueNLowPower = opamp1_trimmingvaluen;
370 /* Write calibration result P */
371 hopamp1->Init.TrimmingValuePLowPower = opamp1_trimmingvaluep;
374 if (hopamp2->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
376 /* Write calibration result N */
377 hopamp2->Init.TrimmingValueN = opamp2_trimmingvaluen;
378 /* Write calibration result P */
379 hopamp2->Init.TrimmingValueP = opamp2_trimmingvaluep;
383 /* Write calibration result N */
384 hopamp2->Init.TrimmingValueNLowPower = opamp2_trimmingvaluen;
385 /* Write calibration result P */
386 hopamp2->Init.TrimmingValuePLowPower = opamp2_trimmingvaluep;
389 if (hopamp3->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
391 /* Write calibration result N */
392 hopamp3->Init.TrimmingValueN = opamp3_trimmingvaluen;
393 /* Write calibration result P */
394 hopamp3->Init.TrimmingValueP = opamp3_trimmingvaluep;
398 /* Write calibration result N */
399 hopamp3->Init.TrimmingValueNLowPower = opamp3_trimmingvaluen;
400 /* Write calibration result P */
401 hopamp3->Init.TrimmingValuePLowPower = opamp3_trimmingvaluep;
404 /* Update OPAMP state */
405 hopamp1->State = HAL_OPAMP_STATE_READY;
406 hopamp2->State = HAL_OPAMP_STATE_READY;
407 hopamp3->State = HAL_OPAMP_STATE_READY;
412 /* OPAMP can not be calibrated from this mode */
422 /* 2 OPAMPS available */
423 /* 2 OPAMPS can be calibrated in parallel */
426 * @brief Run the self calibration of the 2 OPAMPs in parallel.
427 * @note Trimming values (PMOS & NMOS) are updated and user trimming is
428 * enabled is calibration is succesful.
429 * @note Calibration is performed in the mode specified in OPAMP init
430 * structure (mode normal or low-power). To perform calibration for
431 * both modes, repeat this function twice after OPAMP init structure
432 * accordingly updated.
433 * @note Calibration runs about 10 ms (5 dichotmy steps, repeated for P
434 * and N transistors: 10 steps with 1 ms for each step).
435 * @param hopamp1 handle
436 * @param hopamp2 handle
439 HAL_StatusTypeDef HAL_OPAMPEx_SelfCalibrateAll(OPAMP_HandleTypeDef *hopamp1, OPAMP_HandleTypeDef *hopamp2)
441 HAL_StatusTypeDef status = HAL_OK;
443 uint32_t* opamp1_trimmingvalue = 0;
444 uint32_t opamp1_trimmingvaluen = 0;
445 uint32_t opamp1_trimmingvaluep = 0;
447 uint32_t* opamp2_trimmingvalue = 0;
448 uint32_t opamp2_trimmingvaluen = 0;
449 uint32_t opamp2_trimmingvaluep = 0;
451 uint32_t trimming_diff_pair = 0; /* Selection of differential transistors pair high or low */
453 __IO uint32_t* tmp_opamp1_reg_trimming; /* Selection of register of trimming depending on power mode: OTR or LPOTR */
454 __IO uint32_t* tmp_opamp2_reg_trimming;
455 uint32_t tmp_opamp1_otr_otuser = 0; /* Selection of bit OPAMP_OTR_OT_USER depending on trimming register pointed: OTR or LPOTR */
456 uint32_t tmp_opamp2_otr_otuser = 0;
458 uint32_t tmp_Opa1calout_DefaultSate = 0; /* Bit OPAMP_CSR_OPA1CALOUT default state when trimming value is 00000b. Used to detect the bit toggling */
459 uint32_t tmp_Opa2calout_DefaultSate = 0; /* Bit OPAMP_CSR_OPA2CALOUT default state when trimming value is 00000b. Used to detect the bit toggling */
461 uint32_t tmp_OpaxSwitchesContextBackup = 0;
463 uint8_t trimming_diff_pair_iteration_count = 0;
467 /* Check the OPAMP handle allocation */
468 /* Check if OPAMP locked */
469 if((hopamp1 == HAL_NULL) || (hopamp1->State == HAL_OPAMP_STATE_BUSYLOCKED) ||
470 (hopamp2 == HAL_NULL) || (hopamp2->State == HAL_OPAMP_STATE_BUSYLOCKED) )
477 /* Check if OPAMP in calibration mode and calibration not yet enable */
478 if((hopamp1->State == HAL_OPAMP_STATE_READY) &&
479 (hopamp2->State == HAL_OPAMP_STATE_READY) )
481 /* Check the parameter */
482 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp1->Instance));
483 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp2->Instance));
484 assert_param(IS_OPAMP_POWERMODE(hopamp1->Init.PowerMode));
485 assert_param(IS_OPAMP_POWERMODE(hopamp2->Init.PowerMode));
487 /* Update OPAMP state */
488 hopamp1->State = HAL_OPAMP_STATE_CALIBBUSY;
489 hopamp2->State = HAL_OPAMP_STATE_CALIBBUSY;
491 /* Backup of switches configuration to restore it at the end of the */
493 tmp_OpaxSwitchesContextBackup = READ_BIT(OPAMP->CSR, OPAMP_CSR_ALL_SWITCHES_ALL_OPAMPS);
495 /* Open all switches on non-inverting input, inverting input and output */
497 CLEAR_BIT(OPAMP->CSR, OPAMP_CSR_ALL_SWITCHES_ALL_OPAMPS);
499 /* Set calibration mode to user programmed trimming values */
500 SET_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER);
502 /* Select trimming settings depending on power mode */
503 if (hopamp1->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
505 tmp_opamp1_otr_otuser = OPAMP_OTR_OT_USER;
506 tmp_opamp1_reg_trimming = &OPAMP->OTR;
510 tmp_opamp1_otr_otuser = 0x00000000;
511 tmp_opamp1_reg_trimming = &OPAMP->LPOTR;
514 if (hopamp2->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
516 tmp_opamp2_otr_otuser = OPAMP_OTR_OT_USER;
517 tmp_opamp2_reg_trimming = &OPAMP->OTR;
521 tmp_opamp2_otr_otuser = 0x00000000;
522 tmp_opamp2_reg_trimming = &OPAMP->LPOTR;
525 /* Enable the selected opamp */
526 CLEAR_BIT (OPAMP->CSR, OPAMP_CSR_OPAXPD_ALL);
528 /* Perform trimming for both differential transistors pair high and low */
529 for (trimming_diff_pair_iteration_count = 0; trimming_diff_pair_iteration_count <=1; trimming_diff_pair_iteration_count++)
531 if (trimming_diff_pair_iteration_count == 0)
533 /* Calibration of transistors differential pair high (NMOS) */
534 trimming_diff_pair = OPAMP_FACTORYTRIMMING_N;
535 opamp1_trimmingvalue = &opamp1_trimmingvaluen;
536 opamp2_trimmingvalue = &opamp2_trimmingvaluen;
538 /* Set bit OPAMP_CSR_OPAXCALOUT default state when trimming value */
539 /* is 00000b. Used to detect the bit toggling during trimming. */
540 tmp_Opa1calout_DefaultSate = RESET;
541 tmp_Opa2calout_DefaultSate = RESET;
543 /* Enable calibration for N differential pair */
544 MODIFY_REG(OPAMP->CSR, OPAMP_CSR_OPAXCAL_L_ALL,
545 OPAMP_CSR_OPAXCAL_H_ALL);
547 else /* (trimming_diff_pair_iteration_count == 1) */
549 /* Calibration of transistors differential pair low (PMOS) */
550 trimming_diff_pair = OPAMP_FACTORYTRIMMING_P;
551 opamp1_trimmingvalue = &opamp1_trimmingvaluep;
552 opamp2_trimmingvalue = &opamp2_trimmingvaluep;
554 /* Set bit OPAMP_CSR_OPAXCALOUT default state when trimming value */
555 /* is 00000b. Used to detect the bit toggling during trimming. */
556 tmp_Opa1calout_DefaultSate = __OPAMP_CSR_OPAXCALOUT(hopamp1);
557 tmp_Opa2calout_DefaultSate = __OPAMP_CSR_OPAXCALOUT(hopamp2);
559 /* Enable calibration for P differential pair */
560 MODIFY_REG(OPAMP->CSR, OPAMP_CSR_OPAXCAL_H_ALL,
561 OPAMP_CSR_OPAXCAL_L_ALL);
565 /* Perform calibration parameter search by dichotomy sweep */
566 /* - Delta initial value 16: for 5 dichotomy steps: 16 for the */
567 /* initial range, then successive delta sweeps (8, 4, 2, 1). */
568 /* can extend the search range to +/- 15 units. */
569 /* - Trimming initial value 15: search range will go from 0 to 30 */
570 /* (Trimming value 31 is forbidden). */
571 *opamp1_trimmingvalue = 15;
572 *opamp2_trimmingvalue = 15;
577 /* Set candidate trimming */
579 MODIFY_REG(*tmp_opamp1_reg_trimming, __OPAMP_OFFSET_TRIM_SET(hopamp1, trimming_diff_pair, OPAMP_TRIM_VALUE_MASK) ,
580 __OPAMP_OFFSET_TRIM_SET(hopamp1, trimming_diff_pair, *opamp1_trimmingvalue) | tmp_opamp1_otr_otuser);
582 MODIFY_REG(*tmp_opamp2_reg_trimming, __OPAMP_OFFSET_TRIM_SET(hopamp2, trimming_diff_pair, OPAMP_TRIM_VALUE_MASK) ,
583 __OPAMP_OFFSET_TRIM_SET(hopamp2, trimming_diff_pair, *opamp2_trimmingvalue) | tmp_opamp2_otr_otuser);
586 /* Offset trimming time: during calibration, minimum time needed */
587 /* between two steps to have 1 mV accuracy. */
588 HAL_Delay(OPAMP_TRIMMING_DELAY);
590 /* Divide range by 2 to continue dichotomy sweep */
593 /* Set trimming values for next iteration in function of trimming */
594 /* result toggle (versus initial state). */
595 if (READ_BIT(OPAMP->CSR, __OPAMP_CSR_OPAXCALOUT(hopamp1)) != tmp_Opa1calout_DefaultSate)
597 /* If calibration output is has toggled, try lower trimming */
598 *opamp1_trimmingvalue -= delta;
602 /* If calibration output is has not toggled, try higher trimming */
603 *opamp1_trimmingvalue += delta;
606 /* Set trimming values for next iteration in function of trimming */
607 /* result toggle (versus initial state). */
608 if (READ_BIT(OPAMP->CSR, __OPAMP_CSR_OPAXCALOUT(hopamp2)) != tmp_Opa2calout_DefaultSate)
610 /* If calibration output is has toggled, try lower trimming */
611 *opamp2_trimmingvalue -= delta;
615 /* If calibration output is has not toggled, try higher trimming */
616 *opamp2_trimmingvalue += delta;
623 /* Disable calibration for P and N differential pairs */
624 /* Disable the selected opamp */
625 CLEAR_BIT (OPAMP->CSR, (OPAMP_CSR_OPAXCAL_H_ALL |
626 OPAMP_CSR_OPAXCAL_L_ALL |
627 OPAMP_CSR_OPAXPD_ALL ));
629 /* Backup of switches configuration to restore it at the end of the */
631 SET_BIT(OPAMP->CSR, tmp_OpaxSwitchesContextBackup);
633 /* Self calibration is successful */
634 /* Store calibration (user trimming) results in init structure. */
636 /* Set user trimming mode */
637 hopamp1->Init.UserTrimming = OPAMP_TRIMMING_USER;
638 hopamp2->Init.UserTrimming = OPAMP_TRIMMING_USER;
640 /* Affect calibration parameters depending on mode normal/low power */
641 if (hopamp1->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
643 /* Write calibration result N */
644 hopamp1->Init.TrimmingValueN = opamp1_trimmingvaluen;
645 /* Write calibration result P */
646 hopamp1->Init.TrimmingValueP = opamp1_trimmingvaluep;
650 /* Write calibration result N */
651 hopamp1->Init.TrimmingValueNLowPower = opamp1_trimmingvaluen;
652 /* Write calibration result P */
653 hopamp1->Init.TrimmingValuePLowPower = opamp1_trimmingvaluep;
656 if (hopamp2->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
658 /* Write calibration result N */
659 hopamp2->Init.TrimmingValueN = opamp2_trimmingvaluen;
660 /* Write calibration result P */
661 hopamp2->Init.TrimmingValueP = opamp2_trimmingvaluep;
665 /* Write calibration result N */
666 hopamp2->Init.TrimmingValueNLowPower = opamp2_trimmingvaluen;
667 /* Write calibration result P */
668 hopamp2->Init.TrimmingValuePLowPower = opamp2_trimmingvaluep;
671 /* Update OPAMP state */
672 hopamp1->State = HAL_OPAMP_STATE_READY;
673 hopamp2->State = HAL_OPAMP_STATE_READY;
678 /* OPAMP can not be calibrated from this mode */
686 #endif /* STM32L151xD || STM32L152xD || STM32L162xD */
692 /** @defgroup OPAMPEx_Exported_Functions_Group2 Extended Peripheral Control functions
693 * @brief Extended control functions
696 ===============================================================================
697 ##### Peripheral Control functions #####
698 ===============================================================================
707 * @brief Unlock the selected opamp configuration.
708 * This function must be called only when OPAMP is in state "locked".
709 * @param hopamp: OPAMP handle
712 HAL_StatusTypeDef HAL_OPAMPEx_Unlock(OPAMP_HandleTypeDef* hopamp)
714 HAL_StatusTypeDef status = HAL_OK;
716 /* Check the OPAMP handle allocation */
717 /* Check if OPAMP locked */
718 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET)
719 || (hopamp->State == HAL_OPAMP_STATE_READY)
720 || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
721 || (hopamp->State == HAL_OPAMP_STATE_BUSY))
728 /* Check the parameter */
729 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
731 /* OPAMP state changed to locked */
732 hopamp->State = HAL_OPAMP_STATE_BUSY;
746 #endif /* STM32L151xCA || STM32L151xD || STM32L152xCA || STM32L152xD || STM32L162xCA || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE || STM32L162xC || STM32L152xC || STM32L151xC */
748 #endif /* HAL_OPAMP_MODULE_ENABLED */
757 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/