Simple Audio DSP Module: Low Power, 50 MIPS, 24-bit 48kHz Stereo



Comments, suggestions and questions are welcome!
mark.seel@gmail.com
Next Audio, Inc.

Specifications
  • 50 MIPS Fixed-Point DSP
    • One clock cycle per instruction
    • 28-bit fixed point multiply/accumulate
    • Base 16 Logarithm and Exponentiation
    • Conditional Branches/Jumps
    • 1024 40-Bit Word Program Memory
    • 1024 28-Bit Word Data Memory
  • Stereo Codec
    • Stereo ADC and Stereo DAC
    • 48 kHz Sampling Rate
    • 24-Bit Sampling Resolution
  • Microcontroller
    • Stores Full DSP Program
    • Three Low Speed ADC Inputs for Potentiometers
    • Serial Communications (1 Start, 8 Data, 1 Stop) for Downloading DSP Programs to FLASH Memory
  • Power Supply
    • Regulated 3.3 Volt @ 50 mA max
Hardware
  • Wavefront DSP-1K IC (specifically the AL3102).  This device executes a sequence of up to 1024 simple DSP instructions (multiply, add, mac, logarithm, anti-log, jump/skip, etc) per audio sample.  In other words, the DSP program will execute it's program sequence on each audio sample and then repeat.  It's a simple paradigm that's easy to grasp.  The AL3102 has I2S-like ports that allow for up to eight analog in/out channels although this design uses only two (stereo in and stereo out).
  • Wolfson WM8731M Codec.  The CODEC supports 24-bit 48 kHz stereo ADC's and DAC's.
  • Atmel Attiny84 Micro-controller.  This is used for providing low-speed ADC's (usually connected to potentiometers in order to control DSP algorithm), to store the 1024-word DSP program (in FLASH), to allow for DSP program downloading via the serial port, and to update the DSP with Pot (low speed ADC) values when they change.
  • 12.288 MHz crystal, various capacitors and resistors.
  • 4-Layer PCB with dedicated power and ground planes and careful layout for low-noise operation.
Board Pin-Out

 PinUsageNotes
 1Serial Programming Pin
At power-up and reset this pin determines operational mode based on logic level.  A value of high puts firmware in PROGRAM mode, low puts firmware in NORMAL mode.
 2Low Speed ADC #1
In NORMAL mode the low-speed ADC samples are written to DSP memory at 0x40F at a rate of approximately 10 Hz.
 3Low Speed ADC #2
In NORMAL mode the low-speed ADC samples are written to DSP memory at 0x40E at a rate of approximately 10 Hz.
 4Low Speed ADC #3
In NORMAL mode the low-speed ADC samples are written to DSP memory at 0x40D at a rate of approximately 10 Hz.
 5Power Supply
3.3 Volts (consumes approximately 50 mA)
 6Ground
Analog and Digital Ground
 7Audio Output (Right Side)
Connects directly to the CODEC's right DAC output.
 8Audio Output (Left Side)
Connects directly to the CODEC's left DAC output.
9
Audio Input (Left Side)
Connects directly to the CODEC's left ADC input.
 10Audio Input (Right Side)
Connects directly to the CODEC's right ADC input.

Hookup

 Using DSP board with Line-Level Equipment: Using DSP board as a guitar effects processor:
 
 

Operation

The DSP board contains an Atmel micro-controller that handles configuration of the audio CODEC, configuration and program loading for the Wavefront AL3102 DSP, serial communications handling for program downloading to FLASH memory and the updating of DSP RAM with low-speed ADC values.



When the micro-controller boots the firmware selects one of two modes of operation based on the value of the board's RX pin.  If the pin is high then the firmware runs in PROGRAM mode otherwise the firmware runs in NORMAL mode.

In PROGRAM mode the firmware handles serial communications.  Serial communication is used to download a DSP program to non-volatile (FLASH) memory.

In NORMAL mode the firmware samples each of the three low-speed ADC inputs and writes the sampled values to DSP memory starting as offset 0x40F and working down to 0x40D.  Low-speed ADC Samples are written to DSP memory at a rate of approximately 10 Hz.

Communications

A simple serial communications protocol is used to communicate with the board's firmware in order to download DSP program object code to FLASH memory.  A Python script (see the 'Programming' section below) is supplied to perform DSP program downloading via the serial protocol.

The serial protocol for each byte transfer is:


A write of 0x55 allows the micro-controller firmware to determine the baud rate.  It also starts the FLASH programming process.  80 write sequences of 64 bytes each should be performed repeatedly until 5120 bytes (a complete DSP program) have been written.  A 25 millisecond delay is required after each 64-byte block transmission. The firmware will automatically reboot after the last 64-byte block has been received by the firmware and burned into FLASH memory.

The serial communications sequence for writing DSP object code to FLASH memory is:
  1. Write 0x55
  2. Wait 100 milliseconds
  3. Write the 64 bytes of object code
  4. Wait 50 milliseconds
  5. Repeat steps three and four 79 times
