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

Committer:
manitou
Date:
Fri Nov 13 13:20:03 2015 +0000
Revision:
0:b0470b4e6b60
F446RE ADC with DMA, hack

Who changed what in which revision?

UserRevisionLine numberNew contents of line
manitou 0:b0470b4e6b60 1 // F446RE ADC with DMA
manitou 0:b0470b4e6b60 2 // ADC read shifted to 16 bits, our readn is only 12 bits
manitou 0:b0470b4e6b60 3 // messy, TODO need ADC channel from pin number
manitou 0:b0470b4e6b60 4
manitou 0:b0470b4e6b60 5 #include "mbed.h"
manitou 0:b0470b4e6b60 6
manitou 0:b0470b4e6b60 7 #define PRREG(z) printf(#z" 0x%x\n",z)
manitou 0:b0470b4e6b60 8
manitou 0:b0470b4e6b60 9 AnalogIn adc(A1); // init GPIO stuff
manitou 0:b0470b4e6b60 10 Timer tmr;
manitou 0:b0470b4e6b60 11
manitou 0:b0470b4e6b60 12
manitou 0:b0470b4e6b60 13 static ADC_HandleTypeDef AdcHandle;
manitou 0:b0470b4e6b60 14
manitou 0:b0470b4e6b60 15 void adc_init() {
manitou 0:b0470b4e6b60 16 // we assume AnalogIn has configureed GPIO, we need ADC channel ?
manitou 0:b0470b4e6b60 17 __ADC1_CLK_ENABLE(); // Enable ADC clock
manitou 0:b0470b4e6b60 18
manitou 0:b0470b4e6b60 19 // Configure ADC
manitou 0:b0470b4e6b60 20 AdcHandle.Instance = (ADC_TypeDef *)ADC1;
manitou 0:b0470b4e6b60 21 AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
manitou 0:b0470b4e6b60 22 AdcHandle.Init.Resolution = ADC_RESOLUTION12b;
manitou 0:b0470b4e6b60 23 AdcHandle.Init.ScanConvMode = DISABLE;
manitou 0:b0470b4e6b60 24 AdcHandle.Init.ContinuousConvMode = ENABLE; // DMA
manitou 0:b0470b4e6b60 25 AdcHandle.Init.DiscontinuousConvMode = DISABLE;
manitou 0:b0470b4e6b60 26 AdcHandle.Init.NbrOfDiscConversion = 0;
manitou 0:b0470b4e6b60 27 AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
manitou 0:b0470b4e6b60 28 AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
manitou 0:b0470b4e6b60 29 AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
manitou 0:b0470b4e6b60 30 AdcHandle.Init.NbrOfConversion = 1;
manitou 0:b0470b4e6b60 31 AdcHandle.Init.DMAContinuousRequests = ENABLE; // DMA
manitou 0:b0470b4e6b60 32 AdcHandle.Init.EOCSelection = DISABLE;
manitou 0:b0470b4e6b60 33 HAL_ADC_Init(&AdcHandle);
manitou 0:b0470b4e6b60 34 }
manitou 0:b0470b4e6b60 35
manitou 0:b0470b4e6b60 36 static DMA_HandleTypeDef DMA_Handle;
manitou 0:b0470b4e6b60 37
manitou 0:b0470b4e6b60 38 void dma_init() {
manitou 0:b0470b4e6b60 39 // DMA init ADC1 is DMA2 channel0 stream 0 or 4 use DMA2_Stream0 thd
manitou 0:b0470b4e6b60 40
manitou 0:b0470b4e6b60 41 __DMA2_CLK_ENABLE();
manitou 0:b0470b4e6b60 42 DMA_Handle.Instance = DMA2_Stream0;
manitou 0:b0470b4e6b60 43 DMA_Handle.State = HAL_DMA_STATE_READY;
manitou 0:b0470b4e6b60 44 HAL_DMA_DeInit(&DMA_Handle);
manitou 0:b0470b4e6b60 45
manitou 0:b0470b4e6b60 46 DMA_Handle.Init.Channel = DMA_CHANNEL_0;
manitou 0:b0470b4e6b60 47 DMA_Handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
manitou 0:b0470b4e6b60 48 DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE;
manitou 0:b0470b4e6b60 49 DMA_Handle.Init.MemInc = DMA_MINC_ENABLE;
manitou 0:b0470b4e6b60 50 DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
manitou 0:b0470b4e6b60 51 DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
manitou 0:b0470b4e6b60 52 DMA_Handle.Init.Mode = DMA_NORMAL;
manitou 0:b0470b4e6b60 53 DMA_Handle.Init.Priority = DMA_PRIORITY_HIGH;
manitou 0:b0470b4e6b60 54 DMA_Handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
manitou 0:b0470b4e6b60 55 DMA_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
manitou 0:b0470b4e6b60 56 DMA_Handle.Init.MemBurst = DMA_MBURST_SINGLE;
manitou 0:b0470b4e6b60 57 DMA_Handle.Init.PeriphBurst = DMA_PBURST_SINGLE;
manitou 0:b0470b4e6b60 58 HAL_DMA_Init(&DMA_Handle);
manitou 0:b0470b4e6b60 59
manitou 0:b0470b4e6b60 60 __HAL_LINKDMA(&AdcHandle, DMA_Handle, DMA_Handle);
manitou 0:b0470b4e6b60 61 }
manitou 0:b0470b4e6b60 62
manitou 0:b0470b4e6b60 63 void adc_readn( uint16_t * data, uint32_t nelems) {
manitou 0:b0470b4e6b60 64 ADC_ChannelConfTypeDef sConfig;
manitou 0:b0470b4e6b60 65 sConfig.Channel = ADC_CHANNEL_1; // A1 need to derive
manitou 0:b0470b4e6b60 66 sConfig.Rank = 1;
manitou 0:b0470b4e6b60 67 sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
manitou 0:b0470b4e6b60 68 sConfig.Offset = 0;
manitou 0:b0470b4e6b60 69 HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
manitou 0:b0470b4e6b60 70
manitou 0:b0470b4e6b60 71 HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)data, nelems);
manitou 0:b0470b4e6b60 72 while (DMA_Handle.Instance->CR & DMA_SxCR_EN); // spin
manitou 0:b0470b4e6b60 73 HAL_ADC_Stop(&AdcHandle);
manitou 0:b0470b4e6b60 74 }
manitou 0:b0470b4e6b60 75
manitou 0:b0470b4e6b60 76 #define SAMPLES 1000
manitou 0:b0470b4e6b60 77
manitou 0:b0470b4e6b60 78 int main() {
manitou 0:b0470b4e6b60 79 uint16_t samples[SAMPLES];
manitou 0:b0470b4e6b60 80 uint32_t t1;
manitou 0:b0470b4e6b60 81 int i;
manitou 0:b0470b4e6b60 82
manitou 0:b0470b4e6b60 83 printf("\nSystemCoreClock %d %s %s\n",SystemCoreClock,__TIME__,__DATE__);
manitou 0:b0470b4e6b60 84 tmr.start();
manitou 0:b0470b4e6b60 85
manitou 0:b0470b4e6b60 86 memset(samples,0,sizeof samples);
manitou 0:b0470b4e6b60 87 t1=tmr.read_us();
manitou 0:b0470b4e6b60 88 for(i=0;i<SAMPLES;i++) samples[i] = adc.read_u16();
manitou 0:b0470b4e6b60 89 t1=tmr.read_us() - t1;
manitou 0:b0470b4e6b60 90 printf("loop sample time %.1f us %d elapsed %d us\n", (float)t1 / SAMPLES,samples[5],t1);
manitou 0:b0470b4e6b60 91
manitou 0:b0470b4e6b60 92 adc_init();
manitou 0:b0470b4e6b60 93 dma_init();
manitou 0:b0470b4e6b60 94 memset(samples,77,sizeof samples);
manitou 0:b0470b4e6b60 95 t1=tmr.read_us();
manitou 0:b0470b4e6b60 96 adc_readn(samples,SAMPLES);
manitou 0:b0470b4e6b60 97 t1=tmr.read_us() - t1;
manitou 0:b0470b4e6b60 98 printf("DMA sample time %.2f us %d elapsed %d us\n", (float)t1 / SAMPLES,samples[5],t1);
manitou 0:b0470b4e6b60 99 }