Skip to content

Commit d49a547

Browse files
Tobias Badertscherdpgeorge
authored andcommitted
stmhal: L4: Modify adc.c to add support for STM32L4 series.
1 parent 69f26c6 commit d49a547

File tree

1 file changed

+91
-17
lines changed

1 file changed

+91
-17
lines changed

stmhal/adc.c

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
defined(STM32F437xx) || defined(STM32F439xx) || \
6666
defined(STM32F746xx)
6767
#define VBAT_DIV (4)
68+
#elif defined(STM32L476xx)
69+
#define VBAT_DIV (3)
6870
#else
6971
#error Unsupported processor
7072
#endif
@@ -80,8 +82,45 @@ typedef struct _pyb_obj_adc_t {
8082
ADC_HandleTypeDef handle;
8183
} pyb_obj_adc_t;
8284

85+
STATIC bool is_adcx_channel(int channel) {
86+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
87+
return IS_ADC_CHANNEL(channel);
88+
#elif defined(MCU_SERIES_L4)
89+
ADC_HandleTypeDef handle;
90+
handle.Instance = ADCx;
91+
return IS_ADC_CHANNEL(&handle, channel);
92+
#else
93+
#error Unsupported processor
94+
#endif
95+
}
96+
97+
STATIC void adc_wait_for_eoc_or_timeout(int32_t timeout) {
98+
uint32_t tickstart = HAL_GetTick();
99+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
100+
while ((ADCx->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
101+
#elif defined(MCU_SERIES_L4)
102+
while (READ_BIT(ADCx->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {
103+
#else
104+
#error Unsupported processor
105+
#endif
106+
if (((HAL_GetTick() - tickstart ) > timeout)) {
107+
break; // timeout
108+
}
109+
}
110+
}
111+
112+
STATIC void adcx_clock_enable(void) {
113+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
114+
ADCx_CLK_ENABLE();
115+
#elif defined(MCU_SERIES_L4)
116+
__HAL_RCC_ADC_CLK_ENABLE();
117+
#else
118+
#error Unsupported processor
119+
#endif
120+
}
121+
83122
STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
84-
if (!IS_ADC_CHANNEL(adc_obj->channel)) {
123+
if (!is_adcx_channel(adc_obj->channel)) {
85124
return;
86125
}
87126

@@ -97,22 +136,33 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
97136
HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure);
98137
}
99138

100-
ADCx_CLK_ENABLE();
139+
adcx_clock_enable();
101140

102141
ADC_HandleTypeDef *adcHandle = &adc_obj->handle;
103142
adcHandle->Instance = ADCx;
104-
adcHandle->Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
105143
adcHandle->Init.Resolution = ADC_RESOLUTION12b;
106-
adcHandle->Init.ScanConvMode = DISABLE;
107144
adcHandle->Init.ContinuousConvMode = DISABLE;
108145
adcHandle->Init.DiscontinuousConvMode = DISABLE;
109146
adcHandle->Init.NbrOfDiscConversion = 0;
110147
adcHandle->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
111-
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
112148
adcHandle->Init.DataAlign = ADC_DATAALIGN_RIGHT;
113149
adcHandle->Init.NbrOfConversion = 1;
114150
adcHandle->Init.DMAContinuousRequests = DISABLE;
115151
adcHandle->Init.EOCSelection = DISABLE;
152+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
153+
adcHandle->Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
154+
adcHandle->Init.ScanConvMode = DISABLE;
155+
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
156+
#elif defined(MCU_SERIES_L4)
157+
adcHandle->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
158+
adcHandle->Init.ScanConvMode = ADC_SCAN_DISABLE;
159+
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1;
160+
adcHandle->Init.LowPowerAutoWait = DISABLE;
161+
adcHandle->Init.Overrun = ADC_OVR_DATA_PRESERVED;
162+
adcHandle->Init.OversamplingMode = DISABLE;
163+
#else
164+
#error Unsupported processor
165+
#endif
116166

117167
HAL_ADC_Init(adcHandle);
118168
}
@@ -122,7 +172,13 @@ STATIC void adc_config_channel(pyb_obj_adc_t *adc_obj) {
122172

123173
sConfig.Channel = adc_obj->channel;
124174
sConfig.Rank = 1;
175+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
125176
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
177+
#elif defined(MCU_SERIES_L4)
178+
sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
179+
#else
180+
#error Unsupported processor
181+
#endif
126182
sConfig.Offset = 0;
127183

128184
HAL_ADC_ConfigChannel(&adc_obj->handle, &sConfig);
@@ -173,7 +229,7 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uin
173229
channel = pin->adc_channel;
174230
}
175231

176-
if (!IS_ADC_CHANNEL(channel)) {
232+
if (!is_adcx_channel(channel)) {
177233
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "not a valid ADC Channel: %d", channel));
178234
}
179235
if (pin_adc1[channel] == NULL) {
@@ -274,17 +330,18 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
274330
HAL_ADC_Start(&self->handle);
275331
} else {
276332
// for subsequent samples we can just set the "start sample" bit
333+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
277334
ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
335+
#elif defined(MCU_SERIES_L4)
336+
SET_BIT(ADCx->CR, ADC_CR_ADSTART);
337+
#else
338+
#error Unsupported processor
339+
#endif
278340
}
279341

280342
// wait for sample to complete
281-
uint32_t tickstart = HAL_GetTick();
282-
while ((ADCx->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
283-
#define READ_TIMED_TIMEOUT (10) // in ms
284-
if (((HAL_GetTick() - tickstart ) > READ_TIMED_TIMEOUT)) {
285-
break; // timeout
286-
}
287-
}
343+
#define READ_TIMED_TIMEOUT (10) // in ms
344+
adc_wait_for_eoc_or_timeout(READ_TIMED_TIMEOUT);
288345

289346
// read value
290347
uint value = ADCx->DR;
@@ -357,22 +414,33 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution) {
357414
HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure);
358415
}
359416

