Flipper Zero Firmware
Loading...
Searching...
No Matches
furi_hal_adc.h File Reference

ADC HAL API. More...

#include <furi.h>
#include <stdbool.h>
#include <stdint.h>

Go to the source code of this file.

Typedefs

typedef struct FuriHalAdcHandle FuriHalAdcHandle
 

Enumerations

enum  FuriHalAdcScale { FuriHalAdcScale2048 , FuriHalAdcScale2500 }
 
enum  FuriHalAdcClock { FuriHalAdcClockSync16 , FuriHalAdcClockSync32 , FuriHalAdcClockSync64 }
 
enum  FuriHalAdcOversample {
  FuriHalAdcOversample2 , FuriHalAdcOversample4 , FuriHalAdcOversample8 , FuriHalAdcOversample16 ,
  FuriHalAdcOversample32 , FuriHalAdcOversample64 , FuriHalAdcOversample128 , FuriHalAdcOversample256 ,
  FuriHalAdcOversampleNone
}
 
enum  FuriHalAdcSamplingTime {
  FuriHalAdcSamplingtime2_5 , FuriHalAdcSamplingtime6_5 , FuriHalAdcSamplingtime12_5 , FuriHalAdcSamplingtime24_5 ,
  FuriHalAdcSamplingtime47_5 , FuriHalAdcSamplingtime92_5 , FuriHalAdcSamplingtime247_5 , FuriHalAdcSamplingtime640_5
}
 
enum  FuriHalAdcChannel {
  FuriHalAdcChannel0 , FuriHalAdcChannel1 , FuriHalAdcChannel2 , FuriHalAdcChannel3 ,
  FuriHalAdcChannel4 , FuriHalAdcChannel5 , FuriHalAdcChannel6 , FuriHalAdcChannel7 ,
  FuriHalAdcChannel8 , FuriHalAdcChannel9 , FuriHalAdcChannel10 , FuriHalAdcChannel11 ,
  FuriHalAdcChannel12 , FuriHalAdcChannel13 , FuriHalAdcChannel14 , FuriHalAdcChannel15 ,
  FuriHalAdcChannel16 , FuriHalAdcChannel17 , FuriHalAdcChannel18 , FuriHalAdcChannelVREFINT ,
  FuriHalAdcChannelTEMPSENSOR , FuriHalAdcChannelVBAT , FuriHalAdcChannelNone
}
 

Functions

void furi_hal_adc_init (void)
 Initialize ADC subsystem.
 
FuriHalAdcHandlefuri_hal_adc_acquire (void)
 Acquire ADC handle.
 
void furi_hal_adc_release (FuriHalAdcHandle *handle)
 Release ADC handle.
 
void furi_hal_adc_configure (FuriHalAdcHandle *handle)
 Configure with default parameters and enable ADC.
 
void furi_hal_adc_configure_ex (FuriHalAdcHandle *handle, FuriHalAdcScale scale, FuriHalAdcClock clock, FuriHalAdcOversample oversample, FuriHalAdcSamplingTime sampling_time)
 Configure with extended parameters and enable ADC.
 
uint16_t furi_hal_adc_read (FuriHalAdcHandle *handle, FuriHalAdcChannel channel)
 Read single ADC value.
 
float furi_hal_adc_convert_to_voltage (FuriHalAdcHandle *handle, uint16_t value)
 Convert sampled value to voltage.
 
float furi_hal_adc_convert_vref (FuriHalAdcHandle *handle, uint16_t value)
 Convert sampled VREFINT value to voltage.
 
float furi_hal_adc_convert_temp (FuriHalAdcHandle *handle, uint16_t value)
 Convert sampled TEMPSENSOR value to temperature.
 
float furi_hal_adc_convert_vbat (FuriHalAdcHandle *handle, uint16_t value)
 Convert sampled VBAT value to voltage.
 

Detailed Description

ADC HAL API.

For the sake of simplicity this API implements only small subset of what ADC is actually capable of. Feel free to visit Reference Manual for STM32WB series and implement any other modes by your self.

Couple things to keep in mind:

  • ADC resolution is 12 bits, but effective number of bits is ~10 at the best and further depends on how you use and configure it.
  • Analog domain is fed from SMPS which is quite noisy.
  • Because of that we use internal on-chip voltage reference for ADC.
  • It's capable of producing 2 voltages: 2.5V and 2.048V. This is the scale for your signal.
  • Only single ended mode is available. But you can implement differential one by using low level controls directly.
  • No DMA or interrupt API available at this point. But can be implemented with low level controls.

