cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Interface with FSMC and DMA

ginnikhanna27
Associate II
Posted on March 21, 2012 at 12:56

Hi,

I have to read a 15 bit parallel data coming from a camera sensor and one bit as a request signal which tells whether the micrcontroller should initiate memory transfer or not.

Does FSMC has any trigger signal within itself so that I dont want to use any external interrupt or timer to trigger the transfer ?

Please help me out.
34 REPLIES 34
ginnikhanna27
Associate II
Posted on April 12, 2012 at 10:56

Each pulse should initiate a 15 bit transfer at one go from GPIOE IDR to SRAM

ginnikhanna27
Associate II
Posted on April 12, 2012 at 14:16

NEW UPDATE!!

My DMA transfer is working on external clock and the counter is counting on external pulse. However it is transferring only the data from the registers related to TIMERS to the SRAM, but not from GPIO!

Posted on April 12, 2012 at 19:22

So your GPIOE bus is only 8-bits wide? I thought you said it was 15-bit parallel. You've also set the DMA to transfer 8-bit bytes, this is not correlating with what you say you need.

As the GPIO is on the AHB, not APB1 or APB2, the memory-to-memory mode would probably be the next thing to try. Again you'll probably need to review the matrix in the manual to confirm if it routes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ginnikhanna27
Associate II
Posted on April 13, 2012 at 13:14

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6at&d=%2Fa%2F0X0000000brL%2F187wyi47aSJ_2m_rvyoYVCpxNciLQZdLQJT0gX8AvlQ&asPdf=false
firatparlak
Associate II
Posted on June 10, 2013 at 16:38

Hello,

I have a similar problem. I want to put the datas which are in the SRC_Buffer to the GPIOE via DMA. An external 8Khz clock comes to pin0 of GPIOB port. I want to trigger DMA with the external clock so I'm trying to use Timer in input capture mode. Would you kindly help me, please? Where is(are) the problem(s)? Microcontroller is STM32F207VC

#define BPLTx_DMA DMA2
#define BPLTx_DMA_CLK RCC_AHB1Periph_DMA2
//BPLTxDMA definitions //firat
#define BPLTx_DMA_STREAM DMA2_Stream1
#define BPLTx_DMA_CHANNEL DMA_Channel_0
#define BPLTx_DMA_FLAG_FEIF DMA_FLAG_FEIF1
#define BPLTx_DMA_FLAG_DMEIF DMA_FLAG_DMEIF1
#define BPLTx_DMA_FLAG_TEIF DMA_FLAG_TEIF1
#define BPLTx_DMA_FLAG_HTIF DMA_FLAG_HTIF1
#define BPLTx_DMA_FLAG_TCIF DMA_FLAG_TCIF1
#define BPLTx_DMA_IRQn DMA2_Stream1_IRQn
#define BPLTx_DMA_IRQHANDLER DMA2_Stream1_IRQHandler 
#define BPLTx_DMA_PREPRIO 0
#define BPLTx_DMA_SUBPRIO 0 
//BPLRxDMA definitions //firat
#define BPLRx_DMA_STREAM DMA2_Stream3
#define BPLRx_DMA_CHANNEL DMA_Channel_3
#define BPLRx_DMA_FLAG_FEIF DMA_FLAG_FEIF3
#define BPLRx_DMA_FLAG_DMEIF DMA_FLAG_DMEIF3
#define BPLRx_DMA_FLAG_TEIF DMA_FLAG_TEIF3
#define BPLRx_DMA_FLAG_HTIF DMA_FLAG_HTIF3
#define BPLRx_DMA_FLAG_TCIF DMA_FLAG_TCIF3
#define BPLRx_DMA_IRQn DMA2_Stream3_IRQn
#define BPLRx_DMA_IRQHANDLER DMA2_Stream3_IRQHandler
#define GPIOD_IDR_ADDRESS ((uint32_t)0x40020C10) //GPIOD input data register address
#define GPIOD_ODR_ADDRESS ((uint32_t)0x40020C14) //GPIOD output data register address
#define GPIOE_IDR_ADDRESS ((uint32_t)0x40021010) //GPIOE input data register address
#define GPIOE_ODR_ADDRESS ((uint32_t)0x40021014) //GPIOE output data register address
uint16_t SRC_Buffer[256];
uint16_t destAddress[256];
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured to 
120 MHz, this is done through SystemInit() function which is called from
startup file (startup_stm32f2xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f2xx.c file
*/
uint32_t i;
#ifdef SERIAL_DEBUG
DebugComPort_Init();
#endif
//initialize array
for (i=0; i<256;i++)
SRC_Buffer[i]=1;
/*Initialize LCD and Leds */ 
LCD_LED_Init();
/* Initializes peripherals used by the I2C EEPROM driver. */
sEE_Init(); //firat
GPIO_ResetBits(GPIOD, GPIO_Pin_0); //Clears the BPL_CLK_CNT pin //sets this pin as '0'.
TimerInit();
#ifdef USE_DHCP
/* Start DHCPClient */
xTaskCreate(LwIP_DHCP_task, ''DHCPClient'', configMINIMAL_STACK_SIZE * 2, NULL,DHCP_TASK_PRIO, NULL);
#endif
xTaskCreate(ToggleLedDbg, ''LEDDBG'', configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL); //firat
/* Start scheduler */
vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler */
for( ;; );
}
void TimerInit(void)
{
/* TIM3 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
/* GPIOC clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* TIM8 channel 2 pin (PB.0) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM pins to AF2 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM8);
//Enable the TIM1 global Interrupt
NVIC_InitStructure_.NVIC_IRQChannel = TIM8_CC_IRQn;
NVIC_InitStructure_.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure_.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure_.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure_);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
DMA_DeInit(DMA2_Stream2);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = GPIOE_ODR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)SRC_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream2, &DMA_InitStructure);
// Configure Channel 2 for external signal//
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
//External clock mode 1 configured//
TIM_ETRClockMode1Config(TIM8, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);
TIM_SelectInputTrigger(TIM8, TIM_TS_TI2FP2);
TIM_ICInit(TIM8, &TIM_ICInitStructure);
TIM_DMACmd(TIM8,TIM_DMA_CC2,ENABLE);
DMA_Cmd(DMA2_Stream2, ENABLE);
/* TIM enable counter */
TIM_Cmd(TIM8, ENABLE);
// Enable the Timer 2 Interrupt Request */
TIM_ITConfig(TIM8, TIM_IT_CC2, ENABLE);
}
void TIM8_CC_IRQHandler()
{
TIM_ClearFlag(TIM8, TIM_FLAG_CC2);
}

