This is a voltage controlled DDS, implemented with a Cypress PSoC (Programmable System-on-Chip). It uses standard 1V/Octave control voltages over a 0-10V range and generates 8 different waveforms with a +/-5V swing as output. Output frequencies from 20Hz-20kHz are possible, and falling-edge sensitive hard-sync is also provided.
The waveforms are:
These were all recorded through a mixer and a USB A/D on a Mac with Felt-tip Sound Studio. Note that these are plain .WAV files and thus rather large. I tried using lame to encode them as .MP3, but the results weren't very much like the original.
PSoC Designer project files
Matlab scripts for lookup tables
Since the summation stage is inverting, we need to invert again to restore the sense of direction. Also, there's a gain of ~1/2 to get the 0-10V range down to 0-5V required by the PSoC ADC input. The gain of this stage is set with a trimmer pot to allow calibration after assembly. To reduce the sensitivity of the calibration, the feedback resistance is a combination of fixed and variable resistors.
Note that the control voltage sum may exceed 5V even after scaling, which could exceed the input voltage range of the PSoC. A 10k resistor is in-line between the op-amp and PSoC to limit the input current and allow the PSoC ESD diodes to clamp the input voltage.
The Digital VCO uses 95% of the flash memory, all of the digital blocks, 4 of the 6 analog blocks, the MAC, the decimator and all of the GPIO. The digital and analog blocks are divided among four user modules (Cypress' terminology for their hardware macro functions):
Running on the MCU is a fairly simple program which consists of a main routine that initializes the hardware blocks and then enters a loop waiting for the ADC results. When a new ADC sample is available, it is converted to an exponential frequency and saved in the DDS frequency register. After updating the frequency value, the waveform select pins are sampled and the waveform jump address is updated.
The exponential conversion calculation converts the 11-bit ADC samples into 24-bit frequency words for the NCO (numerically controlled oscillator). It does this by first scaling the 11-bit value so that there are 256 lsbs per volt, then using the bottom byte of the result as an index into a fractional exponent table. The output of this lookup operation is then scaled by integer powers of two using the value in the top byte of the scaled ADC value. The PSoC's 8x8 MAC is very useful in these calculations, which provide an exponential response that is within 0.5% of ideal.
There are two ISRs running in the background: The first is the DELSIG11 ISR which handles housekeeping functions for the ADC and is automatically generated by the PSoC Designer application. The second ISR is in sync with the DAC update rate and ensures that new samples of digital data are always available for the DAC. Part of this routine's task is to update the NCO which provides the address into the waveform tables.
The DAC update ISR contains 8 distinct waveform computation routines, one for each unique waveform. The sine, triangle and sawtooth waveforms all use 256-entry 16-bit lookup tables which contain the 11-bit DAC data as well as control bits for the DAC so they don't have to be computed in the ISR. The square, pulse and double-pulse waveforms are computed based on the msbs of the NCO phase. The random waveforms are triggered by the overflow of the NCO and read random data directly from the top two bytes of the PRS24 module.
The PSoC is clocked by its on-chip master clock which is factory-trimmed to run within 2.5% of 24MHz. Using an external 32768kHz crystal it would be possible to ensure 3ppm frequency accuracy, but that would use up two of the GPIO pins, and the sync and waveform select functions were felt to be more important.
The main thing to remember is that when you're generating signals with sharp transitions at low sampling rates, the aliases are going to hit you hard. There are a number of techniques for reducing or controlling this effect, but they unfortunately require either lots of computation or lots of memory, neither of which are available on this particular PSoC. Using a higher-end chip with more flash memory it might be possible to do multiple wave-tables with band-limited waveforms. In this technique, the frequency computation routine would also generate a pointer to the wavetable which is dependent not only on the waveform selection, but also on the current frequency. I'll probably play around with this for a future version of the firmware.
For more details on this, see Dr. Aaron Lanterman's series of lectures on Synthesis. He has an excellent discussion of digital oscillators here: Alias-free synthesis of classic analog waveforms; digital state variable filters (Warning: this is a ~200MB RealMedia file).
The hardware capabilities are truly stunning though, especially the analog modules. Using just three unique blocks they've cooked up a broad range of functions that, while primarily targeted at low-speed signal conditioning and data acquisition, can be pushed into audio-speed DSP. The digital blocks are useful as well, although I would have loved to see one additional function: an accumulator for quick computation of NCOs would have been a really nice additional feature.
I'll probably be exploring some of these in the future.
If no +5V is available, a standard LM7805 type regulator may be used on the +12V line to provide power for the PSoC. Since the PSoC and it's associated circuitry draw very little current (I measured 19mA), an LM78L05 might be used to reduce size.
Cypress provides PSoC Designer free of charge. It's a decent integrated development environment (IDE) which allows you to pick and place the hardware functions you want, configure them and link them into the firmware. After you've specified the hardware, you can write the firmware and debug it. The free version provides only assembly language support with no real debugging, but it can be augmented with a C compiler and In-Circuit Emulation (ICE). For this project, I found that assembly language was more than adequate, and I didn't need the ICE. Instead of spending $700+, I just routed debugging signals out to GPIO pins to monitor internal conditions.
There are over two hundred PSoC application notes available at Cypress' website. These cover both hardware and firmware topics and a wide variety of target applications.
Programming the PSoc requires special hardware. I used the CY3210-Miniprog1 which is available for a reasonable price from Digi-Key. It's a pretty good deal, and includes several of the high-pincount PSoC devices which are useful for developing complex applications.
Return to Synth page.