cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 TIM12 TRGO DAC DMA syncronization

Ersin Kuscu
Associate II

Hello,

I am trying to generate a pulse-triggered waveform continuously by using DAC and DMA in STM32H735RGV6. To do this, I have opened DAC OUT1 with the following configuration.

ErsinKuscu_0-1707732708749.png

After that, I set up the TIM12 with the following configuration and expected that the DAC output would be synchronous with the timer but I got nothing out of the DAC.

I am not sure about that I have done all the necessary things. I need help from the one who did the same thing or has the information on DAC synchronization with a timer pulse.

Could you help me on this?

Thanks

10 REPLIES 10
LCE
Principal

Check the timer settings, and debug to check if the timer is actually running (read the CNT register).

I am also producing a PWM signal to check that the timer is running. I can see that there is no problem with producing the PWM signal. I suppose that the timer is running.

Ersin Kuscu
Associate II

ErsinKuscu_0-1707738413890.png

ErsinKuscu_1-1707738440129.png

TIM12 Timer settings

Then check the DAC registers next.

I never used timer-triggered DAC on a H7,

here's some setup code for an F767, maybe you can compare anyway:

/**
  * @brief DAC Initialization Function
  * @PAram None
  * @retval None
  */
void DAC_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	/* Peripheral clock enable */
	__HAL_RCC_DAC_CLK_ENABLE();

	hdac.Instance = DAC;

	/**DAC GPIO Configuration
	PA4     ------> DAC_OUT1
	PA5     ------> DAC_OUT2
	*/
	GPIO_InitStruct.Pin 	= DAC1_OUTPUT_Pin | DAC2_OUTPUT_Pin;
	GPIO_InitStruct.Mode 	= GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull 	= GPIO_NOPULL;
	HAL_GPIO_Init(DAC12_OUTPUT_Port, &GPIO_InitStruct);

	/* DAC2 DMA Init */
	hdma_dac2.Instance = DMA1_Stream6;

	hdma_dac2.Init.Channel 				= DMA_CHANNEL_7;
	hdma_dac2.Init.Direction 			= DMA_MEMORY_TO_PERIPH;
	hdma_dac2.Init.PeriphInc 			= DMA_PINC_DISABLE;
	hdma_dac2.Init.MemInc 				= DMA_MINC_ENABLE;
	hdma_dac2.Init.PeriphDataAlignment 	= DMA_PDATAALIGN_HALFWORD;
	hdma_dac2.Init.MemDataAlignment 	= DMA_MDATAALIGN_HALFWORD;
	hdma_dac2.Init.Mode 				= DMA_CIRCULAR;
	hdma_dac2.Init.Priority 			= DMA_PRIORITY_MEDIUM;
	hdma_dac2.Init.FIFOMode 			= DMA_FIFOMODE_ENABLE;
	hdma_dac2.Init.FIFOThreshold 		= DMA_FIFO_THRESHOLD_FULL;
	hdma_dac2.Init.MemBurst 			= DMA_MBURST_SINGLE;
	hdma_dac2.Init.PeriphBurst 			= DMA_PBURST_SINGLE;
	if( HAL_DMA_Init(&hdma_dac2) != HAL_OK ) Error_Handler_FL(__FILE__, __LINE__);

	__HAL_LINKDMA(&hdac, DMA_Handle2, hdma_dac2);

	/* calculate sample rate, depends on timer 6 */
	flDAC2SampleRate = 2.0f * (float)HAL_RCC_GetPCLK1Freq() / (float)(u32Tim6Period + 1);

/* DAC 12bit TIM6 */
	HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 9, 0);
	HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
/* DAC 12bit DMA */
	/* DMA1_Stream6_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 9, 0);
	HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);

	/* DAC direct register settings */
	DAC->CR = 0;

	/* channel 1, enable only, DC output, no trigger, no DMA */
	DAC->CR |= DAC_CR_EN1;

	/* channel 2, enable, trigger timer 6 (only enable) - later: DMA, DMA underrun IE */
	/* started with DMA! */
}


#if DAC2_IS_USED
void DMA1_Stream6_IRQHandler(void)
{
	HAL_DMA_IRQHandler(&hdma_dac2);
}
#endif
TDK
Guru

Are you starting the DAC? Is the DAC working in any capacity? Show the relevant code.

If you feel a post has answered your question, please click "Accept as Solution".
LCE
Principal

Are you starting the DAC? Is the DAC working in any capacity? Show the relevant code.

Good point, that is something that CubeMX usually does not do for you.
You need something like this:

HAL_DMA_Start_IT(hdac.DMA_Handle2, (uint32_t)u16DAC2DataBuf, (uint32_t)&(DAC->DHR12R2), (uint32_t)u16DAC2BufLen)

 

Ersin Kuscu
Associate II

This is the relevant code for the DAC DMA start. 

HAL_DAC_Start_DMA(&hdac1, DAC1_CHANNEL_1, triang_val, N, DAC_ALIGN_12B_R);

Where triang_val is a triangular waveform.

If I do not use DMA request synchronization I can see the waveform on oscilloscope perfectly. 

> If I do not use DMA request synchronization I can see the waveform on oscilloscope perfectly. 

So probably the issue is your sync signal, TIM12_TRGO. You haven't shown any code related to that. What is configured as the TIM12_TRGO signal?

If you feel a post has answered your question, please click "Accept as Solution".

Exactly, I have configured DAC and DMA for TIM12_TRGO synchronization request but I didn't type any code to route TIM12_TRGO to DMA. Could you share a reference or an example of how to do that?