cancel
Showing results for 
Search instead for 
Did you mean: 

DAC maximum sampling rate of STM32F407

Willunen
Associate III

In AN4566 the maximum sampling rate of the DAC of a STM32F407 is claimed to be 10.5 Msps but I'm not able to get any faster than 7 Msps before it starts to skip samples.

The clock of the STM32F407 is set to 168 MHz.

TIM8 triggers the DAC via TRGO.

DAC1 is setup to do simultaneous conversions and therefore receives 32bit words on DAC1->DHR12RD.

DMA uses LL_DMA_STREAM_5, LL_DMA_CHANNEL_7, is setup in double buffer mode (and thus circular)

DMA1_Stream5_IRQHandler has ample time to do its job so that isn't a problem. (I use GPIOE_0 to see the processing time on an oscilloscope.)

Any idea where I have gone wrong?

here are the relevant (I think) parts of the code :

DMA:
 
LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_5, LL_DMA_CHANNEL_7);
 
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_5, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
 
LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_5, LL_DMA_PRIORITY_VERYHIGH);
 
LL_DMA_SetMode(DMA1, LL_DMA_STREAM_5, LL_DMA_MODE_CIRCULAR);
 
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_5, LL_DMA_PERIPH_NOINCREMENT);
 
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_5, LL_DMA_MEMORY_INCREMENT);
 
LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_5, LL_DMA_PDATAALIGN_WORD);
 
LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_5, LL_DMA_MDATAALIGN_WORD);
 
LL_DMA_EnableDoubleBufferMode(DMA1, LL_DMA_STREAM_5);
 
LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_5, (uint32_t) &DAC1->DHR12RD);
 
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_5, (uint32_t) &dac_buffer_a[0]);
 
LL_DMA_SetMemory1Address(DMA1, LL_DMA_STREAM_5, (uint32_t) &dac_buffer_b[0]);
 
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_5, STEPS);
 
LL_DMA_EnableIT_TC(DMA1, LL_DMA_STREAM_5);
 
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);
 
 
 
DAC:
 
LL_DAC_InitTypeDef DAC_InitStruct = {0};
 
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DAC1);
 
DAC_InitStruct.TriggerSource = LL_DAC_TRIG_EXT_TIM8_TRGO;
 
DAC_InitStruct.WaveAutoGeneration = LL_DAC_WAVE_AUTO_GENERATION_NONE;
 
DAC_InitStruct.OutputBuffer = LL_DAC_OUTPUT_BUFFER_DISABLE;
 
LL_DAC_Init(DAC, LL_DAC_CHANNEL_1, &DAC_InitStruct);
 
LL_DAC_Init(DAC, LL_DAC_CHANNEL_2, &DAC_InitStruct);
 
 
LL_DAC_EnableTrigger(DAC1, LL_DAC_CHANNEL_1);
 
LL_DAC_EnableTrigger(DAC1, LL_DAC_CHANNEL_2);
 
LL_DAC_EnableDMAReq(DAC1, LL_DAC_CHANNEL_1);
 
LL_DAC_EnableDMAReq(DAC1, LL_DAC_CHANNEL_2);
 
LL_DAC_Enable(DAC1, LL_DAC_CHANNEL_1);
 
LL_DAC_Enable(DAC1, LL_DAC_CHANNEL_2);
 
 
 
IRQ:
 
void DMA1_Stream5_IRQHandler(void)
 
{
 
   static uint32_t phase = 0;
 
   uint16_t x;
 
   LL_GPIO_SetOutputPin(GPIOE, LL_GPIO_PIN_0);
 
   if (LL_DMA_IsActiveFlag_TC5(DMA1))
 
   {
 
      LL_DMA_ClearFlag_TC5(DMA1);
 
      if (LL_DMA_GetCurrentTargetMem(DMA1, LL_DMA_STREAM_5))
 
      {
 
         for (x = 0; x < STEPS; x++)
 
         {
 
            dac_buffer_a[x] = waveform[phase >> 22];
 
            phase += stepsize;
 
         }
 
      }
 
      else
 
      {
 
         for (x = 0; x < STEPS; x++)
 
         {
 
            dac_buffer_b[x] = waveform[phase >> 22];
 
            phase += stepsize;
 
         }
 
      }
 
   }
 
   LL_GPIO_ResetOutputPin(GPIOE, LL_GPIO_PIN_0);
 
}

