diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig index a3d9d316b8..e9f3eb914c 100644 --- a/arch/arm/src/sama5/Kconfig +++ b/arch/arm/src/sama5/Kconfig @@ -1678,6 +1678,32 @@ config SAMA5_ADC_DMA is that there will be one DMA interrupt per conversion sequence vs. one interrupt per conversion. +config SAMA5_ADC_DMASAMPLES + int "Number of DMA samples" + default 2 + depends on SAMA5_ADC_DMA + ---help--- + If DMA is enabled, then this will specify the number of sample to + collect before the DMA completes. This is actually the number of + triggers; the number of collected samples will be this value times + the number of channels that are enabled. You should also enable the + sequencer if you are DMAing multiple channels. + + A value of "1" would DMA one set of samples. That is not advised. + In that case the processing and data transfer overhead would be + greater than if DMA were disabled. A value of 2 or more should be + selected. + + The DMA logic uses ping-pong buffers, so the total buffering + requirement will be + + 2 Buffers * Number_of_ADC_Channels * SAMA5_ADC_DMASAMPLES * sizeof(uint32_t) + + So, for example, if you had 8 ADC channels and 8 triggers per DMA + transfer, then the total DMA buffering requirment would be: + + 2 * 8 * 8 * 4 = 512 bytes. + config SAMA5_ADC_AUTOCALIB bool "ADC auto-calibration" default n diff --git a/arch/arm/src/sama5/sam_adc.c b/arch/arm/src/sama5/sam_adc.c index f5dfb64819..512e1fe292 100644 --- a/arch/arm/src/sama5/sam_adc.c +++ b/arch/arm/src/sama5/sam_adc.c @@ -357,6 +357,19 @@ # undef SAMA5_ADC_UNUSED #endif +/* Number of DMA samples to collect */ + +#if !defined(CONFIG_SAMA5_ADC_DMA) +# undef CONFIG_SAMA5_ADC_DMASAMPLES +# define CONFIG_SAMA5_ADC_DMASAMPLES 1 +#elif !defined(CONFIG_SAMA5_ADC_DMASAMPLES) +# error CONFIG_SAMA5_ADC_DMASAMPLES must be defined +#elif CONFIG_SAMA5_ADC_DMASAMPLES < 2 +# warning Values of ONFIG_SAMA5_ADC_DMASAMPLES < 2 are inefficient +#endif + +#define SAMA5_ADC_SAMPLES (CONFIG_SAMA5_ADC_DMASAMPLES * SAMA5_NCHANNELS) + /* Clocking */ #if BOARD_MCK_FREQUENCY <= SAM_ADC_MAXPERCLK @@ -405,8 +418,8 @@ struct sam_adc_s /* DMA sample data buffer */ #ifdef CONFIG_SAMA5_ADC_DMA - uint32_t evenbuf[SAMA5_NCHANNELS]; - uint32_t oddbuf[SAMA5_NCHANNELS]; + uint32_t evenbuf[SAMA5_ADC_SAMPLES]; + uint32_t oddbuf[SAMA5_ADC_SAMPLES]; #endif #endif /* SAMA5_ADC_HAVE_CHANNELS */ @@ -617,11 +630,11 @@ static void sam_adc_dmadone(void *arg) */ cp15_invalidate_dcache((uintptr_t)buffer, - (uintptr_t)buffer + SAMA5_NCHANNELS * sizeof(uint32_t)); + (uintptr_t)buffer + SAMA5_ADC_SAMPLES * sizeof(uint32_t)); /* Process each sample */ - for (i = 0; i < SAMA5_NCHANNELS; i++, buffer++) + for (i = 0; i < SAMA5_ADC_SAMPLES; i++, buffer++) { /* Get the sample and the channel number */ @@ -684,7 +697,7 @@ static void sam_adc_dmacallback(DMA_HANDLE handle, void *arg, int result) sam_adc_dmasetup(priv->dma, priv->odd ? (void *)priv->oddbuf : (void *)priv->evenbuf, - SAMA5_NCHANNELS * sizeof(uint32_t)); + SAMA5_ADC_SAMPLES * sizeof(uint32_t)); } #endif @@ -1008,7 +1021,7 @@ static int sam_adc_setup(struct adc_dev_s *dev) priv->ready = true; priv->enabled = false; - sam_adc_dmasetup(priv, (void *)priv->evenbuf, SAMA5_NCHANNELS); + sam_adc_dmasetup(priv, (void *)priv->evenbuf, SAMA5_ADC_SAMPLES); #else /* Enable end-of-conversion interrupts for all enabled channels. */