2017-11-04 03:17 AM
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 theminto 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.2017-11-04 06:07 AM
>>
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