cancel
Showing results for 
Search instead for 
Did you mean: 

DAC with DMA not working for STM32H753VIT6

TPanc.1
Associate II

Hi there,

Here is the code for DAC with DMA. I can not see the error in the code. I have been looking at the oscilloscope for the sine wave but it is not coming. I tried without DMA, and works nice. But the DAC with DMA is not working. Please someone guide me. Thanks.

/* USER CODE BEGIN PV */

uint32_t sine_val[100];

/* USER CODE END PV */

/* USER CODE BEGIN PFP */

void get_sineval(void);

/* USER CODE END PFP */

int main(void)

{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */

 SystemClock_Config();

/* Configure the peripherals common clocks */

 PeriphCommonClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */

 MX_GPIO_Init();

 MX_DMA_Init();

 MX_ADC1_Init();

 MX_ADC3_Init();

 MX_DAC1_Init();

 MX_I2C1_Init();

 MX_SPI1_Init();

 MX_SPI2_Init();

 MX_SPI3_Init();

 MX_SPI4_Init();

 MX_UART4_Init();

 MX_UART5_Init();

 MX_TIM1_Init();

 MX_TIM6_Init();

 /* USER CODE BEGIN 2 */

 if (HAL_TIM_Base_Start(&htim6) != HAL_OK)

 Error_Handler();

 get_sineval();

 if (HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t *)sine_val, 100, DAC_ALIGN_12B_R) != HAL_OK)

 Error_Handler();

 /* USER CODE END 2 */

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

 }

 /* USER CODE END 3 */

}

void get_sineval()

{

for (int i=0;i<100;i++)

{

sine_val[i] = ((sin(i*2*pi/100)+1)*(4096/2));

}

}

Also, find the driver for DAC and Timer6 as below:

void MX_TIM6_Init(void)

{

 /* USER CODE BEGIN TIM6_Init 0 */

 /* USER CODE END TIM6_Init 0 */

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 /* USER CODE BEGIN TIM6_Init 1 */

 /* USER CODE END TIM6_Init 1 */

 htim6.Instance = TIM6;

 htim6.Init.Prescaler = 96-1;

 htim6.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim6.Init.Period = 100-1;

 htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_Base_Init(&htim6) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM6_Init 2 */

 /* USER CODE END TIM6_Init 2 */

}

void MX_DAC1_Init(void)

{

 /* USER CODE BEGIN DAC1_Init 0 */

 /* USER CODE END DAC1_Init 0 */

 DAC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN DAC1_Init 1 */

 /* USER CODE END DAC1_Init 1 */

 /** DAC Initialization

 */

 hdac1.Instance = DAC1;

 if (HAL_DAC_Init(&hdac1) != HAL_OK)

 {

  Error_Handler();

 }

 /** DAC channel OUT2 config

 */

 sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;

 sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;

 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;

 sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;

 sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;

 if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN DAC1_Init 2 */

 /* USER CODE END DAC1_Init 2 */

}

10 REPLIES 10
AbidSulaiman
Associate III

Hi,

is the DMA configured correctly, connected to the DAC?

I am not really familiar with DAC and your microcontroller, but from the MX_DAC1_Init(), I didn't see the DMA Enable bit being set.

Note: Please use the code snippet feature. It makes the reading easier (at least for me).

Regards

TPanc.1
Associate II

Hi, I have tried initializing the void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle) function within the MX_DAC1_init() function. But still does not work. Please let me know if you found some thing more.

DAC_HandleTypeDef hdac1;
DMA_HandleTypeDef hdma_dac1_ch2;
 
