Skip to content

Commit dfad7f4

Browse files
committed
stmhal: Optimise ADC.read_timed() so that it can sample up to 750kHz.
1 parent 44cd46a commit dfad7f4

1 file changed

Lines changed: 31 additions & 4 deletions

File tree

stmhal/adc.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,22 +225,49 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
225225
// Start timer
226226
HAL_TIM_Base_Start(&TIM6_Handle);
227227

228-
// This uses the timer in polling mode to do the sampling
229-
// We could use DMA, but then we can't convert the values correctly for the buffer
228+
// configure the ADC channel
230229
adc_config_channel(self);
230+
231+
// This uses the timer in polling mode to do the sampling
232+
// TODO use DMA
233+
231234
uint nelems = bufinfo.len / typesize;
232235
for (uint index = 0; index < nelems; index++) {
233-
// Wait for the timer to trigger
236+
// Wait for the timer to trigger so we sample at the correct frequency
234237
while (__HAL_TIM_GET_FLAG(&TIM6_Handle, TIM_FLAG_UPDATE) == RESET) {
235238
}
236239
__HAL_TIM_CLEAR_FLAG(&TIM6_Handle, TIM_FLAG_UPDATE);
237-
uint value = adc_read_channel(&self->handle);
240+
241+
if (index == 0) {
242+
// for the first sample we need to turn the ADC on
243+
HAL_ADC_Start(&self->handle);
244+
} else {
245+
// for subsequent samples we can just set the "start sample" bit
246+
ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
247+
}
248+
249+
// wait for sample to complete
250+
uint32_t tickstart = HAL_GetTick();
251+
while ((ADCx->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
252+
#define READ_TIMED_TIMEOUT (10) // in ms
253+
if (((HAL_GetTick() - tickstart ) > READ_TIMED_TIMEOUT)) {
254+
break; // timeout
255+
}
256+
}
257+
258+
// read value
259+
uint value = ADCx->DR;
260+
261+
// store value in buffer
238262
if (typesize == 1) {
239263
value >>= 4;
240264
}
241265
mp_binary_set_val_array_from_int(bufinfo.typecode, bufinfo.buf, index, value);
242266
}
243267

268+
// turn the ADC off
269+
HAL_ADC_Stop(&self->handle);
270+
244271
// Stop timer
245272
HAL_TIM_Base_Stop(&TIM6_Handle);
246273

0 commit comments

Comments
 (0)