2019-09-11 05:24 AM
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
Solved! Go to Solution.
2019-09-12 01:45 AM
Try to set DMAMUX channel 2.
It appers to me that DMA channels are numbered based 1 whereas DMAMUX channels based 0.
JW
2019-09-11 12:21 PM
Manually feeding DAC works?
DAC clock is enabled?
Read back content of all relevant registers and check.
JW
2019-09-11 11:04 PM
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
2019-09-11 11:15 PM
DAC and TIM2 registers: after first TIM2 trigger for 0x7FF:
2019-09-11 11:18 PM
2019-09-12 12:54 AM
DAC trigger sequence (only once...):
2019-09-12 01:45 AM
Try to set DMAMUX channel 2.
It appers to me that DMA channels are numbered based 1 whereas DMAMUX channels based 0.
JW
2019-09-12 04:09 AM
Jan, great!! Thank you!
Now it works.