One of the neat features of the Buffalo III-SE is that it allows you to have both a SPDIF and I2S source connected and to switch between them using the on-board IP_S pins, thus obviating the need for an OTTO or other external switching mechanism. And if you’re controlling the BIII-SE with an Arduino you only need to use a single (digital) pin to switch between sources. Turns out it’s very easy to implement, but I couldn’t find any guidance on the web.
The following assumes that you have a SPDIF and I2S source connected the BIII-SE (block “1” in the picture below). ALl you need to do is connect a digital pin (I use pin #6) on the Arduino to the pin below the “S” on the IP_S header on the DAC – circled in red in the picture below with a red arrow pointing to it.
The code is simple as well.
Put this in your initialization block:
#define IPSPIN 6 // Or whatever pin you're using pinMode(IPSPIN, OUTPUT); digitalWrite(IPSPIN, HIGH); //Enable pull-up resistor - default is SPDIF
And then just switch the pin HIGH when you want SPDIF and LOW when you want I2S.
If you’re using the HiFiDuino code, then just swap out the setAndPrintInputFormat function for this one:
void setAndPrintInputFormat(byte value){ // This register also controls mono-8channel operation, thus more code... lcd.setCursor(8,0); switch(value){ case 0: // Enable SPDIF for DATA 1 pin writeSabreReg(0x08,0xE8); // Reg 8: Enable SPDIF input format bitSet(reg17L,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: write value into register #ifdef DUALMONO bitSet(reg17R,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: write value into register #endif DUALMONO writeSabreReg(0x12,0x01); // Set SPDIF to input #1 (only input valid for BII is 1 and 5) spdifIn=true; // Indicates input format is spdif. lcd.print("SPd"); break; case 1: // Enable SPDIF for DATA 3 pin (For BIII use) writeSabreReg(0x08,0xE8); // Reg 8: Enable SPDIF input format bitSet(reg17L,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: write value into register #ifdef DUALMONO bitSet(reg17R,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: write value into register #endif DUALMONO writeSabreReg(0x12,0x02); // Set SPDIF to input #3 spdifIn=true; // Indicates input format is spdif. lcd.print("Sp3"); break; case 2: // Enable SPDIF for DATA 7 pin (For BIII use) writeSabreReg(0x08,0xE8); // Reg 8: Enable SPDIF input format bitSet(reg17L,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: write value into register #ifdef DUALMONO bitSet(reg17R,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: write value into register #endif DUALMONO writeSabreReg(0x12,0x40); // Set SPDIF to input #7 spdifIn=true; // Indicates input format is spdif. lcd.print("Sp7"); break; case 3: // Enable SPDIF for DATA 7 pin (For BIII use) writeSabreReg(0x08,0xE8); // Reg 8: Enable SPDIF input format bitSet(reg17L,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: write value into register #ifdef DUALMONO bitSet(reg17R,3); // Reg 17: auto spdif detection ON -Set bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: write value into register #endif DUALMONO writeSabreReg(0x12,0x80); // Set SPDIF to input #7 spdifIn=true; // Indicates input format is spdif. lcd.print("Sp8"); break; case 4: // I2S 32 bit bitClear(reg17L,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: Auto spdif detection OFF #ifdef DUALMONO bitClear(reg17R,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: Auto spdif detection OFF #endif DUALMONO writeSabreReg(0x08,0x68); // Reg 8: Enable I2S/DSD input format spdifIn=false; // Set variable to indicate input format is I2S/DSD mode bitClear(reg10,4); // Setting to I2S (2 bits required) bitClear(reg10,5); bitSet(reg10,6); // Setting to 32 bit (2 bits required) bitSet(reg10,7); writeSabreReg(0x0A,reg10); lcd.print("I2S"); break; case 5: // LJ 32 bit bitClear(reg17L,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: Auto spdif detection OFF #ifdef DUALMONO bitClear(reg17R,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: Auto spdif detection OFF #endif DUALMONO writeSabreReg(0x08,0x68); // Reg 8: Enable I2S/DSD input format spdifIn=false; // Set variable to indicate input format is I2S/DSD mode bitSet(reg10,4); // Set to LJ bitClear(reg10,5); bitSet(reg10,6); // Set to 32 bit bitSet(reg10,7); writeSabreReg(0x0A,reg10); lcd.print("LJF"); break; case 6: // RJ 32 bit bitClear(reg17L,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: Auto spdif detection OFF #ifdef DUALMONO bitClear(reg17R,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: Auto spdif detection OFF #endif DUALMONO writeSabreReg(0x08,0x68); // Reg 8: Enable I2S/DSD input format spdifIn=false; // Set variable to indicate input format is I2S/DSD mode bitSet(reg10,5); // Set to right justified format bitClear(reg10,4); bitSet(reg10,6); // Set to 32 bit bitSet(reg10,7); writeSabreReg(0x0A,reg10); lcd.print("R32"); break; case 7: // LRJ 24 bit bitClear(reg17L,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: Auto spdif detection OFF #ifdef DUALMONO bitClear(reg17R,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: Auto spdif detection OFF #endif DUALMONO writeSabreReg(0x08,0x68); // Reg 8: Enable I2S/DSD input format spdifIn=false; // Set variable to indicate input format is I2S/DSD mode bitSet(reg10,5); // Set to right justified format bitClear(reg10,4); bitClear(reg10,6); // Set to 24 bits mode bitClear(reg10,7); writeSabreReg(0x0A,reg10); lcd.print("R24"); break; case 8: // LRJ 24 bit bitClear(reg17L,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: Auto spdif detection OFF #ifdef DUALMONO bitClear(reg17R,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: Auto spdif detection OFF #endif DUALMONO writeSabreReg(0x08,0x68); // Reg 8: Enable I2S/DSD input format spdifIn=false; // Set variable to indicate input format is I2S/DSD mode bitSet(reg10,5); // Set to right justified format bitClear(reg10,4); bitSet(reg10,6); // Set to 20 bits mode bitClear(reg10,7); writeSabreReg(0x0A,reg10); lcd.print("R20"); break; case 9: // LRJ 16 bit bitClear(reg17L,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreLeftReg(0x11,reg17L); // Reg 17: Auto spdif detection OFF #ifdef DUALMONO bitClear(reg17R,3); // Reg 17: manual SPDIF -Clear bit 3 writeSabreRightReg(0x11,reg17R); // Reg 17: Auto spdif detection OFF #endif DUALMONO writeSabreReg(0x08,0x68); // Reg 8: Enable I2S/DSD input format spdifIn=false; // Set variable to indicate input format is I2S/DSD mode bitSet(reg10,5); // Set to right justified mode bitClear(reg10,4); bitClear(reg10,6); // Set to 16 bit mode bitSet(reg10,7); writeSabreReg(0x0A,reg10); lcd.print("R16"); break; // lcd.write(127); // Print Arrow to indicate this is input seletion and not signal } if (spdifIn) { //If we're expecting SPDIF input, we want to pull IPS high on the DAC digitalWrite(IPSPIN, HIGH); } else { //If we're not expecting SPDIF, pull IPS low digitalWrite(IPSPIN, LOW); } }
Thanks to LeonvB and the folks at TPA for talking me through the process.