cancel
Showing results for 
Search instead for 
Did you mean: 

Two different DMA-Channels with same target?

michaelmayer49
Associate II
Posted on September 03, 2014 at 07:15

Hello,

i was thinking about, if it would be possible to write to one peripherie register (for example the CCR1 of a Timer) with two different DMA-Channels. For sure not at the same time, but at different points in time. I have tried it a while on my own, but now i am not sure if it is possible at all. Thanks for helping in advance.

Best regards Michael Mayer

#dma
6 REPLIES 6
Posted on September 03, 2014 at 10:33

I would think it's viable provided you use the correct combination of unit/channel/stream and triggers.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmayer49
Associate II
Posted on September 03, 2014 at 19:47

Hello,

Thanks for your answer! It works if I only write one variable to the CCR1 register. But if I write two variables to CCR1 and to CCR2 it goes wrong (increasing DMA_BufferSize to 2). CCR1 is written one time, afterwards only CCR2 is updated. Can you find the failure in my DMA-inits?

void DMA_Timer
1
_up_ini(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA
1
, ENABLE);
DMA_InitStructure.DMA_BufferSize = 
2
;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_M
2
M = DMA_M
2
M_Disable;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint
32
_t)&(pwm_aktuell.up);
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint
32
_t)&(TIM
1
->CCR
1
);
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA
1
_Channel
6
, &DMA_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA
1
_Channel
6
_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 
1
;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 
1
;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA
1
_Channel
6
, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA
1
_Channel
6
, ENABLE);
}
void DMA_Timer
1
_down_ini(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA
1
, ENABLE);
DMA_InitStructure.DMA_BufferSize = 
2
;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_M
2
M = DMA_M
2
M_Disable;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint
32
_t)&(pwm_aktuell.down);
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint
32
_t)&(TIM
1
->CCR
1
);
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA
1
_Channel
2
, &DMA_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA
1
_Channel
2
_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 
1
;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 
1
;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA
1
_Channel
2
, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA
1
_Channel
2
, ENABLE);
}

Best regards Michael

Posted on September 03, 2014 at 20:53

I'd expect the address to toggle at each trigger event.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmayer49
Associate II
Posted on September 04, 2014 at 20:40

hello,

unfortunately I do not understand exactly what yout mean. Could you explain it to me again?

Regards Michael

Posted on September 04, 2014 at 21:12

The DMA unit does not block-transfer at each trigger event, it just does one transfer. You have configured two transfers and circular. It's going to therefore ping-pong between two addresses alternately.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 05, 2014 at 09:22

The general-purpose and the advanced timers have a DMA burst feature, controlled by the TIMx_DCR register. Besides the brief description in RM at the related registers' chapter, it is mentioned also in AN4507.

Never tried personally, though.

JW