SAMA5 ADC: If DMA is enabled, then you should be able to configuration larger DMA transfers

This commit is contained in:
Gregory Nutt 2013-10-27 12:04:37 -06:00
parent 13ec431d75
commit da251ade8b
2 changed files with 45 additions and 6 deletions

View File

@ -1678,6 +1678,32 @@ config SAMA5_ADC_DMA
is that there will be one DMA interrupt per conversion sequence vs. is that there will be one DMA interrupt per conversion sequence vs.
one interrupt per conversion. 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 config SAMA5_ADC_AUTOCALIB
bool "ADC auto-calibration" bool "ADC auto-calibration"
default n default n

View File

@ -357,6 +357,19 @@
# undef SAMA5_ADC_UNUSED # undef SAMA5_ADC_UNUSED
#endif #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 */ /* Clocking */
#if BOARD_MCK_FREQUENCY <= SAM_ADC_MAXPERCLK #if BOARD_MCK_FREQUENCY <= SAM_ADC_MAXPERCLK
@ -405,8 +418,8 @@ struct sam_adc_s
/* DMA sample data buffer */ /* DMA sample data buffer */
#ifdef CONFIG_SAMA5_ADC_DMA #ifdef CONFIG_SAMA5_ADC_DMA
uint32_t evenbuf[SAMA5_NCHANNELS]; uint32_t evenbuf[SAMA5_ADC_SAMPLES];
uint32_t oddbuf[SAMA5_NCHANNELS]; uint32_t oddbuf[SAMA5_ADC_SAMPLES];
#endif #endif
#endif /* SAMA5_ADC_HAVE_CHANNELS */ #endif /* SAMA5_ADC_HAVE_CHANNELS */
@ -617,11 +630,11 @@ static void sam_adc_dmadone(void *arg)
*/ */
cp15_invalidate_dcache((uintptr_t)buffer, 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 */ /* 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 */ /* 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, sam_adc_dmasetup(priv->dma,
priv->odd ? (void *)priv->oddbuf : (void *)priv->evenbuf, priv->odd ? (void *)priv->oddbuf : (void *)priv->evenbuf,
SAMA5_NCHANNELS * sizeof(uint32_t)); SAMA5_ADC_SAMPLES * sizeof(uint32_t));
} }
#endif #endif
@ -1008,7 +1021,7 @@ static int sam_adc_setup(struct adc_dev_s *dev)
priv->ready = true; priv->ready = true;
priv->enabled = false; priv->enabled = false;
sam_adc_dmasetup(priv, (void *)priv->evenbuf, SAMA5_NCHANNELS); sam_adc_dmasetup(priv, (void *)priv->evenbuf, SAMA5_ADC_SAMPLES);
#else #else
/* Enable end-of-conversion interrupts for all enabled channels. */ /* Enable end-of-conversion interrupts for all enabled channels. */