The XMOS is much faster than the Arduino. It has a clever hardware trick which allows you to control the exact timing of when values appear on its output ports. So if you can get a good frequency from it, you could also have high precision on the timing. The MCP4921 can be set to buffer the new samples and only apply them on toggling a pin called -LDAC. So you could connect this to a port of the XMOS and use it to control precisely when the samples take effect. I didn't actually do this, it's just something to note.
So how fast can you drive the DAC from XMOS? The first thing I did was to see what the maximum rate I could get on an output port is. I wrote a very simple program which just toggles a port between zero and one and loops round. This gives 14MHz.
The DAC uses the SPI interface, and XMOS provides a library for controlling it. There are synchronous and asynchronous flavors. Note that although we are only writing to the DAC (using the MOSI), you do also have to read from it (MISO). However, the SPI protocol is supposed to do both simultaneously, so I don't think this affects the speed. For the synchronous version, I got 25kHz, and for the asynchronous one 33KHz. These figures are quite disappointing, and suggest that the library has quite a lot of overhead. I found another SPI library on Github, and this got me to 128kHz. Note that at this frequency, we are well beyond the settling time of the DAC, and so even toggling the DAC value between it minimum and maximum of 4095, the output looks triangular. For the MCP4921, the settling time is 4.5us, which is close to the half-wave period at 128kHz. Note that this means we are sending bits over the serial line at 2MHz - a long way off the tight loop value of 14MHz, but in a believable range.
Here's a summary of the numbers, with estimates of the frequency at 50 samples per cycle, and for a parallel DAC, calculated as above.
|Platform||Max freq||Max @ 50 samples||Parallel @ 50 samples|
|Arduino||20 kHz||400 Hz||6400 kHz|
|XMOS sync||25 kHz||500 Hz||8000 Hz|
|XMOS async||33 kHz||660 Hz||10560 Hz|
|XMOS Github library||128 kHz||2560 Hz||40960 Hz|