AnsweredAssumed Answered

APB1-TIM Inputcapture with DMA1 not working [solved]

Question asked by lx00n.sh on May 13, 2016
Latest reply on May 13, 2016 by lx00n.sh
Hello,

I tried to use the TIM2/3/4/5 Input-Capture with DMA ("TIM_DMA_CC1") to trigger a DMA-Transfer (this writes to a GPIO-Port for parallel Data-transmission) but it just Work with DMA2, not DMA1.
All (TIM2/3/4/5) APB1-Timer (with DMA1) didn't trigger a DMA-Transfer, but with the APB2-Timers TIM1 and TIM8 (with DMA2) will work correctly. (Yes , I checked the correct GPIO-Input-Pin by every Timer-change)
Can someone explain, why the DMA1 in the Reference under 10.3.3 have not working TIM mappings ?

Tried with STM32F407 and STM32F429 and got same results.

Code:
001.void setupParallelPort(){
002.    GPIO_InitTypeDef GPIO_InitStructure;
003. 
004.    // Enable the GPIOD
005.    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
006. 
007.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All ;
008.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
009.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
010.    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
011.    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
012.    GPIO_Init(GPIOD, &GPIO_InitStructure);
013. 
014.}
015. 
016.int main(void) {
017.    GPIO_InitTypeDef GPIO_InitStructure;
018.    TIM_ICInitTypeDef  TIM_ICInitStructure;
019.    DMA_InitTypeDef       DMA_InitStructure;
020.    NVIC_InitTypeDef NVIC_InitStructure;
021.    uint16_t testData[2048];
022. 
023.      /* write a Ramp for OutputData */
024.    for (ct = 0; ct < sizeof(testData)/sizeof(*testData); ct++) {
025.        testData[ct] = ct;
026.    }
027. 
028.    setupParallelPort();
029. 
030.    /* TIM5 clock enable */
031.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
032.    /* GPIOA clock enable */
033.    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
034.    // Clock Enable
035.    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
036. 
037. 
038.    /* PH10 == TIM5CH1 */
039.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;
040.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
041.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
042.    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
043.    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
044.    GPIO_Init(GPIOH, &GPIO_InitStructure);
045. 
046.    GPIO_PinAFConfig(GPIOH, GPIO_PinSource10, GPIO_AF_TIM5);
047. 
048.    /* ** IC-Pin ** */
049.    TIM_ICInitStructure.TIM_Channel     = TIM_Channel_1;
050.    TIM_ICInitStructure.TIM_ICFilter     = 0;
051.    TIM_ICInitStructure.TIM_ICPolarity     = TIM_ICPolarity_Rising;
052.    TIM_ICInitStructure.TIM_ICPrescaler     = TIM_ICPSC_DIV1;
053.    TIM_ICInitStructure.TIM_ICSelection     = TIM_ICSelection_DirectTI;
054.    TIM_ICInit(TIM5,&TIM_ICInitStructure);
055. 
056.    // DMA-Disable
057.    DMA_Cmd(DMA1_Stream2, DISABLE);
058.    // warten bis DMA-Stream disable
059.    while(DMA_GetCmdStatus(DMA1_Stream2) == ENABLE);
060.    DMA_DeInit(DMA1_Stream2);
061. 
062.    // DMA-Config
063.    DMA_StructInit(&DMA_InitStructure);
064.    DMA_InitStructure.DMA_Channel = DMA_Channel_6;
065.    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOD->ODR;
066.    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)testData;
067.    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
068.    DMA_InitStructure.DMA_BufferSize = sizeof(testData)/sizeof(*testData);
069.    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
070.    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
071.    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
072.    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
073.    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
074.    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
075.    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
076.    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
077.    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
078.    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
079.    DMA_Init(DMA1_Stream2, &DMA_InitStructure);
080. 
081.      // clear the DMA-Flag
082.    DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF6);
083. 
084.      // DMA-enable
085.    DMA_Cmd(DMA1_Stream2, ENABLE);
086.    while(DMA_GetCmdStatus(DMA1_Stream2) == DISABLE);
087. 
088.      // NVIC-Config
089.    DMA_ITConfig(DMA1_Stream2, DMA_IT_TC , ENABLE);
090.    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;
091.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
092.    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
093.    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
094.    NVIC_Init(&NVIC_InitStructure);
095. 
096. 
097.    TIM_DMACmd(TIM5,TIM_DMA_CC1,ENABLE);
098.}
099. 
100.void DMA1_Stream2_IRQHandler(){
101.    printf("interrupt ...");//DEBUG: this will never executed
102.    if (DMA_GetFlagStatus(DMA1_Stream2,DMA_FLAG_TCIF6) == SET){
103.        TIM_Cmd(TIM5, DISABLE);
104.        DMA_Cmd(DMA1_Stream2, DISABLE);
105.        DMA_ClearITPendingBit(DMA1_Stream2,DMA_FLAG_TCIF6);
106.    }
107.}

Outcomes