Close

More DAC Output Design Details

A project log for 3-Chip Z80 Design

Combining a Z80 retro design with a modern PSoC CPU.

land-boardscomland-boards.com 11/01/2019 at 21:490 Comments

The Wave DAC in the PSoC doesn't allow the sin wave frequency to be set directly. The configuration screen for the WaveDAC8 lets you set:

This shows 200 samples, every 100 KHz. The scope shows a 1 KHz waveform which is correct.

The two waveform selects are done with an internal hardware "pin". The API does allow several controls which the Z80 uses to control the DAC. I have taken the pin to ground so I'm only generating sine waves. It would be easy to add a control for sine/triangle waves. All it would take would be a register bit. Let's add that capability.

That works nicely.

The control/status register for the DAC is at 98 (dec) from the Z80. The data register is at 99 (dec) from the Z80.

Control register values are:

Changing the sample frequency can be done via an external pin. Replacing the 100 KHz internal clock with an external 100 KHz clock does exactly the same thing as above.

The Clock_2 above has an API which can allow the PSoC to set some values. Unfortunately, there's no way to set the clock for an arbitrary frequency which would be nice for tone generation. There is an API for:

This would not be a great choice since it lacks the sort of resolution to code a grand piano keyboard but it's a good place to play around with the idea. Changed the number of samples to 16 which is a bit blocky but should be fine for this test. Left the clock at 100 KHz. Added a call to the function when the Z80 writes to the DAC data port.

Results are:

OUT 98,XFrequency
068 Hz
114.6 KHz
27.3 KHz
34.9 KHz
43.6 KHz
25467 Hz
25568 Hz

The top frequency should be 100 KHz divided by 16 or 6.25 KHz. The difference could be accounted for due the the extension of the 8-bit value from the CPU to the 16-bit counter value. Could probably figure it out mathematically, but it's pretty easy to just OUT values and see what I get. Middle C is 261.6 Hz.  OUT 98,62 gets pretty close.

A table of notes to frequency values could give additional precision. I'm taking the 8-bit frequency value and shifting it into the 16-bit value to load the register. Should be able to get some precision doing that. I did something similar for my R32V2020 32-Bit RISC CPU design. The PSoC can easily do a lookup into a 256 entry table of 16-bit values.

With a bottom frequency of 68 Hz, that's a pretty good range. 57 hZ is the bottom end (when setting the divisor to 0xFFFE. The other end is well above the audio range I care about (14.6 KHz).

Also, if we set the clock to the precise clock we can get 0.25% accuracy. Not that my tone deaf ear can tell the difference.

I spent a couple of hours working on a 24-bit counter to pre-scale the 60 MHz PSoC CPU clock but am having trouble getting it to count.

Discussions