cancel
Showing results for 
Search instead for 
Did you mean: 

Reducing DAC jitter

SSmit.0
Associate II

Hi,

I'm writing data to a 24 bit register of an AD5664 DAC from an STM32F429 discovery board which I am using to produce sinewaves and slower sawtooth ramps. The full loop lasts approximately 200000 bytes which gives sufficient resolution over all waveforms.

At the moment I am getting quite a lot of jitter on the sinewaves of about 2.5hz at approx 400Hz sinewave frequency. Ideally I'd like below 0.1Hz if possible via this method.  

I have streamlined the loop to be as small as possible but the jitter is still similar to my previous much longer loop. I've tried HAL_SPI_Transmit, HAL_SPI_Transmit_IT which was too slow to reach 400Hz, DMA didn't produce data that worked with the DAC for some reason. I'm not sure it would help much though. I've stripped quite a lot of code out from the HAL_SPI_Transmit function which has greatly increased my effective resolution for a given freq, but not so much the jitter. I also tried using a one pulse timer for the NSS/SYNC line but it actually seemed to perform worse.

Is there a way to reduce the jitter further? I understand there will be quite a large number of instruction cycles involved so perhaps I am quite close to what can be achieved for a relatively complex operation. 

for(p=0;p<200000;p+=3) 
{
GPIOG->BSRR = 0x10000000;		// NSS/SYNC low
//if (hspi1.State != HAL_SPI_STATE_BUSY_RX)  //Commented out as working without 
HAL_SPI_Transmit(&hspi1,&first[p],3,0); // Send a 24 bit packet as 3x8 bytes
GPIOG->BSRR = 0x1000;			// NSS/SYNC high 
**Accurate 15uS delay code here**	
}

I need to change between different modes where the sinewave DAC channel changes to a sawtooth, etc which is why I'm not just smoothing out square waves or using an external generator IC. Any help would be greatly appreciated. 

Thanks,

16 REPLIES 16
SSmit.0
Associate II

Someone?

TDK
Guru

Your application is a pretty specific need. This is just a community forum, you typically aren't going to find someone to do a lot of work on your particular problem for free. I'm fairly certain your problem can be solved by what's onboard the STM32, but it'll take some work on your part, or paying someone else to do it.

Might even be possible using a timer channel output as the SYNC signal and SPI_MOSI as DIN.

If you feel a post has answered your question, please click "Accept as Solution".
SSmit.0
Associate II

Thanks for the reply but I don't follow? I'm not asking anyone to write code for me or even to tell me exactly what to do. I'm just inquiring about how the different i2s modes can be configured, and if it's possible to maintain comparability between i2s and SPI via the CubeMX configuration and HAL. 

I've already read quite a lot but the configurations are very complex and I'm no expert. While the application is specific, my questions are fairly generic. I.e.

Can i2s be configured to be compatible with a standard SPI device, and is it possible using HAL? 

Would DSP mode work and could I use it with just one extra clock to allow toggling of WS? 

I already through about using a timer channel like that but it would be running asynchronous to the data stream. Eventually it would result in invalid data. I really need to tie all the SPI pins to a sample rate like with i2s, not just the SYNC channel.

Many thanks

RMcCa
Senior II

We have been trying to help.

These chips are designed ​for real-time operation, you just need to ditch HAL and learn about the timers, dma and interrupts. It's not super complicated, build the thing one step at a time. Use dds, the algorithm is simple and you can generate any waveform at any frequency up to half the sample rate. Trying to make variable frequencies by altering the sample rate in a for loop is the wrong way to go about what you are trying to do. Why? Because of signal processing. Everything you need to know is readily available online. At some point it is up to you to put it all together or hire somebody that can.

Piranha
Chief II

As I already said, the SAI can do this easily. So have you read RM0090 section 29.7 and the respective register descriptions? It has all the answers on your questions about nSYNC/WS etc. That's CubeMX/HAL crapware, which is hard to understand and overcomplicated, but the SAI peripheral itself is easy to use.

S.Ma
Principal

More or less you want to generate arbitrary waveform generator without using wull waveform in memory.

So take a RAM buffer of twice the size needed to output say 1 msec of DAC throughput (1000 samples at 1Msps = 4kbytex2=8kbyte of SRAM.

Use a Timer to generate the DAC update pulse (use a timer output channel and connect it with a wire to the DAC trigger pin, so you can probe on a scope before using internal-chip routing). Then set the DAC DMA to cycle through the double buffer and get interrupt on half and full transfer. Normally, you will have 1 msec to prepare the next 1 msec throughput. It's timeslicing. Try to have interrupt frequency in the kHz range, once you add more ISRs and latencys/lags your debug time will be a breeze. Use HW assist function as much as possible to get closer to an ASIC situation (full HW implementation, no SW)

Look at my first post in this topic... ;) Why are people recommending all of this when there is SAI?