I can't get the DAC to extract values from the buffer with DMA.
I have only been able to get it to output individual values without DMA.
ChatGPT does not help either.
dac.c:
#include <ctype.h>
#include "main.h"
#include "dac.h"
uint16_t dac1_buff[DAC1_BUFF_SIZE];
uint16_t dac2_buff[DAC2_BUFF_SIZE];
void dac1_dma_init(void) {
/*
* DAC Initialization
*/
// Configure PA4 for analog output
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// Configure DAC1
__HAL_RCC_DAC1_CLK_ENABLE();
DAC_HandleTypeDef hdac1;
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK) {
dac_Error_Handler();
}
/*
* DAC channel OUT1 config
*/
DAC_ChannelConfTypeDef sConfig = { 0 };
sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC;
sConfig.DAC_DMADoubleDataMode = DISABLE;
sConfig.DAC_SignedFormat = DISABLE;
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_T2_TRGO;
sConfig.DAC_Trigger2 = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1);
// Enable the DAC channel
HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);
// Configure DMA1 Channel 3
DMA_HandleTypeDef hdma1_dac1;
__HAL_RCC_DMA1_CLK_ENABLE();
hdma1_dac1.Instance = DMA1_Channel3;
hdma1_dac1.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma1_dac1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma1_dac1.Init.MemInc = DMA_MINC_ENABLE;
hdma1_dac1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma1_dac1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma1_dac1.Init.Mode = DMA_CIRCULAR;
hdma1_dac1.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma1_dac1);
// Enable interrupts of full transfer and half transfer
__HAL_DMA_ENABLE_IT(&hdma1_dac1, DMA_IT_TC | DMA_IT_HT);
// Link DMA to DAC
__HAL_LINKDMA(&hdac1, DMA_Handle1, hdma1_dac1);
// Configure NVIC for DMA
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 2048);
// Start DAC with DMA
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*) dac1_buff,
DAC1_BUFF_SIZE * sizeof(uint16_t) / sizeof(uint32_t),
DAC_ALIGN_12B_R);
}
void DMA1_Channel3_IRQHandler(void) {
// Half transfer
if (DMA1->ISR & DMA_ISR_HTIF3) {
DMA1->IFCR = DMA_IFCR_CHTIF3;
}
// Full transfer
if (DMA1->ISR & DMA_ISR_TCIF3) {
DMA1->IFCR = DMA_IFCR_CTCIF3;
}
}
void dac_Error_Handler(void) {
}
timer.c:
#include <ctype.h>
#include "timer.h"
#include "stm32g4xx_hal.h"
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
void timer_Error_Handler(void);
void timer2_init(void) {
TIM_ClockConfigTypeDef sClockSourceConfig = { 0 };
TIM_MasterConfigTypeDef sMasterConfig = { 0 };
TIM_OC_InitTypeDef sConfigOC = { 0 };
// Initialize TIM2 instance
TIM_HandleTypeDef htim2;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 17 - 1; // Set prescaler. Divide by 17
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 10 - 1; // Set period to 10
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
// Base initialization
if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
timer_Error_Handler();
}
// Configure clock source
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
timer_Error_Handler();
}
// Initialize PWM
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) {
timer_Error_Handler();
}
// Configure master synchronization
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig)
!= HAL_OK) {
timer_Error_Handler();
}
// Configure PWM channel
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 5; // Set pulse width to 5
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4)
!= HAL_OK) {
timer_Error_Handler();
}
// Post-initialize TIM2 (configure GPIO)
HAL_TIM_MspPostInit(&htim2);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);
}
void timer_Error_Handler(void) {
}
Timer2 is running with PWM output at PA10.