2025-12-09 3:02 AM
Hardware Platform: STM32H750XBH6
Software: MDK + CubeMX FW_H7_V1.12.1
github: https://github.com/Q-DEBUG/DMAMUX.git
Background: The timers TIM12/LPTIM1/2/3 used by DMAMUX1/2 to generate synchronization/trigger signals for H7 peripherals are all 16-bit, resulting in low precision. To improve precision and facilitate jitter compensation (testing shows a deviation of approximately 0.3ms–0.5ms per second), I intend to use the internal 32-bit timer peripheral TIM2.
The entire chain is divided into two parts:
Part 1: DMAMUX1-CH0, using direct mode (without any synchronization signal), maps the TIM2_UP event to HAL_DMAMUX1_SYNC_DMAMUX1_CH0_EVT.
Part 2: DMAMUX1-CH1, using synchronization trigger mode , uses HAL_DMAMUX1_SYNC_DMAMUX1_CH0_EVT as the synchronization signal to trigger UART4_TX.
My current test involves modifying the original LPTIM2-triggered UART periodic output routine by changing HAL_DMAMUX1_SYNC_LPTIM2_OUT to HAL_DMAMUX1_SYNC_DMAMUX1_CH0_EVT. At present, I can only observe that Timer 2 is running normally, but the UART does not output signals periodically. Since events are cleared by hardware, it is difficult for me to observe whether HAL_DMAMUX1_SYNC_DMAMUX1_CH0_EVT is effectively generated for further troubleshooting. Therefore, I am seeking assistance.
After reviewing the manual, the register status and event generation timing diagram appear to be the same.
Key code is as follows:
uint8_t UART_BUF1[]="1:hello world\r\n";
uint8_t UART_BUF2[]="2:hello world\r\n";
HAL_DMAEx_MultiBufferStart(&hdma_uart4_tx, UART_BUF1, &huart4.Instance->TDR, UART_BUF2,sizeof(UART_BUF1));
ATOMIC_SET_BIT(huart4.Instance->CR3, USART_CR3_DMAT);
HAL_LPTIM_Counter_Start(&hlptim2,37500-1);
HAL_TIM_Base_Start(&htim2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
HAL_DMA_MuxSyncConfigTypeDef pSyncConfig= {0};
if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspInit 0 */
/* USER CODE END TIM2_MspInit 0 */
/* TIM2 clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();
/* TIM2 DMA Init */
/* TIM2_UP Init */
hdma_tim2_up.Instance = DMA1_Stream0;
hdma_tim2_up.Init.Request = DMA_REQUEST_TIM2_UP;
hdma_tim2_up.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim2_up.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim2_up.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim2_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim2_up.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim2_up.Init.Mode = DMA_NORMAL;
hdma_tim2_up.Init.Priority = DMA_PRIORITY_LOW;
hdma_tim2_up.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_tim2_up) != HAL_OK)
{
Error_Handler();
}
pSyncConfig.SyncSignalID = HAL_DMAMUX1_SYNC_EXTI0;
pSyncConfig.SyncPolarity = HAL_DMAMUX_SYNC_NO_EVENT;
pSyncConfig.SyncEnable = DISABLE;
pSyncConfig.EventEnable = ENABLE;
pSyncConfig.RequestNumber = 1;
if (HAL_DMAEx_ConfigMuxSync(&hdma_tim2_up, &pSyncConfig) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(tim_baseHandle,hdma[TIM_DMA_ID_UPDATE],hdma_tim2_up);
/* USER CODE BEGIN TIM2_MspInit 1 */
// SET_BIT(DMAMUX1_Channel0->CCR,DMAMUX_CxCR_SYNC_ID_1 | DMAMUX_CxCR_SYNC_ID_2);
// SET_BIT(DMAMUX1_Channel0->CCR,DMAMUX_CxCR_SPOL_0);
// SET_BIT(DMAMUX1_Channel0->CCR,DMAMUX_CxCR_SE);
// SET_BIT(DMAMUX1_Channel0->CCR,DMAMUX_CxCR_SOIE);
SET_BIT(DMAMUX1_Channel0->CCR,DMAMUX_CxCR_EGE);
/* USER CODE END TIM2_MspInit 1 */
}
}