Since the board communicates using a standard serial protocol a 3.3V serial port is required.  These are widely available as USB to serial adapters.  In general the USB/serial adapters appear as virtual communications ports to Windows, Linux and Mac OSX and therefore drivers are not needed for communications as these operating systems provide a standard means of serial port control.

One such USB/serial adapter board is available from Sparkfun for less then $25:
http://www.sparkfun.com/commerce/product_info.php?products_id=198

The USB/Serial board provides a 3.3 Volt supply, a 3.3 volt serial TX pin and ground therefore it can be connected directly to the 10-Pin DSP board which requires 3.3 volt serial logic levels and a 3.3 volt power supply.

Software

A single python script is provided (see 'Programming' section below).  It supports DSP program assembling and downloading, DSP program simulation and graphing and WAVE file reading and writing.  More specifically it:
  • Provides the DSP instruction code generators for a simplified DSP instruction set (shown in a previous posting).
  • Assembles DSP programs (written using Python) into a Wavefront DSP-1K (AL3101 and AL3102 DSP chips) object code.
  • Downloads object code to FLASH memory using a PC COM port (specifically using a virtual COM port created by USB to Serial converter devices - these are cheap and easy to find/buy/use).  Object code files from Wavefront's DSP-1K assembler can also be downloaded (but not simulated - yet).
  • Simulates the DSP programs in case you want to use Python to create test signals and plot time or frequency domain results, play WAVE files (not in real time), etc.
  • Graphs input audio data or the resulting audio data from DSP simulation
The python script generates DSP program code and therefore allows for python code generators to be written by the user (for instance, you can write a code generator to emit DSP code for a low pass filter based on filter parameters rather than hard-coding the coefficients in the program).

Note that the simulator does not simulate the fixed-point math of the DSP-1K but rather uses the PC's floating point capabilities instead.  Therefore the simulation won't exhibit numerical problems (truncation, rounding error, log/anti-log approximation) to the same degree as the actual DSP (which uses fixed point math with S3.18 and S3.24 formats).  But it does prove useful for checking the programs general functions.

Instruction Set

The DSP memory as seen by a DSP program is:

0x000 - 0x3FF --> Sample Data Memory
0x400 - 0x40C --> General Purpose Registers
0x40D - 0x40F --> Low speed ADC (Potentiometers) Values
0x410 - 0x417 --> Audio input and output samples

The instruction set supported by the Python assembler is as follows:

DSP Instruction (Python Generator)Description
JMP(label)
Jump forward to 'label
'
JZ(label)
Jump 
forward to 'label' if Accumulator == 0.0
JNZ(label)
Jump 
forward 
to 'label' if Accumulator != 0.0

JP(label)
Jump 
forward 
to 'label' if Accumulator > 0.0
JN(label)
Jump 
forward 
to 'label' if Accumulator < 0.0
JZP(label)
Jump 
forward 
to 'label' if Accumulator >= 0.0
JZN(label)
Jump 
forward 
to 'label' if Accumulator <= 0.0

Put(address)
Memory[offset] = Accumulator
Get(address)
Accumulator = Memory[address + (Accumulator & 0xFF)]
Set(address)
Memory[address + (Accumulator & 0xFF)] = Accumulator
Log()
Accumulator = Logarithm16( Accumulator )
Exp()
Accumulator = Antilog16( Accumulator)
00C(constant)
Accumulator = 0.000000000     * 0.000000000     + constant
1AC(constant)
Accumulator = 1.000000000     * Accumulator     + constant
AC0(constant)
Accumulator = Accumulator     * constant        + 0.000000000
AAC(constant)
Accumulator = Accumulator     * Accumulator     + constant
1CM(constant,address)
Accumulator = 1.000000000     * constant        + Memory[address]
CM0(constant,address)
Accumulator = constant        * Memory[address] + 0.000000000
CMA(constant,address)
Accumulator = constant        * Memory[address] + Accumulator
ACM(constant,address)
Accumulator = Accumulator     * constant        + Memory[address]
AMC(constant,address)
Accumulator = Accumulator     * Memory[address] + constant
MMC(constant,address)
Accumulator = Memory[address] * Memory[address] + constant

Programming

Step 1: Install Python.

Step 2: Download nextdsp.zip

Step 3: Assemble and download your program using the script file named "nextdsp.py"

This script defines the DSP instruction set and implements the assembler, down-loader and simulator.  The script can be executed from the command line and will print syntax and usage information.  The following table shows examples for each function:

 Assemble a program and display the resulting assembly listing nextdsp.py program.py
 Assemble a program and download the image to FLASH memory nextdsp.py program.py COM3
 Assemble a program and simulate it using WAVE files for input/output nextdsp.py program.py output.wav input.wav

