
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
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
Revision 0:b0470b4e6b60, committed 2015-11-13
- 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