2020-07-08 05:31 AM
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?
Solved! Go to Solution.
2020-07-10 03:02 AM
I have found the problem! DMA CCR must access DAC peripheral by word.
2020-07-08 03:49 PM
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
2020-07-09 12:01 AM
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.
2020-07-09 01:38 AM
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;
2020-07-09 12:40 PM
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
2020-07-10 03:02 AM
I have found the problem! DMA CCR must access DAC peripheral by word.
2020-07-10 04:30 AM
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