cancel
Showing results for 
Search instead for 
Did you mean: 

DMA triggering via Timer(Input capture mode)

Pooya Alirezaei
Associate
Posted on November 04, 2017 at 11:17

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?0690X00000604CAQAY.jpg

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.
1 REPLY 1
Posted on November 04, 2017 at 14:07

>>

Do you have any idea?

You want to trigger using TIM8_CC4, not TIM8_UP

Per Reference Manual that would be DMA2 Stream7 Channel7

dma.DMA_PeripheralBaseAddr

= (uint32_t)&GPIOE->IDR; // Input Address

Assuming PC9 is correct..

Set up timer properly

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); /* TIM8 clock enable */

TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; // TIM8_CC4

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 0x0;

TIM_ICInit(TIM8, &TIM_ICInitStructure);

TIM_CtrlPWMOutputs(TIM8, ENABLE); /* TIM Main Inputs/Output Enable */

TIM_Cmd(TIM8, ENABLE); /* TIM enable counter */

TIM_DMACmd(TIM8, TIM_DMA_CC4, ENABLE); /* Enable TIM8_CC4 DMA Requests */

Don't enable interrupt until the service routine is done

F4 GPIO+DMA+TIM External Trigger Example

https://community.st.com/thread/22634#comment-54386

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..