dsPIC/PIC32 tone generator

gen.jpg

This is a project for the dsPIC33FJ128GP802 or PIC32MX150F128B acting as a tone generator connected to a Raspberry Pi.

Four separate tones may be generated simultaneously from five different waves and each tone can be any audible frequency.

A tone may also be triggered and it has a standard four stage envelope (ADSR).

This project is under development and certain aspects may change and features added or removed at any time.

Waves

There are standard wave types supported for generating tones.

sine.jpg triangle.jpg sawtooth.jpg square.jpg

A noise generator is also available which operates at the current frequency.

noise.jpg

Schematic

This is the bare minimum layout required for this project using the dsPIC with integrated audio DAC. We use a RPi for communication and ICSP.

For PIC32 an external audio DAC is required. Only the CS4334K and PT8211 are supported at present and are selected at compile time. Connection to either device is as follows.

CS4334K WITH Vcc = 5V.

PIC32MX150   CS4334K         COMMENT
----------   -------         -------
PIN 15 RPB6  PIN 4 MCLK      128X OVERSAMPLING CLOCK
PIN 16 RPB7  PIN 3 LRCK      SAMPLE RATE LEFT/RIGHT CLOCK
PIN 17 RPB8  PIN 1 SDATA     SERIAL DATA INPUT
PIN 18 RPB9  PIN 2 DEM/SCLK  DE-EMPHASIS FILTER OFF/ON
PIN 25 SCK1                  UNUSED
PT8211 WITH Vdd = 5V.

PIC32MX150   PT8211          COMMENT
----------   -------         -------
PIN 15 RPB6                  UNUSED
PIN 16 RPB7  PIN 2 WS        SAMPLE RATE LEFT/RIGHT CLOCK
PIN 17 RPB8  PIN 3 SDATA     SERIAL DATA INPUT
PIN 18 RPB9                  UNUSED
PIN 25 SCK1  PIN 1 BCK       SERIAL BIT CLOCK

The CS4334K is a far superior device, but the PT8211 is incredibly cheap (15p each).

Firmware

For dSPIC First install a working XC16 compiler, for PIC32, install XC32.

Now build the dsPIC/PIC32 applications.

hg clone http://hg.kewl.org/pub/generator
cd generator/src
make

Pickle must be installed and configured and when ready we can write the firmware.

Eg.

p24 lvp program dspic.hex

Usage

Controlling the tone generator is accomplished via the RPi UART at 115200 baud.

When connected a prompt is displayed which contains the currently selected voice. If no prompt is seen, pressing enter will bring it up.

Commands are entered following a parameter entry. Parameter entry is done via a 32-bit accumulator. As each nibble of a hexadecimal value is entered the current accumulator value is shifted left 4 bits and the new value added. To clear the accumulator, enter eight noughts in succession or a full-stop.

Once the accumulator has been set, and a single character command may be entered. The command operates on the current accumulator value.

Commands

Here is the command table, most commands operate on the current accumulated value described in usage above.

Command Description
. The accumulator is reset
+ The accumulator is incremented
- The accumulator is decremented
~ The accumulator low nibble is transferred to the voice function selection byte
= The accumulator is transferred to the voice control word
/ The accumulator low word is transferred to the voice volume word
% The accumulator low word is transferred to the voice square wave duty word
@ The accumulater low word is transferred to the voice ADSR envelope generator
! Trigger the voice ADSR envelope
> The accumulator low nibble is transferred to the voice selection byte
\ The accumulator low word is transferred to the master volume word
# The accumulator low byte is evaluated as a midi note and used to update the voice control word
< The accumulator is evaluated as a frequency and used to update the voice control word
$ The accumulator is evaluated as SID HI/LO registers and used to update the voice control word

If updating the voice control word directly using '=' (rather than using a midi note, frequency or SID value) the following formula must be used.

CONTROL WORD = 2^32 / 78000 * FREQUENCY

Using GNU bc from the shell we can calculate the above for 440 Hz like this.

printf "%08X=\n" `echo "scale=10; 2^32 / 78000 * 440" | bc`
0171B0B4=

Examples

Here are some examples showing the parameter entry followed by a command and the function performed.

Entry Function
1~ Select sine waveform
2~ Select triangle waveform
3~ Select saw-tooth waveform
4~ Select square waveform
5~ Select noise
0~ Select nothing (OFF)
7FFF/ Set max volume
8000% Set 50% duty cycle
AAAA@ Set ADSR
! Trigger ADSR

Resources

NCO