The ABDAC peripheral on AVR32 MCUs is quite suitable for generating audio playback. This article explains how to do it and includes a link to an example driver that generates a sine wave output.
Many embedded applications increasingly feature audio playback, whether simple audio feedback in response to user inputs or full high-speed streaming audio. By using the generic clock interface, the ABDAC on Atmel AVR32 MCUs is capable of supporting a wide range of playback frequencies.Functional description
The ABDAC is a very simple peripheral and its use is straightforward. It needs a clock signal provided from the generic clock system, and data input to the channels. The block diagram in Figure 1 gives an overview of the module. For a detailed description of the ABDAC peripheral see the datasheet for the device.
Figure 1: Clock and data path block diagram.
The ABDAC uses a generic clock to provide the sample frequency. This generic clock is hard wired inside the device and must be 256 times the sample frequency.
The generic clock should be configured and enabled before the ABDAC is enabled. For a description of which generic clock is used, see the clock section in the datasheet for the device. Further configurations of the generic clock are also described in this section.
The generic clock output range may be limited by its source clock frequency. It is therefore vital to design in an oscillator which can provide a base frequency that is dividable by the generic clock divider in order to reach the required output sample rate. Table 1 shows examples.Channels
When the ABDAC is enabled; it expects the Sample Data Register (SDR) to be updated at the same interval as the output sample rate. Both channels can be updated with one written instruction, since they are in the same I/O register (SDR).
|Output sample rates
||OSC or PLL frequency
|48000 Hz, 240000 Hz, 12000 Hz
||2, 4, 8
|44100 Hz, 22050 Hz, 11025 Hz
||2, 4, 8
|32000 Hz, 16000 Hz, 8000 Hz
||2, 4, 8
Table 1: Base frequencies needed for an output sample rate.
If the sample data register is not updated within 256 clock cycles from the generic clock input to the ABDAC, the underrun bit will be set in the Interrupt Status Register (ISR). Underruns are a sign of too much CPU load, and therefore the application should be implemented by using interrupts, or even better, direct memory access (DMA) if available in the device.Interrupts
There are two interrupts available to offload the CPU. The TX_READY interrupt can be used as a trigger to signal that the next sample for each channel can be written.
The application should also enable the underrun interrupt to handle underruns when filling the Sample Data Register (SDR). Underruns will cause glitches and noise on the output signals.
If the underrun interrupt triggers, it is a sign of CPU overloading because the application was not able to provide the data in time.DMA
The ABDAC may be connected to a DMA controller on the device. This will offload the CPU when transferring data from a buffer in RAM to the ABDAC. The application will only need to fill a buffer and pass the buffer address to the DMA controller.
Triggers for when a buffer is complete will let the application know when to pass a new buffer to the DMA controller.
The underrun interrupt is vital for DMA transfers, as it will indicate that the data busses in the device are overloaded or the DMA transfer to the ABDAC does not have enough priority.Electrical connection
The output from the device is not intended for driving headphones or speakers. The pads limit the maximum amount of current. In the majority of all practical cases, this will not be enough to drive a low-impedance source.
Because of this limitation, an external amplifier should be connected to the output lines to amplify these signals. This amplifier device could also be used to control the volume.
For testing purposes, a line in or microphone input on a sound system can be used to evaluate the output signal.Passive filter
For connecting the ABDAC to high-impedance devices, such as line in on an amplifier, a passive filter should be added. Figure 2 shows an example schematic.
Figure 2: Line out with passive filter schematic.
An external amplifier is required if the ABDAC is driving low-impedance headphones or speakers directly. Figure 3 shows an example schematic using Texas Instruments' TPA152 stereo audio amplifier.Driver implementationFiles
Full source code for the driver discussed in this article can be found at www.atmel.com/dyn/resources/prod_documents/AVR32120.zip.
The driver consists of two files, "dac.c" and "dac.h," where "dac.h" declares all functions and "dac.c" contains the source code. The only change needed in the driver is to specify the target device. The target device is specified at the top in "dac.h."Example code
The example code for the driver outputs a sinus wave on both DAC channels. This output is enabled by a user input on a GPIO line. The wiring information is included in the documentation which accompanies the source code.
The example code is targeted for the ATSTK1000, but can, with some tweaking, work with any AVR32 devices with an ABDAC.
Figure 3: High power output with external amplifier schematic.
Figure 4 shows the flow of the example application. The application is implemented by polled function calls to make it less dependent on other modules.
Figure 4: ABDAC example application flowchart.
The ABDAC interface has an interrupt line connected to the interrupt controller (IC). Handling the ABDAC interrupt requires programming the IC before configuring the ABDAC. For more information and details about the interrupt controller, see the application note AVR32101: "The AVR32 Interrupt Controller."