F446RE ADC with DMA hack (need pin to ADC channel) 1000 samples, for loop adc.read_u16() rate is 2.2us/sample for DMA block read, rate is 0.34us/sample

Dependencies:   mbed

F446RE ADC with DMA for 1000 samples. (a hack for now, need to get ADC channel from pin name, for asynch operation would need callback)

For 1000 samples with loop adc.read_u16(), sample rate is 2.2us/sample

For DMA, 0.34us/sample.

This matches expected rate: ADC clock at 45MHz, ADC configured for 3CYCLES/sample, cycles = 12+3, rate = 15/45 =0.33us/sample

Files at this revision

API Documentation at this revision

Comitter:
manitou
Date:
Fri Nov 13 13:20:03 2015 +0000
Commit message:
F446RE ADC with DMA, hack

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r b0470b4e6b60 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Nov 13 13:20:03 2015 +0000
@@ -0,0 +1,99 @@
+//  F446RE ADC with DMA
+// ADC read shifted to 16 bits, our readn is only 12 bits
+//  messy, TODO need ADC channel from pin number
+
+#include "mbed.h"
+
+#define PRREG(z) printf(#z" 0x%x\n",z) 
+
+AnalogIn adc(A1);   // init GPIO stuff
+Timer tmr;
+
+
+static ADC_HandleTypeDef AdcHandle;
+
+void adc_init() {
+        // we assume AnalogIn has configureed GPIO, we need ADC channel ?  
+        __ADC1_CLK_ENABLE();  // Enable ADC clock
+
+        // Configure ADC
+        AdcHandle.Instance = (ADC_TypeDef *)ADC1;
+        AdcHandle.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV2;
+        AdcHandle.Init.Resolution            = ADC_RESOLUTION12b;
+        AdcHandle.Init.ScanConvMode          = DISABLE;
+        AdcHandle.Init.ContinuousConvMode    = ENABLE;    // DMA
+        AdcHandle.Init.DiscontinuousConvMode = DISABLE;
+        AdcHandle.Init.NbrOfDiscConversion   = 0;
+        AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
+        AdcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_CC1;
+        AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
+        AdcHandle.Init.NbrOfConversion       = 1;
+        AdcHandle.Init.DMAContinuousRequests = ENABLE;    // DMA
+        AdcHandle.Init.EOCSelection          = DISABLE;
+        HAL_ADC_Init(&AdcHandle);
+}
+
+static DMA_HandleTypeDef DMA_Handle;
+
+void dma_init() {
+    //  DMA init  ADC1 is DMA2 channel0 stream 0 or 4 use DMA2_Stream0  thd
+
+    __DMA2_CLK_ENABLE();
+    DMA_Handle.Instance = DMA2_Stream0;
+    DMA_Handle.State = HAL_DMA_STATE_READY;
+    HAL_DMA_DeInit(&DMA_Handle);
+
+    DMA_Handle.Init.Channel = DMA_CHANNEL_0;   
+    DMA_Handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
+    DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE;
+    DMA_Handle.Init.MemInc = DMA_MINC_ENABLE;
+    DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+    DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+    DMA_Handle.Init.Mode =  DMA_NORMAL;
+    DMA_Handle.Init.Priority = DMA_PRIORITY_HIGH;
+    DMA_Handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+    DMA_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
+    DMA_Handle.Init.MemBurst = DMA_MBURST_SINGLE;   
+    DMA_Handle.Init.PeriphBurst = DMA_PBURST_SINGLE;
+    HAL_DMA_Init(&DMA_Handle);
+
+    __HAL_LINKDMA(&AdcHandle, DMA_Handle, DMA_Handle);
+}
+
+void adc_readn( uint16_t * data, uint32_t nelems) {
+    ADC_ChannelConfTypeDef sConfig;
+    sConfig.Channel = ADC_CHANNEL_1;  // A1  need to derive
+    sConfig.Rank = 1;
+    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+    sConfig.Offset = 0;
+    HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
+
+    HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)data, nelems);
+    while (DMA_Handle.Instance->CR & DMA_SxCR_EN);   // spin
+    HAL_ADC_Stop(&AdcHandle);
+}
+
+#define SAMPLES 1000
+
+int main() {
+    uint16_t samples[SAMPLES];
+    uint32_t t1;
+    int i;
+
+    printf("\nSystemCoreClock %d  %s %s\n",SystemCoreClock,__TIME__,__DATE__);
+    tmr.start();
+    
+    memset(samples,0,sizeof samples);
+    t1=tmr.read_us();
+    for(i=0;i<SAMPLES;i++) samples[i] = adc.read_u16();
+    t1=tmr.read_us() - t1;
+    printf("loop sample time %.1f us  %d elapsed %d us\n", (float)t1 / SAMPLES,samples[5],t1);
+    
+    adc_init();
+    dma_init();
+    memset(samples,77,sizeof samples);
+    t1=tmr.read_us();
+    adc_readn(samples,SAMPLES);
+    t1=tmr.read_us() - t1;
+    printf("DMA sample time %.2f us  %d  elapsed %d us\n", (float)t1 / SAMPLES,samples[5],t1);
+}
diff -r 000000000000 -r b0470b4e6b60 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Nov 13 13:20:03 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/9296ab0bfc11
\ No newline at end of file