Skip to main content
TMeeh.1
Associate II
July 8, 2021
Solved

DAC driven by DMA on Nucleo L476RG (works in polling mode, but I can't seem to figure out DMA).

  • July 8, 2021
  • 6 replies
  • 2141 views

I have tried to set up the second example from "Mastering STM32" in the DAC chapter using STM32CubeMX. I'm struggling a bit with DMA in general as well. The first (non-DMA) example seemed to work fine for me in making the LED breathe. I then modified the STM32CubeMX project to try it out with DMA, and got stuck. I was hoping that there was something simple that I missed (I did start the timer ...).

I have overridden the PA5 pin for DAC1_OUT_2.

I have used TIM6, which is connected to APB1 at 80 MHz (I assume).

pseudo-code-y setup for ease of reading?

TIM6.Prescaler = 8192 - 1

TIM6.CounterMode = Up

TIM6.CounterPeriod = 8192 - 1

TIM6.Auto-ReloadPreload = Disable

TIM6.EventTriggerSelection = Update Event

I also set up the DMA for TIM6 with the "ADD" button. I set it to be circular, peripheral not incremented, memory *is* incremented, transfer is half-word to half-word, and is DMA1_Channel3.

For DAC1, I have set Channel 1 to disabled, Channel 2 to connect only to the external pin (PA5, which is connected to the on-board LED).

DAC1.Out2.OutputBuffer = Enable

DAC1.Out2.Trigger = Timer 6 Trigger Out event

DAC1.Out2.WaveGenerationMode = Disable

DAC1.Out2.UserTrimming = Factory

DAC1.Out2.SampleAndHold = Disable

The only C code I wrote was in main, so I'll put that here, it is all before the infinite loop.

/* USER CODE BEGIN 2 */
#define SAMPLES 200
#define PI 3.14159f
 uint16_t IV[SAMPLES];
 for (uint16_t i = 0; i < SAMPLES; ++i) {
 uint16_t value = (uint16_t) rint(2048 * (sinf(2*PI*i/SAMPLES) + 1));
 IV[i] = value < 4096 ? value : 4095;
 }
 
 HAL_DAC_Init(&hdac1);
 HAL_TIM_Base_Start(&htim6);
 HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t *) IV, SAMPLES, DAC_ALIGN_12B_R); /* USER CODE END 2 */

 /* USER CODE BEGIN 2 */

This topic has been closed for replies.
Best answer by TMeeh.1

I figured it out, it was something goofy on my part. When I was configuring the project in STM32CubeMX, I configured the DMA for TIM6 rather than configuring the DMA for the DAC. I don't completely understand STM32CubeMX's choices here, but the setup I had was TIM6->DMA Settings->Add->TIM6_UP. This gave me DMA1_Channel3.

When I deleted that DMA setting and went to DAC1->DMA Settings->Add->DAC_CH2, It set up DMA1_Channel4.

So the "DMA error" that I was seeing was because the DAC DMA wasn't set up correctly.

6 replies

TDK
July 9, 2021

And what happens when you run it?

Do the DAC registers indicate an error, or that no transfers are done?

It's usually better to just attach main.c rather than writing pseudocode. If you make a typo in the original code or in your translation of it, there's no hope of catching it.

"If you feel a post has answered your question, please click ""Accept as Solution""."
TMeeh.1
TMeeh.1Author
Associate II
July 9, 2021

The LED didn't light up, but I didn't have a good idea of where to look with a debugger. I verified that the "IV" array looked like it had sine-wave-ish looking contents (which it did). I would have attached "main.c" but the website complains that it is too large.

Forgive my ignorance, but how would I check the DAC registers for an error with gdb? (In the mean time, I will have a closer look at the reference manual)

waclawek.jan
Super User
July 9, 2021

It's even better to read it and observe content of DMA, TIM and DAC registers.

JW

TMeeh.1
TMeeh.1Author
Associate II
July 9, 2021

Thanks JW, once I get my Nucleo board back later today I will run the debugger and see what I get.

TMeeh.1
TMeeh.1AuthorBest answer
Associate II
July 9, 2021

I figured it out, it was something goofy on my part. When I was configuring the project in STM32CubeMX, I configured the DMA for TIM6 rather than configuring the DMA for the DAC. I don't completely understand STM32CubeMX's choices here, but the setup I had was TIM6->DMA Settings->Add->TIM6_UP. This gave me DMA1_Channel3.

When I deleted that DMA setting and went to DAC1->DMA Settings->Add->DAC_CH2, It set up DMA1_Channel4.

So the "DMA error" that I was seeing was because the DAC DMA wasn't set up correctly.