TUKS MCU Introductory course / TUKS-COURSE-TIMER
Committer:
elmot
Date:
Fri Feb 24 21:13:56 2017 +0000
Revision:
1:d0dfbce63a89
Ready-to-copy

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elmot 1:d0dfbce63a89 1 /**
elmot 1:d0dfbce63a89 2 ******************************************************************************
elmot 1:d0dfbce63a89 3 * @file stm32l4xx_hal_opamp_ex.c
elmot 1:d0dfbce63a89 4 * @author MCD Application Team
elmot 1:d0dfbce63a89 5 * @version V1.5.1
elmot 1:d0dfbce63a89 6 * @date 31-May-2016
elmot 1:d0dfbce63a89 7 * @brief Extended OPAMP HAL module driver.
elmot 1:d0dfbce63a89 8 * This file provides firmware functions to manage the following
elmot 1:d0dfbce63a89 9 * functionalities of the operational amplifier(s)(OPAMP1, OPAMP2 etc)
elmot 1:d0dfbce63a89 10 * peripheral:
elmot 1:d0dfbce63a89 11 * + Extended Initialization and de-initialization functions
elmot 1:d0dfbce63a89 12 * + Extended Peripheral Control functions
elmot 1:d0dfbce63a89 13 *
elmot 1:d0dfbce63a89 14 @verbatim
elmot 1:d0dfbce63a89 15 ******************************************************************************
elmot 1:d0dfbce63a89 16 * @attention
elmot 1:d0dfbce63a89 17 *
elmot 1:d0dfbce63a89 18 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
elmot 1:d0dfbce63a89 19 *
elmot 1:d0dfbce63a89 20 * Redistribution and use in source and binary forms, with or without modification,
elmot 1:d0dfbce63a89 21 * are permitted provided that the following conditions are met:
elmot 1:d0dfbce63a89 22 * 1. Redistributions of source code must retain the above copyright notice,
elmot 1:d0dfbce63a89 23 * this list of conditions and the following disclaimer.
elmot 1:d0dfbce63a89 24 * 2. Redistributions in binary form must reproduce the above copyright notice,
elmot 1:d0dfbce63a89 25 * this list of conditions and the following disclaimer in the documentation
elmot 1:d0dfbce63a89 26 * and/or other materials provided with the distribution.
elmot 1:d0dfbce63a89 27 * 3. Neither the name of STMicroelectronics nor the names of its contributors
elmot 1:d0dfbce63a89 28 * may be used to endorse or promote products derived from this software
elmot 1:d0dfbce63a89 29 * without specific prior written permission.
elmot 1:d0dfbce63a89 30 *
elmot 1:d0dfbce63a89 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
elmot 1:d0dfbce63a89 32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
elmot 1:d0dfbce63a89 33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
elmot 1:d0dfbce63a89 34 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
elmot 1:d0dfbce63a89 35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
elmot 1:d0dfbce63a89 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
elmot 1:d0dfbce63a89 37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
elmot 1:d0dfbce63a89 38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
elmot 1:d0dfbce63a89 39 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
elmot 1:d0dfbce63a89 40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
elmot 1:d0dfbce63a89 41 *
elmot 1:d0dfbce63a89 42 ******************************************************************************
elmot 1:d0dfbce63a89 43 */
elmot 1:d0dfbce63a89 44
elmot 1:d0dfbce63a89 45 /* Includes ------------------------------------------------------------------*/
elmot 1:d0dfbce63a89 46 #include "stm32l4xx_hal.h"
elmot 1:d0dfbce63a89 47
elmot 1:d0dfbce63a89 48 /** @addtogroup STM32L4xx_HAL_Driver
elmot 1:d0dfbce63a89 49 * @{
elmot 1:d0dfbce63a89 50 */
elmot 1:d0dfbce63a89 51
elmot 1:d0dfbce63a89 52 /** @defgroup OPAMPEx OPAMPEx
elmot 1:d0dfbce63a89 53 * @brief OPAMP Extended HAL module driver
elmot 1:d0dfbce63a89 54 * @{
elmot 1:d0dfbce63a89 55 */
elmot 1:d0dfbce63a89 56
elmot 1:d0dfbce63a89 57 #ifdef HAL_OPAMP_MODULE_ENABLED
elmot 1:d0dfbce63a89 58
elmot 1:d0dfbce63a89 59 /* Private typedef -----------------------------------------------------------*/
elmot 1:d0dfbce63a89 60 /* Private define ------------------------------------------------------------*/
elmot 1:d0dfbce63a89 61 /* Private macro -------------------------------------------------------------*/
elmot 1:d0dfbce63a89 62 /* Private variables ---------------------------------------------------------*/
elmot 1:d0dfbce63a89 63 /* Private function prototypes -----------------------------------------------*/
elmot 1:d0dfbce63a89 64 /* Exported functions --------------------------------------------------------*/
elmot 1:d0dfbce63a89 65
elmot 1:d0dfbce63a89 66 /** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions
elmot 1:d0dfbce63a89 67 * @{
elmot 1:d0dfbce63a89 68 */
elmot 1:d0dfbce63a89 69
elmot 1:d0dfbce63a89 70 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx)
elmot 1:d0dfbce63a89 71
elmot 1:d0dfbce63a89 72 /** @addtogroup OPAMPEx_Exported_Functions_Group1
elmot 1:d0dfbce63a89 73 * @brief Extended operation functions
elmot 1:d0dfbce63a89 74 *
elmot 1:d0dfbce63a89 75 @verbatim
elmot 1:d0dfbce63a89 76 ===============================================================================
elmot 1:d0dfbce63a89 77 ##### Extended IO operation functions #####
elmot 1:d0dfbce63a89 78 ===============================================================================
elmot 1:d0dfbce63a89 79 [..]
elmot 1:d0dfbce63a89 80 (+) OPAMP Self calibration.
elmot 1:d0dfbce63a89 81
elmot 1:d0dfbce63a89 82 @endverbatim
elmot 1:d0dfbce63a89 83 * @{
elmot 1:d0dfbce63a89 84 */
elmot 1:d0dfbce63a89 85
elmot 1:d0dfbce63a89 86 /* 2 OPAMPS available */
elmot 1:d0dfbce63a89 87 /* 2 OPAMPS can be calibrated in parallel */
elmot 1:d0dfbce63a89 88 /* Not available on STM32L43x/STM32L44x where only one OPAMP available */
elmot 1:d0dfbce63a89 89
elmot 1:d0dfbce63a89 90 /**
elmot 1:d0dfbce63a89 91 * @brief Run the self calibration of the 2 OPAMPs in parallel.
elmot 1:d0dfbce63a89 92 * @note Trimming values (PMOS & NMOS) are updated and user trimming is
elmot 1:d0dfbce63a89 93 * enabled is calibration is successful.
elmot 1:d0dfbce63a89 94 * @note Calibration is performed in the mode specified in OPAMP init
elmot 1:d0dfbce63a89 95 * structure (mode normal or low-power). To perform calibration for
elmot 1:d0dfbce63a89 96 * both modes, repeat this function twice after OPAMP init structure
elmot 1:d0dfbce63a89 97 * accordingly updated.
elmot 1:d0dfbce63a89 98 * @note Calibration runs about 10 ms (5 dichotomy steps, repeated for P
elmot 1:d0dfbce63a89 99 * and N transistors: 10 steps with 1 ms for each step).
elmot 1:d0dfbce63a89 100 * @param hopamp1 handle
elmot 1:d0dfbce63a89 101 * @param hopamp2 handle
elmot 1:d0dfbce63a89 102 * @retval HAL status
elmot 1:d0dfbce63a89 103 */
elmot 1:d0dfbce63a89 104
elmot 1:d0dfbce63a89 105 HAL_StatusTypeDef HAL_OPAMPEx_SelfCalibrateAll(OPAMP_HandleTypeDef *hopamp1, OPAMP_HandleTypeDef *hopamp2)
elmot 1:d0dfbce63a89 106 {
elmot 1:d0dfbce63a89 107 HAL_StatusTypeDef status = HAL_OK;
elmot 1:d0dfbce63a89 108
elmot 1:d0dfbce63a89 109 uint32_t trimmingvaluen1 = 0;
elmot 1:d0dfbce63a89 110 uint32_t trimmingvaluep1 = 0;
elmot 1:d0dfbce63a89 111 uint32_t trimmingvaluen2 = 0;
elmot 1:d0dfbce63a89 112 uint32_t trimmingvaluep2 = 0;
elmot 1:d0dfbce63a89 113
elmot 1:d0dfbce63a89 114 /* Selection of register of trimming depending on power mode: OTR or LPOTR */
elmot 1:d0dfbce63a89 115 __IO uint32_t* tmp_opamp1_reg_trimming;
elmot 1:d0dfbce63a89 116 __IO uint32_t* tmp_opamp2_reg_trimming;
elmot 1:d0dfbce63a89 117
elmot 1:d0dfbce63a89 118 uint32_t delta;
elmot 1:d0dfbce63a89 119 uint32_t opampmode1;
elmot 1:d0dfbce63a89 120 uint32_t opampmode2;
elmot 1:d0dfbce63a89 121
elmot 1:d0dfbce63a89 122 if((hopamp1 == NULL) || (hopamp1->State == HAL_OPAMP_STATE_BUSYLOCKED) || \
elmot 1:d0dfbce63a89 123 (hopamp2 == NULL) || (hopamp2->State == HAL_OPAMP_STATE_BUSYLOCKED))
elmot 1:d0dfbce63a89 124 {
elmot 1:d0dfbce63a89 125 status = HAL_ERROR;
elmot 1:d0dfbce63a89 126 }
elmot 1:d0dfbce63a89 127 else
elmot 1:d0dfbce63a89 128 {
elmot 1:d0dfbce63a89 129 /* Check if OPAMP in calibration mode and calibration not yet enable */
elmot 1:d0dfbce63a89 130 if((hopamp1->State == HAL_OPAMP_STATE_READY) && (hopamp2->State == HAL_OPAMP_STATE_READY))
elmot 1:d0dfbce63a89 131 {
elmot 1:d0dfbce63a89 132 /* Check the parameter */
elmot 1:d0dfbce63a89 133 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp1->Instance));
elmot 1:d0dfbce63a89 134 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp2->Instance));
elmot 1:d0dfbce63a89 135
elmot 1:d0dfbce63a89 136 assert_param(IS_OPAMP_POWERMODE(hopamp1->Init.PowerMode));
elmot 1:d0dfbce63a89 137 assert_param(IS_OPAMP_POWERMODE(hopamp2->Init.PowerMode));
elmot 1:d0dfbce63a89 138
elmot 1:d0dfbce63a89 139 /* Save OPAMP mode as in */
elmot 1:d0dfbce63a89 140 /* STM32L471xx STM32L475xx STM32L476xx STM32L485xx STM32L486xx */
elmot 1:d0dfbce63a89 141 /* the calibration is not working in PGA mode */
elmot 1:d0dfbce63a89 142 opampmode1 = READ_BIT(hopamp1->Instance->CSR,OPAMP_CSR_OPAMODE);
elmot 1:d0dfbce63a89 143 opampmode2 = READ_BIT(hopamp2->Instance->CSR,OPAMP_CSR_OPAMODE);
elmot 1:d0dfbce63a89 144
elmot 1:d0dfbce63a89 145 /* Use of standalone mode */
elmot 1:d0dfbce63a89 146 MODIFY_REG(hopamp1->Instance->CSR, OPAMP_CSR_OPAMODE, OPAMP_STANDALONE_MODE);
elmot 1:d0dfbce63a89 147 MODIFY_REG(hopamp2->Instance->CSR, OPAMP_CSR_OPAMODE, OPAMP_STANDALONE_MODE);
elmot 1:d0dfbce63a89 148
elmot 1:d0dfbce63a89 149 /* user trimming values are used for offset calibration */
elmot 1:d0dfbce63a89 150 SET_BIT(hopamp1->Instance->CSR, OPAMP_CSR_USERTRIM);
elmot 1:d0dfbce63a89 151 SET_BIT(hopamp2->Instance->CSR, OPAMP_CSR_USERTRIM);
elmot 1:d0dfbce63a89 152
elmot 1:d0dfbce63a89 153 /* Select trimming settings depending on power mode */
elmot 1:d0dfbce63a89 154 if (hopamp1->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
elmot 1:d0dfbce63a89 155 {
elmot 1:d0dfbce63a89 156 tmp_opamp1_reg_trimming = &OPAMP1->OTR;
elmot 1:d0dfbce63a89 157 }
elmot 1:d0dfbce63a89 158 else
elmot 1:d0dfbce63a89 159 {
elmot 1:d0dfbce63a89 160 tmp_opamp1_reg_trimming = &OPAMP1->LPOTR;
elmot 1:d0dfbce63a89 161 }
elmot 1:d0dfbce63a89 162
elmot 1:d0dfbce63a89 163 if (hopamp2->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
elmot 1:d0dfbce63a89 164 {
elmot 1:d0dfbce63a89 165 tmp_opamp2_reg_trimming = &OPAMP2->OTR;
elmot 1:d0dfbce63a89 166 }
elmot 1:d0dfbce63a89 167 else
elmot 1:d0dfbce63a89 168 {
elmot 1:d0dfbce63a89 169 tmp_opamp2_reg_trimming = &OPAMP2->LPOTR;
elmot 1:d0dfbce63a89 170 }
elmot 1:d0dfbce63a89 171
elmot 1:d0dfbce63a89 172 /* Enable calibration */
elmot 1:d0dfbce63a89 173 SET_BIT (hopamp1->Instance->CSR, OPAMP_CSR_CALON);
elmot 1:d0dfbce63a89 174 SET_BIT (hopamp2->Instance->CSR, OPAMP_CSR_CALON);
elmot 1:d0dfbce63a89 175
elmot 1:d0dfbce63a89 176 /* 1st calibration - N */
elmot 1:d0dfbce63a89 177 CLEAR_BIT (hopamp1->Instance->CSR, OPAMP_CSR_CALSEL);
elmot 1:d0dfbce63a89 178 CLEAR_BIT (hopamp2->Instance->CSR, OPAMP_CSR_CALSEL);
elmot 1:d0dfbce63a89 179
elmot 1:d0dfbce63a89 180 /* Enable the selected opamp */
elmot 1:d0dfbce63a89 181 SET_BIT (hopamp1->Instance->CSR, OPAMP_CSR_OPAMPxEN);
elmot 1:d0dfbce63a89 182 SET_BIT (hopamp2->Instance->CSR, OPAMP_CSR_OPAMPxEN);
elmot 1:d0dfbce63a89 183
elmot 1:d0dfbce63a89 184 /* Init trimming counter */
elmot 1:d0dfbce63a89 185 /* Medium value */
elmot 1:d0dfbce63a89 186 trimmingvaluen1 = 16;
elmot 1:d0dfbce63a89 187 trimmingvaluen2 = 16;
elmot 1:d0dfbce63a89 188 delta = 8;
elmot 1:d0dfbce63a89 189
elmot 1:d0dfbce63a89 190 while (delta != 0)
elmot 1:d0dfbce63a89 191 {
elmot 1:d0dfbce63a89 192 /* Set candidate trimming */
elmot 1:d0dfbce63a89 193 /* OPAMP_POWERMODE_NORMAL */
elmot 1:d0dfbce63a89 194 MODIFY_REG(*tmp_opamp1_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen1);
elmot 1:d0dfbce63a89 195 MODIFY_REG(*tmp_opamp2_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen2);
elmot 1:d0dfbce63a89 196
elmot 1:d0dfbce63a89 197 /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
elmot 1:d0dfbce63a89 198 /* Offset trim time: during calibration, minimum time needed between */
elmot 1:d0dfbce63a89 199 /* two steps to have 1 mV accuracy */
elmot 1:d0dfbce63a89 200 HAL_Delay(OPAMP_TRIMMING_DELAY);
elmot 1:d0dfbce63a89 201
elmot 1:d0dfbce63a89 202 if (READ_BIT(hopamp1->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
elmot 1:d0dfbce63a89 203 {
elmot 1:d0dfbce63a89 204 /* OPAMP_CSR_CALOUT is HIGH try lower trimming */
elmot 1:d0dfbce63a89 205 trimmingvaluen1 -= delta;
elmot 1:d0dfbce63a89 206 }
elmot 1:d0dfbce63a89 207 else
elmot 1:d0dfbce63a89 208 {
elmot 1:d0dfbce63a89 209 /* OPAMP_CSR_CALOUT is LOW try higher trimming */
elmot 1:d0dfbce63a89 210 trimmingvaluen1 += delta;
elmot 1:d0dfbce63a89 211 }
elmot 1:d0dfbce63a89 212
elmot 1:d0dfbce63a89 213 if (READ_BIT(hopamp2->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
elmot 1:d0dfbce63a89 214 {
elmot 1:d0dfbce63a89 215 /* OPAMP_CSR_CALOUT is HIGH try lower trimming */
elmot 1:d0dfbce63a89 216 trimmingvaluen2 -= delta;
elmot 1:d0dfbce63a89 217 }
elmot 1:d0dfbce63a89 218 else
elmot 1:d0dfbce63a89 219 {
elmot 1:d0dfbce63a89 220 /* OPAMP_CSR_CALOUT is LOW try higher trimming */
elmot 1:d0dfbce63a89 221 trimmingvaluen2 += delta;
elmot 1:d0dfbce63a89 222 }
elmot 1:d0dfbce63a89 223 /* Divide range by 2 to continue dichotomy sweep */
elmot 1:d0dfbce63a89 224 delta >>= 1;
elmot 1:d0dfbce63a89 225 }
elmot 1:d0dfbce63a89 226
elmot 1:d0dfbce63a89 227 /* Still need to check if right calibration is current value or one step below */
elmot 1:d0dfbce63a89 228 /* Indeed the first value that causes the OUTCAL bit to change from 0 to 1 */
elmot 1:d0dfbce63a89 229 /* Set candidate trimming */
elmot 1:d0dfbce63a89 230 MODIFY_REG(*tmp_opamp1_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen1);
elmot 1:d0dfbce63a89 231 MODIFY_REG(*tmp_opamp2_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen2);
elmot 1:d0dfbce63a89 232
elmot 1:d0dfbce63a89 233 /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
elmot 1:d0dfbce63a89 234 /* Offset trim time: during calibration, minimum time needed between */
elmot 1:d0dfbce63a89 235 /* two steps to have 1 mV accuracy */
elmot 1:d0dfbce63a89 236 HAL_Delay(OPAMP_TRIMMING_DELAY);
elmot 1:d0dfbce63a89 237
elmot 1:d0dfbce63a89 238 if ((READ_BIT(hopamp1->Instance->CSR, OPAMP_CSR_CALOUT)) == 0)
elmot 1:d0dfbce63a89 239 {
elmot 1:d0dfbce63a89 240 /* Trimming value is actually one value more */
elmot 1:d0dfbce63a89 241 trimmingvaluen1++;
elmot 1:d0dfbce63a89 242 MODIFY_REG(*tmp_opamp1_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen1);
elmot 1:d0dfbce63a89 243 }
elmot 1:d0dfbce63a89 244
elmot 1:d0dfbce63a89 245 if ((READ_BIT(hopamp2->Instance->CSR, OPAMP_CSR_CALOUT)) == 0)
elmot 1:d0dfbce63a89 246 {
elmot 1:d0dfbce63a89 247 /* Trimming value is actually one value more */
elmot 1:d0dfbce63a89 248 trimmingvaluen2++;
elmot 1:d0dfbce63a89 249 MODIFY_REG(*tmp_opamp2_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen2);
elmot 1:d0dfbce63a89 250 }
elmot 1:d0dfbce63a89 251
elmot 1:d0dfbce63a89 252 /* 2nd calibration - P */
elmot 1:d0dfbce63a89 253 SET_BIT (hopamp1->Instance->CSR, OPAMP_CSR_CALSEL);
elmot 1:d0dfbce63a89 254 SET_BIT (hopamp2->Instance->CSR, OPAMP_CSR_CALSEL);
elmot 1:d0dfbce63a89 255
elmot 1:d0dfbce63a89 256 /* Init trimming counter */
elmot 1:d0dfbce63a89 257 /* Medium value */
elmot 1:d0dfbce63a89 258 trimmingvaluep1 = 16;
elmot 1:d0dfbce63a89 259 trimmingvaluep2 = 16;
elmot 1:d0dfbce63a89 260 delta = 8;
elmot 1:d0dfbce63a89 261
elmot 1:d0dfbce63a89 262 while (delta != 0)
elmot 1:d0dfbce63a89 263 {
elmot 1:d0dfbce63a89 264 /* Set candidate trimming */
elmot 1:d0dfbce63a89 265 /* OPAMP_POWERMODE_NORMAL */
elmot 1:d0dfbce63a89 266 MODIFY_REG(*tmp_opamp1_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep1<<OPAMP_INPUT_NONINVERTING));
elmot 1:d0dfbce63a89 267 MODIFY_REG(*tmp_opamp2_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep2<<OPAMP_INPUT_NONINVERTING));
elmot 1:d0dfbce63a89 268
elmot 1:d0dfbce63a89 269 /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
elmot 1:d0dfbce63a89 270 /* Offset trim time: during calibration, minimum time needed between */
elmot 1:d0dfbce63a89 271 /* two steps to have 1 mV accuracy */
elmot 1:d0dfbce63a89 272 HAL_Delay(OPAMP_TRIMMING_DELAY);
elmot 1:d0dfbce63a89 273
elmot 1:d0dfbce63a89 274 if (READ_BIT(hopamp1->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
elmot 1:d0dfbce63a89 275 {
elmot 1:d0dfbce63a89 276 /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
elmot 1:d0dfbce63a89 277 trimmingvaluep1 += delta;
elmot 1:d0dfbce63a89 278 }
elmot 1:d0dfbce63a89 279 else
elmot 1:d0dfbce63a89 280 {
elmot 1:d0dfbce63a89 281 /* OPAMP_CSR_CALOUT is HIGH try lower trimming */
elmot 1:d0dfbce63a89 282 trimmingvaluep1 -= delta;
elmot 1:d0dfbce63a89 283 }
elmot 1:d0dfbce63a89 284
elmot 1:d0dfbce63a89 285 if (READ_BIT(hopamp2->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
elmot 1:d0dfbce63a89 286 {
elmot 1:d0dfbce63a89 287 /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
elmot 1:d0dfbce63a89 288 trimmingvaluep2 += delta;
elmot 1:d0dfbce63a89 289 }
elmot 1:d0dfbce63a89 290 else
elmot 1:d0dfbce63a89 291 {
elmot 1:d0dfbce63a89 292 /* OPAMP_CSR_CALOUT is LOW try lower trimming */
elmot 1:d0dfbce63a89 293 trimmingvaluep2 -= delta;
elmot 1:d0dfbce63a89 294 }
elmot 1:d0dfbce63a89 295 /* Divide range by 2 to continue dichotomy sweep */
elmot 1:d0dfbce63a89 296 delta >>= 1;
elmot 1:d0dfbce63a89 297 }
elmot 1:d0dfbce63a89 298
elmot 1:d0dfbce63a89 299 /* Still need to check if right calibration is current value or one step below */
elmot 1:d0dfbce63a89 300 /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0 */
elmot 1:d0dfbce63a89 301 /* Set candidate trimming */
elmot 1:d0dfbce63a89 302 MODIFY_REG(*tmp_opamp1_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep1<<OPAMP_INPUT_NONINVERTING));
elmot 1:d0dfbce63a89 303 MODIFY_REG(*tmp_opamp2_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep2<<OPAMP_INPUT_NONINVERTING));
elmot 1:d0dfbce63a89 304
elmot 1:d0dfbce63a89 305 /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */
elmot 1:d0dfbce63a89 306 /* Offset trim time: during calibration, minimum time needed between */
elmot 1:d0dfbce63a89 307 /* two steps to have 1 mV accuracy */
elmot 1:d0dfbce63a89 308 HAL_Delay(OPAMP_TRIMMING_DELAY);
elmot 1:d0dfbce63a89 309
elmot 1:d0dfbce63a89 310 if (READ_BIT(hopamp1->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
elmot 1:d0dfbce63a89 311 {
elmot 1:d0dfbce63a89 312 /* Trimming value is actually one value more */
elmot 1:d0dfbce63a89 313 trimmingvaluep1++;
elmot 1:d0dfbce63a89 314 MODIFY_REG(*tmp_opamp1_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep1<<OPAMP_INPUT_NONINVERTING));
elmot 1:d0dfbce63a89 315 }
elmot 1:d0dfbce63a89 316
elmot 1:d0dfbce63a89 317 if (READ_BIT(hopamp2->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
elmot 1:d0dfbce63a89 318 {
elmot 1:d0dfbce63a89 319 /* Trimming value is actually one value more */
elmot 1:d0dfbce63a89 320 trimmingvaluep2++;
elmot 1:d0dfbce63a89 321 MODIFY_REG(*tmp_opamp2_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep2<<OPAMP_INPUT_NONINVERTING));
elmot 1:d0dfbce63a89 322 }
elmot 1:d0dfbce63a89 323
elmot 1:d0dfbce63a89 324 /* Disable the OPAMPs */
elmot 1:d0dfbce63a89 325 CLEAR_BIT (hopamp1->Instance->CSR, OPAMP_CSR_OPAMPxEN);
elmot 1:d0dfbce63a89 326 CLEAR_BIT (hopamp2->Instance->CSR, OPAMP_CSR_OPAMPxEN);
elmot 1:d0dfbce63a89 327
elmot 1:d0dfbce63a89 328 /* Disable calibration & set normal mode (operating mode) */
elmot 1:d0dfbce63a89 329 CLEAR_BIT (hopamp1->Instance->CSR, OPAMP_CSR_CALON);
elmot 1:d0dfbce63a89 330 CLEAR_BIT (hopamp2->Instance->CSR, OPAMP_CSR_CALON);
elmot 1:d0dfbce63a89 331
elmot 1:d0dfbce63a89 332 /* Self calibration is successful */
elmot 1:d0dfbce63a89 333 /* Store calibration (user trimming) results in init structure. */
elmot 1:d0dfbce63a89 334
elmot 1:d0dfbce63a89 335 /* Set user trimming mode */
elmot 1:d0dfbce63a89 336 hopamp1->Init.UserTrimming = OPAMP_TRIMMING_USER;
elmot 1:d0dfbce63a89 337 hopamp2->Init.UserTrimming = OPAMP_TRIMMING_USER;
elmot 1:d0dfbce63a89 338
elmot 1:d0dfbce63a89 339 /* Affect calibration parameters depending on mode normal/low power */
elmot 1:d0dfbce63a89 340 if (hopamp1->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
elmot 1:d0dfbce63a89 341 {
elmot 1:d0dfbce63a89 342 /* Write calibration result N */
elmot 1:d0dfbce63a89 343 hopamp1->Init.TrimmingValueN = trimmingvaluen1;
elmot 1:d0dfbce63a89 344 /* Write calibration result P */
elmot 1:d0dfbce63a89 345 hopamp1->Init.TrimmingValueP = trimmingvaluep1;
elmot 1:d0dfbce63a89 346 }
elmot 1:d0dfbce63a89 347 else
elmot 1:d0dfbce63a89 348 {
elmot 1:d0dfbce63a89 349 /* Write calibration result N */
elmot 1:d0dfbce63a89 350 hopamp1->Init.TrimmingValueNLowPower = trimmingvaluen1;
elmot 1:d0dfbce63a89 351 /* Write calibration result P */
elmot 1:d0dfbce63a89 352 hopamp1->Init.TrimmingValuePLowPower = trimmingvaluep1;
elmot 1:d0dfbce63a89 353 }
elmot 1:d0dfbce63a89 354
elmot 1:d0dfbce63a89 355 if (hopamp2->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
elmot 1:d0dfbce63a89 356 {
elmot 1:d0dfbce63a89 357 /* Write calibration result N */
elmot 1:d0dfbce63a89 358 hopamp2->Init.TrimmingValueN = trimmingvaluen2;
elmot 1:d0dfbce63a89 359 /* Write calibration result P */
elmot 1:d0dfbce63a89 360 hopamp2->Init.TrimmingValueP = trimmingvaluep2;
elmot 1:d0dfbce63a89 361 }
elmot 1:d0dfbce63a89 362 else
elmot 1:d0dfbce63a89 363 {
elmot 1:d0dfbce63a89 364 /* Write calibration result N */
elmot 1:d0dfbce63a89 365 hopamp2->Init.TrimmingValueNLowPower = trimmingvaluen2;
elmot 1:d0dfbce63a89 366 /* Write calibration result P */
elmot 1:d0dfbce63a89 367 hopamp2->Init.TrimmingValuePLowPower = trimmingvaluep2;
elmot 1:d0dfbce63a89 368 }
elmot 1:d0dfbce63a89 369
elmot 1:d0dfbce63a89 370 /* Update OPAMP state */
elmot 1:d0dfbce63a89 371 hopamp1->State = HAL_OPAMP_STATE_READY;
elmot 1:d0dfbce63a89 372 hopamp2->State = HAL_OPAMP_STATE_READY;
elmot 1:d0dfbce63a89 373
elmot 1:d0dfbce63a89 374 /* Restore OPAMP mode after calibration */
elmot 1:d0dfbce63a89 375 MODIFY_REG(hopamp1->Instance->CSR, OPAMP_CSR_OPAMODE, opampmode1);
elmot 1:d0dfbce63a89 376 MODIFY_REG(hopamp2->Instance->CSR, OPAMP_CSR_OPAMODE, opampmode2);
elmot 1:d0dfbce63a89 377 }
elmot 1:d0dfbce63a89 378 else
elmot 1:d0dfbce63a89 379 {
elmot 1:d0dfbce63a89 380 /* At least one OPAMP can not be calibrated */
elmot 1:d0dfbce63a89 381 status = HAL_ERROR;
elmot 1:d0dfbce63a89 382 }
elmot 1:d0dfbce63a89 383 }
elmot 1:d0dfbce63a89 384 return status;
elmot 1:d0dfbce63a89 385 }
elmot 1:d0dfbce63a89 386
elmot 1:d0dfbce63a89 387 /**
elmot 1:d0dfbce63a89 388 * @}
elmot 1:d0dfbce63a89 389 */
elmot 1:d0dfbce63a89 390
elmot 1:d0dfbce63a89 391 #endif
elmot 1:d0dfbce63a89 392
elmot 1:d0dfbce63a89 393 /** @defgroup OPAMPEx_Exported_Functions_Group2 Peripheral Control functions
elmot 1:d0dfbce63a89 394 * @brief Peripheral Control functions
elmot 1:d0dfbce63a89 395 *
elmot 1:d0dfbce63a89 396 @verbatim
elmot 1:d0dfbce63a89 397 ===============================================================================
elmot 1:d0dfbce63a89 398 ##### Peripheral Control functions #####
elmot 1:d0dfbce63a89 399 ===============================================================================
elmot 1:d0dfbce63a89 400 [..]
elmot 1:d0dfbce63a89 401 (+) OPAMP unlock.
elmot 1:d0dfbce63a89 402
elmot 1:d0dfbce63a89 403 @endverbatim
elmot 1:d0dfbce63a89 404 * @{
elmot 1:d0dfbce63a89 405 */
elmot 1:d0dfbce63a89 406
elmot 1:d0dfbce63a89 407 /**
elmot 1:d0dfbce63a89 408 * @brief Unlock the selected OPAMP configuration.
elmot 1:d0dfbce63a89 409 * @note This function must be called only when OPAMP is in state "locked".
elmot 1:d0dfbce63a89 410 * @param hopamp: OPAMP handle
elmot 1:d0dfbce63a89 411 * @retval HAL status
elmot 1:d0dfbce63a89 412 */
elmot 1:d0dfbce63a89 413 HAL_StatusTypeDef HAL_OPAMPEx_Unlock(OPAMP_HandleTypeDef* hopamp)
elmot 1:d0dfbce63a89 414 {
elmot 1:d0dfbce63a89 415 HAL_StatusTypeDef status = HAL_OK;
elmot 1:d0dfbce63a89 416
elmot 1:d0dfbce63a89 417 /* Check the OPAMP handle allocation */
elmot 1:d0dfbce63a89 418 /* Check if OPAMP locked */
elmot 1:d0dfbce63a89 419 if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET)
elmot 1:d0dfbce63a89 420 || (hopamp->State == HAL_OPAMP_STATE_READY)
elmot 1:d0dfbce63a89 421 || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
elmot 1:d0dfbce63a89 422 || (hopamp->State == HAL_OPAMP_STATE_BUSY))
elmot 1:d0dfbce63a89 423
elmot 1:d0dfbce63a89 424 {
elmot 1:d0dfbce63a89 425 status = HAL_ERROR;
elmot 1:d0dfbce63a89 426 }
elmot 1:d0dfbce63a89 427 else
elmot 1:d0dfbce63a89 428 {
elmot 1:d0dfbce63a89 429 /* Check the parameter */
elmot 1:d0dfbce63a89 430 assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
elmot 1:d0dfbce63a89 431
elmot 1:d0dfbce63a89 432 /* OPAMP state changed to locked */
elmot 1:d0dfbce63a89 433 hopamp->State = HAL_OPAMP_STATE_BUSY;
elmot 1:d0dfbce63a89 434 }
elmot 1:d0dfbce63a89 435 return status;
elmot 1:d0dfbce63a89 436 }
elmot 1:d0dfbce63a89 437
elmot 1:d0dfbce63a89 438 /**
elmot 1:d0dfbce63a89 439 * @}
elmot 1:d0dfbce63a89 440 */
elmot 1:d0dfbce63a89 441
elmot 1:d0dfbce63a89 442 /**
elmot 1:d0dfbce63a89 443 * @}
elmot 1:d0dfbce63a89 444 */
elmot 1:d0dfbce63a89 445
elmot 1:d0dfbce63a89 446 #endif /* HAL_OPAMP_MODULE_ENABLED */
elmot 1:d0dfbce63a89 447 /**
elmot 1:d0dfbce63a89 448 * @}
elmot 1:d0dfbce63a89 449 */
elmot 1:d0dfbce63a89 450
elmot 1:d0dfbce63a89 451 /**
elmot 1:d0dfbce63a89 452 * @}
elmot 1:d0dfbce63a89 453 */
elmot 1:d0dfbce63a89 454
elmot 1:d0dfbce63a89 455 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/