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.
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

View File

@ -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. */