cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G0, DAC, DMA, TIM2

JuM
Senior

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

1 ACCEPTED SOLUTION

Accepted Solutions

Try to set DMAMUX channel 2.

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

JW

View solution in original post

7 REPLIES 7

Manually feeding DAC works?

DAC clock is enabled?

Read back content of all relevant registers and check.

JW

JuM
Senior

​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
Senior

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

JuM
Senior

0690X00000AR8DbQAL.jpg0690X00000AR8DWQA1.jpg

JuM
Senior

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

Try to set DMAMUX channel 2.

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

JW

JuM
Senior

​Jan, great!! Thank you!

Now it works.