]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F3/stm32f3xx_hal_opamp.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F3 / stm32f3xx_hal_opamp.c
1 /**
2 ******************************************************************************
3 * @file stm32f3xx_hal_opamp.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 12-Sept-2014
7 * @brief OPAMP HAL module driver.
8 *
9 * This file provides firmware functions to manage the following
10 * functionalities of the operational amplifiers (OPAMP1,...OPAMP4)
11 * peripheral:
12 * + OPAMP Configuration
13 * + OPAMP calibration
14 *
15 * Thanks to
16 * + Initialization/de-initialization functions
17 * + I/O operation functions
18 * + Peripheral Control functions
19 * + Peripheral State functions
20 *
21 @verbatim
22 ================================================================================
23 ##### OPAMP Peripheral Features #####
24 ================================================================================
25
26 [..] The device integrates up to 4 operational amplifiers OPAMP1, OPAMP2,
27 OPAMP3 and OPAMP4:
28
29 (#) The OPAMP(s) provides several exclusive running modes.
30 (+) Standalone mode
31 (+) Programmable Gain Amplifier (PGA) mode (Resistor feedback output)
32 (+) Follower mode
33
34 (#) The OPAMP(s) provide(s) calibration capabilities.
35 (+) Calibration aims at correcting some offset for running mode.
36 (+) The OPAMP uses either factory calibration settings OR user defined
37 calibration (trimming) settings (i.e. trimming mode).
38 (+) The user defined settings can be figured out using self calibration
39 handled by HAL_OPAMP_SelfCalibrate, HAL_OPAMPEx_SelfCalibrateAll
40 (+) HAL_OPAMP_SelfCalibrate:
41 (++) Runs automatically the calibration in 2 steps.
42 (90% of VDDA for NMOS transistors, 10% of VDDA for PMOS transistors).
43 (As OPAMP is Rail-to-rail input/output, these 2 steps calibration is
44 appropriate and enough in most cases).
45 (++) Enables the user trimming mode
46 (++) Updates the init structure with trimming values with fresh calibration
47 results.
48 The user may store the calibration results for larger
49 (ex monitoring the trimming as a function of temperature
50 for instance)
51 (++) for STM32F3 devices having 2 or 4 OPAMPs
52 HAL_OPAMPEx_SelfCalibrateAll
53 runs calibration of 2 or 4 OPAMPs in parallel.
54
55 (#) For any running mode, an additional Timer-controlled Mux (multiplexer)
56 mode can be set on top.
57 (+) Timer-controlled Mux mode allows Automatic switching between inverting
58 and non-inverting input.
59 (+) Hence on top of defaults (primary) inverting and non-inverting inputs,
60 the user shall select secondary inverting and non inverting inputs.
61 (+) TIM1 CC6 provides the alternate switching tempo between defaults
62 (primary) and secondary inputs.
63
64 (#) Running mode: Standalone mode
65 (+) Gain is set externally (gain depends on external loads).
66 (+) Follower mode also possible externally by connecting the inverting input to
67 the output.
68
69 (#) Running mode: Follower mode
70 (+) No Inverting Input is connected.
71
72 (#) Running mode: Programmable Gain Amplifier (PGA) mode
73 (Resistor feedback output)
74 (+) The OPAMP(s) output(s) can be internally connected to resistor feedback
75 output.
76 (+) OPAMP gain is either 2, 4, 8 or 16.
77
78 (#) The OPAMPs non inverting input (both default and secondary) can be
79 selected among the list shown by table below.
80
81 (#) The OPAMPs non inverting input (both default and secondary) can be
82 selected among the list shown by table below.
83
84 [..] Table 1. OPAMPs inverting/non-inverting inputs for the STM32F3 devices:
85
86 +--------------------------------------------------------------+
87 | | | OPAMP1 | OPAMP2 | OPAMP3 | OPAMP4 |
88 |-----------------|--------|--------|--------|--------|--------|
89 | | No conn| X | X | X | X |
90 | Inverting Input | VM0 | PC5 | PC5 | PB10 | PB10 |
91 | (1) | VM1 | PA3 | PA5 | PB2 | PD8 |
92 |-----------------|--------|--------|--------|--------|--------|
93 | | VP0 | PA1 | PA7 | PB0 | PB13 |
94 | Non Inverting | VP1 | PA7 | PD14 | PB13 | PD11 |
95 | Input | VP2 | PA3 | PB0 | PA1 | PA4 |
96 | | VP3 | PA5 | PB14 | PA5 | PB11 |
97 +--------------------------------------------------------------+
98 (1): NA in follower mode.
99
100 [..] Table 2. OPAMPs outputs for the STM32F3 devices:
101
102 +--------------------------------------------------------------+
103 | | | OPAMP1 | OPAMP2 | OPAMP3 | OPAMP4 |
104 |-----------------|--------|--------|--------|--------|--------|
105 | Output | | PA2 | PA6 | PB1 | PB12 |
106 |-----------------|--------|--------|--------|--------|--------|
107
108
109 ##### How to use this driver #####
110 ================================================================================
111 [..]
112
113 *** Calibration ***
114 ============================================
115 To run the opamp calibration self calibration:
116
117 (#) Start calibration using HAL_OPAMP_SelfCalibrate.
118 Store the calibration results.
119
120 *** Running mode ***
121 ============================================
122
123 To use the opamp, perform the following steps:
124
125 (#) Fill in the HAL_OPAMP_MspInit() to
126 (+) Configure the opamp input AND output in analog mode using
127 HAL_GPIO_Init() to map the opamp output to the GPIO pin.
128
129 (#) Configure the opamp using HAL_OPAMP_Init() function:
130 (+) Select the mode
131 (+) Select the inverting input
132 (+) Select the non-inverting input
133 (+) Select if the Timer controlled Mux mode is enabled/disabled
134 (+) If the Timer controlled Mux mode is enabled, select the secondary inverting input
135 (+) If the Timer controlled Mux mode is enabled, Select the secondary non-inverting input
136 (+) If PGA mode is enabled, Select if inverting input is connected.
137 (+) Select either factory or user defined trimming mode.
138 (+) If the user defined trimming mode is enabled, select PMOS & NMOS trimming values
139 (typ. settings returned by HAL_OPAMP_SelfCalibrate function).
140
141 (#) Enable the opamp using HAL_OPAMP_Start() function.
142
143 (#) Disable the opamp using HAL_OPAMP_Stop() function.
144
145 (#) Lock the opamp in running mode using HAL_OPAMP_Lock() function. From then The configuration
146 can only be modified after HW reset.
147
148 *** Running mode: change of configuration while OPAMP ON ***
149 ============================================
150 To Re-configure OPAMP when OPAMP is ON (change on the fly)
151 (#) If needed, Fill in the HAL_OPAMP_MspInit()
152 (+) This is the case for instance if you wish to use new OPAMP I/O
153
154 (#) Configure the opamp using HAL_OPAMP_Init() function:
155 (+) As in configure case, selects first the parameters you wish to modify.
156
157 @endverbatim
158 ******************************************************************************
159 * @attention
160 *
161 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
162 *
163 * Redistribution and use in source and binary forms, with or without modification,
164 * are permitted provided that the following conditions are met:
165 * 1. Redistributions of source code must retain the above copyright notice,
166 * this list of conditions and the following disclaimer.
167 * 2. Redistributions in binary form must reproduce the above copyright notice,
168 * this list of conditions and the following disclaimer in the documentation
169 * and/or other materials provided with the distribution.
170 * 3. Neither the name of STMicroelectronics nor the names of its contributors
171 * may be used to endorse or promote products derived from this software
172 * without specific prior written permission.
173 *
174 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
175 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
176 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
177 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
178 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
179 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
180 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
181 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
182 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
183 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
184 *
185 ******************************************************************************
186 */
187
188 /* Includes ------------------------------------------------------------------*/
189 #include "stm32f3xx_hal.h"
190
191 /** @addtogroup STM32F3xx_HAL_Driver
192 * @{
193 */
194
195 /** @defgroup OPAMP OPAMP HAL module driver
196 * @brief OPAMP HAL module driver
197 * @{
198 */
199
200 #ifdef HAL_OPAMP_MODULE_ENABLED
201
202 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx) || \
203 defined(STM32F302xC) || defined(STM32F303xC) || defined(STM32F358xx) || \
204 defined(STM32F303x8) || defined(STM32F334x8) || defined(STM32F328xx) || \
205 defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F318xx)
206
207 /* Private typedef -----------------------------------------------------------*/
208 /* Private define ------------------------------------------------------------*/
209 /** @defgroup OPAMP_Private_Define OPAMP Private Define
210 * @{
211 */
212 /* CSR register reset value */
213 #define OPAMP_CSR_RESET_VALUE ((uint32_t)0x00000000)
214 /**
215 * @}
216 */
217
218 /* Private macro -------------------------------------------------------------*/
219 /* Private variables ---------------------------------------------------------*/
220 /* Private function prototypes -----------------------------------------------*/
221 /* Exported functions ---------------------------------------------------------*/
222
223 /** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions
224 * @{
225 */
226
227 /** @defgroup OPAMP_Exported_Functions_Group1 Initialization and de-initialization functions
228 * @brief Initialization and Configuration functions
229 *
230 @verbatim
231 ===============================================================================
232 ##### Initialization/de-initialization functions #####
233 ===============================================================================
234 [..] This section provides functions allowing to:
235
236 @endverbatim
237 * @{
238 */
239
240 /**
241 * @brief Initializes the OPAMP according to the specified
242 * parameters in the OPAMP_InitTypeDef and create the associated handle.
243 * @note If the selected opamp is locked, initialization can't be performed.
244 * To unlock the configuration, perform a system reset.
245 * @param hopamp: OPAMP handle
246 * @retval HAL status
247 */
248 HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp)
249
250 {
251 HAL_StatusTypeDef status = HAL_OK;
252
253 /* Check the OPAMP handle allocation and lock status */
254 /* Init not allowed if calibration is ongoing */
255 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) \
256 || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
257 {
258 return HAL_ERROR;
259 }
260 else
261 {
262
263 /* Check the parameter */
264 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
265
266 /* Set OPAMP parameters */
267 assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode));
268 assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput));
269 if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE)
270 {
271 assert_param(IS_OPAMP_INVERTING_INPUT(hopamp->Init.InvertingInput));
272 }
273
274 assert_param(IS_OPAMP_TIMERCONTROLLED_MUXMODE(hopamp->Init.TimerControlledMuxmode));
275
276 if ((hopamp->Init.TimerControlledMuxmode) == OPAMP_TIMERCONTROLLEDMUXMODE_ENABLE)
277 {
278 assert_param(IS_OPAMP_SEC_NONINVERTINGINPUT(hopamp->Init.NonInvertingInputSecondary));
279 if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE)
280 {
281 assert_param(IS_OPAMP_SEC_INVERTINGINPUT(hopamp->Init.InvertingInputSecondary));
282 }
283 }
284
285 if ((hopamp->Init.Mode) == OPAMP_PGA_MODE)
286 {
287 assert_param(IS_OPAMP_PGACONNECT(hopamp->Init.PgaConnect));
288 assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain));
289 }
290
291 assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming));
292 if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER)
293 {
294 assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP));
295 assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN));
296 }
297
298 /* Init SYSCFG and the low level hardware to access opamp */
299 __SYSCFG_CLK_ENABLE();
300
301 /* Call MSP init function */
302 HAL_OPAMP_MspInit(hopamp);
303
304 /* Set OPAMP parameters */
305 /* Set bits according to hopamp->hopamp->Init.Mode value */
306 /* Set bits according to hopamp->hopamp->Init.InvertingInput value */
307 /* Set bits according to hopamp->hopamp->Init.NonInvertingInput value */
308 /* Set bits according to hopamp->hopamp->Init.TimerControlledMuxmode value */
309 /* Set bits according to hopamp->hopamp->Init.InvertingInputSecondary value */
310 /* Set bits according to hopamp->hopamp->Init.NonInvertingInputSecondary value */
311 /* Set bits according to hopamp->hopamp->Init.PgaConnect value */
312 /* Set bits according to hopamp->hopamp->Init.PgaGain value */
313 /* Set bits according to hopamp->hopamp->Init.UserTrimming value */
314 /* Set bits according to hopamp->hopamp->Init.TrimmingValueP value */
315 /* Set bits according to hopamp->hopamp->Init.TrimmingValueN value */
316
317
318 /* check if OPAMP_PGA_MODE & in Follower mode */
319 /* - InvertingInput */
320 /* - InvertingInputSecondary */
321 /* are Not Applicable */
322
323 if ((hopamp->Init.Mode == OPAMP_PGA_MODE) || (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE))
324 {
325 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_UPDATE_PARAMETERS_INIT_MASK, \
326 hopamp->Init.Mode | \
327 hopamp->Init.NonInvertingInput | \
328 hopamp->Init.TimerControlledMuxmode | \
329 hopamp->Init.NonInvertingInputSecondary | \
330 hopamp->Init.PgaConnect | \
331 hopamp->Init.PgaGain | \
332 hopamp->Init.UserTrimming | \
333 (hopamp->Init.TrimmingValueP << OPAMP_INPUT_NONINVERTING) | \
334 (hopamp->Init.TrimmingValueN << OPAMP_INPUT_INVERTING));
335 }
336 else /* OPAMP_STANDALONE_MODE */
337 {
338 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_UPDATE_PARAMETERS_INIT_MASK, \
339 hopamp->Init.Mode | \
340 hopamp->Init.InvertingInput | \
341 hopamp->Init.NonInvertingInput | \
342 hopamp->Init.TimerControlledMuxmode | \
343 hopamp->Init.InvertingInputSecondary | \
344 hopamp->Init.NonInvertingInputSecondary | \
345 hopamp->Init.PgaConnect | \
346 hopamp->Init.PgaGain | \
347 hopamp->Init.UserTrimming | \
348 (hopamp->Init.TrimmingValueP << OPAMP_INPUT_NONINVERTING) | \
349 (hopamp->Init.TrimmingValueN << OPAMP_INPUT_INVERTING));
350 }
351
352 /* Update the OPAMP state*/
353 if (hopamp->State == HAL_OPAMP_STATE_RESET)
354 {
355 /* From RESET state to READY State */
356 hopamp->State = HAL_OPAMP_STATE_READY;
357 }
358 /* else: remain in READY or BUSY state (no update) */
359
360 return status;
361 }
362 }
363
364
365 /**
366 * @brief DeInitializes the OPAMP peripheral
367 * @note Deinitialization can't be performed if the OPAMP configuration is locked.
368 * To unlock the configuration, perform a system reset.
369 * @param hopamp: OPAMP handle
370 * @retval HAL status
371 */
372 HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef *hopamp)
373 {
374 HAL_StatusTypeDef status = HAL_OK;
375
376 /* Check the OPAMP handle allocation */
377 /* Check if OPAMP locked */
378 /* DeInit not allowed if calibration is ongoing */
379 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) \
380 || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
381 {
382 status = HAL_ERROR;
383 }
384 else
385 {
386 /* Check the parameter */
387 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
388
389 /* Set OPAMP_CSR register to reset value */
390 WRITE_REG(hopamp->Instance->CSR, OPAMP_CSR_RESET_VALUE);
391
392 /* DeInit the low level hardware: GPIO, CLOCK and NVIC */
393 HAL_OPAMP_MspDeInit(hopamp);
394
395 /* Update the OPAMP state*/
396 hopamp->State = HAL_OPAMP_STATE_RESET;
397 }
398 return status;
399 }
400
401 /**
402 * @brief Initializes the OPAMP MSP.
403 * @param hopamp: OPAMP handle
404 * @retval None
405 */
406 __weak void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef *hopamp)
407 {
408 /* NOTE : This function should not be modified, when the callback is needed,
409 the HAL_OPAMP_MspInit could be implemented in the user file
410 */
411
412 /* Example */
413 }
414
415 /**
416 * @brief DeInitializes OPAMP MSP.
417 * @param hopamp: OPAMP handle
418 * @retval None
419 */
420 __weak void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef *hopamp)
421 {
422 /* NOTE : This function should not be modified, when the callback is needed,
423 the HAL_OPAMP_MspDeInit could be implemented in the user file
424 */
425
426 }
427
428 /**
429 * @}
430 */
431
432
433 /** @defgroup OPAMP_Exported_Functions_Group2 Input and Output operation functions
434 * @brief Data transfers functions
435 *
436 @verbatim
437 ===============================================================================
438 ##### IO operation functions #####
439 ===============================================================================
440 [..]
441 This subsection provides a set of functions allowing to manage the OPAMP data
442 transfers.
443
444 @endverbatim
445 * @{
446 */
447
448 /**
449 * @brief Start the opamp
450 * @param hopamp: OPAMP handle
451 * @retval HAL status
452 */
453
454 HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef *hopamp)
455 {
456 HAL_StatusTypeDef status = HAL_OK;
457
458 /* Check the OPAMP handle allocation */
459 /* Check if OPAMP locked */
460 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
461
462 {
463 status = HAL_ERROR;
464 }
465 else
466 {
467 /* Check the parameter */
468 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
469
470 if(hopamp->State == HAL_OPAMP_STATE_READY)
471 {
472 /* Enable the selected opamp */
473 SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
474
475 /* Update the OPAMP state*/
476 /* From HAL_OPAMP_STATE_READY to HAL_OPAMP_STATE_BUSY */
477 hopamp->State = HAL_OPAMP_STATE_BUSY;
478 }
479 else
480 {
481 status = HAL_ERROR;
482 }
483
484
485 }
486 return status;
487 }
488
489 /**
490 * @brief Stop the opamp
491 * @param hopamp: OPAMP handle
492 * @retval HAL status
493 */
494 HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef *hopamp)
495 {
496 HAL_StatusTypeDef status = HAL_OK;
497
498 /* Check the OPAMP handle allocation */
499 /* Check if OPAMP locked */
500 /* Check if OPAMP calibration ongoing */
501 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) \
502 || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
503 {
504 status = HAL_ERROR;
505 }
506 else
507 {
508 /* Check the parameter */
509 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
510
511 if(hopamp->State == HAL_OPAMP_STATE_BUSY)
512 {
513 /* Disable the selected opamp */
514 CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
515
516 /* Update the OPAMP state*/
517 /* From HAL_OPAMP_STATE_BUSY to HAL_OPAMP_STATE_READY*/
518 hopamp->State = HAL_OPAMP_STATE_READY;
519 }
520 else
521 {
522 status = HAL_ERROR;
523 }
524 }
525 return status;
526 }
527
528 /**
529 * @brief Run the self calibration of one OPAMP
530 * @param hopamp handle
531 * @retval Updated offset trimming values (PMOS & NMOS), user trimming is enabled
532 * @retval HAL status
533 * @note Calibration runs about 25 ms.
534 */
535
536 HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef *hopamp)
537 {
538
539 HAL_StatusTypeDef status = HAL_OK;
540
541 uint32_t trimmingvaluen = 0;
542 uint32_t trimmingvaluep = 0;
543 uint32_t delta;
544
545 /* Check the OPAMP handle allocation */
546 /* Check if OPAMP locked */
547 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
548 {
549 status = HAL_ERROR;
550 }
551 else
552 {
553
554 /* Check if OPAMP in calibration mode and calibration not yet enable */
555 if(hopamp->State == HAL_OPAMP_STATE_READY)
556 {
557 /* Check the parameter */
558 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
559
560 /* Set Calibration mode */
561 /* Non-inverting input connected to calibration reference voltage. */
562 SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_FORCEVP);
563
564 /* user trimming values are used for offset calibration */
565 SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_USERTRIM);
566
567 /* Enable calibration */
568 SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
569
570 /* 1st calibration - N */
571 /* Select 90% VREF */
572 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_90VDDA);
573
574 /* Enable the selected opamp */
575 SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
576
577 /* Init trimming counter */
578 /* Medium value */
579 trimmingvaluen = 16;
580 delta = 8;
581
582 while (delta != 0)
583 {
584 /* Set candidate trimming */
585 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
586
587 /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
588 /* Offset trim time: during calibration, minimum time needed between */
589 /* two steps to have 1 mV accuracy */
590 HAL_Delay(2);
591
592 if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
593 {
594 /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
595 trimmingvaluen += delta;
596 }
597 else
598 {
599 /* OPAMP_CSR_OUTCAL is LOW try lower trimming */
600 trimmingvaluen -= delta;
601 }
602
603 delta >>= 1;
604 }
605
606 /* Still need to check if righ calibration is current value or un step below */
607 /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0 */
608 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
609
610 /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
611 /* Offset trim time: during calibration, minimum time needed between */
612 /* two steps to have 1 mV accuracy */
613 HAL_Delay(2);
614
615 if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
616 {
617 /* OPAMP_CSR_OUTCAL is actually one value more */
618 trimmingvaluen++;
619 /* Set right trimming */
620 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
621 }
622
623 /* 2nd calibration - P */
624 /* Select 10% VREF */
625 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_10VDDA);
626
627 /* Init trimming counter */
628 /* Medium value */
629 trimmingvaluep = 16;
630 delta = 8;
631
632 while (delta != 0)
633 {
634 /* Set candidate trimming */
635 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
636
637 /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
638 /* Offset trim time: during calibration, minimum time needed between */
639 /* two steps to have 1 mV accuracy */
640 HAL_Delay(2);
641
642 if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
643 {
644 /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
645 trimmingvaluep += delta;
646 }
647 else
648 {
649 trimmingvaluep -= delta;
650 }
651
652 delta >>= 1;
653 }
654
655 /* Still need to check if righ calibration is current value or un step below */
656 /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0 */
657 /* Set candidate trimming */
658 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
659
660 /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
661 /* Offset trim time: during calibration, minimum time needed between */
662 /* two steps to have 1 mV accuracy */
663 HAL_Delay(2);
664
665 if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
666 {
667 /* OPAMP_CSR_OUTCAL is actually one value more */
668 trimmingvaluep++;
669 /* Set right trimming */
670 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
671 }
672
673 /* Disable calibration */
674 CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
675
676 /* Disable the OPAMP */
677 CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
678
679 /* Set normale operating mode */
680 /* Non-inverting input connected to calibration reference voltage. */
681 CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_FORCEVP);
682
683 /* Self calibration is successful */
684 /* Store calibration(user timming) results in init structure. */
685
686 /* Write calibration result N */
687 hopamp->Init.TrimmingValueN = trimmingvaluen;
688
689 /* Write calibration result P */
690 hopamp->Init.TrimmingValueP = trimmingvaluep;
691
692 /* Select user timming mode */
693 /* And updated with calibrated settings */
694 hopamp->Init.UserTrimming = OPAMP_TRIMMING_USER;
695 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
696 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
697 }
698
699 else
700 {
701 /* OPAMP can not be calibrated from this mode */
702 status = HAL_ERROR;
703 }
704 }
705 return status;
706 }
707
708 /**
709 * @}
710 */
711
712 /** @defgroup OPAMP_Exported_Functions_Group3 Peripheral Control functions
713 * @brief management functions
714 *
715 @verbatim
716 ===============================================================================
717 ##### Peripheral Control functions #####
718 ===============================================================================
719 [..]
720 This subsection provides a set of functions allowing to control the OPAMP data
721 transfers.
722
723
724
725 @endverbatim
726 * @{
727 */
728
729 /**
730 * @brief Lock the selected opamp configuration.
731 * @param hopamp: OPAMP handle
732 * @retval HAL status
733 */
734 HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef *hopamp)
735 {
736 HAL_StatusTypeDef status = HAL_OK;
737
738 /* Check the OPAMP handle allocation */
739 /* Check if OPAMP locked */
740 /* OPAMP can be locked when enabled and running in normal mode */
741 /* It is meaningless otherwise */
742 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET) \
743 || (hopamp->State == HAL_OPAMP_STATE_READY) \
744 || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)\
745 || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
746
747 {
748 status = HAL_ERROR;
749 }
750
751 else
752 {
753 /* Check the parameter */
754 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
755
756 /* Lock OPAMP */
757 SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_LOCK);
758
759 /* OPAMP state changed to locked */
760 hopamp->State = HAL_OPAMP_STATE_BUSYLOCKED;
761 }
762 return status;
763 }
764
765 /**
766 * @}
767 */
768
769 /** @defgroup OPAMP_Exported_Functions_Group4 Peripheral State functions
770 * @brief Peripheral State functions
771 *
772 @verbatim
773 ===============================================================================
774 ##### Peripheral State functions #####
775 ===============================================================================
776 [..]
777 This subsection permit to get in run-time the status of the peripheral
778 and the data flow.
779
780 @endverbatim
781 * @{
782 */
783
784 /**
785 * @brief Return the OPAMP state
786 * @param hopamp : OPAMP handle
787 * @retval HAL state
788 */
789 HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(OPAMP_HandleTypeDef *hopamp)
790 {
791 /* Check the OPAMP handle allocation */
792 if(hopamp == HAL_NULL)
793 {
794 return HAL_OPAMP_STATE_RESET;
795 }
796
797 /* Check the parameter */
798 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
799
800 return hopamp->State;
801 }
802
803 /**
804 * @brief Return the OPAMP factory trimming value
805 * @param hopamp : OPAMP handle
806 * @param trimmingoffset : Trimming offset (P or N)
807 * @retval Trimming value (P or N): range: 0->31
808 * or OPAMP_FACTORYTRIMMING_DUMMY if trimming value is not available
809 */
810
811 OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset (OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset)
812 {
813 uint32_t oldusertrimming = 0;
814 OPAMP_TrimmingValueTypeDef oldtrimmingvaluep = 0, oldtrimmingvaluen = 0, trimmingvalue = 0;
815
816 /* Check the OPAMP handle allocation */
817 /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
818 if((hopamp == HAL_NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET) \
819 || (hopamp->State == HAL_OPAMP_STATE_BUSY) \
820 || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)\
821 || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
822 {
823 return OPAMP_FACTORYTRIMMING_DUMMY;
824 }
825 else
826 {
827 /* Check the parameter */
828 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
829 assert_param(IS_OPAMP_FACTORYTRIMMING(trimmingoffset));
830
831 /* Check the trimming mode */
832 if ((READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_USERTRIM)) != RESET)
833 {
834 /* User trimming is used */
835 oldusertrimming = OPAMP_TRIMMING_USER;
836 /* Store the TrimmingValueP & TrimmingValueN */
837 oldtrimmingvaluep = (hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING;
838 oldtrimmingvaluen = (hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETN) >> OPAMP_INPUT_INVERTING;
839 }
840
841 /* Set factory timming mode */
842 CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_USERTRIM);
843
844 /* Get factory trimming */
845 if (trimmingoffset == OPAMP_FACTORYTRIMMING_P)
846 {
847 /* Return TrimOffsetP */
848 trimmingvalue = ((hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING);
849 }
850 else
851 {
852 /* Return TrimOffsetN */
853 trimmingvalue = ((hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETN) >> OPAMP_INPUT_INVERTING);
854 }
855
856 /* Restore user trimming configuration if it was formerly set */
857 /* Check if user trimming was used */
858 if (oldusertrimming == OPAMP_TRIMMING_USER)
859 {
860 /* Restore user trimming */
861 SET_BIT(hopamp->Instance->CSR,OPAMP_CSR_USERTRIM);
862 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, oldtrimmingvaluep<<OPAMP_INPUT_NONINVERTING);
863 MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, oldtrimmingvaluen<<OPAMP_INPUT_INVERTING);
864 }
865 }
866 return trimmingvalue;
867 }
868 /**
869 * @}
870 */
871
872 /**
873 * @}
874 */
875 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
876 /* STM32F302xC || STM32F303xC || STM32F358xx || */
877 /* STM32F303x8 || STM32F334x8 || STM32F328xx || */
878 /* STM32F301x8 || STM32F302x8 || STM32F318xx */
879
880 #endif /* HAL_OPAMP_MODULE_ENABLED */
881 /**
882 * @}
883 */
884
885 /**
886 * @}
887 */
888
889 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Imprint / Impressum