/var/www/restricted/ssh/stm32/www/stm32circle/ STM CircleOS forum / DMA Circular mode

Username:     
Password:     
             

Forum

# 1   2010-07-01 10:55:51 DMA Circular mode

alpha
New member
Registered: 2010-06-24
Posts: 5

DMA Circular mode

Hello
I found the documentation about the halfway done interrupt and circular DMA a bit lacking. Could someone please verify my understanding of the operation ?

Say I have an array of 12 elements. This is being filled by the DMA in circular mode. When I enable the halfway done interrupt, I will then have the data in element [0-5] and the DMA is filling element [6-11] if the halfway done flag is enabled?

Offline

 

# 2   2010-07-03 14:03:16 DMA Circular mode

ntrf.zns
Member
From: Belgorod, Russia
Registered: 2009-11-01
Posts: 134

Re: DMA Circular mode

Yes. But when DMA done with elements [6-11] it will be "Transfer complete" interrupt instead of "Half-complete". So if you have HC fired - you can work with [0-5], when you have TC - you can work with [6-11] elements.

Offline

 

# 3   2011-02-05 06:38:43 DMA Circular mode

kevinpeter
New member
Registered: 2011-02-05
Posts: 5

Re: DMA Circular mode

"without CPU intervention. Is there a way to set up the upper address so as soon as the upper address is reached, the address pointer would be reloaded with the lower address?"

Which hardware can do it? It can't.

As the orthodox way, generate End-Of-Process interrupt using Repeat Counter.

Offline

 

# 4   2011-04-25 05:45:18 DMA Circular mode

mickamark
New member
Registered: 2011-04-25
Posts: 5

Re: DMA Circular mode

My application requires that the data received in the USART1 is to be transmitted to USART2. USART1 operates at 115200,8,n,1 and USART2 operates at 9600,8,n,1.I m tying to do FIFO emulation using DMA with USART1 and USART2 in circular mode. The target that i m using is STM32F103VBT6.
My application requires that the data received in the USART1 is to be transmitted to USART2. USART1 operates at 115200,8,n,1 and USART2 operates at 9600,8,n,1.
Initially i tried using the interrupt routines. But due to the transimission of data from the higher baud rate to lower rate there was hug data loss. The data that i tried is transfer is around 1KB.

Offline

 

# 5   2011-05-02 21:10:44 DMA Circular mode

pfandler
Member
From: Hungary
Registered: 2011-02-16
Posts: 26

Re: DMA Circular mode

Hi, this is a part from my working DMA code, where the A/D data are continuously written into a circular buffer and the DMA half done and DMA full done interrupts are set up.

Note1: the code was written for an STM32VLDiscovery, so the peripheries may not be compatible with the CircleOS.
Note2: this is a code snippet only, but shows the way how to start...

Code:

  TIM_DeInit(TIM4);
  TIM_TimeBaseStructure.TIM_Period = TIM4_ARR;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;       
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;    
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_Update);
  /* Enable TIM4 DMA (DMA1 Ch7)*/
  TIM_DMACmd(TIM4, TIM_DMA_Update, ENABLE);
  TIM_ITConfig(TIM4, TIM_IT_Trigger, ENABLE);

  ADC_InitTypeDef   ADC_InitStructure;
  // ADC Deinit
  ADC_DeInit(ADC1);
  // ADC Structure Initialization
  ADC_StructInit(&ADC_InitStructure);

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_13Cycles5);
  // Enable the ADC
  ADC_Cmd(ADC1, ENABLE);

  // ADC calibration
  // Enable ADC1 reset calibration register
  ADC_ResetCalibration(ADC1);
  // Check the end of ADC1 reset calibration register
  while(ADC_GetResetCalibrationStatus(ADC1) == SET);

  // Start ADC1 calibration
  ADC_StartCalibration(ADC1);
  // Check the end of ADC1 calibration
  while(ADC_GetCalibrationStatus(ADC1) == SET);
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);


  /* this DMA channel is triggered by TIM4*/
  DMA_DeInit(DMA1_Channel7);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address/*(uint32_t)SRC_Const_Buffer*/;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValueTab;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//direction adc->mem
  DMA_InitStructure.DMA_BufferSize = 16;//sizeof(ADC_ConvertedValueTab);
  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_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
  /* Enable DMA1 Channel7 Transfer Complete, Half Transfer and Transfer Error interrupt */
  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC|DMA_IT_HT|DMA_IT_TE, ENABLE);

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC|DMA_IT_HT|DMA_IT_TE, ENABLE);
  __enable_interrupt();
  /* Enable DMA1 Channel7 transfer */
  DMA_Cmd(DMA1_Channel7, ENABLE);
  /* Enable TIM4 counter (this initiates the DMA ADC transfer)*/
  TIM_Cmd(TIM4, ENABLE);

Offline

 

Board footer