Step 4: Check out the Download utilities <TODO: synth.py> and <TODO: plot.py> to help with DSP algorithm development.  The following table shows examples for these two scripts:

 Store samples for 1.0 seconds of a 500 Hz sine wave in WAVE file
 synth.py S data.wav 48000 1.0 500
 Store samples for 1.0 seconds of 10 to 10000 Hz sine log sweep ...
 synth.py S data.wav 48000 1.0 10 10000
 1.0 seconds of 100, 200 and 500 Hz sine waves combined
 synth.py M data.wav 48000 1.0 100 200 500
 1.0 seconds of random / white noise
 synth.py N data.wav 48000 1.0
 Piece-wise linear waveform (25 msecond ramp from -1.0 to 1.0)
 synth.py R data.wav 48000 0.0 -1.0 0.025 +1.0
 Display time-domain plot for samples in WAVE file
 plot.py T data.wav
 Display frequency-domain plot for samples in WAVE file
 plot.py F data.wav

Companion Board

This board is designed to work with the DSP  board and supplies the following:
  1. Micro-USB connector and USB to Serial adapter for DSP board programming!
  2. Switched capacitor voltage divider to lower power drain for 9V operation (like in a stomp-box)
  3. Voltage regulator for the DSP board's 3.3 volt supply
  4. Buffered input for pre-ADC filtering and direct connection to guitar
  5. Buffered output for post-DAC filtering and direct connection to amp or pedal
 Pin Usage Notes
 1Serial RX
Serial port receive.  Not used.
 2Serial TX
Serial port transmit.  Connect to DSP board serial programming pin (pin #1).
 3USB Power (5.0V)
5.0 volt power from USB adapter.
 4Power Supply
Companion board supply.  Connect to external power source (such as a 9 volt battery) or to the companion board's USB power pin.
 5Regulated Power (3.3V)
3.3 volt regulated supply.  Connect to DSP board power supply pin (pin #5).
 6GroundAnalog and digital ground.  Connect to DSP board ground pin (pin #6).
 7Analog Return
Input to buffer #2 for the DSP board analog output.  Connect to DSP board analog output (pin #7 or #8).
 8Analog Output
Output from buffer #2 for the DSP board analog output.  Connect to amp or other pedal input.
 9Analog Send
Output from buffer #1 for the DSP board analog input.  Connect to DSP board analog input (pin #9 or #10).
 10Analog Input
Input to buffer #1 for DSP board analog input.  Connect to guitar or other pedal output.

<TODO> Show Hookup Example !!!

Design Files

Want to build your own instead of buying pre-built and tested boards from me?  This ZIP file has everything you need to order PCB's, to build boards, to program the micro-controller, and to create and download DSP programs!!!  It contains:
  1. The DSP board and companion board PCB layout file (for FreePCB): nextdsp.fpc
  2. The ATtiny84 firmware files (source code, make-file and build file) for the DSP board:  nextdsp.c, nextdsp.mak, nextdsp.bat
  3. The Python assembler/down-loader script, utility scripts and DSP code examples: nextdsp.py, test.py, etc
  4. The component listings and placement for the boards are show below:
DSP Board:

Label(s) Part
 Notes
 U1 AL3102 (16-pin SOIC Wide) 
 U2 WM8731 (28-pin TSSOP) 
 U3 ATtiny84 (14-pin SOIC Narrow)
 
 C1,C2,C3 0.1uF 0603, 10uF 0603, ?uF 0603
 C3 can be added for more noise reduction
 C4,C5 22nF 0603
 
 C6,C7 0.1uF 0603, 10uF 0603
 
 C8,C9,C10 0.1uF 0603, 10uF 0603, ?uF 0603
 C3 can be added for more noise reduction
 C11,C12,C13 0.1uF 0603, 10uF 0603, ?uF 0603
 C3 can be added for more noise reduction
 C14,C15 Unspecified (Not Used)
 Use to reduce DSP serial interface noise if needed
 C16,C17,C18 0.1uF 0603, 10uF 0603, ?uF 0603
 C3 can be added for more noise reduction
 R1 10K 0603
 
 R2,R5 Both are 47K 0603
 
 R4,R5 Both are 1K 0603
 
 D1,D2 Both are LED 0603
 
 X1 <FIXME>
 12.288 MHz Crystal
Companion Board:

 Label(s) Part Notes
 U1 FT232R (28-pin TSSOP)
 USB to serial converter
 U2 TPS71533 (6-pin SC-70)
 3.3V LDO linear vreg
 U3 MAX1044 (MSOP-8/uMAX-8) Switched capacitor voltage divider
 U4 Dual Opamp (MSOP-8/uMAX-8)
 Should have Rail-to-Rail I/O capability
 C1,C2,C5 470pF 0603, 1uF 0603, 1uF 0603
 
 R1,R2,R5 10K 0603, 10K 0603, 1K 0603
 
 C4,C3,C8 470pF 0603, 1uF 0603, 1uF 0603 
 R4,R3,R8 10K 0603, 10K 0603, 1K 0603 
 C6,C7 22nF 0603, 22nF 0603
 
 C10,C11,C12,C13 All are 10uF 0805
 
 R11,R12 Both are 1K 0603
 
 D1,D2 Both are LED 0603
 
 C16 10nF 0603
 
 L1 Inductor <FIXME> 0805
 
 C18,C19 0.1uF 0603, 10uF 0603
 
 USB <FIXME>Micro Type-B  USB connector



Comments