Skip to content

Commit a76e0e4

Browse files
authored
Added member functions ready(), start() and clear()
ready() and start() are just the begin() function split into two pieces. ready() does everything except start the ADC capture. clear() is calling the DMABufferPool routine to flush out anything in the DMA buffers.
1 parent 7a77b31 commit a76e0e4

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

src/AdvancedADC.cpp

+116
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,128 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
221221
return 1;
222222
}
223223

224+
int AdvancedADC::ready(uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers) {
225+
ADCName instance = ADC_NP;
226+
227+
// Sanity checks.
228+
if (resolution >= AN_ARRAY_SIZE(ADC_RES_LUT) || (descr && descr->pool)) {
229+
return 0;
230+
}
231+
232+
// Clear ALTx pin.
233+
for (size_t i=0; i<n_channels; i++) {
234+
adc_pins[i] = (PinName) (adc_pins[i] & ~(ADC_PIN_ALT_MASK));
235+
}
236+
237+
// Find an ADC that can be used with these set of pins/channels.
238+
for (size_t i=0; instance == ADC_NP && i<AN_ARRAY_SIZE(adc_pin_alt); i++) {
239+
// Calculate alternate function pin.
240+
PinName pin = (PinName) (adc_pins[0] | adc_pin_alt[i]); // First pin decides the ADC.
241+
242+
// Check if pin is mapped.
243+
if (pinmap_find_peripheral(pin, PinMap_ADC) == NC) {
244+
break;
245+
}
246+
247+
// Find the first free ADC according to the available ADCs on pin.
248+
for (size_t j=0; instance == ADC_NP && j<AN_ARRAY_SIZE(adc_descr_all); j++) {
249+
descr = &adc_descr_all[j];
250+
if (descr->pool == nullptr) {
251+
ADCName tmp_instance = (ADCName) pinmap_peripheral(pin, PinMap_ADC);
252+
if (descr->adc.Instance == ((ADC_TypeDef*) tmp_instance)) {
253+
instance = tmp_instance;
254+
adc_pins[0] = pin;
255+
}
256+
}
257+
}
258+
}
259+
260+
if (instance == ADC_NP) {
261+
// Couldn't find a free ADC/descriptor.
262+
descr = nullptr;
263+
return 0;
264+
}
265+
266+
// Configure ADC pins.
267+
pinmap_pinout(adc_pins[0], PinMap_ADC);
268+
uint8_t ch_init = 1;
269+
for (size_t i=1; i<n_channels; i++) {
270+
for (size_t j=0; j<AN_ARRAY_SIZE(adc_pin_alt); j++) {
271+
// Calculate alternate function pin.
272+
PinName pin = (PinName) (adc_pins[i] | adc_pin_alt[j]);
273+
// Check if pin is mapped.
274+
if (pinmap_find_peripheral(pin, PinMap_ADC) == NC) {
275+
break;
276+
}
277+
// Check if pin is connected to the selected ADC.
278+
if (instance == pinmap_peripheral(pin, PinMap_ADC)) {
279+
pinmap_pinout(pin, PinMap_ADC);
280+
adc_pins[i] = pin;
281+
ch_init++;
282+
break;
283+
}
284+
}
285+
}
286+
287+
// All channels must share the same instance; if not, bail out.
288+
if (ch_init < n_channels) {
289+
return 0;
290+
}
291+
292+
// Allocate DMA buffer pool.
293+
descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
294+
if (descr->pool == nullptr) {
295+
return 0;
296+
}
297+
298+
descr->dmabuf[0] = descr->pool->allocate();
299+
descr->dmabuf[1] = descr->pool->allocate();
300+
301+
302+
// Init and config DMA.
303+
if (hal_dma_config(&descr->dma, descr->dma_irqn, DMA_PERIPH_TO_MEMORY) < 0) {
304+
return 0;
305+
}
306+
307+
if (hal_adc_config(&descr->adc, ADC_RES_LUT[resolution], descr->tim_trig, adc_pins, n_channels) < 0) {
308+
return 0;
309+
}
310+
311+
return(1);
312+
}
313+
314+
int AdvancedADC::start(uint32_t sample_rate)
315+
{
316+
317+
// Link DMA handle to ADC handle, and start the ADC.
318+
__HAL_LINKDMA(&descr->adc, DMA_Handle, descr->dma);
319+
if (HAL_ADC_Start_DMA(&descr->adc, (uint32_t *) descr->dmabuf[0]->data(), descr->dmabuf[0]->size()) != HAL_OK) {
320+
return 0;
321+
}
322+
323+
// Re/enable DMA double buffer mode.
324+
hal_dma_enable_dbm(&descr->dma, descr->dmabuf[0]->data(), descr->dmabuf[1]->data());
325+
326+
// Init, config and start the ADC timer.
327+
hal_tim_config(&descr->tim, sample_rate);
328+
if (HAL_TIM_Base_Start(&descr->tim) != HAL_OK) {
329+
return 0;
330+
}
331+
332+
return 1;
333+
}
334+
224335
int AdvancedADC::stop()
225336
{
226337
dac_descr_deinit(descr, true);
227338
return 1;
228339
}
229340

341+
void AdvancedADC::clear()
342+
{
343+
descr->pool->flush();
344+
}
345+
230346
AdvancedADC::~AdvancedADC()
231347
{
232348
dac_descr_deinit(descr, true);

0 commit comments

Comments
 (0)