15 REPLIES 15

Isn't this bus limitation? Is there any other DMA process running? Try to write a minimal code and observe.

JW

Ozone
Lead

> In AN4566 the maximum sampling rate of the DAC of a STM32F407 is claimed to be 10.5 Msps but I'm not able to get any faster than 7 Msps before it starts to skip samples.

Having some trouble to understand this. A DAC is not sampled.

Anyway, the actual output bandwidth of the F407 DAC is at least one order of magnitude below the sustainable write rate to the DAC.DR register. Check the settling times in the datasheet.

Nothing else is running, no DMA, no IRQ's What do you mean with bus-limitation? And what bus? I have to say that is odd that in AN4566 the example makes the DAC run at 5 Msps... as if the knew... 🙂

Wilko

Yes, the choice of "samples per seconds" is strange, but I assume they mean the number of words per second written into the DAC. (update-rate)

And yes, the buildin opamp of the STM32F407 has way too low a slew rate to be of use. But a solution to that is given in AN4566, with an external high speed opamp and the internal one disabled. That works fine up to well over 1 MHz with me. The trouble is that the DAC starts to miss data when it is written (too?) fast. Or is it DMA that is the problem?

The datasheet of the STM32F407 (pag. 141) only tells me that the update-rate of the DAC for a correct DAC_OUT change for small variations (1 LSB) is 1 MS/s, but not the maximum rate of actual data written into it. That claim is in AN4566 (pag. 😎 10.5 MS/s.

I'm confused.

Wilko

> What do you mean with bus-limitation?

Whatever bus is involved, i.e. the bus where RAM sits on the input side of DMA, and the bus where the DAC sits on the output side of DMA.

If the processor or any other busmaster (this or the other DMA, ETH, HS USB) access these buses heavily, the DMA would see some waitstates.

But you may be hitting the limits of the triggered mode. RM says, in that mode the holding-to-output register transfer occurs 3 APB1 clocks after the trigger that's 12 AHB clocks; add to that time the DMA's latency - I'm lazy to calculate that, look it up in the 'F4 DMA AN - I wouldn't be surprised if it would be another dozen or so AHB clocks, and that gets surprisingly close to 7MHz.

Try timer-triggered DMA transfers and the no-triggered mode of DAC, I'd bet you'd then be able to reach the quoted 10.5Msps.

JW

> A DAC is not sampled.

This here refers to the triggered mode of DAC.

JW

Even in unbuffered mode, the DAC is still quite slow IMHO. Anyway.

> The datasheet of the STM32F407 (pag. 141) only tells me that the update-rate of the DAC for a correct DAC_OUT change for small variations (1 LSB) is 1 MS/s, ...

Mine (DocID022152 Rev 6) specifies 3..6 us for a full-range swing (lowest to highest code, until reaches +- 4LSB).

As Jan suggested, bus contentions might interfere with DMA transfers.

But I would suggest to check the DAC output (settling times) first. If the DAC is as slow as the microseconds settling times suggest, any hunt for internal bus contentions would be futile.

S.Ma
Principal

Careful, DAC is not a digital output, it has a max slew rate which is described in teh datasheet electrical tables.

If the DAC can spit at 10 MHz, it won't be a square wave, more like a triangle one.

Datasheet:

tSETTLING(4) Settling time (full scale:

for a 10-bit input code transition between the lowest and the highest input codes when DAC_OUT reaches final value ±4LSB -

3 6 µs

CLOAD ≤ 50 pF, RLOAD ≥ 5 kΩ

==> 140 kHz square wave limit?

Update rate(2) Max frequency for a correct DAC_OUT change when small variation in the input code (from code i to i+1LSB) - - 1 MS/s CLOAD ≤ 50 pF, RLOAD ≥ 5 kΩ

Your limit for small incremental is 1 Msps, per the datasheet. Would it mean the DAC is "overclocked"?

Non-triggered mode is something I haven't even thought of. Actually, I didn't even know it existed, but as there is the option not-to-set the TENx register there apparently is one. I'll check it. For the application though, it isn't an option, I need to know the precise frequency of the triggering, so I have accepted that 7 MHz is the limit.