How to initialize the 16-bit audio DAC?

mkoch

Active member
Hello,

I'd like to know how the 16-bit DAC on the TEENSY4_AUDIO module must be initialized and how a 16-bit value can be written to the DAC. Are there any examples?
I'm hopelessly lost with the documentation of the Teensy Audio Library and would prefer not to use this library.

Thanks,
Michael
 
Like most audio DACs, internally it uses delta-sigma modulation, so it can only work if you supply a stream of audio samples at a consistent rate. It doesn't work if you send just one 16 bit sample. If fact, the chip even has a special low power reset mode at startup which is only ended when it hears a steady MCLK signal. The hardware through and through is designed for a steady stream of samples at a consistent audio sample rate.

2 communication channels are used between the SGTL5000 chip and Teensy, I2C for configuration and I2S for the audio stream data. Even though the names look similar, they are nothing alike. Both have special hardware inside the processor which is very powerful but also quite complex. Normally software libraries like Wire and Audio are used to access that hardware, since writing your own code to directly manipulate the hardware is a huge project which would take even the most experienced firmware developers quite a lot of time and effort.

The Teensy Audio Library really is pretty easy to use. This tutorial is the place to start. It's 31 pages covering a lot of features, but just getting the hardware to make test beeps is covered on page 3, and playing music from the SD card is covered on page 4. There is also a full walkthrough video, if you get stuck or if you just prefer to watch and hear a demo rather than read 31 pages.

https://www.pjrc.com/store/audio_tutorial_kit.html

If you *really* want to dive into the difficult low-level details of how to use the hardware to talk to the SGTL5000 chip, you certainly can. But it's a steep learning curve. You can find working code inside the audio library. Of course the hardware is documented in the reference manual. The I2S hardware is covered in chapter 38 starting on page 1985. But alone that hardware usually isn't very useful. It's almost always used together with DMA, which is covered in chapter 6 starting on page 89.
 
Is it possible with the audio library to have an interrupt routine running at 44.1kHz, so that inside this routine I can calculate the 16-bit value that's sent to the DAC?
 
No, that's not how the audio library works. The I2S hardware generates 44.1 kHz DMA requests. The DMA engine automatically moves the samples between 128 sample buffers and the hardware. Interrupts are generated once every 128 samples, approx every 2.9 ms.

Yes, it is possible if you write your own low-level code, you could design it this way to have the I2S not use DMA and generate interrupts at 44.1 kHz. Using the I2S hardware for unusual projects has come up several times before on this forum, where some non-DMA code has been written. Maybe you can find it by searching.

But generating an interrupt for every audio sample has 2 major problems. First, it's quite inefficient on multiple levels. Second, it gives only about 22 us tolerance for interrupt latency imposed by USB, timers or other libraries using interrupts. You can (probably) mitigate this configuring the I2S interrupt to have higher priority than the others. But unless you are very careful, it is an approach that tends to corrupt the audio when you combine with other code using interrupts.

The audio library is easy to use, not just because it has a design tool and extensive tutorial and many examples, but also because the DMA-based approach is very efficient and the 2-level priority interrupt approach is highly resilient to other libraries corrupting the audio.
 
It seems easier not to use the audio module and the audio library, but instead use a PWM output on Teensy 4.0 with 12 or 13 bit resolution, with a carefully designed low pass filter. I don't need more than 10kHz bandwidth at the output. What a pity that Teensy 4.0 has no built-in DAC. The DAC in Teensy LC works great, but for a new project I need more CPU speed. My old project is described here, it's a multi-function accessory for an analog computer. Can be used as user-defined transfer function, delay line or signal generator:
https://www.facebook.com/groups/theanalogthing/posts/400329198856542/
 
Indeed, I really with NXP would have put a DAC in this chip, but sadly they did not.

They probably realized that a DAC implemented in the same CMOS process as a 600MHz logic chip and on the same die is not going to be very performant. If they had I expect it would be un-exciting in its specs.

And I'll second that sigma-delta techniques require very clean clocks, i.e. quartz-derived, for their basic function (which is at its most basic counting timed packets of charge - any jitter in the timing directly injects noise on the output).
 
Back
Top