AD9833/AD9837 Waveform Generator / DDS Driver in Rust

Simple MIDI player playing Beethoven's Ninth Symphony. (source code)

   

Today I present you an waveform generator / direct digital synthesizer (DDS) Rust driver compatible with the devices AD9833 and AD9837 (more in the future).

The devices

The AD9833 and AD9837 are low power, programmable waveform generators capable of producing sine, triangular, and square wave outputs. Waveform generation is required in various types of sensing, actuation, and time domain reflectometry (TDR) applications. The output frequency and phase are software programmable, allowing easy tuning. No external components are needed. The frequency registers are 28 bits wide: with a 25 MHz clock rate, resolution of 0.1 Hz can be achieved; with a 1 MHz clock rate, the AD9833 can be tuned to 0.004 Hz resolution.

The AD9833 and AD9837 are written to via a 3-wire serial interface (SPI).

Using the driver

To use the device from Rust, you have to add the ad983x crate to your project as well as a concrete implementation of the embedded-hal traits. For example if you are using the Raspberry Pi running Linux (see driver-examples for bare-metal hardware):

1
2
3
4
5
# Cargo.toml
...
[dependencies]
ad983x = "0.1"
linux-embedded-hal = "0.3"

This is an example program which will generate a 440 Hz sinus wave given a 25 MHz clock which corresponds to a standard A4 tone (source):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
extern crate ad983x;
extern crate linux_embedded_hal;

use ad983x::{Ad983x, FrequencyRegister};
use linux_embedded_hal::{Pin, Spidev};

fn main() {
let spi = Spidev::open("/dev/spidev0.0").unwrap();
let chip_select = Pin::new(25);
let mut dds = Ad983x::new_ad9833(spi, chip_select);
dds.reset().unwrap();
dds.set_frequency(FrequencyRegister::F0, 4724).unwrap();
dds.enable().unwrap();
// Given a 25 MHz clock, this now outputs a sine wave
// with a frequency of 440 Hz, which is a standard
// A4 tone.

// Get SPI device and CS pin back
let (_spi, _chip_select) = dds.destroy();
}

I also created a simple MIDI player example program that runs on the STM32F1 “BluePill” board and plays the last part of Beethoven’s Ninth Symphony. That is the program running in the title video. You can find the application source code here.

In the driver-examples repository you can find further examples which you can adapt to do other things with this device.

Where to go from here?

There is much more information and example programs in the crate documentation.
Please give this driver a try and report any issues you may encounter in the issue tracker.
Feedback, suggestions and improvements are gladly welcome.

What’s next?

I have been writing many other platform-agnostic Rust drivers although I am slow to announce them here. If you want to know what I am currently working on you can follow me on github.

Thanks for reading and stay tuned!

Links: Source code - Crate - Documentation

Share