How to use:

  • furi_hal_gpio_init - Configure your pins in GpioModeAnalog
  • furi_hal_adc_acquire - acquire ADC handle to work with
  • furi_hal_adc_configure - configure ADC block
  • furi_hal_adc_read - read value
  • furi_hal_adc_release - release ADC handle

Enumeration Type Documentation

◆ FuriHalAdcChannel

Enumerator
FuriHalAdcChannel0 

Internal channel, see FuriHalAdcChannelVREFINT.

FuriHalAdcChannel1 

Channel 1p.

FuriHalAdcChannel2 

Channel 2p or 1n.

FuriHalAdcChannel3 

Channel 3p or 2n.

FuriHalAdcChannel4 

Channel 4p or 3n.

FuriHalAdcChannel5 

Channel 5p or 4n.

FuriHalAdcChannel6 

Channel 6p or 5n.

FuriHalAdcChannel7 

Channel 7p or 6n.

FuriHalAdcChannel8 

Channel 8p or 7n.

FuriHalAdcChannel9 

Channel 9p or 8n.

FuriHalAdcChannel10 

Channel 10p or 9n.

FuriHalAdcChannel11 

Channel 11p or 10n.

FuriHalAdcChannel12 

Channel 12p or 11n.

FuriHalAdcChannel13 

Channel 13p or 12n.

FuriHalAdcChannel14 

Channel 14p or 13n.

FuriHalAdcChannel15 

Channel 15p or 14n.

FuriHalAdcChannel16 

Channel 16p or 15n.

FuriHalAdcChannel17 

Internal channel, see FuriHalAdcChannelTEMPSENSOR.

FuriHalAdcChannel18 

Internal channel, see FuriHalAdcChannelVBAT.

FuriHalAdcChannelVREFINT 

Special channel for VREFINT, used for calibration and self test.

FuriHalAdcChannelTEMPSENSOR 

Special channel for on-die temperature sensor, requires at least 5us of sampling time.

FuriHalAdcChannelVBAT 

Special channel for VBAT/3 voltage, requires at least 12us of sampling time.

FuriHalAdcChannelNone 

No channel.

◆ FuriHalAdcClock

Enumerator
FuriHalAdcClockSync16 

16MHZ, synchronous

FuriHalAdcClockSync32 

32MHZ, synchronous

FuriHalAdcClockSync64 

64MHz, synchronous

◆ FuriHalAdcOversample

Enumerator
FuriHalAdcOversample2 

ADC will take 2 samples per each value.

FuriHalAdcOversample4 

ADC will take 4 samples per each value.

FuriHalAdcOversample8 

ADC will take 8 samples per each value.

FuriHalAdcOversample16 

ADC will take 16 samples per each value.

FuriHalAdcOversample32 

ADC will take 32 samples per each value.

FuriHalAdcOversample64 

ADC will take 64 samples per each value.

FuriHalAdcOversample128 

ADC will take 128 samples per each value.

FuriHalAdcOversample256 

ADC will take 256 samples per each value.

FuriHalAdcOversampleNone 

disable oversampling

◆ FuriHalAdcSamplingTime

Enumerator
FuriHalAdcSamplingtime2_5 

Sampling time 2.5 ADC clock.

FuriHalAdcSamplingtime6_5 

Sampling time 6.5 ADC clock.

FuriHalAdcSamplingtime12_5 

Sampling time 12.5 ADC clock.

FuriHalAdcSamplingtime24_5 

Sampling time 24.5 ADC clock.

FuriHalAdcSamplingtime47_5 

Sampling time 47.5 ADC clock.

FuriHalAdcSamplingtime92_5 

Sampling time 92.5 ADC clock.

FuriHalAdcSamplingtime247_5 

Sampling time 247.5 ADC clock.

FuriHalAdcSamplingtime640_5 

Sampling time 640.5 ADC clock.

◆ FuriHalAdcScale

Enumerator
FuriHalAdcScale2048 

2.048V scale

FuriHalAdcScale2500 

2.5V scale

Function Documentation

◆ furi_hal_adc_acquire()

