AnsweredAssumed Answered

DMA triggering via Timer(Input capture mode)

Question asked by Pooya Alirezaei on Nov 4, 2017
Latest reply on Nov 4, 2017 by Clive One

I want to transfer some data between two microcontrollers via 16 lines of data and one clk line.

(Based on STM Application note AN4666 "Parallel synchronous transmition using GPIO and DMA").


I use two STM32f407 for this Application.
In transmitter side micro puts 16 bits of data on port when clk line goes high(Rising edge).
In receiver side I want to read 16 bits of data from Port when clk line goes high and put them

into Tx_Buff array via DMA.


I want when the rising edge of clk has been detected by Timer8-CH4(PC.9) -which configured in input capture mode-

it acts as DMA trigger for transmitting the 16 bits data to TX_Buff.
Finally I expect DMA Interrupt occurs when 750 transfers completed.

 

While testing, the Transmitter side works fine (clk and data) and I monitored them in Logic analayzer and the Timer works fine too, but the problem is DMA not triggering (I'm sure of it because I check the registers) so as follow, no interrupt occurs in receiver side.
This is my code.
Do you have any idea?

 

void Receiver_Config(void)
{
    GPIO_InitTypeDef gpioClk;
    GPIO_InitTypeDef gpioData;
    TIM_ICInitTypeDef icTIM;
    DMA_InitTypeDef dma;
    NVIC_InitTypeDef nvic;
    
    /* CLK - GPIO (PC.9) */
    /* ************************************************************************************************************* */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC , ENABLE);
    
    gpioClk.GPIO_Mode = GPIO_Mode_AF;
    gpioClk.GPIO_OType = GPIO_OType_OD;
    gpioClk.GPIO_Pin = GPIO_Pin_9;
    gpioClk.GPIO_PuPd = GPIO_PuPd_NOPULL;
    gpioClk.GPIO_Speed = GPIO_High_Speed;
    GPIO_Init(GPIOC , &gpioClk);
    GPIO_PinAFConfig(GPIOC , GPIO_PinSource9 , STU_CLK_GPIO_AF);
    /* ************************************************************************************************************* */
    
    /* Data - GPIO (PORT_E) */
    /* ************************************************************************************************************* */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE , ENABLE);
    
    gpioData.GPIO_Mode = GPIO_Mode_IN;
    gpioData.GPIO_OType = GPIO_OType_OD;
    gpioData.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6                                       | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 |                                         GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    gpioData.GPIO_PuPd = GPIO_PuPd_DOWN;
    gpioData.GPIO_Speed = GPIO_High_Speed;
    GPIO_Init(GPIOE , &gpioData);
    /* ************************************************************************************************************* */
    
    /* CLK - Timer */
    /* ************************************************************************************************************* */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8 , ENABLE);
    
    icTIM.TIM_Channel = TIM_Channel_4;
    icTIM.TIM_ICPolarity = TIM_ICPolarity_Rising;
    icTIM.TIM_ICSelection = TIM_ICSelection_DirectTI;
    icTIM.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    icTIM.TIM_ICFilter = 0;
    TIM_ICInit(TIM8 , &icTIM);
    
    TIM_SelectOutputTrigger(TIM8 , TIM_TRGOSource_Reset);
    TIM_DMAConfig(TIM8 , TIM_DMABase_CR1 , TIM_DMABurstLength_1Transfer);
    TIM_SelectCCDMA(TIM8 , ENABLE);
    TIM_DMACmd(TIM8 , TIM_DMA_Trigger , ENABLE);
    /* ************************************************************************************************************* */
    
    /* DMA : DMA2 Stream1 Channel7 */
    /* ************************************************************************************************************* */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);
    
    dma.DMA_BufferSize = 750;
    dma.DMA_Channel = DMA_Channel_7;
    dma.DMA_DIR = DMA_DIR_PeripheralToMemory;
    dma.DMA_FIFOMode = DMA_FIFOMode_Disable;
    dma.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    dma.DMA_Memory0BaseAddr = (uint32_t)&(Tx_Buff[0][0]);
    dma.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
    dma.DMA_Mode = DMA_Mode_Normal;
    dma.DMA_PeripheralBaseAddr = 0x40021014; /* GPIOE_ODR : GPIOE Output Data Register */
    dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    dma.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_Init(DMA2_Stream1 , &dma);
    
    DMA_ITConfig(DMA2_Stream1 , DMA_IT_TC ,  ENABLE);
    DMA_Cmd(DMA2_Stream1 , 750);
    /* ************************************************************************************************************* */
    
    /* DMA - Interrupt */
    /* ************************************************************************************************************* */
    nvic.NVIC_IRQChannel = DMA2_Stream1_IRQn;
    nvic.NVIC_IRQChannelCmd = ENABLE;
    nvic.NVIC_IRQChannelPreemptionPriority = 0;
    nvic.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&nvic);
    /* ************************************************************************************************************* */
}

 

void main(void)
{
    // Initialization
    Receiver_Config();
    while(1);
}

 

void DMA2_Stream1_IRQHandler(void)
{
    // TODO : Clear IT pending flags & etc
}

 

Looking forward hearing from you.
Best Regards.

Outcomes