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

Did you check that the memory destination for the DMA is suitable? Because maybe your whole stack & globals (i.e. sine_val) are somewhere near 0x2000 0000, and that section is not accessible to the DMA on the H7 AFAICT!

In that case, you might need to modify the linker script a bit, and declare the variable accordingly

This goes into the linker script (after the .data section i'd suggest, but anywhere inside the SECTIONS {} block is fine).

RAM_D2 has to match with the name defined inside the MEMORY {} block (earlier in the file):

  /* D2 RAM accessible to DMA */
  .dma_d2_ram (NOLOAD) :
  {
    *(.dma_d2_ram)
  } >RAM_D2

Then you declare the buffer like this (you can access the values normally, but it won't be zero-initialized because of the NOLOAD; that would mean additional complexity in linker script and also need modifications to the startup code):

static __attribute__((section(".dma_d2_ram"))) uint32_t sine_val[100];

You can declare multiple values like this, everything will work as expected, those variables will just end up in the D2 RAM section but you can use them normally from C!