2 ******************************************************************************
\r
3 * @file stm32l1xx_opamp.c
\r
4 * @author MCD Application Team
\r
6 * @date 05-March-2012
\r
7 * @brief This file provides firmware functions to manage the following
\r
8 * functionalities of the operational amplifiers (opamp) peripheral:
\r
9 * + Initialization and configuration
\r
10 * + Calibration management
\r
13 ==============================================================================
\r
14 ##### How to use this driver #####
\r
15 ==============================================================================
\r
16 [..] The device integrates three independent rail-to-rail operational amplifiers
\r
17 OPAMP1, OPAMP2 and OPAMP3:
\r
18 (+) Internal connections to the ADC.
\r
19 (+) Internal connections to the DAC.
\r
20 (+) Internal connection to COMP1 (only OPAMP3).
\r
21 (+) Internal connection for unity gain (voltage follower) configuration.
\r
22 (+) Calibration capability.
\r
23 (+) Selectable gain-bandwidth (2MHz in normal mode, 500KHz in low power mode).
\r
25 (#) COMP AHB clock must be enabled to get write access
\r
26 to OPAMP registers using
\r
27 (#) RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE)
\r
29 (#) Configure the corresponding GPIO to OPAMPx INP, OPAMPx_INN (if used)
\r
30 and OPAMPx_OUT in analog mode.
\r
32 (#) Configure (close/open) the OPAMP switches using OPAMP_SwitchCmd()
\r
34 (#) Enable the OPAMP peripheral using OPAMP_Cmd()
\r
36 -@- In order to use OPAMP outputs as ADC inputs, the opamps must be enabled
\r
37 and the ADC must use the OPAMP output channel number:
\r
38 (+@) OPAMP1 output is connected to ADC channel 3.
\r
39 (+@) OPAMP2 output is connected to ADC channel 8.
\r
40 (+@) OPAMP3 output is connected to ADC channel 13 (SW1 switch must be closed).
\r
44 ******************************************************************************
\r
47 * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
\r
49 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
\r
50 * You may not use this file except in compliance with the License.
\r
51 * You may obtain a copy of the License at:
\r
53 * http://www.st.com/software_license_agreement_liberty_v2
\r
55 * Unless required by applicable law or agreed to in writing, software
\r
56 * distributed under the License is distributed on an "AS IS" BASIS,
\r
57 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
58 * See the License for the specific language governing permissions and
\r
59 * limitations under the License.
\r
61 ******************************************************************************
\r
64 /* Includes ------------------------------------------------------------------*/
\r
65 #include "stm32l1xx_opamp.h"
\r
68 /** @addtogroup STM32L1xx_StdPeriph_Driver
\r
72 /** @defgroup OPAMP
\r
73 * @brief OPAMP driver modules
\r
77 /* Private typedef -----------------------------------------------------------*/
\r
78 /* Private define ------------------------------------------------------------*/
\r
79 /* Private macro -------------------------------------------------------------*/
\r
80 /* Private variables ---------------------------------------------------------*/
\r
81 /* Private function prototypes -----------------------------------------------*/
\r
82 /* Private functions ---------------------------------------------------------*/
\r
84 /** @defgroup OPAMP_Private_Functions
\r
88 /** @defgroup OPAMP_Group1 Initialization and configuration
\r
89 * @brief Initialization and configuration
\r
92 ===============================================================================
\r
93 ##### Initialization and configuration #####
\r
94 ===============================================================================
\r
101 * @brief Deinitialize the OPAMPs register to its default reset value.
\r
102 * @note At startup, OTR and LPOTR registers are set to factory programmed values.
\r
106 void OPAMP_DeInit(void)
\r
108 /*!< Set OPAMP_CSR register to reset value */
\r
109 OPAMP->CSR = 0x00010101;
\r
110 /*!< Set OPAMP_OTR register to reset value */
\r
111 OPAMP->OTR = (uint32_t)(* (uint32_t*)FLASH_R_BASE + 0x00000038);
\r
112 /*!< Set OPAMP_LPOTR register to reset value */
\r
113 OPAMP->LPOTR = (uint32_t)(* (uint32_t*)FLASH_R_BASE + 0x0000003C);
\r
117 * @brief Close or Open the OPAMP switches.
\r
118 * @param OPAMP_OPAMPxSwitchy: selects the OPAMPx switch.
\r
119 * This parameter can be any combinations of the following values:
\r
120 * @arg OPAMP_OPAMP1Switch3: used to connect internally OPAMP1 output to
\r
121 * OPAMP1 negative input (internal follower)
\r
122 * @arg OPAMP_OPAMP1Switch4: used to connect PA2 to OPAMP1 negative input
\r
123 * @arg OPAMP_OPAMP1Switch5: used to connect PA1 to OPAMP1 positive input
\r
124 * @arg OPAMP_OPAMP1Switch6: used to connect DAC_OUT1 to OPAMP1 positive input
\r
125 * @arg OPAMP_OPAMP1SwitchANA: used to meet 1 nA input leakage
\r
126 * @arg OPAMP_OPAMP2Switch3: used to connect internally OPAMP2 output to
\r
127 * OPAMP2 negative input (internal follower)
\r
128 * @arg OPAMP_OPAMP2Switch4: used to connect PA7 to OPAMP2 negative input
\r
129 * @arg OPAMP_OPAMP2Switch5: used to connect PA6 to OPAMP2 positive input
\r
130 * @arg OPAMP_OPAMP2Switch6: used to connect DAC_OUT1 to OPAMP2 positive input
\r
131 * @arg OPAMP_OPAMP2Switch7: used to connect DAC_OUT2 to OPAMP2 positive input
\r
132 * @arg OPAMP_OPAMP2SwitchANA: used to meet 1 nA input leakage
\r
133 * @arg OPAMP_OPAMP3Switch3: used to connect internally OPAMP3 output to
\r
134 * OPAMP3 negative input (internal follower)
\r
135 * @arg OPAMP_OPAMP3Switch4: used to connect PC2 to OPAMP3 negative input
\r
136 * @arg OPAMP_OPAMP3Switch5: used to connect PC1 to OPAMP3 positive input
\r
137 * @arg OPAMP_OPAMP3Switch6: used to connect DAC_OUT1 to OPAMP3 positive input
\r
138 * @arg OPAMP_OPAMP3SwitchANA: used to meet 1 nA input leakage on negative input
\r
140 * @param NewState: New state of the OPAMP switch.
\r
141 * This parameter can be:
\r
142 * ENABLE to close the OPAMP switch
\r
143 * or DISABLE to open the OPAMP switch
\r
144 * @note OPAMP_OPAMP2Switch6 and OPAMP_OPAMP2Switch7 mustn't be closed together.
\r
147 void OPAMP_SwitchCmd(uint32_t OPAMP_OPAMPxSwitchy, FunctionalState NewState)
\r
149 /* Check the parameter */
\r
150 assert_param(IS_OPAMP_SWITCH(OPAMP_OPAMPxSwitchy));
\r
151 assert_param(IS_FUNCTIONAL_STATE(NewState));
\r
153 if (NewState != DISABLE)
\r
155 /* Close the selected switches */
\r
156 OPAMP->CSR |= (uint32_t) OPAMP_OPAMPxSwitchy;
\r
160 /* Open the selected switches */
\r
161 OPAMP->CSR &= (~(uint32_t)OPAMP_OPAMPxSwitchy);
\r
166 * @brief Enable or disable the OPAMP peripheral.
\r
167 * @param OPAMP_Selection: the selected OPAMP.
\r
168 * This parameter can be one of the following values:
\r
169 * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected
\r
170 * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected
\r
171 * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected
\r
172 * @param NewState: new state of the selected OPAMP peripheral.
\r
173 * This parameter can be: ENABLE or DISABLE.
\r
176 void OPAMP_Cmd(uint32_t OPAMP_Selection, FunctionalState NewState)
\r
178 /* Check the parameter */
\r
179 assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
\r
180 assert_param(IS_FUNCTIONAL_STATE(NewState));
\r
182 if (NewState != DISABLE)
\r
184 /* Enable the selected OPAMP */
\r
185 OPAMP->CSR &= (~(uint32_t) OPAMP_Selection);
\r
189 /* Disable the selected OPAMP */
\r
190 OPAMP->CSR |= (uint32_t) OPAMP_Selection;
\r
195 * @brief Enable or disable the low power mode for OPAMP peripheral.
\r
196 * @param OPAMP_Selection: the selected OPAMP.
\r
197 * This parameter can be one of the following values:
\r
198 * @arg OPAMP_Selection_OPAMP1: OPAMP1 selected
\r
199 * @arg OPAMP_Selection_OPAMP2: OPAMP2 selected
\r
200 * @arg OPAMP_Selection_OPAMP3: OPAMP3 selected
\r
201 * @param NewState: new low power state of the selected OPAMP peripheral.
\r
202 * This parameter can be: ENABLE or DISABLE.
\r
205 void OPAMP_LowPowerCmd(uint32_t OPAMP_Selection, FunctionalState NewState)
\r
207 /* Check the parameter */
\r
208 assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
\r
209 assert_param(IS_FUNCTIONAL_STATE(NewState));
\r
211 if (NewState != DISABLE)
\r
213 /* Set the selected OPAMP in low power mode */
\r
214 OPAMP->CSR |= (uint32_t) (OPAMP_Selection << 7);
\r
218 /* Disable the low power mode for the selected OPAMP */
\r
219 OPAMP->CSR &= (~(uint32_t) (OPAMP_Selection << 7));
\r
224 * @brief Select the OPAMP power range.
\r
225 * @note The OPAMP power range selection must be performed while OPAMPs are powered down.
\r
226 * @param OPAMP_Range: the selected OPAMP power range.
\r
227 * This parameter can be one of the following values:
\r
228 * @arg OPAMP_PowerRange_Low: Low power range is selected (VDDA is lower than 2.4V).
\r
229 * @arg OPAMP_PowerRange_High: High power range is selected (VDDA is higher than 2.4V).
\r
232 void OPAMP_PowerRangeSelect(uint32_t OPAMP_PowerRange)
\r
234 /* Check the parameter */
\r
235 assert_param(IS_OPAMP_RANGE(OPAMP_PowerRange));
\r
237 /* Reset the OPAMP range bit */
\r
238 OPAMP->CSR &= (~(uint32_t) (OPAMP_CSR_AOP_RANGE));
\r
240 /* Select the OPAMP power range */
\r
241 OPAMP->CSR |= OPAMP_PowerRange;
\r
248 /** @defgroup OPAMP_Group2 Calibration functions
\r
249 * @brief Calibration functions
\r
252 ===============================================================================
\r
253 ##### Calibration functions #####
\r
254 ===============================================================================
\r
261 * @brief Select the trimming mode.
\r
262 * @param OffsetTrimming: the selected offset trimming mode.
\r
263 * This parameter can be one of the following values:
\r
264 * @arg OffsetTrimming_Factory: factory trimming values are used for offset
\r
266 * @arg OffsetTrimming_User: user trimming values are used for offset
\r
268 * @note When OffsetTrimming_User is selected, use OPAMP_OffsetTrimConfig()
\r
269 * function or OPAMP_OffsetTrimLowPowerConfig() function to adjust
\r
273 void OPAMP_OffsetTrimmingModeSelect(uint32_t OPAMP_Trimming)
\r
275 /* Check the parameter */
\r
276 assert_param(IS_OPAMP_TRIMMING(OPAMP_Trimming));
\r
278 /* Reset the OPAMP_OTR range bit */
\r
279 OPAMP->CSR &= (~(uint32_t) (OPAMP_OTR_OT_USER));
\r
281 /* Select the OPAMP offset trimming */
\r
282 OPAMP->CSR |= OPAMP_Trimming;
\r
287 * @brief Configure the trimming value of OPAMPs in normal mode.
\r
288 * @param OPAMP_Selection: the selected OPAMP.
\r
289 * This parameter can be one of the following values:
\r
290 * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected to configure the trimming value.
\r
291 * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected to configure the trimming value.
\r
292 * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected to configure the trimming value.
\r
293 * @param OPAMP_Input: the selected OPAMP input.
\r
294 * This parameter can be one of the following values:
\r
295 * @arg OPAMP_Input_NMOS: NMOS input is selected to configure the trimming value.
\r
296 * @arg OPAMP_Input_PMOS: PMOS input is selected to configure the trimming value.
\r
297 * @param OPAMP_TrimValue: the trimming value. This parameter can be any value lower
\r
298 * or equal to 0x0000001F.
\r
301 void OPAMP_OffsetTrimConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue)
\r
303 uint32_t tmpreg = 0;
\r
305 /* Check the parameter */
\r
306 assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
\r
307 assert_param(IS_OPAMP_INPUT(OPAMP_Input));
\r
308 assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue));
\r
310 /* Get the OPAMP_OTR value */
\r
311 tmpreg = OPAMP->OTR;
\r
313 if(OPAMP_Selection == OPAMP_Selection_OPAMP1)
\r
315 /* Reset the OPAMP inputs selection */
\r
316 tmpreg &= (uint32_t)~(OPAMP_CSR_OPA1CAL_L | OPAMP_CSR_OPA1CAL_H);
\r
317 /* Select the OPAMP input */
\r
318 tmpreg |= OPAMP_Input;
\r
320 if(OPAMP_Input == OPAMP_Input_PMOS)
\r
322 /* Reset the trimming value corresponding to OPAMP1 PMOS input */
\r
323 tmpreg &= (0xFFFFFFE0);
\r
324 /* Set the new trimming value corresponding to OPAMP1 PMOS input */
\r
325 tmpreg |= (OPAMP_TrimValue);
\r
329 /* Reset the trimming value corresponding to OPAMP1 NMOS input */
\r
330 tmpreg &= (0xFFFFFC1F);
\r
331 /* Set the new trimming value corresponding to OPAMP1 NMOS input */
\r
332 tmpreg |= (OPAMP_TrimValue<<5);
\r
335 else if (OPAMP_Selection == OPAMP_Selection_OPAMP2)
\r
337 /* Reset the OPAMP inputs selection */
\r
338 tmpreg &= (uint32_t)~(OPAMP_CSR_OPA2CAL_L | OPAMP_CSR_OPA2CAL_H);
\r
339 /* Select the OPAMP input */
\r
340 tmpreg |= (uint32_t)(OPAMP_Input<<8);
\r
342 if(OPAMP_Input == OPAMP_Input_PMOS)
\r
344 /* Reset the trimming value corresponding to OPAMP2 PMOS input */
\r
345 tmpreg &= (0xFFFF83FF);
\r
346 /* Set the new trimming value corresponding to OPAMP2 PMOS input */
\r
347 tmpreg |= (OPAMP_TrimValue<<10);
\r
351 /* Reset the trimming value corresponding to OPAMP2 NMOS input */
\r
352 tmpreg &= (0xFFF07FFF);
\r
353 /* Set the new trimming value corresponding to OPAMP2 NMOS input */
\r
354 tmpreg |= (OPAMP_TrimValue<<15);
\r
359 /* Reset the OPAMP inputs selection */
\r
360 tmpreg &= (uint32_t)~(OPAMP_CSR_OPA3CAL_L | OPAMP_CSR_OPA3CAL_H);
\r
361 /* Select the OPAMP input */
\r
362 tmpreg |= (uint32_t)(OPAMP_Input<<16);
\r
364 if(OPAMP_Input == OPAMP_Input_PMOS)
\r
366 /* Reset the trimming value corresponding to OPAMP3 PMOS input */
\r
367 tmpreg &= (0xFE0FFFFF);
\r
368 /* Set the new trimming value corresponding to OPAMP3 PMOS input */
\r
369 tmpreg |= (OPAMP_TrimValue<<20);
\r
373 /* Reset the trimming value corresponding to OPAMP3 NMOS input */
\r
374 tmpreg &= (0xC1FFFFFF);
\r
375 /* Set the new trimming value corresponding to OPAMP3 NMOS input */
\r
376 tmpreg |= (OPAMP_TrimValue<<25);
\r
380 /* Set the OPAMP_OTR register */
\r
381 OPAMP->OTR = tmpreg;
\r
385 * @brief Configure the trimming value of OPAMPs in low power mode.
\r
386 * @param OPAMP_Selection: the selected OPAMP.
\r
387 * This parameter can be one of the following values:
\r
388 * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected to configure the trimming value.
\r
389 * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected to configure the trimming value.
\r
390 * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected to configure the trimming value.
\r
391 * @param OPAMP_Input: the selected OPAMP input.
\r
392 * This parameter can be one of the following values:
\r
393 * @arg OPAMP_Input_NMOS: NMOS input is selected to configure the trimming value.
\r
394 * @arg OPAMP_Input_PMOS: PMOS input is selected to configure the trimming value.
\r
395 * @param OPAMP_TrimValue: the trimming value.
\r
396 * This parameter can be any value lower or equal to 0x0000001F.
\r
399 void OPAMP_OffsetTrimLowPowerConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue)
\r
401 uint32_t tmpreg = 0;
\r
403 /* Check the parameter */
\r
404 assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
\r
405 assert_param(IS_OPAMP_INPUT(OPAMP_Input));
\r
406 assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue));
\r
408 /* Get the OPAMP_LPOTR value */
\r
409 tmpreg = OPAMP->LPOTR;
\r
411 if(OPAMP_Selection == OPAMP_Selection_OPAMP1)
\r
413 /* Reset the OPAMP inputs selection */
\r
414 tmpreg &= (uint32_t)~(OPAMP_CSR_OPA1CAL_L | OPAMP_CSR_OPA1CAL_H);
\r
415 /* Select the OPAMP input */
\r
416 tmpreg |= OPAMP_Input;
\r
418 if(OPAMP_Input == OPAMP_Input_PMOS)
\r
420 /* Reset the trimming value corresponding to OPAMP1 PMOS input */
\r
421 tmpreg &= (0xFFFFFFE0);
\r
422 /* Set the new trimming value corresponding to OPAMP1 PMOS input */
\r
423 tmpreg |= (OPAMP_TrimValue);
\r
427 /* Reset the trimming value corresponding to OPAMP1 NMOS input */
\r
428 tmpreg &= (0xFFFFFC1F);
\r
429 /* Set the new trimming value corresponding to OPAMP1 NMOS input */
\r
430 tmpreg |= (OPAMP_TrimValue<<5);
\r
433 else if (OPAMP_Selection == OPAMP_Selection_OPAMP2)
\r
435 /* Reset the OPAMP inputs selection */
\r
436 tmpreg &= (uint32_t)~(OPAMP_CSR_OPA2CAL_L | OPAMP_CSR_OPA2CAL_H);
\r
437 /* Select the OPAMP input */
\r
438 tmpreg |= (uint32_t)(OPAMP_Input<<8);
\r
440 if(OPAMP_Input == OPAMP_Input_PMOS)
\r
442 /* Reset the trimming value corresponding to OPAMP2 PMOS input */
\r
443 tmpreg &= (0xFFFF83FF);
\r
444 /* Set the new trimming value corresponding to OPAMP2 PMOS input */
\r
445 tmpreg |= (OPAMP_TrimValue<<10);
\r
449 /* Reset the trimming value corresponding to OPAMP2 NMOS input */
\r
450 tmpreg &= (0xFFF07FFF);
\r
451 /* Set the new trimming value corresponding to OPAMP2 NMOS input */
\r
452 tmpreg |= (OPAMP_TrimValue<<15);
\r
457 /* Reset the OPAMP inputs selection */
\r
458 tmpreg &= (uint32_t)~(OPAMP_CSR_OPA3CAL_L | OPAMP_CSR_OPA3CAL_H);
\r
459 /* Select the OPAMP input */
\r
460 tmpreg |= (uint32_t)(OPAMP_Input<<16);
\r
462 if(OPAMP_Input == OPAMP_Input_PMOS)
\r
464 /* Reset the trimming value corresponding to OPAMP3 PMOS input */
\r
465 tmpreg &= (0xFE0FFFFF);
\r
466 /* Set the new trimming value corresponding to OPAMP3 PMOS input */
\r
467 tmpreg |= (OPAMP_TrimValue<<20);
\r
471 /* Reset the trimming value corresponding to OPAMP3 NMOS input */
\r
472 tmpreg &= (0xC1FFFFFF);
\r
473 /* Set the new trimming value corresponding to OPAMP3 NMOS input */
\r
474 tmpreg |= (OPAMP_TrimValue<<25);
\r
478 /* Set the OPAMP_LPOTR register */
\r
479 OPAMP->LPOTR = tmpreg;
\r
483 * @brief Checks whether the specified OPAMP calibration flag is set or not.
\r
484 * @note User should wait until calibration flag change the value when changing
\r
485 * the trimming value.
\r
486 * @param OPAMP_Selection: the selected OPAMP.
\r
487 * This parameter can be one of the following values:
\r
488 * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected.
\r
489 * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected.
\r
490 * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected.
\r
491 * @retval The new state of the OPAMP calibration flag (SET or RESET).
\r
493 FlagStatus OPAMP_GetFlagStatus(uint32_t OPAMP_Selection)
\r
495 FlagStatus bitstatus = RESET;
\r
496 uint32_t tmpreg = 0;
\r
498 /* Check the parameter */
\r
499 assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
\r
501 /* Get the CSR register value */
\r
502 tmpreg = OPAMP->CSR;
\r
504 /* Check if OPAMP1 is selected */
\r
505 if(OPAMP_Selection == OPAMP_Selection_OPAMP1)
\r
507 /* Check OPAMP1 CAL bit status */
\r
508 if ((tmpreg & OPAMP_CSR_OPA1CALOUT) != (uint32_t)RESET)
\r
517 /* Check if OPAMP2 is selected */
\r
518 else if(OPAMP_Selection == OPAMP_Selection_OPAMP2)
\r
520 /* Check OPAMP2 CAL bit status */
\r
521 if ((tmpreg & OPAMP_CSR_OPA2CALOUT) != (uint32_t)RESET)
\r
532 /* Check OPAMP3 CAL bit status */
\r
533 if ((tmpreg & OPAMP_CSR_OPA3CALOUT) != (uint32_t)RESET)
\r
557 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r