cancel
Showing results for 
Search instead for 
Did you mean: 

DMA timer capture

Adalgiso
Associate II
Posted on July 16, 2013 at 16:42

Hi,

I need to do some timming analyses on signal. I use the capture mode of a timer.

When I use the interrupt to capture event, it works but when the signal is fatser I get into overrun issue, I cannot run my CPU faster as I will draw too much current.

I was thinking to use the DMA to save the timer capture events allowing to run the CPU slower but it does not work. I have the following code

  /* DMA clock enable */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);

  DMA_DeInit(DMA2_Stream6);

  DMA_StructInit(&DMA_InitStructure);

  DMA_InitStructure.DMA_Channel = DMA_Channel_6;  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&TIM1->CCR3) ;

  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)delta_buf;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

  DMA_InitStructure.DMA_BufferSize = 256;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

  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(DMA2_Stream6, &DMA_InitStructure);

  TIM_DeInit(TIM1);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;

  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(TIM1, &TIM_ICInitStructure);

  

  /* Enable the TIMER CAPTURE DMA requests */

  TIM_SelectCCDMA(TIM1, ENABLE);

  TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);

  /* TIM enable counter */

  TIM_Cmd(TIM1, ENABLE);

Any idea?

#dma-timer #capture
2 REPLIES 2
Posted on July 17, 2013 at 05:22

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
'',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, 122 KHz not quite 50/50 duty
while(1); // Do not exit
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 17, 2013 at 05:26

#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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..