Subtle Q on 32F4 dual DAC (32 bit data feed) mode
I am finding that with DAC1 triggered from TIM5, DAC2 can be set either for the same trigger (the doc implies that) or for no trigger ("software" trigger). Both work.
I would have expected software trigger / no trigger to work on DAC2 because the 32-bit mode feeds both DACs directly, so DAC2 should not care what caused the load to it.
Obviously they can't both trigger the DMA transfer! But ST might have put in logic to prevent DAC2 running unless its trigger is set the same as DAC1. And they could both trigger the DMA (although it would be pointless).
Entire code is below but my Q is around the init code for the two DACs. There is a bug in the code insertion on this forum and it clips a big chunk out but it is just a long comment and you can see the actual code.
void KDE_config_wave_gen( uint32_t *buffer, uint32_t num_values, uint16_t tim_pre, uint32_t tim_tc)
{
// We get here with both DACs enabled from main.c, and outputting that init value
TIM4->CR1 &= 0xfffe; // disable TIM4 (DAC trigger, DAC then triggers DMA)
// set both DAC outputs to Vref/2
KDE_DAC_set_value(1, 2048);
KDE_DAC_set_value(2, 2048);
// DMA1_S5C5 EN=0 - disable DMA1 just in case (also needed at any time to write the address etc)
DMA1_Stream5->CR &= 0xfffffffe;
hang_around_us(10); // this should wait on EN changing to 0, but is ok here
// Config DAC1 for TIM5 trigger. DAC2 doesn't need anything because it gets loaded with the int32.
DAC_ChannelConfTypeDef sConfig = {0};
DAC_HandleTypeDef KDE_dac;
KDE_dac.Instance = DAC;
HAL_DAC_Init(&KDE_dac);
// DAC1 config - gets fed with the DMA data (low 16 bits)
sConfig.DAC_Trigger = DAC_TRIGGER_T5_TRGO;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
HAL_DAC_ConfigChannel(&KDE_dac, &sConfig, DAC_CHANNEL_1);
// DAC2 config - gets fed with the DMA data (high 16 bits)
sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE; // doc asks for DAC_TRIGGER_T5_TRGO for DAC2!
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; // but either works.
HAL_DAC_ConfigChannel(&KDE_dac, &sConfig, DAC_CHANNEL_2);
// The following appears to do a spurious data transfer to both DACs, zeroing them
DAC->CR = (1u << 12) // DMAEN1=1 - DAC1 DMA1 enabled
|(5u << 3) // TSEL1=5 - DAC1 trigger source Timer 4 (Timer 4 TRGO event)
|(1u << 2); // TEN1=1 - DAC1 trigger enabled
// set both DAC outputs to Vref/2 again, due to the above (there is a very short spike)
KDE_DAC_set_value(1, 2048);
KDE_DAC_set_value(2, 2048);
// Timer 4 config - triggers both DACs
RCC->APB1ENR |= (1u << 2); // TIM4EN=1 - TIM 4 clock enable
TIM4->CR1 = (1u << 7); // Auto reload register (sample period) is buffered
TIM4->CR2 = (2u << 4); // master mode select for TRGO on update event
TIM4->SMCR=0; // disable slave mode, etc
TIM4->PSC = tim_pre; // prescaler for above
TIM4->ARR = tim_tc; // time constant
// Config DMA1 Stream 7 Channel 7 to feed both DACs concurrently
RCC->AHB1ENR |= (1u << 21); // DMA1EN=1 - DMA1 clock enable
hang_around_us(1); // give it a chance to wake up
DMA1->HIFCR = (0x03du << 8); // clear Stream 5 interrupt flags
DMA1_Stream5->CR = (0x07u << 25) // DMA1, Stream5 channel 7 is the DAC
|(0u << 23) // mburst single transfer
|(0u << 21) // pburst single transfer
|(1u << 18) // double buffer mode on
|(2u << 16) // priority = high
|(2u << 14) // msize = 32 bits
|(2u << 11) // psize = 32 bits (DAC using double register)
|(1u << 10) // minc = 1
|(0u << 9) // pinc = 0
|(1u << 8) // circular mode buffering
|(1u << 6) // memory to peripheral
|(0u << 5) // dma is flow controller
|(0u << 4) // no interrupts TCIE
|(0u << 3) // no interrupts HTIE
|(0u << 2) // no interrupts TEIE
|(0u << 1) // no interrupts DMEIE
; // DMA is not yet enabled
DMA1_Stream5->NDTR = num_values; // buffer size
DMA1_Stream5->PAR = (uint32_t) (&DAC1->DHR12RD); // destination (DAC) address, 32 bit DAC mode
DMA1_Stream5->M0AR = (uint32_t) buffer; // both buffers are the same address
DMA1_Stream5->M1AR = (uint32_t) buffer; // code may alter this once the system is running
DMA1_Stream5->CR |= 1; // enable DMA to DACs
TIM4->CR1 |= 1; // start the timer
}