2014-12-02 09:10 AM
OK, I'm interfacing with a parallel bus that gives me 8 bits on an external clock pulse. I have working code with an interrupt and manually shuffling the data into memory, but I'd like to use a DMA approach, similar to
/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Data%20transfer%20from%20GPIO%20port%20to%20RAM%20buffer%20using%20DMA%20upon%20receiving%20a%20trigger%20signal%20on%20the%20timer%20capture%20input%20channel&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=2630
, where the code under discussion configures a timer to initiate DMA transfering from the GPIO IDR to a region of memory. Here are snippets from that code:void TIM1_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* TIM1 clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* TIM1 channel 1 pin (PA8) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); // PB3 TIM1_CH1
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
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(TIM1, &TIM_ICInitStructure);
TIM_CtrlPWMOutputs(TIM1, ENABLE); /* TIM Main Inputs/Output Enable */
TIM_Cmd(TIM1, ENABLE); /* TIM enable counter */
TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE ); /* Enable TIM1_CC1 DMA Requests */
}
void DMA2_Configuration(void)
{
/***************************************************************************************************************************************/
DMA_InitTypeDef DMA_InitStructure;
/* Enable the DMA clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* Configure the DMA Stream */
DMA_Cmd(DMA2_Stream6, DISABLE);
DMA_DeInit(DMA2_Stream6);
/* Set the parameters to be configured */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOC->IDR; /* Read fron GPIO input data register */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&GPIO_DATA[0]; /* Send the data to the RAM buffer */
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = BufferSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream6, &DMA_InitStructure);
/* Enable DMA Transfer Complete interrupt */
DMA_ITConfig(DMA2_Stream6, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA2_Stream6, ENABLE);
/***************************************************************************************************************************************/
}
The problem is, the above code doesn't use the HAL that I downloaded, so everything's completely different. I'm really confused about how to do this with the HAL.
How do I associate the DMA with the GPIO port? There's no ''DMA_PeripheralBaseAddr'' or ''DMA_Memory0BaseAddr'' when initializing the DMA.
Then, how do I associate the timer with the DMA channel? In the linked code from above, I'm not even quite sure where that connection is, but I don't see anything in UM1725 (Description of the HAL drivers) that connects the two.
I am new to the STM32s, so please be kind if I've just totally missed something. Thanks!
#i-can''t-help-you-with-that
2014-12-02 09:23 AM
The problem is, the above code doesn't use the HAL that I downloaded, so everything's completely different. I'm really confused about how to do this with the HAL.
Most of the pro's here aren't using it because it doesn't really solve their issues, just creates a bunch of new ones. No one is forcing you to adopt it, you can chose not too. I have no plans to rework it.2014-12-02 11:12 AM
I didn't realize that the non-HAL libraries were still supported and appropriate for use. Coming from other platforms, I've been trying to understand the STM32 ecosystem, and that detail had escaped me.
Thanks for clarifying that!2015-01-16 07:25 AM
Hi,
Can you please send back more information about the STM32 device and the FW package you are using ?I don't really have enough insight into what specifically you are doing, and how.Regards,Heisenberg.2015-01-16 07:46 AM
Figure:
STM32F4 8-bit port on GPIO bank C, bits 0 thru 7 : PC[0..7] External clock edge, or strobe (Think Centronics type parallel interface, or ADC with an EOC pulse) Clock caught by TIMx_CHx so as to generate DMA through internal trigger routing. Higher rate, perhaps 1-10 MHz so beyond realistic interrupt rate. Once you've worked a solution for that, then consider one where the TIM paces the output/input at a fixed rate. Think 8-bit DAC, or FPGA, where FSMC might be overkill, or pin limited, or otherwise in use.2015-01-16 07:53 AM
For that matter create it for all STM32 platforms, it's not an uncommon use case, and the STM32 design completely ignores the concept of external DMA triggering, ie DRQ/DACK of olden days.