DMA/TIM capture
This is a more free standing example measuring the LSI (TIM5_CH4 internally)
and demonstrating DMA/TIM capture with granularity of APB1 * 2
// STM32F4-Discovery LSI Bench using DMA/TIM - sourcer32@gmail.com // SWV code redacted #include "stm32f4_discovery.h" #include <stdio.h> #include <string.h> /**************************************************************************/ #define DELTA_SAMPLES 16 volatile uint32_t DeltaBuffer[DELTA_SAMPLES]; // TIM5 is 32-bit void TimerCapture(void) { DMA_InitTypeDef DMA_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* Enable the LSI source, as an available built in asych source */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Allow access to BKP Domain */ PWR_BackupAccessCmd(ENABLE); /* Enable the LSI OSC */ RCC_LSICmd(ENABLE); /* Wait till LSI is ready */ while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); /* TIM5 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); /* DMA clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // TIM5_CH4 DMA1 Stream1 or 3, Channel 6, per RM0090 DMA_DeInit(DMA1_Stream1); DMA_StructInit(&DMA_InitStructure); /* not required - fully qualified below */ DMA_InitStructure.DMA_Channel = DMA_Channel_6; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&TIM5->CCR4); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&DeltaBuffer[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = DELTA_SAMPLES; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; // 32-bit DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream1, &DMA_InitStructure); TIM_DeInit(TIM5); /* not required? */ /* Connect internally the TIM5_CH4 Input Capture to the LSI clock output */ TIM_RemapConfig(TIM5, TIM5_LSI); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; // 32-bit maximal TIM_TimeBaseStructure.TIM_Prescaler = 0; // Highest Rate (DIV4 on APB1, DIV2 on TIMCLK5, 84 MHz?) TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); /* Channel configuration */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x00; TIM_ICInit(TIM5, &TIM_ICInitStructure); /* Enable the TIM Capture/Compare DMA requests */ // TIM_SelectCCDMA(TIM5, ENABLE); /* not required - Output Compare, want CCDS=0 (DISABLED) for CC rather than Update? */ TIM_DMACmd(TIM5, TIM_DMA_CC4, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM5, ENABLE); /* Main Output Enable, and Input - TIM1/8 */ //TIM_CtrlPWMOutputs(TIMx, ENABLE); } /**************************************************************************/ int main(void) { int i; memset((void *)DeltaBuffer, 0xCD, sizeof(DeltaBuffer)); // Flood buffer to prove it fills TimerCapture(); /* Clear DMA1_Stream1 Terminal Count */ DMA_ClearFlag(DMA1_Stream1, DMA_FLAG_TCIF1); /* Enable DMA1_Stream1 */ DMA_Cmd(DMA1_Stream1, ENABLE); /* Wait on DMA1 Stream1 Terminal Count */ while(DMA_GetFlagStatus(DMA1_Stream1, DMA_FLAG_TCIF1) == RESET); for(i=1; i<DELTA_SAMPLES; i++) printf("#%03d - Abs:%10d Delta:%10d\n",i,DeltaBuffer[i],DeltaBuffer[i] - DeltaBuffer[i-1]); // Delta for 40 KHz measured at 84 MHz is 2100 cycle, or 1050 cycles for half period (both edges) // Measuring 1300/1315, 32.122 KHz not quite 50/50 duty while(1); // Do not exit }
#001 - Abs: 2196 Delta: 1316 #002 - Abs: 3499 Delta: 1303 #003 - Abs: 4816 Delta: 1317 #004 - Abs: 6117 Delta: 1301 #005 - Abs: 7435 Delta: 1318 #006 - Abs: 8736 Delta: 1301 #007 - Abs: 10048 Delta: 1312 #008 - Abs: 11351 Delta: 1303 #009 - Abs: 12667 Delta: 1316 #010 - Abs: 13971 Delta: 1304 #011 - Abs: 15285 Delta: 1314 #012 - Abs: 16588 Delta: 1303 #013 - Abs: 17903 Delta: 1315 #014 - Abs: 19207 Delta: 1304 #015 - Abs: 20522 Delta: 1315