cancel
Showing results for 
Search instead for 
Did you mean: 

Checking of the Internal OPAMP self-calibration function on the STM32U083C-DK

ssHan
Associate II

I'm checking the output of internal opamp in the STM32U083C-DK.
In both PGA and Follower modes, I found that the opamp output voltage was lower than the actual input signal.

Follower mode/before calibration(Factory trim/0xe13):

- Input signal: 0.2502V -> Output signal: 0.2488V

PGA mode(Gain: x8)/before calibration:

- Input signal: 0.1010V -> Output signal: 0.7942V


So, I used the opamp's internal calibration function.

Follower mode/after calibration(User trim/0x1f12):

- Input signal: 0.2502V -> Output signal: 0.2350V

PGA mode(Gain: x8)/after calibration(User trim/0x1f12):

- Input signal: 0.1010V -> Output signal: 0.6852V


However, the opamp output signal level was further reduced, indicating that something was wrong.
Before calibration, the opamp's factory trim code was 0xe13, but after calibration, the user trim code was set to 0x1f12. It appeared that the P terminal calibration value was set to the max (0x1f). (As an additional condition, I opened SB12 on the STM32U083C-DK board to use the Vref+ pin as an external output/VREFBUFF: 2.048V.)

 

I couldn't help but question the calibration function's behavior, and I think there are some malfunctions in the HAL_OPAMP_SelfCalibrate() function in stm32u00x_hal_opamp.c.
1. 1st calibration - If OPAMP_CSR_CALOUT = 0 in N, the current value should be maintained instead of trimmingvaluen++;.
If OPAMP_CSR_CALOUT = 1, trimmingvaluen--; should be used.

/* 1st calibration - N */
if ((READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT)) == 0U)
      {
        /* Trimming value is actually one value more */
        trimmingvaluen++;
        /* Set right trimming */
        MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
      }

//modified code...

if ((READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT)) != 0U)
      {
        /* Trimming value is actually one value less */
        trimmingvaluen--;
        /* Set right trimming */
        MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
      }

 

2. 2nd calibration - P: The exact reason is unknown, but the positions of the trimmingvaluep addition/subtraction seem to have changed.

It seems that the correct calibration can only be achieved by changing the positions of the addition/subtraction.

/* 2nd calibration - P */
if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U)
{
/* OPAMP_CSR_CALOUT is HIGH: try higher trimming */
trimmingvaluep -= delta;
}
else
{
/* OPAMP_CSR_CALOUT is LOW: try lower trimming */
trimmingvaluep += delta;
}

//Modified code...

if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U)
{
/* OPAMP_CSR_CALOUT is HIGH, try higher trimming */
//trimmingvaluep -= delta;
trimmingvaluep += delta;
}
else
{
/* OPAMP_CSR_CALOUT is LOW, try lower trimming */
//trimmingvaluep += delta;
trimmingvaluep -= delta;
}

 

3. 2nd calibration - P, the exact reason is unknown, but it was measured that the OPAMP output range was normalized only when the trimmingvaluep value was reduced.

/* 2nd calibration - P */ 
if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U) 
{ 
/* Trimming value is actually one value more */ 
trimmingvaluep++; 
MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep << OPAMP_INPUT_NONINVERTING)); 
}

//modified code... 

if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) == 0U) { 
/* Trimming value is actually one value less */ 
//trimmingvaluep++; 
trimmingvaluep--; 

MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep << OPAMP_INPUT_NONINVERTING));
}

 

If, like me, you need to amplify signals using the built-in OPAMP and want to further reduce error, consider modifying this HAL_OPAMP_SelfCalibrate().

Follower mode/after calibration/modified code(User trim/0xc11):

- Input signal: 0.2507V -> Output signal: 0.2509V

PGA mode(Gain: x8)/after calibration/modified code(User trim/0xc11):

- Input signal: 0.1010V -> Output signal: 0.8055V

0 REPLIES 0