2021-08-09 03:29 AM
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 */
}
2021-08-09 04:09 AM
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
2021-08-09 04:45 AM
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 */
}
}
2021-08-09 05:43 AM
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
2021-08-09 05:55 AM
DMA_REQUEST_DAC2 but initially you configured DAC1 ?
And where is config TIM6 ?
2021-08-09 06:01 AM
Can DMA access the memory used by sine_val?
https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices
2021-08-09 06:44 AM
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 */
2021-08-09 06:47 AM
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 */
}
}
2021-08-09 07:11 AM
Not sure. Might be worth trying to get a (very likely) known working example up and running.
2021-08-09 07:17 AM
DAC1 on H7 has 2 output, DAC1 ch 1 on PA4 and ch 2 on PA5.