2019-03-17 05:19 AM
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?
Solved! Go to Solution.
2019-03-17 07:47 AM
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.
2019-03-17 06:41 AM
For debugging do use a timer output pin and wire it to the dac trigger input pin so you can check both stages.
2019-03-17 07:47 AM
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.