STM32F756 use TIMER event DMA from GPIO to Memory
Hello,
now I will record 32 GPIO's via DMA for the analyse. The DMA itself shall triggered with a timer.
So first I have found different information to solve this. So I have tested some solution, but on the STM32F756 will it not run.
My solution is: GPIOD and GPIOE tranfer with two DMA streams to an public array. After the DMA transmition complete I will start the ISR to switch the buffer.
At the moment, the DMA transfer is not started. The timer runs, but the NTDR register is not changed.
Here my configuration for the DMA and timer:
/* DMA1 inititialisation */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
NVIC_SetPriority(DMA1_Stream1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA1_Stream1_IRQn);
NVIC_SetPriority(DMA1_Stream2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA1_Stream2_IRQn);
/* TIM2 initialisation */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_1, LL_DMA_CHANNEL_3);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_1, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MODE_NORMAL);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_WORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_1, LL_DMA_MDATAALIGN_WORD);
LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_1);
LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_1, (uint32_t)&GPIOD->IDR);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_STREAM_1);
LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_1, LL_DMA_CHANNEL_3);
TIM_InitStruct.Prescaler = 11;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 588;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM2, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM2);
LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE);
LL_TIM_DisableMasterSlaveMode(TIM2);
LL_TIM_CC_SetDMAReqTrigger(TIM2, LL_TIM_CCDMAREQUEST_UPDATE);
LL_TIM_EnableCounter(TIM2);
/* TIM3 initialisation */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_2, LL_DMA_CHANNEL_5);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_2, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_2, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA1, LL_DMA_STREAM_2, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_2, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_2, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_2, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_2, LL_DMA_MDATAALIGN_HALFWORD);
LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_2);
TIM_InitStruct.Prescaler = 11;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 588;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM3, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM3);
LL_TIM_SetClockSource(TIM3, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_UPDATE);
LL_TIM_DisableMasterSlaveMode(TIM3);
LL_TIM_CC_SetDMAReqTrigger(TIM3, LL_TIM_CCDMAREQUEST_UPDATE);
LL_TIM_EnableCounter(TIM3);
/* start transfer */
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, 10);
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_1,(uint32_t)bufferA);
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_2, 10);
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_2,(uint32_t)bufferB);
LL_DMA_ClearFlag_TC1(DMA1);
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1);
LL_DMA_ClearFlag_TC2(DMA1);
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_2);
So I've read in the web different information and it is unclair why or what is correct:
- using transfer direction priphery to memory and/or memory to memory
- using of DMA2 instead of DMA1
Have everyone an idee why it is not work?
Thanks for our help,
Bernd
