AnsweredAssumed Answered

STM32F207 DMA PWM

Question asked by saponja.darko.001 on Nov 24, 2016
Latest reply on Nov 28, 2016 by saponja.darko.001
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...

CaptureAcePWM.PNG
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!

Outcomes