cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H723 Input capture timer over DMA using Low Layer

adakPal
Associate II

 

Hello STM Community,

 

I want to implement on STM32H723 ultrasonic sensor and I use TIM8 Input Capture mode to read time between falling edges. It worked on interrupts, but I want to use DMA in order prevent interrupt storm and to speed up calculations.  For such a purpose I want to use DMA1 Stream 0 for Channel 1 and Stream1 for Channel2. I configure it using Low Layer library:

#define CAPTURE_BUFFER_LENGTH 1

static uint16_t captureBufferCH1;
static uint16_t captureBufferCH2;

LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM8);
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOC);

GPIO_InitStruct.Pin = LL_GPIO_PIN_6 | LL_GPIO_PIN_7;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_3;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

TIM_InitStruct.Prescaler = (13750-1);
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = (UINT32_MAX - 1);
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
TIM_InitStruct.RepetitionCounter = 0;
LL_TIM_Init(TIM8, &TIM_InitStruct) != SUCCESS;

LL_TIM_SetClockSource(TIM8, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_GenerateEvent_UPDATE(TIM8);
LL_TIM_ClearFlag_UPDATE(TIM8);
LL_TIM_SetRemap(TIM8, LL_TIM_TIM8_TI1_RMP_GPIO);

LL_TIM_IC_SetActiveInput(TIM8, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
LL_TIM_IC_SetPrescaler(TIM8, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
LL_TIM_IC_SetFilter(TIM8, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
LL_TIM_IC_SetPolarity(TIM8, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_FALLING);

LL_TIM_IC_SetActiveInput(TIM8, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
LL_TIM_IC_SetPrescaler(TIM8, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
LL_TIM_IC_SetFilter(TIM8, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1);
LL_TIM_IC_SetPolarity(TIM8, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING);

LL_TIM_CC_EnableChannel(TIM8, LL_TIM_CHANNEL_CH1);
LL_TIM_CC_EnableChannel(TIM8, LL_TIM_CHANNEL_CH2);

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);

LL_DMA_SetPeriphRequest(DMA1, LL_DMA_STREAM_0, DMA_REQUEST_TIM8_CH1);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_0, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_0, LL_DMA_PRIORITY_HIGH);
LL_DMA_SetMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MEMORY_NOINCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_0, LL_DMA_MDATAALIGN_HALFWORD);
LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_0);

LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_0, (uint32_t)&(TIM8->CCR1));
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_0, (uint32_t)&captureBufferCH1);
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, CAPTURE_BUFFER_LENGTH);

LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);

LL_DMA_SetPeriphRequest(DMA1, LL_DMA_STREAM_1, DMA_REQUEST_TIM8_CH2);
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_HIGH);
LL_DMA_SetMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MEMORY_NOINCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_1, LL_DMA_MDATAALIGN_HALFWORD);
LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_1);

LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_1, (uint32_t)&(TIM8->CCR2));
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_1, (uint32_t)&captureBufferCH2);
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, CAPTURE_BUFFER_LENGTH);

LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1);

LL_TIM_EnableDMAReq_CC1(TIM8);
LL_TIM_EnableDMAReq_CC2(TIM8);

NVIC_SetPriority(DMA1_Stream1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0,0));
NVIC_EnableIRQ(DMA1_Stream1_IRQn);
NVIC_SetPriority(DMA1_Stream0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0,0));
NVIC_EnableIRQ(DMA1_Stream0_IRQn);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_STREAM_0);
LL_DMA_EnableIT_HT(DMA1, LL_DMA_STREAM_0);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_STREAM_1);
LL_DMA_EnableIT_HT(DMA1, LL_DMA_STREAM_1);
LL_TIM_EnableCounter(TIM8);

When using mentioned configuration  I enter DMA_Stream_TC interrupt first and DMA_Stream_TE interrupt straigth after . If I increase buffer size I don't enter any DMA interrupt. Do I have to initialize any peripherals like DMAMUX1? In this initialization values inside captureBufferCH1 and captureBufferCH2 have never changed.

2 REPLIES 2
SofLit
ST Employee

Hello @adakPal ,

Please in next time kindly use </>  button to share your code. I've edited your post then ..

You can review our tips on posting.

Thank you.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Sarra.S
ST Employee

Hello @adakPal

Please note that the STM32H723 uses DMAMUX to route DMA requests to the appropriate DMA channels,

so, DMAMUX1 needs to be configured to route the DMA requests to the appropriate DMA streams. 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.