@@ -97,6 +97,20 @@ static void dac_descr_deinit(adc_descr_t *descr, bool dealloc_pool) {
9797 }
9898}
9999
100+ int AdvancedADC::id () {
101+ if (descr) {
102+ ADC_TypeDef *adc = descr->adc .Instance ;
103+ if (adc == ADC1) {
104+ return 1 ;
105+ } else if (adc == ADC2) {
106+ return 2 ;
107+ } else if (adc == ADC3) {
108+ return 3 ;
109+ }
110+ }
111+ return -1 ;
112+ }
113+
100114bool AdvancedADC::available () {
101115 if (descr != nullptr ) {
102116 return descr->pool ->readable ();
@@ -115,9 +129,9 @@ DMABuffer<Sample> &AdvancedADC::read() {
115129 return NULLBUF;
116130}
117131
118- int AdvancedADC::begin (uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers) {
132+ int AdvancedADC::begin (uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers, bool start) {
133+
119134 ADCName instance = ADC_NP;
120-
121135 // Sanity checks.
122136 if (resolution >= AN_ARRAY_SIZE (ADC_RES_LUT) || (descr && descr->pool )) {
123137 return 0 ;
@@ -159,6 +173,7 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
159173
160174 // Configure ADC pins.
161175 pinmap_pinout (adc_pins[0 ], PinMap_ADC);
176+
162177 uint8_t ch_init = 1 ;
163178 for (size_t i=1 ; i<n_channels; i++) {
164179 for (size_t j=0 ; j<AN_ARRAY_SIZE (adc_pin_alt); j++) {
@@ -188,6 +203,8 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
188203 if (descr->pool == nullptr ) {
189204 return 0 ;
190205 }
206+
207+ // Allocate the two DMA buffers used for double buffering.
191208 descr->dmabuf [0 ] = descr->pool ->allocate ();
192209 descr->dmabuf [1 ] = descr->pool ->allocate ();
193210
@@ -212,27 +229,89 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
212229 hal_dma_enable_dbm (&descr->dma , descr->dmabuf [0 ]->data (), descr->dmabuf [1 ]->data ());
213230 HAL_NVIC_EnableIRQ (descr->dma_irqn );
214231
215- // Init, config and start the ADC timer.
232+ if (start) {
233+ return this ->start (sample_rate);
234+ }
235+
236+ return 1 ;
237+ }
238+
239+ int AdvancedADC::start (uint32_t sample_rate){
240+ // Initialize and configure the ADC timer.
216241 hal_tim_config (&descr->tim , sample_rate);
242+
243+ // Start the ADC timer. Note, if dual ADC mode is enabled,
244+ // this will also start ADC2.
217245 if (HAL_TIM_Base_Start (&descr->tim ) != HAL_OK) {
218246 return 0 ;
219247 }
220-
248+
221249 return 1 ;
222250}
223251
224- int AdvancedADC::stop ()
225- {
252+ int AdvancedADC::stop () {
226253 dac_descr_deinit (descr, true );
227254 return 1 ;
228255}
229256
230- AdvancedADC::~AdvancedADC ()
231- {
257+ void AdvancedADC::clear () {
258+ if (descr && descr->pool ) {
259+ descr->pool ->flush ();
260+ }
261+ }
262+
263+ size_t AdvancedADC::channels () {
264+ return n_channels;
265+ }
266+
267+ AdvancedADC::~AdvancedADC () {
232268 dac_descr_deinit (descr, true );
233269}
234270
271+ int AdvancedADCDual::begin (uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers) {
272+ // The two ADCs must have the same number of channels.
273+ if (adc1.channels () != adc2.channels ()) {
274+ return 0 ;
275+ }
276+
277+ // Configure the ADCs.
278+ if (!adc1.begin (resolution, sample_rate, n_samples, n_buffers, false )) {
279+ return 0 ;
280+ }
281+
282+ if (!adc2.begin (resolution, sample_rate, n_samples, n_buffers, false )) {
283+ adc1.stop ();
284+ return 0 ;
285+ }
286+
287+ // Note only ADC1 (master) and ADC2 can be used in dual mode.
288+ if (adc1.id () != 1 || adc2.id () != 2 ) {
289+ adc1.stop ();
290+ adc2.stop ();
291+ return 0 ;
292+ }
293+
294+ // Enable dual ADC mode.
295+ hal_adc_enable_dual_mode (true );
296+
297+ // Start ADC1, note ADC2 is also automatically started.
298+ return adc1.start (sample_rate);
299+ }
300+
301+ int AdvancedADCDual:: stop() {
302+ adc1.stop ();
303+ adc2.stop ();
304+ // Disable dual mode.
305+ hal_adc_enable_dual_mode (false );
306+ return 1 ;
307+ }
308+
309+ AdvancedADCDual::~AdvancedADCDual () {
310+ stop ();
311+ }
312+
235313extern " C" {
314+
236315void HAL_ADC_ConvCpltCallback (ADC_HandleTypeDef *adc) {
237316 adc_descr_t *descr = adc_descr_get (adc->Instance );
238317 // NOTE: CT bit is inverted, to get the DMA buffer that's Not currently in use.
0 commit comments