8000 stmhal/adc.c: Get ADC working on STM32L4 MCUs. · sparkfun/circuitpython@af9889f · GitHub
[go: up one dir, main page]

Skip to content

Commit af9889f

Browse files
tobbaddpgeorge
authored andcommitted
stmhal/adc.c: Get ADC working on STM32L4 MCUs.
Fixing Issue adafruit#2243. Main problems were: - HAL_ADC_GetState(adcHandle) may return other bits set (not only HAL_ADC_STATE_EOC_REG) when called - so I AND-ed it out as proposed by mattbrejza in Issue adafruit#2243. - ADC Pin has to be configured as GPIO_MODE_ANALOG_ADC_CONTROL not only GPIO_MODE_ANALOG. - Resolved ADC resolution L4 specific (Use L4 define ADC_RESOLUTION_12B). - Changed setting of Init.EOCSelection toADC_EOC_SINGLE_CONV for L4. - Added call to ADC_MultiModeTypeDef as this is done on a STM32Cube generated project too. - Clean up: Configuration of ADC is done only in ONE function not the same is done in two functions. Test is done on PA5 pin of STM32L4Discovery-Kit which is connected to the DOWN button. Thanks to mattbrejza for discovering the bug.
1 parent dfb8144 commit af9889f

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

stmhal/adc.c

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
131131
mp_hal_gpio_clock_enable(pin->gpio);
132132
GPIO_InitTypeDef GPIO_InitStructure;
133133
GPIO_InitStructure.Pin = pin->pin_mask;
134+
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
134135
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
136+
#elif defined(MCU_SERIES_L4)
137+
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
138+
#else
139+
#error Unsupported processor
140+
#endif
135141
GPIO_InitStructure.Pull = GPIO_NOPULL;
136142
HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure);
137143
}
@@ -140,23 +146,26 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
140146

141147
ADC_HandleTypeDef *adcHandle = &adc_obj->handle;
142148
adcHandle->Instance = ADCx;
143-
adcHandle->Init.Resolution = ADC_RESOLUTION12b;
144149
adcHandle->Init.ContinuousConvMode = DISABLE;
145150
adcHandle->Init.DiscontinuousConvMode = DISABLE;
146151
adcHandle->Init.NbrOfDiscConversion = 0;
147152
adcHandle->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
148153
adcHandle->Init.DataAlign = ADC_DATAALIGN_RIGHT;
149154
adcHandle->Init.NbrOfConversion = 1;
150155
adcHandle->Init.DMAContinuousRequests = DISABLE;
151-
adcHandle->Init.EOCSelection = DISABLE;
152156
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
157+
adcHandle->Init.Resolution = ADC_RESOLUTION12b;
153158
adcHandle->Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
154159
adcHandle->Init.ScanConvMode = DISABLE;
155160
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
161+
adcHandle->Init.EOCSelection = DISABLE;
156162
#elif defined(MCU_SERIES_L4)
157-
adcHandle->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
163+
adcHandle->Init.Resolution = ADC_RESOLUTION_12B;
164+
adcHandle->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
158165
adcHandle->Init.ScanConvMode = ADC_SCAN_DISABLE;
159-
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1;
166+
adcHandle->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
167+
adcHandle->Init.ExternalTrigConv = ADC_SOFTWARE_START;
168+
adcHandle->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
160169
adcHandle->Init.LowPowerAutoWait = DISABLE;
161170
adcHandle->Init.Overrun = ADC_OVR_DATA_PRESERVED;
162171
adcHandle->Init.OversamplingMode = DISABLE;
@@ -165,30 +174,42 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
165174
#endif
166175

167176
HAL_ADC_Init(adcHandle);
177+
178+
#if defined(MCU_SERIES_L4)
179+
ADC_MultiModeTypeDef multimode;
180+
multimode.Mode = ADC_MODE_INDEPENDENT;
181+
if (HAL_ADCEx_MultiModeConfigChannel(adcHandle, &multimode) != HAL_OK)
182+
{
183+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Can not set multimode on ADC1 channel: %d", adc_obj->channel));
184+
}
185+
#endif
168186
}
169187

170-
STATIC void adc_config_channel(pyb_obj_adc_t *adc_obj) {
188+
STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel) {
171189
ADC_ChannelConfTypeDef sConfig;
172190

173-
sConfig.Channel = adc_obj->channel;
191+
sConfig.Channel = channel;
174192
sConfig.Rank = 1;
175193
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
176194
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
177195
#elif defined(MCU_SERIES_L4)
178196
sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
197+
sConfig.SingleDiff = ADC_SINGLE_ENDED;
198+
sConfig.OffsetNumber = ADC_OFFSET_NONE;
179199
#else
180200
#error Unsupported processor
181201
#endif
182202
sConfig.Offset = 0;
183203

184-
HAL_ADC_ConfigChannel(&adc_obj->handle, &sConfig);
204+
HAL_ADC_ConfigChannel(adc_handle, &sConfig);
185205
}
186206

187207
STATIC uint32_t adc_read_channel(ADC_HandleTypeDef *adcHandle) {
188208
uint32_t rawValue = 0;
189209

190210
HAL_ADC_Start(adcHandle);
191-
if (HAL_ADC_PollForConversion(adcHandle, 10) == HAL_OK && HAL_ADC_GetState(adcHandle) == HAL_ADC_STATE_EOC_REG) {
211+
if (HAL_ADC_PollForConversion(adcHandle, 10) == HAL_OK
212+
&& (HAL_ADC_GetState(adcHandle) & HAL_ADC_STATE_EOC_REG) == HAL_ADC_STATE_EOC_REG) {
192213
rawValue = HAL_ADC_GetValue(adcHandle);
193214
}
194215
HAL_ADC_Stop(adcHandle);
@@ -252,7 +273,7 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uin
252273
STATIC mp_obj_t adc_read(mp_obj_t self_in) {
253274
pyb_obj_adc_t *self = self_in;
254275

255-
adc_config_channel(self);
276+
adc_config_channel(&self->handle, self->channel);
256277
uint32_t data = adc_read_channel(&self->handle);
257278
return mp_obj_new_int(data);
258279
}
@@ -313,7 +334,7 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
313334
}
314335

315336
// configure the ADC channel
316-
adc_config_channel(self);
337+
adc_config_channel(&self->handle, self->channel);
317338

318339
// This uses the timer in polling mode to do the sampling
319340
// TODO use DMA
@@ -446,19 +467,7 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution) {
446467
}
447468

448469
uint32_t adc_config_and_read_channel(ADC_HandleTypeDef *adcHandle, uint32_t channel) {
449-
ADC_ChannelConfTypeDef sConfig;
450-
sConfig.Channel = channel;
451-
sConfig.Rank = 1;
452-
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
453-
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
459-
sConfig.Offset = 0;
460-
HAL_ADC_ConfigChannel(adcHandle, &sConfig);
461-
470+
adc_config_channel(adcHandle, channel);
462471
return adc_read_channel(adcHandle);
463472
}
464473

0 commit comments

Comments
 (0)
0