11static void _ADC_init(ADC_TypeDef *,
ADC_Config *);
25 if (interface == NULL)
26 return (
ADC_t){.interface = NULL};
29 ADC_t adc = {.interface = interface};
57static void _ADC_init(ADC_TypeDef *interface,
ADC_Config *config) {
59 interface->CR2 &= ~ADC_CR2_ADON;
64 interface->CR1 &= ~ADC_CR1_CONFIG_MASK;
66 (config->
RES << ADC_CR1_RES_Pos)
67 | (config->
AWDEN << ADC_CR1_AWDEN_Pos)
68 | (config->
JAWDEN << ADC_CR1_JAWDEN_Pos)
69 | (config->
AWDSGL << ADC_CR1_AWDSGL_Pos)
70 | (config->
SCAN << ADC_CR1_SCAN_Pos)
71 | (config->
JEOCIE << ADC_CR1_JEOCIE_Pos)
72 | (config->
AWDIE << ADC_CR1_AWDIE_Pos)
73 | (config->
EOCIE << ADC_CR1_EOCIE_Pos)
74 | (config->
AWDCH << ADC_CR1_AWDCH_Pos)
81 interface->CR2 &= ~ADC_CR2_CONFIG_MASK;
83 (config->
ALIGN << ADC_CR2_ALIGN_Pos)
84 | (config->
EOCS << ADC_CR2_EOCS_Pos)
85 | (config->
DMA << ADC_CR2_DMA_Pos)
86 | (config->
CONT << ADC_CR2_CONT_Pos)
92 interface->SMPR2 &= ~ADC_SMPR2_CONFIG_MASK;
93 for (uint8_t i = 0; i < 10; i++)
94 interface->SMPR2 |= (config->
SMP[i] << (i * 3));
97 interface->SMPR1 &= ~ADC_SMPR1_CONFIG_MASK;
98 for (uint8_t i = 0; i < 9; i++)
99 interface->SMPR1 |= (config->
SMP[10 + i] << (i * 3));
103 interface->HTR &= ~ADC_HTR_HT;
104 interface->HTR |= config->
HTR & ADC_HTR_HT_Msk;
107 interface->LTR &= ~ADC_LTR_LT;
108 interface->LTR |= config->
LTR & ADC_LTR_LT_Msk;
114 interface->SQR1 &= ~ADC_SQR1_CONFIG_MASK;
115 interface->SQR1 |= (config->
L << ADC_SQR1_L_Pos);
118 interface->SQR3 &= ~ADC_SQR3_CONFIG_MASK;
119 uint8_t conversions = config->
L + 1;
120 for (uint8_t i = 0; i < 6 && i < conversions; i++) {
121 interface->SQR3 |= (config->
SQ[i] << (i * 5));
125 interface->SQR2 &= ~ADC_SQR2_CONFIG_MASK;
126 for (uint8_t i = 0; i < 6 && (i + 6) < conversions; i++) {
127 interface->SQR2 |= (config->
SQ[i + 6] << (i * 5));
132 for (uint8_t i = 0; i < 4 && (i + 12) < conversions; i++) {
133 interface->SQR1 |= (config->
SQ[i + 12] << (i * 5));
137 interface->JSQR &= ~ADC_JSQR_CONFIG_MASK;
138 interface->JSQR |= (config->
JL << ADC_JSQR_JL_Pos);
139 conversions = config->
JL + 1;
140 for (uint8_t i = 0; i < 4 && i < conversions; i++) {
141 interface->JSQR |= (config->
JSQ[i] << (i * 4));
145 ADC123_COMMON->CCR &= ~(ADC_CCR_TSVREFE_Msk | ADC_CCR_VBATE_Msk | ADC_CCR_ADCPRE_Msk);
146 ADC123_COMMON->CCR |= (
147 ((config->
TSVREFE & 1) << ADC_CCR_TSVREFE_Pos)
148 | ((config->
VBATE & 1) << ADC_CCR_VBATE_Pos)
149 | ((config->
ADCPRE & 3) << ADC_CCR_ADCPRE_Pos)
153 interface->CR2 |= ADC_CR2_ADON;
154 for (
volatile int i = 0; i < 500; ++i);
172 if (adc == NULL || adc->
interface == NULL)
176 if ((adc->
interface->CR2 & ADC_CR2_ADON) == 0) {
203 if (adc == NULL || adc->
interface == NULL)
208 while (!(adc->
interface->SR & ADC_SR_EOC));
227 if (config == NULL) {
228 config = &ADC_CONFIG_DEFAULT;
bool(* startConversion)(struct _ADC *adc, ADC_ConversionType type)
Function pointer to start an ADC conversion (regular or injected).
bool DMA
Direct Memory Access mode enable for regular channels (CR2.DMA).
ADC_Config config
Current configuration of the ADC peripheral.
ADC_Prescale ADCPRE
ADC prescaler for ADCCLK (ADC_CCR.ADCPRE).
bool AWDSGL
Analog Watchdog on single channel (true) or all (false) (CR1.AWDSGL).
uint16_t LTR
Analog watchdog lower threshold (LTR). Value should be 12-bit.
bool EOCIE
Interrupt Enable for End Of regular Conversion (CR1.EOCIE).
ADC_EocSelect EOCS
End Of Conversion Selection (CR2.EOCS).
bool VBATE
VBAT channel enable (ADC_CCR.VBATE).
ADC_Align ALIGN
Data alignment (CR2.ALIGN).
bool SCAN
Scan mode enable for regular channels (CR1.SCAN).
ADC_SequenceLength JL
Injected channel sequence length (1 to 4 conversions) (JSQR.JL).
uint16_t(* readData)(struct _ADC *adc)
Function pointer to read the ADC regular conversion result.
bool AWDEN
Analog Watchdog Enable on regular channels (CR1.AWDEN).
ADC_TypeDef * interface
Pointer to the STM32 ADC peripheral register map (e.g., ADC1).
bool AWDIE
Interrupt Enable for Analog Watchdog (CR1.AWDIE).
bool CONT
Continuous conversion mode for regular channels (CR2.CONT).
bool JAWDEN
Analog Watchdog Enable on injected channels (CR1.JAWDEN).
bool(* updateConfig)(struct _ADC *adc, ADC_Config *config)
Function pointer to update the ADC configuration.
ADC_Resolution RES
Resolution of the ADC (CR1.RES).
ADC_Channel SQ[16]
Regular channel sequence definition (SQ1 to SQ16) (SQR1, SQR2, SQR3).
ADC_SampleTime SMP[19]
Sampling time for each channel (0-18) (SMPR1, SMPR2).
bool JEOCIE
Interrupt Enable for End Of Injected Conversion (CR1.JEOCIE).
ADC_Channel JSQ[4]
Injected channel sequence definition (JSQ1 to JSQ4) (JSQR).
ADC_Channel AWDCH
Analog Watchdog Channel Select (if AWDSGL is true) (CR1.AWDCH).
bool TSVREFE
Temperature sensor and VREFINT enable (ADC_CCR.TSVREFE).
ADC_SequenceLength L
Regular channel sequence length (1 to 16 conversions) (SQR1.L).
uint16_t HTR
Analog watchdog higher threshold (HTR). Value should be 12-bit.
ADC_t ADC_init(ADC_TypeDef *interface, ADC_Config *config)
uint16_t ADC_readData(ADC_t *adc)
Reads the data from the last ADC regular conversion.
bool ADC_startConversion(ADC_t *adc, ADC_ConversionType type)
Starts a regular ADC conversion.
bool ADC_updateConfig(ADC_t *adc, ADC_Config *config)
Update ADC peripheral configuration.
ADC_ConversionType
ADC conversion type enumeration.
@ ADC_CONVERSION_REGULAR
Start a regular group conversion.
@ ADC_CONVERSION_INJECTED
Start an injected group conversion.
ADC configuration structure.
Struct definition for ADC interface. Provides the API handle for consumers to interact with an ADC pe...