Can audio samples be written over the SPI port on the ADAU1701?
Hello,
I designed a custom board that uses the ADAU1701. I have several external ADC's, which output I2S over to a PIC32MZ microcontroller. The PIC is connected to the ADAU1701 with a SPI port, and a few GPIO. I wanted the PIC to have direct access to the audio samples, for processing and re-routing to other devices. Unfortunately, I didn't think it through very well, as I made the assumption that I could mix the samples in my microcontroller, and just write them over to the DSP over SPI (I'm using the SPI port to program the DSP, so I wanted to kill two birds with one stone). Now that I'm writing the code for it, it doesn't look like there's a direct way to write audio samples into the DSP. I've thought of a few possible workarounds, and I'm curious if these could work:
1. Use an Interface Register, ala the attached picture. At this point, I'm just looking at doing a simple audio pass-through. The datasheet states that these are typically used for volume and EQ settings, but also states that the settings are updated at the sampling frequency. This would be exactly what I'm looking for.
2. If the above solution isn't possible, I thought that it could be possible to have a 1st order FIR filter, with a DC input. I could then write (through safeloading) a scaled version of my audio sample as the coefficient of the filter. Since it's 1st order, the output of the filter would effectively be my audio sample.
Any insight on either of these choices would be appreciated. Once my software is at the point where it can program the ADAU1701, I'll try these out and come back to share if they work or not.
Audio Signal Processors
SigmaDSP Audio Processors
adau1701
Hello,
This is an interesting question! I think you're on the right track with your second idea. The one thing you would want to do would be to add a GPIO output that would send a flag to the PIC at the beginning of each sample, which the PIC would then use as a trigger to write the new data. That would fix any sync issues. Also, instead of a first-order FIR filter, you could just use a gain block, which would reduce the amount of data you would need to write to update the sample.
Some back-of-the-envelope calculations: the ADAU1701 SPI rate is 6.25MHz. We'll assume the PIC can run at that rate. You'll need to write 54 bits for a safeload write (10-bit parameter address, 28-bit parameter data, 16-bit DSP Core Control register to tell it to update from the safeload register). This gives a maximum sample rate of about 115kHz. So, in theory, you should be able to use this method to output up to two 48kHz I2S streams, or one single 96kHz I2S output.
Just note that you'll have very little overhead to do any other safeload writes or control of the chip, unless you interrupt the audio stream.
It's an interesting hack! Let us know how it goes for you.
Best Regards,
Tyler
Thanks for the reply, Tyler. It gave the idea some legitimacy. It turns out that this idea is indeed possible. Here is what I did:
To produce pass through audio, you can connect a DC source to a gain block, then to the DAC output. The value of the DC source is a writable parameter, so there isn't even a need to write to the gain block at all - I just keep it there to scale down the output a little bit. Keep in mind that the data format for the DC source is 5.23, and the DAC format is 1.23, so only write to the lower 24 bits of the parameter.
The timing is a little tricky. Because the max SPI rate is only 6.25 MHz, you cannot do safeloading and maintain a sample rate of 48 kHz. Safeloading requires you to write to three different registers, and they are non-adjacent, so burst mode cannot be used:
Parameter Address: 8 bits for chip address + 16 bits for register address + 16 bits for the written parameter address
Parameter Data: 8 bits for chip address + 16 bits for register address + 32 bits for the written parameter data
Trigger Safeload: 8 bits for chip address + 16 bits for register address + 16 bits for the write to the core control register
Total: 136 bits + at least a few cycles in between each register write = 140 bits
Max rate = 6.25MHz/140 = 44.6 kHz
However, writing to the parameter memory directly requires only one data transfer of 56 bits, which allows one to achieve a sample rate of 48 kHz. To avoid the clicks and pops and stuff that the datasheet warns about, I re-purposed one of the serial data outputs as a "sync pulse" (MP8 was one of the GPIO pins I connected to my PIC). To do this, I used two DC sources, one at 0 and one at 0.875 (three adjacent ones, and the rest zeros), and connected them to the left and right channels of a serial data output, respectively. If you know how I2S works, the DSP outputting those DC values will look just like a small pulse every 48 kHz (or whatever sample rate you set). My microcontroller triggers an interrupt on that pulse, which initiates the write of my audio sample to the ADAU1701 parameter memory. You can change the 0.875 to something else, to move around the location of the pulse and find a sweetspot where there isn't any clicking or popping present, but I have tested my system with this value, and the audio has no artifacts of any kind (or none that I can hear, anyway).
On a side note, it seems you cannot run the SPI port at a rate faster rate than your MCLK input. I do not believe the ADAU1701 datasheet explicitly says this (maybe it is common sense, idk). I have experience writing software for the ADAU1452, which does actually specify this restriction, so it wasn't much of a problem for me personally.
In conclusion, it requires some creativity, and you will not be able to write to any other parameters on the fly (like Tyler said), but audio samples CAN INDEED be written over the SPI control port in the ADAU1701!
I hope this helps somebody else out,
Dave
Please log in to reply.