2020-04-27 11:03 AM
NUCLEO-F103RB with STM32F103RB
I want to use the DMA in a burst mode to write data from buffer in RAM to the TIM1_CCR1,2,3,4? that are in PWM mode. DMA burst transaction is requested on the TIM1 Update (UEV). Number of transactions in Burst mode is set to 4 transactions. According to the Reference Manual on each DMA Burst request 4 values from the buffer in RAM have to be transfered simultaneously to the CCR1,2,3,4. What I actually see is that on each TIM1 Update Event ONLY ONE TIM1_CCRx register is getting updated with a new value from the buffer.
Is that how it sappose to work, and if not where can be a problem?
IDE: arm Keil microVision5
Driver: STMicroelectronics SPL
Sourse code
#define TIM1_DMAR_ADDRESS ((uint32_t)0x40012C4C)
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t SRC_Buffer[] = {0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF};
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 , ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_DMAR_ADDRESS;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 4;
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_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
//TIM1 (PWM Generator)
TIM_DeInit(TIM1);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (SystemCoreClock / 24000000)-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0x0000;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC4Init(TIM1, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_4Transfers);
TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
while(1){}
}
Here is the picture I get in Keil's Logic Analyser
I'm using simulator now and in a long time will not be able to test program on a real MCU.
Solved! Go to Solution.
2020-05-04 03:49 AM
Thank you all for your help. I finally got access to my board and to a real logic analyzer (thanks quarantine for all that wasted time hehe), The Tim DMA-burst feature works fine irl, problem was in the Keil's simulator.
2020-04-27 11:59 AM
> I'm using simulator now
OK, but this can be also consequence of the simulator not being perfect.
JW
2020-05-02 01:18 AM
The answer was hidden in the AppNote AN4776:
In STM32 microcontroller families, there are two DMA peripheral variants:
• The DMA burst transfer feature supported only by the STM32F2 products DMA
peripheral variant where the DMA peripheral can transfer a configurable number of
data elements next to a single data transfer trigger.
• In another variant, like the one on the STM32F1 products, the DMA peripheral variant
supports only single transfers; this means that only one data element is transferred
next to a data transfer trigger.
2020-05-02 01:53 AM
No.
While there are two different DMA IPs in various STM32 families, and the single-port DMA used in 'F1 is indeed not capable of AHB bursts, it's not the cause of your problem, as it's not related to AHB bursts.
There's another feature ST calls - in an unfortunate way, causing this kind of confusion - burst. Namely it's the mechanism where in timers, a single initial trigger source results in a series of triggers for DMA. This mechanism involves the TIMx_DCR/TIMx_DMRA registers, and this mechanism is present in the 'F1 - see what your line
TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_4Transfers);
does, and also see whether your 'F2 code sets any of the burst fields in the DMA control registers (it does not).
JW
2020-05-02 02:08 AM
That paragraph is about the DMA burst feature of the DMA peripheral.
Your program attempts to use the DMA burst feature of the timer peripheral, which is supported across all general and advanced timers on all STM32 products including the STM32F1 series.
As the very next paragraph makes it clear, there is no contradiction at all.
The information stated above aims to mitigate any misunderstanding of this feature and any possible confusion with the STM32 timer burst feature which makes the focus of this chapter.
There is even an example project showing the timer DMA burst feature of the STM32F103 among the example projects in the STM32F10x standard peripheral library distribution, see Project/STM32F10x_StdPeriph_Examples/TIM/DMABurst
2020-05-04 03:49 AM
Thank you all for your help. I finally got access to my board and to a real logic analyzer (thanks quarantine for all that wasted time hehe), The Tim DMA-burst feature works fine irl, problem was in the Keil's simulator.
2020-05-04 01:01 PM
Thanks for coming back with the solution.
>problem was in the Keil's simulator.
The 32-bitters are extraordinarily complex breasts, even the simplest of them is. It's next to impossible to build a faithful simulator.
JW