/* DAC1 init function */
void MX_DAC1_Init(void)
{
 
  /* USER CODE BEGIN DAC1_Init 0 */
 
  /* USER CODE END DAC1_Init 0 */
 
  DAC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN DAC1_Init 1 */
 
  /* USER CODE END DAC1_Init 1 */
  /** DAC Initialization
  */
  hdac1.Instance = DAC1;
  if (HAL_DAC_Init(&hdac1) != HAL_OK)
  {
    Error_Handler();
  }
  /** DAC channel OUT2 config
  */
  sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
  sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
  sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
  sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
  if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN DAC1_Init 2 */
  HAL_DAC_MspInit(&hdac1);
  /* USER CODE END DAC1_Init 2 */
 
}
 
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(dacHandle->Instance==DAC1)
  {
  /* USER CODE BEGIN DAC1_MspInit 0 */
 
  /* USER CODE END DAC1_MspInit 0 */
    /* DAC1 clock enable */
    __HAL_RCC_DAC12_CLK_ENABLE();
 
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**DAC1 GPIO Configuration
    PA5     ------> DAC1_OUT2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    /* DAC1 DMA Init */
    /* DAC1_CH2 Init */
    hdma_dac1_ch2.Instance = DMA1_Stream0;
    hdma_dac1_ch2.Init.Request = DMA_REQUEST_DAC2;
    hdma_dac1_ch2.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_dac1_ch2.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_dac1_ch2.Init.MemInc = DMA_MINC_ENABLE;
    hdma_dac1_ch2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_dac1_ch2.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_dac1_ch2.Init.Mode = DMA_CIRCULAR;
    hdma_dac1_ch2.Init.Priority = DMA_PRIORITY_LOW;
    hdma_dac1_ch2.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_dac1_ch2) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(dacHandle,DMA_Handle2,hdma_dac1_ch2);
 
    /* DAC1 interrupt Init */
    HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
  /* USER CODE BEGIN DAC1_MspInit 1 */
 
  /* USER CODE END DAC1_MspInit 1 */
  }
}

Hi,

I think HAL_DAC_MspInit() is called within the HAL_DAC_Init() function.

I think I see nothing wrong with the code. So maybe check your hardware or circuit again.

Sorry that i could not help you further. Good luck.

Regards

MasterT
Senior III

DMA_REQUEST_DAC2 but initially you configured DAC1 ?

And where is config TIM6 ?

TDK
Guru

Can DMA access the memory used by sine_val?

https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

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

I did something like this to clean the cache. But no change. The DMA and DAC both are in D2 region. I am not sure whether to move further in this direction.

  /* USER CODE BEGIN 2 */
  /* Clean D-cache */
  /* Make sure the address is 32-byte aligned and add 32-bytes to length, in case it overlaps cacheline */
  SCB_CleanDCache_by_Addr((uint32_t*)(((uint32_t)sine_val) & ~(uint32_t)0x1F), 100);
//  HAL_DAC_Start(&hdac1, DAC_CHANNEL_2);	//un-comment incase of polling technique/without DMA
  get_sineval();
  if (HAL_TIM_Base_Start(&htim6) != HAL_OK)
	  Error_Handler();
 
__DSB(); 
  if (HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t *)sine_val, 100, DAC_ALIGN_12B_R) != HAL_OK)
	  Error_Handler();
 
  /* USER CODE END 2 */

Here is the initialization function for TIM6. Sorry that I am putting everything bit by bit. And, yes. I do not know why the CubeMX is generating DMA_REQUEST_DAC2. I updated it to DMA_REQUEST_DAC. But the status remains the same. No sine wave.

void MX_TIM6_Init(void)
{
 
  /* USER CODE BEGIN TIM6_Init 0 */
 
  /* USER CODE END TIM6_Init 0 */
 
  TIM_MasterConfigTypeDef sMasterConfig = {0};
 
  /* USER CODE BEGIN TIM6_Init 1 */
 
  /* USER CODE END TIM6_Init 1 */
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 96-1;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 100-1;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM6_Init 2 */
  HAL_TIM_Base_MspInit(&htim6);
  /* USER CODE END TIM6_Init 2 */
 
}
 
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
 
  if(tim_baseHandle->Instance==TIM1)
  {
  /* USER CODE BEGIN TIM1_MspInit 0 */
 
  /* USER CODE END TIM1_MspInit 0 */
    /* TIM1 clock enable */
    __HAL_RCC_TIM1_CLK_ENABLE();
  /* USER CODE BEGIN TIM1_MspInit 1 */
 
  /* USER CODE END TIM1_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();
  /* USER CODE BEGIN TIM6_MspInit 1 */
 
  /* USER CODE END TIM6_MspInit 1 */
  }
}

Not sure. Might be worth trying to get a (very likely) known working example up and running.

https://github.com/STMicroelectronics/STM32CubeH7/blob/ccb11556044540590ca6e45056e6b65cdca2deb2/Projects/STM32H743I-EVAL/Examples/DAC/DAC_SignalsGeneration/Src/main.c

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

DAC1 on H7 has 2 output, DAC1 ch 1 on PA4 and ch 2 on PA5.