Code:
#define DIN 7
#define BCLK 21 // max 20Mhz (50ns), using 2x slower when HALFCLKns = 50
#define WS 20
#define HALFCLKns 50 // clock cycle duration is twice this
int16_t saw=0;
int16_t saw2=0;
int16_t m[16] = {0x8000,0x4000,0x2000,0x1000,0x0800,0x4000,0x0200,0x0100,0x0080,0x0040,0x0020,0x0010,0x0008,0x0004,0x0002,0x0001};
elapsedMicros sampletime;
void setup()
{
digitalWrite(DIN,0);
digitalWrite(BCLK,0);
digitalWrite(WS,0);
pinMode(DIN, OUTPUT);
pinMode(BCLK, OUTPUT);
pinMode(WS, OUTPUT);
}
void loop() {
if(sampletime >= 25) // 40kHz
{
sampletime=0;
saw += 160; // 400 steps per cycle = 100Hz
if(saw >= 32000)
{
saw -= 64000;
}
saw2 += 320; // 200 steps = 200Hz
if(saw2 >= 32000)
{
saw2 -= 64000;
}
// at 10MHz (HALFCLKns 50) bit banging takes up 3.4us for delaynanoseconds calls, plus around 100x digitalWriteFast times
// total appears to be about 5us
//-- WS=0, Right
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN,0); // probably don't need this
digitalWriteFast(WS,0);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
for (int i=15; i>=0; i--)
{
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN,saw & m[i]);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
}
//-- WS=1, LEFT
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN,0); // probably don't need this
digitalWriteFast(WS,1);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
for (int i=15; i>=0; i--)
{
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN,saw2 & m[i]);
delayNanoseconds(HALFCLKns);
digitalWriteFast(BCLK,1);
delayNanoseconds(HALFCLKns);
}
digitalWriteFast(BCLK,0);
digitalWriteFast(DIN,0); // probably don't need this
digitalWriteFast(WS,0);
}
}