Skip to main content
JuM
Senior
September 11, 2019
Solved

STM32G0, DAC, DMA, TIM2

  • September 11, 2019
  • 7 replies
  • 1577 views

Would like to generate a 100 Hz sine signal using DAC1, channel 1 (PA4, G071 NUCLEO @ CN8.3).

Would like to use TIM2 to trigger the DAC and DMA to feed the DAC.

But am not successful. TIM2 is running, but DAC is not fed.

Please have al look at the (bare metal) code and tell what is wrong or missing:

 //**************** DMA ********//
 //
 //
 RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Enable clock for DMA1
 temp32 = RCC->AHBENR; // Errata sheet(s): Allow some time to avoid hazards after clock enabling
 
 RCC->AHBRSTR |= RCC_AHBRSTR_DMA1RST; // Force reset
 RCC->AHBRSTR &= ~RCC_AHBRSTR_DMA1RST; // Release reset
 
 DMA1_Channel3->CCR = 0x00000000; // reset value, disable
 
 DMA1_Channel3->CMAR = (uint32_t) &sintab[0]; // Source address (memory, uint16_t array of 360 sin values 0..4095)
 DMA1_Channel3->CPAR = (uint32_t) &(DAC1->DHR12R1); // Destination address (DAC)
 DMA1_Channel3->CNDTR = 360; // Size of sin table
 
 temp32 = DMA1_Channel3->CCR;
 temp32 |= (DMA_CCR_MSIZE_0); // 01b: memory data size is 16 bit (uint16_t array)
 temp32 |= (DMA_CCR_PSIZE_0); // 01b: peripheral data size is 16 bit (DAC)
 temp32 |= DMA_CCR_MINC; // source address increment (memory), no increment for det_address (DAC)
 temp32 |= DMA_CCR_CIRC; // circular mode
 temp32 |= DMA_CCR_DIR; // read from memory
 DMA1_Channel3->CCR = temp32;
 
 DMAMUX1_Channel3->CCR |= DMAMUX_CxCR_DMAREQ_ID_3; // Mux input 8 is DAC channel 1
 
 DMA1_Channel3->CCR |= DMA_CCR_EN; // Enable DMA channel 3
 
 
 
 
 
 //**************** Timer ********//
 //
 //
 RCC->APBENR1 |= RCC_APBENR1_TIM2EN; // Enable clock for TIM2
 temp32 = RCC->APBENR1; // Errata sheet(s): Allow some time to avoid hazards after clock enabling
 
 RCC->APBRSTR1 |= RCC_APBRSTR1_TIM2RST; // Force reset
 RCC->APBRSTR1 &= ~RCC_APBRSTR1_TIM2RST; // Release reset
 
 TIM2->CR1 = 0x00000000; // reset value, disable
 
 TIM2->PSC = 0; 
 TIM2->ARR = (SystemCoreClock / (100 * 360)); // Clock prescaler for 100 Hz
 TIM2->CR1 |= TIM_CR1_ARPE; // hold ARR
 
 TIM2->CR2 &= ~TIM_CR2_MMS_Msk;
 TIM2->CR2 |= (TIM_CR2_MMS_1); // 010b: Update event is TRGO
 
 TIM2->CR1 |= TIM_CR1_CEN; // Enable timer 2
 
 
 
 
 
 //*************** DAC *************//
 //
 //
 DAC1->CR &= ~DAC_CR_EN1; // Disable DAC1, channel 1
 
 temp32 = 0x00000000;
 temp32 |= (DAC_CR_TSEL1_1); // 0010b: TIM2_TRGO as trigger (DHR12R1 -> DOR1)
 temp32 |= (DAC_CR_TEN1); // Enable trigger
 temp32 |= DAC_CR_DMAEN1; // Enable DAC DMA requests
 DAC1->CR = temp32;
 
 DAC1->CR |= DAC_CR_EN1; // (Re-)Enable DAC1, channel 1

This topic has been closed for replies.
Best answer by waclawek.jan

Try to set DMAMUX channel 2.

It appers to me that DMA channels are numbered based 1 whereas DMAMUX channels based 0.

JW

7 replies

waclawek.jan
Super User
September 11, 2019

Manually feeding DAC works?

DAC clock is enabled?

Read back content of all relevant registers and check.

JW

JuM
JuMAuthor
Senior
September 12, 2019

​Yes, added feeding DAC manually with 0x7FF. Result is (Vref internal 2.500V): 1.24 V.

So first TIM2 trigger occurs (also proved stepping manually).

TIM2 is running too, but seems not to trigger DAC again, and DAC therefore sends no DMA requests.

...
 DAC1->CR |= DAC_CR_EN1; // (Re-)Enable DAC1, channel 1
 
 DAC1->DHR12R1 = 0x7FF; // pre set DHR, to...
 TIM2->CR1 |= TIM_CR1_CEN; // ...let timer 2 trigger the transfer DHR -> DOR
 
 

JuM
JuMAuthor
Senior
September 12, 2019

DAC and TIM2 registers: after first TIM2 trigger for 0x7FF:0690X00000AR8CnQAL.jpg

JuM
JuMAuthor
Senior
September 12, 2019

0690X00000AR8DbQAL.jpg0690X00000AR8DWQA1.jpg

JuM
JuMAuthor
Senior
September 12, 2019

DAC trigger sequence (only once...):0690X00000AR8X9QAL.jpg

waclawek.jan
waclawek.janBest answer
Super User
September 12, 2019

Try to set DMAMUX channel 2.

It appers to me that DMA channels are numbered based 1 whereas DMAMUX channels based 0.

JW

JuM
JuMAuthor
Senior
September 12, 2019

​Jan, great!! Thank you!

Now it works.