Skip to main content
Graduate
December 10, 2024
Solved

STM32H723 Input capture timer over DMA using Low Layer

  • December 10, 2024
  • 2 replies
  • 994 views

 

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.

    This topic has been closed for replies.
    Best answer by Sarra.S

    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. 

    2 replies

    Technical Moderator
    December 10, 2024

    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.

    Sarra.SAnswer
    ST Employee
    December 11, 2024

    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.