360-
ADCx_CLK_ENABLE();
417+
adcx_clock_enable();
361418

362419
ADC_HandleTypeDef *adcHandle = &adc_all->handle;
363420
adcHandle->Instance = ADCx;
364-
adcHandle->Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
365421
adcHandle->Init.Resolution = resolution;
366-
adcHandle->Init.ScanConvMode = DISABLE;
367422
adcHandle->Init.ContinuousConvMode = DISABLE;
368423
adcHandle->Init.DiscontinuousConvMode = DISABLE;
369424
adcHandle->Init.NbrOfDiscConversion = 0;
370425
adcHandle->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
371-
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
372426
adcHandle->Init.DataAlign = ADC_DATAALIGN_RIGHT;
373427
adcHandle->Init.NbrOfConversion = 1;
374428
adcHandle->Init.DMAContinuousRequests = DISABLE;
375429
adcHandle->Init.EOCSelection = DISABLE;
430+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
431+
adcHandle->Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
432+
adcHandle->Init.ScanConvMode = DISABLE;
433+
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
434+
#elif defined(MCU_SERIES_L4)
435+
adcHandle->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
436+
adcHandle->Init.ScanConvMode = ADC_SCAN_DISABLE;
437+
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1;
438+
adcHandle->Init.LowPowerAutoWait = DISABLE;
439+
adcHandle->Init.Overrun = ADC_OVR_DATA_PRESERVED;
440+
adcHandle->Init.OversamplingMode = DISABLE;
441+
#else
442+
#error Unsupported processor
443+
#endif
376444

377445
HAL_ADC_Init(adcHandle);
378446
}
@@ -381,7 +449,13 @@ uint32_t adc_config_and_read_channel(ADC_HandleTypeDef *adcHandle, uint32_t chan
381449
ADC_ChannelConfTypeDef sConfig;
382450
sConfig.Channel = channel;
383451
sConfig.Rank = 1;
452+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
384453
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
454+
#elif defined(MCU_SERIES_L4)
455+
sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
456+
#else
457+
#error Unsupported processor
458+
#endif
385459
sConfig.Offset = 0;
386460
HAL_ADC_ConfigChannel(adcHandle, &sConfig);
387461

0 commit comments

Comments
 (0)