2025-06-06 5:03 PM - edited 2025-06-06 5:05 PM
Hello,
I am implementing a sine wave generator based on the high-speed DAC3 of the G474.
The DAC is in double-DMA mode and its conversions are triggered periodically by a timer.
Sample and Hold is disabled.
The DAC is connected to an external pin by an OPAMP in the follower mode.
What could be the reason for the downward slope shown on the picture? It is consistent even at low conversion speeds.
Thank you for your help.
2025-06-10 2:43 PM
Thank you, looking more comprehensive.
However, I noticed that HAL_DAC_Stop_DMA does not handle inactive DMA, throws error from HAL_DMA_Abort.
I think it should be a trivial case. Hence, the check in the code above.
HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
{
...
status = HAL_DMA_Abort(hdac->DMA_Handle1);
/* Disable the DAC DMA underrun interrupt */
__HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
...
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
{
...
if(hdma->State != HAL_DMA_STATE_BUSY)
{
/* no transfer ongoing */
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
status = HAL_ERROR;
}
2025-06-15 3:03 PM - edited 2025-06-15 3:10 PM
A related question:
If I supply DMA array 1600 values starting from the exact middle point (blue line on the value chart, Fig.1) then the the output signal starts from a level lower than the middle as on Fig.2.
What is the reason for such behavior?
To return the output signal start to the desired middle level (Fig.3) I have to shift the phase of the input values to the left (red line on the value chart, Fig.1).
if (hdac3.DMA_Handle2->State == HAL_DMA_STATE_BUSY) // this should be in HAL, looks like a bug
{
if(HAL_DAC_Stop_DMA(&hdac3, DAC_CHANNEL_2)) {
Error_Handler();
}
}
/* Start DAC conversion with DMA */
if (HAL_DAC_Start_DMA(&hdac3, DAC_CHANNEL_2, (uint32_t *)sinewave_dmad_buffer, arr_len, DAC_ALIGN_12B_R) != HAL_OK)
{
Error_Handler();
}
/* Start Timer DAC trigger */
HAL_TIM_GenerateEvent(&timer_sine, TIM_EVENTSOURCE_UPDATE);
if (HAL_TIM_Base_Start(&timer_sine) != HAL_OK)
{
Error_Handler();
}