Skip to main content
Lars Beiderbecke
Senior III
March 17, 2019
Solved

Cannot get Cube DAC/TIM/DMA Signal Generation example working

  • March 17, 2019
  • 2 replies
  • 864 views

I've adapted the DAC signal generation example from the HAL samples to my project, but I cannot get any signal from DAC2.

Using CubeMX, I configured TIM6 and DMA1 like this:

/* Includes ------------------------------------------------------------------*/
#include "dac.h"
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
DAC_HandleTypeDef hdac;
DMA_HandleTypeDef hdma_dac2;
 
/* DAC init function */
void MX_DAC_Init(void)
{
 DAC_ChannelConfTypeDef sConfig = {0};
 
 /**DAC Initialization 
 */
 hdac.Instance = DAC;
 if (HAL_DAC_Init(&hdac) != HAL_OK)
 {
 Error_Handler();
 }
 /**DAC channel OUT2 config 
 */
 sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_2) != HAL_OK)
 {
 Error_Handler();
 }
 
}
 
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{
 
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 if(dacHandle->Instance==DAC)
 {
 /* USER CODE BEGIN DAC_MspInit 0 */
 
 /* USER CODE END DAC_MspInit 0 */
 /* DAC clock enable */
 __HAL_RCC_DAC_CLK_ENABLE();
 
 __HAL_RCC_GPIOA_CLK_ENABLE();
 /**DAC GPIO Configuration 
 PA5 ------> DAC_OUT2 
 */
 GPIO_InitStruct.Pin = GPIO_PIN_5;
 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 /* DAC DMA Init */
 /* DAC2 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_BYTE;
 hdma_dac2.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_dac2.Init.Mode = DMA_CIRCULAR;
 hdma_dac2.Init.Priority = DMA_PRIORITY_HIGH;
 hdma_dac2.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 if (HAL_DMA_Init(&hdma_dac2) != HAL_OK)
 {
 Error_Handler();
 }
 
 __HAL_LINKDMA(dacHandle,DMA_Handle2,hdma_dac2);
 
 /* DAC interrupt Init */
 HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 1, 0);
 HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
 /* USER CODE BEGIN DAC_MspInit 1 */
 
 /* USER CODE END DAC_MspInit 1 */
 }
}
 
void HAL_DAC_MspDeInit(DAC_HandleTypeDef* dacHandle)
{
 
 if(dacHandle->Instance==DAC)
 {
 /* USER CODE BEGIN DAC_MspDeInit 0 */
 
 /* USER CODE END DAC_MspDeInit 0 */
 /* Peripheral clock disable */
 __HAL_RCC_DAC_CLK_DISABLE();
 
 /**DAC GPIO Configuration 
 PA5 ------> DAC_OUT2 
 */
 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5);
 
 /* DAC DMA DeInit */
 HAL_DMA_DeInit(dacHandle->DMA_Handle2);
 
 /* DAC interrupt Deinit */
 /* USER CODE BEGIN DAC:TIM6_DAC_IRQn disable */
 /**
 * Uncomment the line below to disable the "TIM6_DAC_IRQn" interrupt
 * Be aware, disabling shared interrupt may affect other IPs
 */
 /* HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn); */
 /* USER CODE END DAC:TIM6_DAC_IRQn disable */
 
 /* USER CODE BEGIN DAC_MspDeInit 1 */
 
 /* USER CODE END DAC_MspDeInit 1 */
 }
} 
 
/* USER CODE BEGIN 1 */
 
/* USER CODE END 1 */
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

and

void MX_TIM6_Init(void)
{
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 
 htim6.Instance = TIM6;
 htim6.Init.Prescaler = 44898;
 htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim6.Init.Period = 21;
 htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 
}
 
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
 
 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();
 /* USER CODE BEGIN TIM2_MspInit 1 */
 
 /* USER CODE END TIM2_MspInit 1 */
 }
 else if(tim_baseHandle->Instance==TIM6)
 {
 /* USER CODE BEGIN TIM6_MspInit 0 */
 
 /* USER CODE END TIM6_MspInit 0 */
 /* TIM6 clock enable */
 __HAL_RCC_TIM6_CLK_ENABLE();
 
 /* TIM6 interrupt Init */
 HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 1, 0);
 HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
 /* USER CODE BEGIN TIM6_MspInit 1 */
 
 /* USER CODE END TIM6_MspInit 1 */
 }
}

TIM6 is configured to convert from 95 MHz peripheral bus clock to about 44.1 kHz. (I guess that's still pretty fast for only 6 values, but decreasing the frequency further didn't help.)

Then, I start signal generation:

const uint8_t aEscalator8bit[6] = {0x0, 0x33, 0x66, 0x99, 0xCC, 0xFF};
 
HAL_TIM_Base_Start(&htim6); // not sure if needed
if (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *)aEscalator8bit, 6, 
 DAC_ALIGN_8B_R) != HAL_OK)
 return error(1);

No error is returned. After this, I only get low-voltage noise on PA5, although I do hear a single click (and see a small spike unlike the desired signal) at the beginning.

The example has an interrupt handler DACx_DMA_IRQHandler(), which is not generated by Cube. Despite from that, I see no differences in code.

There might be lots of higher priority interrupts during signal generation, but I would assume to see at least something on the scope. Which part did I miss?

This topic has been closed for replies.
Best answer by Lars Beiderbecke

I think I got it now ... In above code,

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

is wrong, but this should have been UPDATE all along.

I guess I always had one of the many puzzle pieces wrong, but now everything works together.

2 replies

S.Ma
Principal
March 17, 2019

For debugging do use a timer output pin and wire it to the dac trigger input pin so you can check both stages.

Lars Beiderbecke
Lars BeiderbeckeAuthorBest answer
Senior III
March 17, 2019

I think I got it now ... In above code,

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

is wrong, but this should have been UPDATE all along.

I guess I always had one of the many puzzle pieces wrong, but now everything works together.