firatparlak
Associate II
Posted on June 10, 2013 at 17:17

I also forgot to write GPIOE_Config() function in the project. The code is:

int main(void)
{
uint32_t i;
//initialize array
for (i=0; i<256;i++)
SRC_Buffer[i]=1;
/*Initialize LCD and Leds */ 
LCD_LED_Init();
/* Initializes peripherals used by the I2C EEPROM driver. */
sEE_Init(); //firat
GPIO_ResetBits(GPIOD, GPIO_Pin_0); //Clears the BPL_CLK_CNT pin //sets this pin as '0'.
GPIOE_Config(); 
TimerInit();
xTaskCreate(ToggleLedDbg, ''LEDDBG'', configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL); //firat
/* Start scheduler */
vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler */
for( ;; );
}

Posted on June 10, 2013 at 19:19

PB0 is not connected to TIM8_CH2, it's connected to the inverse channel (CH2N), you want PC7 or PI6 for that.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
firatparlak
Associate II
Posted on June 11, 2013 at 10:05

Thank you for the answer, Clive. 

I change the pin from PB.0 to PA.9 and this works for the TIM1_CH2. Now, I want to ask you another question. Can I use any of the timers of TIM3_CH3 / TIM8_CH2N / TIM1_CH2N(referenced to datasheet) for PB.0? 

Can not inverse channel be used as input capture mode and triggering DMA? Or any other timer except TIM1 and TIM8 can be used? In the startup_stm32f2xx.s file, there are 

TIM1_CC_IRQHandler 

TIM8_CC_IRQHandler

TIM2_IRQHandler                                                           

TIM3_IRQHandler                                                           

TIM4_IRQHandler, etc.

Can I use only TIM1_CC_IRQHandler and TIM8_CC_IRQHandler for the input capture mode or can I select other timers(TIM2, 3, 4 , ..) ? 

firatparlak
Associate II
Posted on June 12, 2013 at 15:15

Can I use TIM3 for ''input capture'' from PB.0 pin?

void Timer3Init(void)
{ 
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* TIM3 channel 3 pin (PB.0) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM pins to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);
//Enable the TIM1 global Interrupt
NVIC_InitStructure_.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure_.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure_.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure_.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure_);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
DMA_DeInit(DMA1_Stream7);
DMA_InitStructure.DMA_Channel = DMA_Channel_5;
DMA_InitStructure.DMA_PeripheralBaseAddr = GPIOE_ODR_ADDRESS; //GPIOE_IDR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)SRC_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 256; //1
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream7, &DMA_InitStructure); 
// Configure Channel 2 for external signal//
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; 
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
//External clock mode 1 configured//
TIM_ETRClockMode1Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);
TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);
TIM_ICInit(TIM3, &TIM_ICInitStructure); 
TIM_DMACmd(TIM3,TIM_DMA_CC3,ENABLE); 
TIM_SelectCCDMA(TIM3, ENABLE);
DMA_Cmd(DMA1_Stream7, ENABLE);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
// Enable the Timer 2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC3, ENABLE); 
}

firatparlak
Associate II
Posted on June 12, 2013 at 15:16