Skip to main content
Handzic.Dirk
Associate III
July 8, 2020
Solved

STM32G431C8

  • July 8, 2020
  • 6 replies
  • 1801 views

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?

This topic has been closed for replies.
Best answer by Handzic.Dirk

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

6 replies

waclawek.jan
Super User
July 8, 2020

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
July 9, 2020

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
July 9, 2020

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;

waclawek.jan
Super User
July 9, 2020

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
Handzic.DirkAuthorBest answer
Associate III
July 10, 2020

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

waclawek.jan
Super User
July 10, 2020

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