Meanwhile I was stuck with figuring out how to do proper ADC conversion on STM32F030.
Lets say I am measuring a voltage on ADC_IN0. The voltage is sampled by ADC and reported as 12-bit value. The value of zero corresponds to 0 Volts on input and value 0xFFF corresponds to Vdda (connected to Vdd in my case).
The problem is that Vdda or Vdd is not stable. On battery the voltage will slowly decrease. On power supply it will float because of noise. In addition, I need precise voltage value, not relative to Vdd.
All the problems above can be solved by sampling internal voltage reference provided by the chip.
So instead sampling just ADC_IN0, I need to enable VREFINT and sample ADC_IN17. Pretty cool, but there is still a problem. As the STM32F030 reference manual (RM0360) states:
The precise voltage of VREFINT is individually measured for each part by ST during production test and stored in the system memory area. It is accessible in read-only mode.That is fine, but no hint to where that voltage value in the system memory. Thanks Tech Overflow blog, I have found a hint about the calibration value and the actual calculation.
The actual address can be found in the chip-specific datasheet (DM00088500 for STM32F030F) in section by searching for VREFINT_CAL. Then actual Vdd can be calculated using simple formula:
Vdd = 3.3V * VREFINT_CAL /ADC_IN17