/** * @brief Configure the trimming value of the OPAMP. * @param OPAMP_Selection: the selected OPAMP. * This parameter can be OPAMP_Selection_OPAMPx where x can be 1 to 4 * to select the OPAMP peripheral. * @param OPAMP_Input: the selected OPAMP input. * This parameter can be one of the following values: * @arg OPAMP_Input_Inverting: Inverting input is selected to configure the trimming value * @arg OPAMP_Input_NonInverting: Non inverting input is selected to configure the trimming value * @param OPAMP_TrimValue: the trimming value. This parameter can be any value lower * or equal to 0x0000001F. * @retval None */ void OPAMP_OffsetTrimConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection)); assert_param(IS_OPAMP_INPUT(OPAMP_Input)); assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue)); /*!< Get the OPAMPx_CSR register value */ tmpreg = *(__IO uint32_t *) (OPAMP_BASE + OPAMP_Selection); /*!< Clear the trimming bits */ tmpreg &= ((uint32_t)~(OPAMP_CSR_TRIMMING_MASK<<OPAMP_Input)); /*!< Configure the new trimming value */ tmpreg |= (uint32_t)(OPAMP_TrimValue<<OPAMP_Input); /*!< Write to OPAMPx_CSR register */ *(__IO uint32_t *) (OPAMP_BASE + OPAMP_Selection) = tmpreg; }
/** * @brief Initializes the OPAMP according to the specified * parameters in the OPAMP_InitTypeDef and create the associated handle. * @note If the selected opamp is locked, initialization can't be performed. * To unlock the configuration, perform a system reset. * @param hopamp: OPAMP handle * @retval HAL status */ HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp) { HAL_StatusTypeDef status = HAL_OK; /* Check the OPAMP handle allocation and lock status */ /* Init not allowed if calibration is ongoing */ if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) \ || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)) { return HAL_ERROR; } else { /* Check the parameter */ assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); /* Set OPAMP parameters */ assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode)); assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput)); if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE) { assert_param(IS_OPAMP_INVERTING_INPUT(hopamp->Init.InvertingInput)); } assert_param(IS_OPAMP_TIMERCONTROLLED_MUXMODE(hopamp->Init.TimerControlledMuxmode)); if ((hopamp->Init.TimerControlledMuxmode) == OPAMP_TIMERCONTROLLEDMUXMODE_ENABLE) { assert_param(IS_OPAMP_SEC_NONINVERTINGINPUT(hopamp->Init.NonInvertingInputSecondary)); if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE) { assert_param(IS_OPAMP_SEC_INVERTINGINPUT(hopamp->Init.InvertingInputSecondary)); } } if ((hopamp->Init.Mode) == OPAMP_PGA_MODE) { assert_param(IS_OPAMP_PGACONNECT(hopamp->Init.PgaConnect)); assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain)); } assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming)); if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER) { assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP)); assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN)); } /* Init SYSCFG and the low level hardware to access opamp */ __HAL_RCC_SYSCFG_CLK_ENABLE(); if(hopamp->State == HAL_OPAMP_STATE_RESET) { /* Allocate lock resource and initialize it */ hopamp->Lock = HAL_UNLOCKED; } /* Call MSP init function */ HAL_OPAMP_MspInit(hopamp); /* Set OPAMP parameters */ /* Set bits according to hopamp->hopamp->Init.Mode value */ /* Set bits according to hopamp->hopamp->Init.InvertingInput value */ /* Set bits according to hopamp->hopamp->Init.NonInvertingInput value */ /* Set bits according to hopamp->hopamp->Init.TimerControlledMuxmode value */ /* Set bits according to hopamp->hopamp->Init.InvertingInputSecondary value */ /* Set bits according to hopamp->hopamp->Init.NonInvertingInputSecondary value */ /* Set bits according to hopamp->hopamp->Init.PgaConnect value */ /* Set bits according to hopamp->hopamp->Init.PgaGain value */ /* Set bits according to hopamp->hopamp->Init.UserTrimming value */ /* Set bits according to hopamp->hopamp->Init.TrimmingValueP value */ /* Set bits according to hopamp->hopamp->Init.TrimmingValueN value */ /* check if OPAMP_PGA_MODE & in Follower mode */ /* - InvertingInput */ /* - InvertingInputSecondary */ /* are Not Applicable */ if ((hopamp->Init.Mode == OPAMP_PGA_MODE) || (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE)) { MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_UPDATE_PARAMETERS_INIT_MASK, \ hopamp->Init.Mode | \ hopamp->Init.NonInvertingInput | \ hopamp->Init.TimerControlledMuxmode | \ hopamp->Init.NonInvertingInputSecondary | \ hopamp->Init.PgaConnect | \ hopamp->Init.PgaGain | \ hopamp->Init.UserTrimming | \ (hopamp->Init.TrimmingValueP << OPAMP_INPUT_NONINVERTING) | \ (hopamp->Init.TrimmingValueN << OPAMP_INPUT_INVERTING)); } else /* OPAMP_STANDALONE_MODE */ { MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_UPDATE_PARAMETERS_INIT_MASK, \ hopamp->Init.Mode | \ hopamp->Init.InvertingInput | \ hopamp->Init.NonInvertingInput | \ hopamp->Init.TimerControlledMuxmode | \ hopamp->Init.InvertingInputSecondary | \ hopamp->Init.NonInvertingInputSecondary | \ hopamp->Init.PgaConnect | \ hopamp->Init.PgaGain | \ hopamp->Init.UserTrimming | \ (hopamp->Init.TrimmingValueP << OPAMP_INPUT_NONINVERTING) | \ (hopamp->Init.TrimmingValueN << OPAMP_INPUT_INVERTING)); } /* Update the OPAMP state*/ if (hopamp->State == HAL_OPAMP_STATE_RESET) { /* From RESET state to READY State */ hopamp->State = HAL_OPAMP_STATE_READY; } /* else: remain in READY or BUSY state (no update) */ return status; } }
/** * @brief Configure the trimming value of OPAMPs in low power mode. * @param OPAMP_Selection: the selected OPAMP. * This parameter can be one of the following values: * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected to configure the trimming value. * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected to configure the trimming value. * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected to configure the trimming value. * @param OPAMP_Input: the selected OPAMP input. * This parameter can be one of the following values: * @arg OPAMP_Input_NMOS: NMOS input is selected to configure the trimming value. * @arg OPAMP_Input_PMOS: PMOS input is selected to configure the trimming value. * @param OPAMP_TrimValue: the trimming value. * This parameter can be any value lower or equal to 0x0000001F. * @retval None */ void OPAMP_OffsetTrimLowPowerConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue) { uint32_t tmpreg = 0; /* Check the parameter */ assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection)); assert_param(IS_OPAMP_INPUT(OPAMP_Input)); assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue)); /* Get the OPAMP_LPOTR value */ tmpreg = OPAMP->LPOTR; if(OPAMP_Selection == OPAMP_Selection_OPAMP1) { /* Reset the OPAMP inputs selection */ tmpreg &= (uint32_t)~(OPAMP_CSR_OPA1CAL_L | OPAMP_CSR_OPA1CAL_H); /* Select the OPAMP input */ tmpreg |= OPAMP_Input; if(OPAMP_Input == OPAMP_Input_PMOS) { /* Reset the trimming value corresponding to OPAMP1 PMOS input */ tmpreg &= (0xFFFFFFE0); /* Set the new trimming value corresponding to OPAMP1 PMOS input */ tmpreg |= (OPAMP_TrimValue); } else { /* Reset the trimming value corresponding to OPAMP1 NMOS input */ tmpreg &= (0xFFFFFC1F); /* Set the new trimming value corresponding to OPAMP1 NMOS input */ tmpreg |= (OPAMP_TrimValue<<5); } } else if (OPAMP_Selection == OPAMP_Selection_OPAMP2) { /* Reset the OPAMP inputs selection */ tmpreg &= (uint32_t)~(OPAMP_CSR_OPA2CAL_L | OPAMP_CSR_OPA2CAL_H); /* Select the OPAMP input */ tmpreg |= (uint32_t)(OPAMP_Input<<8); if(OPAMP_Input == OPAMP_Input_PMOS) { /* Reset the trimming value corresponding to OPAMP2 PMOS input */ tmpreg &= (0xFFFF83FF); /* Set the new trimming value corresponding to OPAMP2 PMOS input */ tmpreg |= (OPAMP_TrimValue<<10); } else { /* Reset the trimming value corresponding to OPAMP2 NMOS input */ tmpreg &= (0xFFF07FFF); /* Set the new trimming value corresponding to OPAMP2 NMOS input */ tmpreg |= (OPAMP_TrimValue<<15); } } else { /* Reset the OPAMP inputs selection */ tmpreg &= (uint32_t)~(OPAMP_CSR_OPA3CAL_L | OPAMP_CSR_OPA3CAL_H); /* Select the OPAMP input */ tmpreg |= (uint32_t)(OPAMP_Input<<16); if(OPAMP_Input == OPAMP_Input_PMOS) { /* Reset the trimming value corresponding to OPAMP3 PMOS input */ tmpreg &= (0xFE0FFFFF); /* Set the new trimming value corresponding to OPAMP3 PMOS input */ tmpreg |= (OPAMP_TrimValue<<20); } else { /* Reset the trimming value corresponding to OPAMP3 NMOS input */ tmpreg &= (0xC1FFFFFF); /* Set the new trimming value corresponding to OPAMP3 NMOS input */ tmpreg |= (OPAMP_TrimValue<<25); } } /* Set the OPAMP_LPOTR register */ OPAMP->LPOTR = tmpreg; }
/** * @brief Initializes the OPAMP according to the specified * parameters in the OPAMP_InitTypeDef and initialize the associated handle. * @note If the selected opamp is locked, initialization can't be performed. * To unlock the configuration, perform a system reset. * @param hopamp: OPAMP handle * @retval HAL status */ HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp) { HAL_StatusTypeDef status = HAL_OK; uint32_t updateotrlpotr = 0; /* Check the OPAMP handle allocation and lock status */ /* Init not allowed if calibration is ongoing */ if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)) { return HAL_ERROR; } else { /* Check the parameter */ assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); /* Set OPAMP parameters */ assert_param(IS_OPAMP_POWER_SUPPLY_RANGE(hopamp->Init.PowerSupplyRange)); assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode)); assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode)); assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput)); if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE) { assert_param(IS_OPAMP_INVERTING_INPUT_STANDALONE(hopamp->Init.InvertingInput)); } if ((hopamp->Init.Mode) == OPAMP_PGA_MODE) { assert_param(IS_OPAMP_INVERTING_INPUT_PGA(hopamp->Init.InvertingInput)); } if ((hopamp->Init.Mode) == OPAMP_PGA_MODE) { assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain)); } assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming)); if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER) { if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL) { assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP)); assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN)); } else { assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValuePLowPower)); assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueNLowPower)); } } if(hopamp->State == HAL_OPAMP_STATE_RESET) { /* Allocate lock resource and initialize it */ hopamp->Lock = HAL_UNLOCKED; } /* Call MSP init function */ HAL_OPAMP_MspInit(hopamp); /* Set operating mode */ CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALON); if (hopamp->Init.Mode == OPAMP_PGA_MODE) { MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_PGA, \ hopamp->Init.PowerMode | \ hopamp->Init.Mode | \ hopamp->Init.PgaGain | \ hopamp->Init.InvertingInput | \ hopamp->Init.NonInvertingInput | \ hopamp->Init.UserTrimming); } if (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE) { /* In Follower mode InvertingInput is Not Applicable */ MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_FOLLOWER, \ hopamp->Init.PowerMode | \ hopamp->Init.Mode | \ hopamp->Init.NonInvertingInput | \ hopamp->Init.UserTrimming); } if (hopamp->Init.Mode == OPAMP_STANDALONE_MODE) { MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_STANDALONE, \ hopamp->Init.PowerMode | \ hopamp->Init.Mode | \ hopamp->Init.InvertingInput | \ hopamp->Init.NonInvertingInput | \ hopamp->Init.UserTrimming); } if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER) { /* Set power mode and associated calibration parameters */ if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER) { /* OPAMP_POWERMODE_NORMAL */ /* Set calibration mode (factory or user) and values for */ /* transistors differential pair high (PMOS) and low (NMOS) for */ /* normal mode. */ updateotrlpotr = (((hopamp->Init.TrimmingValueP) << (OPAMP_INPUT_NONINVERTING)) \ | (hopamp->Init.TrimmingValueN)); MODIFY_REG(hopamp->Instance->OTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr); } else { /* OPAMP_POWERMODE_LOWPOWER */ /* transistors differential pair high (PMOS) and low (NMOS) for */ /* low power mode. */ updateotrlpotr = (((hopamp->Init.TrimmingValuePLowPower) << (OPAMP_INPUT_NONINVERTING)) \ | (hopamp->Init.TrimmingValueNLowPower)); MODIFY_REG(hopamp->Instance->LPOTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr); } } /* Configure the power supply range */ /* The OPAMP_CSR_OPARANGE is common configuration for all OPAMPs */ /* bit OPAMP1_CSR_OPARANGE is used for both OPAMPs */ MODIFY_REG(OPAMP1->CSR, OPAMP1_CSR_OPARANGE, hopamp->Init.PowerSupplyRange); /* Update the OPAMP state*/ if (hopamp->State == HAL_OPAMP_STATE_RESET) { /* From RESET state to READY State */ hopamp->State = HAL_OPAMP_STATE_READY; } /* else: remain in READY or BUSY state (no update) */ return status; } }
/** * @brief Initializes the OPAMP according to the specified * parameters in the OPAMP_InitTypeDef and create the associated handle. * @note If the selected opamp is locked, initialization can't be performed. * To unlock the configuration, perform a system reset. * @param hopamp: OPAMP handle * @retval HAL status */ HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef* hopamp) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmp_csr = 0; /* Temporary variable to update register CSR, except bits ANAWSSELx, S7SEL2, OPA_RANGE, OPAxCALOUT */ /* Check the OPAMP handle allocation and lock status */ /* Init not allowed if calibration is ongoing */ if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY) ) { status = HAL_ERROR; } else { /* Check the parameter */ assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); /* Set OPAMP parameters */ assert_param(IS_OPAMP_POWER_SUPPLY_RANGE(hopamp->Init.PowerSupplyRange)); assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode)); assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode)); assert_param(IS_OPAMP_NONINVERTING_INPUT_CHECK_INSTANCE(hopamp, hopamp->Init.NonInvertingInput)); assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming)); if (hopamp->Init.Mode != OPAMP_FOLLOWER_MODE) { assert_param(IS_OPAMP_INVERTING_INPUT(hopamp->Init.InvertingInput)); } if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER) { if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL) { assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP)); assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN)); } else { assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValuePLowPower)); assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueNLowPower)); } } if(hopamp->State == HAL_OPAMP_STATE_RESET) { /* Allocate lock resource and initialize it */ hopamp->Lock = HAL_UNLOCKED; } /* Call MSP init function */ HAL_OPAMP_MspInit(hopamp); /* Set OPAMP parameters */ /* - Set internal switches in function of: */ /* - OPAMP selected mode: standalone or follower. */ /* - Non-inverting input connection */ /* - Inverting input connection */ /* - Set power supply range */ /* - Set power mode and associated calibration parameters */ /* Get OPAMP CSR register into temporary variable */ /* Note: OPAMP register CSR is written directly, independently of OPAMP */ /* instance, because all OPAMP settings are dispatched in the same */ /* register. */ /* Settings of bits for each OPAMP instances are managed case by */ /* case using macro (OPAMP_CSR_S3SELX(), OPAMP_CSR_ANAWSELX(), ...) */ tmp_csr = OPAMP->CSR; /* Open all switches on non-inverting input, inverting input and output */ /* feedback. */ CLEAR_BIT(tmp_csr, OPAMP_CSR_ALL_SWITCHES(hopamp)); /* Set internal switches in function of OPAMP mode selected: standalone */ /* or follower. */ /* If follower mode is selected, feedback switch S3 is closed and */ /* inverting inputs switches are let opened. */ /* If standalone mode is selected, feedback switch S3 is let opened and */ /* the selected inverting inputs switch is closed. */ if (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE) { /* Follower mode: Close switches S3 and SanB */ SET_BIT(tmp_csr, OPAMP_CSR_S3SELX(hopamp)); } else { /* Set internal switches in function of inverting input selected: */ /* Close switch to connect OPAMP inverting input to the selected */ /* input: dedicated IO pin or alternative IO pin available on some */ /* device packages. */ if (hopamp->Init.InvertingInput == OPAMP_INVERTINGINPUT_IO0) { /* Close switch to connect OPAMP non-inverting input to */ /* dedicated IO pin low-leakage. */ SET_BIT(tmp_csr, OPAMP_CSR_S4SELX(hopamp)); } else { /* Close switch to connect OPAMP inverting input to alternative */ /* IO pin available on some device packages. */ SET_BIT(tmp_csr, OPAMP_CSR_ANAWSELX(hopamp)); } } /* Set internal switches in function of non-inverting input selected: */ /* Close switch to connect OPAMP non-inverting input to the selected */ /* input: dedicated IO pin or DAC channel. */ if (hopamp->Init.NonInvertingInput == OPAMP_NONINVERTINGINPUT_IO0) { /* Close switch to connect OPAMP non-inverting input to */ /* dedicated IO pin low-leakage. */ SET_BIT(tmp_csr, OPAMP_CSR_S5SELX(hopamp)); } else if (hopamp->Init.NonInvertingInput == OPAMP_NONINVERTINGINPUT_DAC_CH1) { /* Particular case for connection to DAC channel 1: */ /* OPAMP_NONINVERTINGINPUT_DAC_CH1 available on OPAMP1 and OPAMP2 only */ /* (OPAMP3 availability depends on device category). */ if ((hopamp->Instance == OPAMP1) || (hopamp->Instance == OPAMP2)) { /* Close switch to connect OPAMP non-inverting input to */ /* DAC channel 1. */ SET_BIT(tmp_csr, OPAMP_CSR_S6SELX(hopamp)); } else { /* Set HAL status to error if another OPAMP instance as OPAMP1 or */ /* OPAMP2 is intended to be connected to DAC channel 2. */ status = HAL_ERROR; } } else /* if (hopamp->Init.NonInvertingInput == */ /* OPAMP_NONINVERTINGINPUT_DAC_CH2 ) */ { /* Particular case for connection to DAC channel 2: */ /* OPAMP_NONINVERTINGINPUT_DAC_CH2 available on OPAMP2 and OPAMP3 only */ /* (OPAMP3 availability depends on device category). */ if (hopamp->Instance == OPAMP2) { /* Close switch to connect OPAMP non-inverting input to */ /* DAC channel 2. */ SET_BIT(tmp_csr, OPAMP_CSR_S7SEL2); } /* If OPAMP3 is selected (if available) */ else if (hopamp->Instance != OPAMP1) { /* Close switch to connect OPAMP non-inverting input to */ /* DAC channel 2. */ SET_BIT(tmp_csr, OPAMP_CSR_S6SELX(hopamp)); } else { /* Set HAL status to error if another OPAMP instance as OPAMP2 or */ /* OPAMP3 (if available) is intended to be connected to DAC channel 2.*/ status = HAL_ERROR; } } /* Continue OPAMP configuration if settings of switches are correct */ if (status != HAL_ERROR) { /* Set power mode and associated calibration parameters */ if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER) { /* Set normal mode */ CLEAR_BIT(tmp_csr, OPAMP_CSR_OPAXLPM(hopamp)); if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER) { /* Set calibration mode (factory or user) and values for */ /* transistors differential pair high (PMOS) and low (NMOS) for */ /* normal mode. */ MODIFY_REG(OPAMP->OTR, OPAMP_OTR_OT_USER | OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, OPAMP_TRIM_VALUE_MASK) | OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, OPAMP_TRIM_VALUE_MASK) , hopamp->Init.UserTrimming | OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, hopamp->Init.TrimmingValueN) | OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, hopamp->Init.TrimmingValueP) ); } else { /* Set calibration mode to factory */ CLEAR_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER); } } else { /* Set low power mode */ SET_BIT(tmp_csr, OPAMP_CSR_OPAXLPM(hopamp)); if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER) { /* Set calibration mode to user trimming */ SET_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER); /* Set values for transistors differential pair high (PMOS) and low */ /* (NMOS) for low power mode. */ MODIFY_REG(OPAMP->LPOTR, OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, OPAMP_TRIM_VALUE_MASK) | OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, OPAMP_TRIM_VALUE_MASK) , OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_N, hopamp->Init.TrimmingValueNLowPower) | OPAMP_OFFSET_TRIM_SET(hopamp, OPAMP_FACTORYTRIMMING_P, hopamp->Init.TrimmingValuePLowPower) ); } else { /* Set calibration mode to factory trimming */ CLEAR_BIT(OPAMP->OTR, OPAMP_OTR_OT_USER); } } /* Configure the power supply range */ MODIFY_REG(tmp_csr, OPAMP_CSR_AOP_RANGE, hopamp->Init.PowerSupplyRange); /* Set OPAMP CSR register from temporary variable */ /* This allows to apply all changes on one time, in case of update on */ /* the fly with OPAMP previously set and running: */ /* - to avoid hazardous transient switches settings (risk of short */ /* circuit) */ /* - to avoid interruption of input signal */ OPAMP->CSR = tmp_csr; /* Update the OPAMP state */ /* If coming from state reset: Update from state RESET to state READY */ if (hopamp->State == HAL_OPAMP_STATE_RESET) { hopamp->State = HAL_OPAMP_STATE_READY; } /* else: OPAMP state remains READY or BUSY state (no update) */ } } return status; }