cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G431C8

Handzic.Dirk
Associate III

I want to use DMA to move data from memory to DAC1 channel 1 and channel 2. Channel 1 uses DMA Channel 5 and that works. CubeMX configured DAC1 Channel 2 for DMA1 Channel 6. The datasheet says STM32G431 is a category 2 device which has only channel 0 to 5 for DMA1 and DMA2. So what is the correct channel to use for DAC1 Channel 2?

1 ACCEPTED SOLUTION

Accepted Solutions
Handzic.Dirk
Associate III

I have found the problem! DMA CCR must access DAC peripheral by word.

View solution in original post

6 REPLIES 6

Whichever you want, that's why you have DMAMUX.

However, I'm afraid you've already exhausted all the available channels, so you need to free up some.

JW

Handzic.Dirk
Associate III

Thanks Jan, I have realized that and used the DMAMUX to assign DMA channels 2 and 3 to the DAC. I thought the CubeMX would generate code that could work on the selected microcontroller though.

Handzic.Dirk
Associate III

Still have a problem, both DMA1 Channel 2 and Channel 3 now give an TEIF interrupt. Is there a limitation to use the same trigger for both DAC channels??

 // DMA setup output 1

       DMA1_Channel2->CCR = (DMA_CCR_PL_1 | DMA_CCR_MINC | DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0 | DMA_CCR_CIRC | DMA_CCR_DIR);              // memory to peripheral, 16 bit aligned, transfer complete

       DMA1_Channel2->CNDTR = SAMPLE_SIZE;

       DMA1_Channel2->CPAR = (ULONG) &DAC1->DHR12R1;

       DMA1_Channel2->CMAR = (ULONG)((UINT *)sample_buffer1);                                                                            // Left channel 12 bit MSB

       DMA1_Channel2->CCR |= DMA_CCR_HTIE | DMA_CCR_TCIE | DMA_CCR_TEIE;

       DMAMUX1_Channel1->CCR = (0x06 << DMAMUX_CxCR_DMAREQ_ID_Pos);                                                                       // DAC1 CH1 ID 6

       DMAMUX1_ChannelStatus->CFR = DMAMUX_CFR_CSOF1;

       NVIC_SetPriority(DMA1_Channel5_IRQn, DMA_PRIO);

       NVIC_EnableIRQ(DMA1_Channel2_IRQn);

       DMA1_Channel2->CCR |= DMA_CCR_EN; 

       // DMA setup output 2

       DMA1_Channel3->CCR = (DMA_CCR_PL_0 | DMA_CCR_MINC | DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0 | DMA_CCR_CIRC | DMA_CCR_DIR );             // memory to peripheral, 16 bit aligned, transfer complete

       DMA1_Channel3->CNDTR = SAMPLE_SIZE;

       DMA1_Channel3->CPAR = (ULONG) &DAC1->DHR12R2;

       DMA1_Channel3->CMAR = (ULONG)((UINT *)sample_buffer1 + 4);                                                                       // Right channel 12 bit MSB

       DMA1_Channel3->CCR |= DMA_CCR_HTIE | DMA_CCR_TCIE | DMA_CCR_TEIE;

       DMAMUX1_Channel2->CCR = (0x07 << DMAMUX_CxCR_DMAREQ_ID_Pos);                                                                       // DAC1 CH2 ID 7

       DMAMUX1_ChannelStatus->CFR = DMAMUX_CFR_CSOF2;

       NVIC_SetPriority(DMA1_Channel3_IRQn, DMA_PRIO);

       NVIC_EnableIRQ(DMA1_Channel3_IRQn);

       DMA1_Channel3->CCR |= DMA_CCR_EN;

       // DAC output trigger

       TIM6->PSC = 0;                                                                                                                    // Timer clock

       TIM6->ARR = (FOSC/(44100));                                                                                                       // Auto reload

       TIM6->CR2 &= ~(TIM_CR2_MMS);

       TIM6->CR2 |= (0x02 << TIM_CR2_MMS_Pos);                                                                                            // TRGO on update

       TIM6->CR1 |= TIM_CR1_CEN;                                                                                                          // Start timer 

       //DAC output

       DAC1->CR &= ~(DAC_CR_TEN1 | DAC_CR_TEN2 | DAC_CR_TSEL1 | DAC_CR_TSEL2 | DAC_CR_EN1 | DAC_CR_EN2);

       DAC1->MCR &= ~(DAC_MCR_MODE1 | DAC_MCR_MODE2);                                                                                     // External buffered output

       DAC1->CR |= (0x07 << DAC_CR_TSEL1_Pos) | (0x07 << DAC_CR_TSEL2_Pos);                                                              // Use TIM8 TGO

       DAC1->CR |= DAC_CR_DMAEN1 | DAC_CR_DMAEN2;

       DAC1->CR |= DAC_CR_EN1 | DAC_CR_EN2;

       DAC1->CR |= DAC_CR_TEN1 | DAC_CR_TEN2; 

       DAC1->DHR12R1 = 0x0FFF;

       DAC1->DHR12R2 = 0x0FFF;

I don't know the answers, so just some blind shots:

Using the channels separately,i.e. one at a time, works?

Read out and check DMA registers, if they are set as intended, pointer registers point to existing memories/registers, alignment is OK.

Try the other DMA...

JW

Handzic.Dirk
Associate III

I have found the problem! DMA CCR must access DAC peripheral by word.

Indeed...

22.7 DAC registers

[...]

The peripheral registers have to be accessed by words (32-bit).

Nice catch!

Thanks for coming back with the result.

Please select your post as Best so that the thread is marked as solved.

JW