//-- WS=1, LEFT
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN,0);
digitalWriteFast(WS,1);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
for (int i=15; i>=0; i--)
{
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN, (L>>i) & 1);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
}
//-- WS=0, Right
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN,0);
digitalWriteFast(WS,0);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
for (int i=15; i>=0; i--)
{
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN, (R>>i) & 1);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
}
True, there is no solution yet that particular DAC behaviour.
Probably not really audible since the error is just one BCLK off versus the sample interval you are talking about.
Paul
Added the following code to the end of the loop to update the channels within 2 usec of each other. See attached scope capture. It's just a blip of the WS. Been stable for hours.*** Please read this if you are wanting to use this bit banging approach to run the PT8211 as a simple stereo DAC ***
I discovered that the stereo code I posted earlier on causes one channel of the DAC to lag the other by 1 sample interval. So if you are running a mono signal into both sides, it will increasingly shift towards the leading side as the sample rate gets lower.
However, if you swap the order of L and R bit banging sequences this is corrected. Presumably the chip synchronizes the transfer of the two channels to the output after the R channel has been written, which unfortunately is not described in the data sheet.
For high sampling rates you will barely notice the change, but if you need to run this at low sample rates (as I do sometimes) you definitely will hear the impact on the stereo field.
Here is the revised code needed to avoid the sample offset ( L and R samples are contained in the variables "L" and "R"):
Code://-- WS=1, LEFT digitalWriteFast(BCLK,0); digitalWriteFast(DIN,0); digitalWriteFast(WS,1); delayNanoseconds(HALFCLKns); digitalWriteFast(BCLK,1); delayNanoseconds(HALFCLKns); for (int i=15; i>=0; i--) { digitalWriteFast(BCLK,0); digitalWriteFast(DIN, (L>>i) & 1); delayNanoseconds(HALFCLKns); digitalWriteFast(BCLK,1); delayNanoseconds(HALFCLKns); } //-- WS=0, Right digitalWriteFast(BCLK,0); digitalWriteFast(DIN,0); digitalWriteFast(WS,0); delayNanoseconds(HALFCLKns); digitalWriteFast(BCLK,1); delayNanoseconds(HALFCLKns); for (int i=15; i>=0; i--) { digitalWriteFast(BCLK,0); digitalWriteFast(DIN, (R>>i) & 1); delayNanoseconds(HALFCLKns); digitalWriteFast(BCLK,1); delayNanoseconds(HALFCLKns); }
//-- Blip the WS to update the Right channel immediatly after valid Data received instead of waiting for the next sampletime
digitalWriteFast(WS,1);
delayNanoseconds(HALFCLKns);
delayNanoseconds(HALFCLKns);
digitalWriteFast(WS,0);
I didn't think you would need to do that if you use the code I posted in #27. I don't have time at the moment to double check that but perhaps you could? I recall the (sparse) data sheet does claim the two DAC outputs are synchronously updated, but it doesn't state whether that's done on L or R write.Added the following code to the end of the loop to update the channels within 2 usec of each other. See attached scope capture. It's just a blip of the WS. Been stable for hours.
Code://-- Blip the WS to update the Right channel immediatly after valid Data received instead of waiting for the next sampletime digitalWriteFast(WS,1); delayNanoseconds(HALFCLKns); delayNanoseconds(HALFCLKns); digitalWriteFast(WS,0);