2016-11-24 01:06 PM
Hi,
I'm using STM32F207 and I would like to trigger DMA transfer on the falling edge of the PWM (duty cycle). So, I have configured TIM1 in PWM mode and enabled CC1DE and CCDS bits. uint8_t outBuffer[16] = {0}; int main(void) { RCC_ClocksTypeDef clocks; RCC_GetClocksFreq(&clocks); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitTypeDef gpioStruct; GPIO_StructInit(&gpioStruct); gpioStruct.GPIO_Mode = GPIO_Mode_OUT; gpioStruct.GPIO_Pin = GPIO_Pin_All; gpioStruct.GPIO_OType = GPIO_OType_PP; gpioStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; gpioStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOE, &gpioStruct); gpioStruct.GPIO_Pin = GPIO_Pin_9; gpioStruct.GPIO_Mode = GPIO_Mode_AF; gpioStruct.GPIO_OType = GPIO_OType_PP; gpioStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; gpioStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &gpioStruct); /* Connect TIM1 pins to AF */ GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1); for (uint32_t i = 0; i < 15; i+=2) { outBuffer[i] = 0xAAAA; outBuffer[i+1] = ~0xAAAA; } TIM1_Config(100000); DMA2_Config(); while(1) { if(TIM_GetFlagStatus(TIM1, TIM_FLAG_CC1) == SET) { GPIO_ToggleBits(GPIOE, GPIO_Pin_14); TIM_ClearFlag(TIM1, TIM_FLAG_CC1); } } } void DMA2_Config(void) { DMA_InitTypeDef DMAInitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE); DMA_DeInit(DMA2_Stream1); DMAInitStruct.DMA_Channel = DMA_Channel_6; DMAInitStruct.DMA_PeripheralBaseAddr = (uint32_t)(GPIOE_BASE) + 0x14; DMAInitStruct.DMA_Memory0BaseAddr = (uint32_t)&outBuffer; DMAInitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMAInitStruct.DMA_BufferSize = 16; DMAInitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMAInitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMAInitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMAInitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMAInitStruct.DMA_Mode = DMA_Mode_Circular; DMAInitStruct.DMA_Priority = DMA_Priority_High; DMAInitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; DMAInitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMAInitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMAInitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream1, &DMAInitStruct); TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE); DMA_Cmd(DMA2_Stream1, ENABLE); TIM_Cmd(TIM1, ENABLE); } But what I get is the DMA transfer triggerd on the Update event... Chanel0...PWM output Chanel2... one of the GPIO bits controlled by the DMA Chanel3... toggle pin on CC1IF set Why is DMA transfer triggered on the Update and not on the Compare event? What am I doing wrong? Thanks! #stm32f2-dma-pwm2016-11-24 04:08 PM
Post the content of timer registers.
JW2016-11-28 10:17 AM
Sorry for the delay, I didn't have the board by my side for a few days...
Here is the content of the TIM1 registers right before enabling the timer2016-11-28 11:30 AM
> CCDS 0x01
Don't. Bit 3 CCDS: Capture/compare DMA selection 0: CCx DMA request sent when CCx event occurs 1: CCx DMA requests sent when update event occurs JW2016-11-28 11:33 AM
I see the source of your confusion.
17.3.9 Output compare modeWhen a match is found between the capture/compare register and the counter, the output
compare function:
[...]
Sends a DMA request if the corresponding enable bit is set (CCxDE bit in the
TIMx_DIER register, CCDS bit in the TIMx_CR2 register for the DMA request
selection).
Very badly formulated, but sadly it's no surprise. JW
2016-11-28 02:04 PM
excellent observation :)
thanks, it works now... btw CCDS basically excludes triggering DMA transfer on CC and Update which means that one can't trigger two different streams with one timer? For example if I would like to trigger two DMA transfers, one on the falling end and the other on the rising edge of a PWM (CC and Update) is it feasible with one timer? Doesn't look so...