FuriHalAdcHandle * furi_hal_adc_acquire ( void )

Acquire ADC handle.

Enables appropriate power and clocking domains

Returns
FuriHalAdcHandle pointer

◆ furi_hal_adc_configure()

void furi_hal_adc_configure ( FuriHalAdcHandle * handle)

Configure with default parameters and enable ADC.

Parameters used:

  • FuriHalAdcScale2048 - 2.048V VREF Scale. Your signal should be in 0 - 2.048V range.
  • FuriHalAdcClockSync64 - Clocked from sysclk bus at 64MHz in synchronous mode. Fast, no delay on data bus access.
  • FuriHalAdcOversample64 - Going to acquire and average 64 samples. For circuits with slowly or not changing signal. Total time per one read: (1/64)*(12.5+247.5)*64 = 260us. The best results you'll get if your signal will stay on the same level all this time.
  • FuriHalAdcSamplingtime247_5 - Sampling(transfer from source to internal sampling capacitor) time is 247.5 ADC clocks: (1/64)*247.5 = 3.8671875us. For relatively high impedance circuits.

Also keep your measurement circuit impedance under 10KOhm or oversampling results will be compromised. Verify your signal with oscilloscope(you may need fast oscilloscope: 200MHz bandwidth, 125MS/s), ensure that signal is not distorted by sampling.

Those parameters were optimized for 0 - 2.048 voltage measurement with ~0.1% precision. You can get more, but it will require some magic.

Parameters
handleThe ADC handle

◆ furi_hal_adc_configure_ex()

void furi_hal_adc_configure_ex ( FuriHalAdcHandle * handle,
FuriHalAdcScale scale,
FuriHalAdcClock clock,
FuriHalAdcOversample oversample,
FuriHalAdcSamplingTime sampling_time )

Configure with extended parameters and enable ADC.

General advice is to start with default parameters, figure out what exactly is not working for you and then tune it. Also in some cases changing circuit(adding caps, lowering impedance, adding opamp) may be better than changing parameters.

Warning
In general ADC is a world of magic: make sure that you understand how your circuit and ADC works. Then carefully read STM32WB series reference manual. Setting incorrect parameters leads to very poor results. Also internal channels require special settings.
Parameters
handleThe ADC handle
[in]scaleThe ADC voltage scale
[in]clockThe ADC clock
[in]oversampleThe ADC oversample mode
[in]sampling_timeThe ADC sampling time

◆ furi_hal_adc_convert_temp()

float furi_hal_adc_convert_temp ( FuriHalAdcHandle * handle,
uint16_t value )

Convert sampled TEMPSENSOR value to temperature.

Parameters
handleThe ADC handle
[in]valueThe value acquired with furi_hal_adc_read for FuriHalAdcChannelTEMPSENSOR channel
Returns
temperature in degree C

◆ furi_hal_adc_convert_to_voltage()

float furi_hal_adc_convert_to_voltage ( FuriHalAdcHandle * handle,
uint16_t value )

Convert sampled value to voltage.

Parameters
handleThe ADC handle
[in]valueThe value acquired with furi_hal_adc_read
Returns
Voltage in mV

◆ furi_hal_adc_convert_vbat()

float furi_hal_adc_convert_vbat ( FuriHalAdcHandle * handle,
uint16_t value )

Convert sampled VBAT value to voltage.

Parameters
handleThe ADC handle
[in]valueThe value acquired with furi_hal_adc_read for FuriHalAdcChannelVBAT channel
Returns
Voltage in mV

◆ furi_hal_adc_convert_vref()

float furi_hal_adc_convert_vref ( FuriHalAdcHandle * handle,
uint16_t value )

Convert sampled VREFINT value to voltage.

Parameters
handleThe ADC handle
[in]valueThe value acquired with furi_hal_adc_read for FuriHalAdcChannelVREFINT channel
Returns
Voltage in mV

◆ furi_hal_adc_read()

uint16_t furi_hal_adc_read ( FuriHalAdcHandle * handle,
FuriHalAdcChannel channel )

Read single ADC value.

Parameters
handleThe ADC handle
[in]channelThe channel to sample
Returns
value, 12 bits

◆ furi_hal_adc_release()

void furi_hal_adc_release ( FuriHalAdcHandle * handle)

Release ADC handle.

Parameters
handleThe ADC handle