Twisted Pear Audio Support
»
Product Support
»
Digital
»
Buffalo DAC
»
NEW! Arduino class library for the ES9028/38 chip
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: Possum - that's PUT the following line as the first line in setup():
Serial.begin(115200)
You can set the baud rate to 9600 but my library has very verbose diagnostics and the higher speed is recommended - change your I2C network sniffer to use the higher baud rate
BTW What Arduino are you using?
Clearly you have I2C comms with the DAC (its address is 48) - so there's no reason why we cant get this puppy to behave :-) Here is the code I am using: #include "ES9028.h" ES9028 dac = ES9028("Stereo DAC", ES9028::Stereo); void configureDAC(ES9028 dac) { dac.setSerialBits(ES9028::Bits_16); dac.setInputSelect(ES9028::InputSelect_SPDIF); dac.setSPDIFInput(ES9028::SPDIF_Data3); dac.setFilterShape(ES9028::Filter_Hybrid); dac.setAutoMute(ES9028::AutoMute_MuteAndRampToGnd); dac.setAutomuteTime(100); dac.setGPIO1(ES9028::GPIO_Automute); dac.setGPIO2(ES9028::GPIO_StandardInput); dac.setGPIO3(ES9028::GPIO_StandardInput); dac.setGPIO4(ES9028::GPIO_Lock); dac.setDpllBandwidthSerial(ES9028::DPLL_Lowest); dac.setVolumeMode(ES9028::Volume_UseChannel1); dac.setAttenuation(25); } void setup() { // initialize digital pin LED_BUILTIN as the DAC lock light. Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); delay(1500); dac.mute(); configureDAC(dac); delay(500); dac.unmute(); } void loop() { Serial.println("Locked"); digitalWrite(LED_BUILTIN, dac.locked()); delay(100); } I still could not get any lock. I have inputs on both SPDIF and I2S. I hope I did not mess up my dac. What could be wrong with my setup? Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: cdeveza Originally Posted by: Possum - that's PUT the following line as the first line in setup():
Serial.begin(115200)
You can set the baud rate to 9600 but my library has very verbose diagnostics and the higher speed is recommended - change your I2C network sniffer to use the higher baud rate
BTW What Arduino are you using?
Clearly you have I2C comms with the DAC (its address is 48) - so there's no reason why we cant get this puppy to behave :-) GOOD NEWS, for some reason, it is now locking. I change the input to "InputSelect_DSD" and its now locking, then I change it back to "InputSelect_SPDIF" and its now locking. Wonderful. Its 2:00am here, so I will try and see if its actually playing music tomorrow. Now next, is there a way to check the sample rate? BTW, what you did here is excellent, it will make it a lot easier for diy'er like me. Thanks again for your help, at least my project is moving, Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/5/2012(UTC) Posts: 208 Thanks: 4 times Was thanked: 16 time(s) in 14 post(s)
|
You need same baud rate as set in bottom right of serial monitor window
Remove firmware chip from dac - switches do nothing once that chip is removed
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
GOOD NEWS, for some reason, it is now locking. I change the input to "InputSelect_DSD" and its now locking, then I change it back to "InputSelect_SPDIF" and its now locking. Wonderful. Its 2:00am here, so I will try and see if its actually playing music tomorrow. Now next, is there a way to check the sample rate? BTW, what you did here is excellent, it will make it a lot easier for diy'er like me. Thanks again for your help, at least my project is moving, Alex
MY BAD, so sorry, I thought its locking but it still is not here are the messages: ErrorAlex1.jpg (250kb) downloaded 4 time(s).
Back to the drawing board...
Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Hi Possum,
I think I found what the problem is. When it writes to the regs, the return status is ok, but when you read to that same reg the return status is NOT ok. In other words, it can write but could not read. Here is my test code:
/*==========*/ void writeSabreReg(byte regAddr, byte regVal) { Wire.beginTransmission(0x48); // Hard coded to the the Sabre/Buffalo device address for stereo // or mono left. For stereo same as writeSabreReg() Wire.write(regAddr); // Specifying the address of register Wire.write(regVal); // Writing the value into the register Wire.endTransmission(); }
byte readOne(byte regAddr) { Wire.beginTransmission(0x48); // Hard coded the Sabre/Buffalo device address Wire.write(regAddr); // Queues the address of the register Wire.endTransmission(); // Sends the address of the register Serial.println(Wire.requestFrom(0x48,1)); // Hard coded to Buffalo, request one byte from address unsigned long retryUntil = millis() + 20; while (!Wire.available()) { Serial.println("Trying..."); if (millis() > retryUntil) { Serial.println("TimeOut..."); return 0; } } return Wire.read(); // Return the value returned by specified register }
void setup() { Serial.begin(115200);
// Serial.begin(9600); lcd.begin(20, 4); // Set up the LCD's number of columns and rows: lcd.setBacklightPin(3,POSITIVE); lcd.setBacklight(1); writeSabreReg(1,1); delay(200);
readOne(1); } This code Times Out..... Is my DAC Bad? I hope not..... There may be something thats preventing it from reading??
Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Hi Possum,
I have been reading your code. Something I am not quite familiar with. You have something like this:
_writeRegisterBits(7, F("001*****"));
What does F("001*****") means? I know its a number, but what notation is this?
Thanks again for your patience,
Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: cdeveza Hi Possum,
I have been reading your code. Something I am not quite familiar with. You have something like this:
_writeRegisterBits(7, F("001*****"));
What does F("001*****") means? I know its a number, but what notation is this?
Thanks again for your patience,
Alex Sorry possum, I am jumping ahead, I think I know how this works, I think you are doing bit wise operation. To set or clear which bit within the register. Sorry, Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/5/2012(UTC) Posts: 208 Thanks: 4 times Was thanked: 16 time(s) in 14 post(s)
|
I see the problem now you have shown the serial monitor output - you need to call Initialise() first like this:
if dac.Initialise() { configureDAC(dac); }
(also see the examples on GitHub)
_writeRegisterBits(7, F("001*****")) does not change the register bits where there is a '*' - but you don't need to know this as the library hides all the bits 'n bytes from you :-)
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/5/2012(UTC) Posts: 208 Thanks: 4 times Was thanked: 16 time(s) in 14 post(s)
|
Originally Posted by: Possum I see the problem now you have shown the serial monitor output - you need to call Initialise() first like this:
if dac.Initialise() { configureDAC(dac); }
(also see the examples on GitHub)
_writeRegisterBits(7, F("001*****")) does not change the register bits where there is a '*' - but you don't need to know this as the library hides all the bits 'n bytes from you :-) BTW Are you using an I2C isolator?
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: Possum Originally Posted by: Possum I see the problem now you have shown the serial monitor output - you need to call Initialise() first like this:
if dac.Initialise() { configureDAC(dac); }
(also see the examples on GitHub)
_writeRegisterBits(7, F("001*****")) does not change the register bits where there is a '*' - but you don't need to know this as the library hides all the bits 'n bytes from you :-) BTW Are you using an I2C isolator? Hi Possum, Yes, I do. I have a little progress. I need to wire up a good reset system, and clean up my wiring a bit. But I got it to work. But I have not tested yet if it actually plays music. After calling dac.initialise(). And calling configureDAC(dac) : void configureDAC(ES9028 dac) { dac.mute(); dac.setInputSelect(ES9028::InputSelect_SERIAL); dac.setSerialBits(ES9028::Bits_24); dac.setSPDIFInput(ES9028::SPDIF_Data3); dac.setFilterShape(ES9028::Filter_Hybrid); dac.setAutoMute(ES9028::AutoMute_MuteAndRampToGnd); dac.setAutomuteTime(100); dac.setGPIO1(ES9028::GPIO_Automute); dac.setGPIO2(ES9028::GPIO_StandardInput); dac.setGPIO3(ES9028::GPIO_StandardInput); dac.setGPIO4(ES9028::GPIO_Lock); dac.setDpllBandwidthSerial(ES9028::DPLL_Lowest); dac.setVolumeMode(ES9028::Volume_UseChannel1); dac.setAttenuation(25); delay(500); dac.unmute(); } Here is what I got: ErrorAlex1.jpg (224kb) downloaded 6 time(s).I will test it whether I get music in it. Thanks again possum for your patience, I really appreciate it, Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: cdeveza Originally Posted by: Possum Originally Posted by: Possum I see the problem now you have shown the serial monitor output - you need to call Initialise() first like this:
if dac.Initialise() { configureDAC(dac); }
(also see the examples on GitHub)
_writeRegisterBits(7, F("001*****")) does not change the register bits where there is a '*' - but you don't need to know this as the library hides all the bits 'n bytes from you :-) BTW Are you using an I2C isolator? Hi Possum, Yes, I do. I have a little progress. I need to wire up a good reset system, and clean up my wiring a bit. But I got it to work. But I have not tested yet if it actually plays music. After calling dac.initialise(). And calling configureDAC(dac) : void configureDAC(ES9028 dac) { dac.mute(); dac.setInputSelect(ES9028::InputSelect_SERIAL); dac.setSerialBits(ES9028::Bits_24); dac.setSPDIFInput(ES9028::SPDIF_Data3); dac.setFilterShape(ES9028::Filter_Hybrid); dac.setAutoMute(ES9028::AutoMute_MuteAndRampToGnd); dac.setAutomuteTime(100); dac.setGPIO1(ES9028::GPIO_Automute); dac.setGPIO2(ES9028::GPIO_StandardInput); dac.setGPIO3(ES9028::GPIO_StandardInput); dac.setGPIO4(ES9028::GPIO_Lock); dac.setDpllBandwidthSerial(ES9028::DPLL_Lowest); dac.setVolumeMode(ES9028::Volume_UseChannel1); dac.setAttenuation(25); delay(500); dac.unmute(); } Here is what I got: ErrorAlex1.jpg (224kb) downloaded 6 time(s).I will test it whether I get music in it. Thanks again possum for your patience, I really appreciate it, Alex Hi Possum, Ok, I just hooked it up to my stereo system, it went through all the codes ok, but still no sound. Can you please check on the my code? I may still be missing something or setting something wrong. I tried SPDIF/Toslink and I2S. BTW, my I2S source is DSD, is that ok? or maybe I should try PCM source and see if it works. Thanks again, Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/5/2012(UTC) Posts: 208 Thanks: 4 times Was thanked: 16 time(s) in 14 post(s)
|
You will need to use InputSelect_SPDIF instead of SERIAL
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: Possum You will need to use InputSelect_SPDIF instead of SERIAL I changed it to InputSelect_SPDIF, but still no go. Question though, does the on-board led lights that shows mute and lock, does it still work? Because on mine, the mute, lights up, but not too bright, so just asking. I may be still missing something. Just to be sure, I put back the on-board controller, and it still works fine. But the external one still not working. Any suggestions? Sorry, its taking so long.. Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: Possum I see the problem now you have shown the serial monitor output - you need to call Initialise() first like this:
if dac.Initialise() { configureDAC(dac); }
(also see the examples on GitHub)
_writeRegisterBits(7, F("001*****")) does not change the register bits where there is a '*' - but you don't need to know this as the library hides all the bits 'n bytes from you :-) I actually got all your files from github, looked thru your examples(they are for dualmono), I honestly do not know what else to do, why it works on others but not on mine. Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/5/2012(UTC) Posts: 208 Thanks: 4 times Was thanked: 16 time(s) in 14 post(s)
|
Originally Posted by: cdeveza Originally Posted by: Possum You will need to use InputSelect_SPDIF instead of SERIAL I changed it to InputSelect_SPDIF, but still no go. Question though, does the on-board led lights that shows mute and lock, does it still work? Because on mine, the mute, lights up, but not too bright, so just asking. I may be still missing something. Just to be sure, I put back the on-board controller, and it still works fine. But the external one still not working. Any suggestions? Sorry, its taking so long.. Alex This is how Russ's firmware works switching between SPDIF and I2s or DSD: for SPDIF: setAutoSelect(ES9028::AutoSelect_Disable); setInputSelect(ES9028::InputSelect_SPDIF); for I2S or DSD: setAutoSelect(ES9028::AutoSelect_DSD_SERIAL); setInputSelect(ES9028::InputSelect_SERIAL); please also set the DpllBandwidth to DPLL_Default to begin with - not DPLL_Lowest, as that may stop you getting a lock. Your current code will configure the GPIO pins as per the on-board firmware (lock light and automute indicator) Give that a try
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/5/2012(UTC) Posts: 208 Thanks: 4 times Was thanked: 16 time(s) in 14 post(s)
|
e.g.: For SPDIF
void configureDAC(ES9028 dac) { dac.mute(); dac.setSPDIFInput(ES9028::SPDIF_Data3); dac.setAutoMute(ES9028::AutoMute_MuteAndRampToGnd); dac.setAutomuteTime(4); dac.setGPIO1(ES9028::GPIO_Automute); dac.setGPIO2(ES9028::GPIO_StandardInput); dac.setGPIO3(ES9028::GPIO_StandardInput); dac.setGPIO4(ES9028::GPIO_Lock); dac.setVolumeMode(ES9028::Volume_UseChannel1); dac.enableVolumeLatching() ; dac.setAutoSelect(ES9028::AutoSelect_Disable); dac.setInputSelect(ES9028::InputSelect_SPDIF); dac.unmute(); }
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: Possum e.g.: For SPDIF
void configureDAC(ES9028 dac) { dac.mute(); dac.setSPDIFInput(ES9028::SPDIF_Data3); dac.setAutoMute(ES9028::AutoMute_MuteAndRampToGnd); dac.setAutomuteTime(4); dac.setGPIO1(ES9028::GPIO_Automute); dac.setGPIO2(ES9028::GPIO_StandardInput); dac.setGPIO3(ES9028::GPIO_StandardInput); dac.setGPIO4(ES9028::GPIO_Lock); dac.setVolumeMode(ES9028::Volume_UseChannel1); dac.enableVolumeLatching() ; dac.setAutoSelect(ES9028::AutoSelect_Disable); dac.setInputSelect(ES9028::InputSelect_SPDIF); dac.unmute(); } Thanks again possum, I really appreciate it. ok, so correct me if I am wrong, the difference between the two are only the setAutoSelect and setInputSelect. I will go ahead and try. Thanks, Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: cdeveza Originally Posted by: Possum e.g.: For SPDIF
void configureDAC(ES9028 dac) { dac.mute(); dac.setSPDIFInput(ES9028::SPDIF_Data3); dac.setAutoMute(ES9028::AutoMute_MuteAndRampToGnd); dac.setAutomuteTime(4); dac.setGPIO1(ES9028::GPIO_Automute); dac.setGPIO2(ES9028::GPIO_StandardInput); dac.setGPIO3(ES9028::GPIO_StandardInput); dac.setGPIO4(ES9028::GPIO_Lock); dac.setVolumeMode(ES9028::Volume_UseChannel1); dac.enableVolumeLatching() ; dac.setAutoSelect(ES9028::AutoSelect_Disable); dac.setInputSelect(ES9028::InputSelect_SPDIF); dac.unmute(); } BTW, how do you set the Volume, do you call dac.setVolumeMode(ES9028::Volume_UseChannel1); once, then keep calling dac.setAttenuation(XX); when to change the volume? Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 5/12/2016(UTC) Posts: 66 Location: Concord Thanks: 6 times
|
Originally Posted by: Possum e.g.: For SPDIF
void configureDAC(ES9028 dac) { dac.mute(); dac.setSPDIFInput(ES9028::SPDIF_Data3); dac.setAutoMute(ES9028::AutoMute_MuteAndRampToGnd); dac.setAutomuteTime(4); dac.setGPIO1(ES9028::GPIO_Automute); dac.setGPIO2(ES9028::GPIO_StandardInput); dac.setGPIO3(ES9028::GPIO_StandardInput); dac.setGPIO4(ES9028::GPIO_Lock); dac.setVolumeMode(ES9028::Volume_UseChannel1); dac.enableVolumeLatching() ; dac.setAutoSelect(ES9028::AutoSelect_Disable); dac.setInputSelect(ES9028::InputSelect_SPDIF); dac.unmute(); } Hi Possum, Its ALIVE!!, finally it works, both SPDIF and I2S/DSD works, thank you so much possum, your the greatest. Next question, I will have my controller the ability to change DpllBandwidth, FilterShape and IIR_Bandwidth, but besides these three, what other stuff can I play with. Things that will affect the sound. Also, is there a way to check the incoming Sample Rate? or when a signal is actually playing? Again, I want to emphasize, your code here makes it a lot simpler to customize a controller. This is the best so far that I have found. Thank you very much, thank you for sharing.. Alex
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/5/2012(UTC) Posts: 208 Thanks: 4 times Was thanked: 16 time(s) in 14 post(s)
|
Originally Posted by: cdeveza
Hi Possum,
Its ALIVE!!, finally it works, both SPDIF and I2S/DSD works, thank you so much possum, your the greatest. Next question, I will have my controller the ability to change DpllBandwidth, FilterShape and IIR_Bandwidth, but besides these three, what other stuff can I play with. Things that will affect the sound.
Also, is there a way to check the incoming Sample Rate? or when a signal is actually playing?
Again, I want to emphasize, your code here makes it a lot simpler to customize a controller. This is the best so far that I have found.
Thank you very much, thank you for sharing..
Alex
Excellent. As you know, the library encapsulates access to all the chip's functionality into an 'ES9028 Object'. Other code libraries can interact with instances of this object to create reusable modules - e.g.: I have other libraries that support infra red control and motorised volume control. This modular approach makes the main code far cleaner than putting everything into Setup() and Loop(). AutoSelect must be disabled for InputSelect to work (I don't use SPDIF so this is the first time I've had to deal with this scenario) Note that DSD has its own DpllBandwidth setting There are a bunch of other filter settings like DeEmph and THD - I've never played with them so can't comment as to how much of an audible difference they make (if any). In any case, I would strongly recommend you power the DAC's analog stage completely independently rather than using the 'default' AVCC SR regulators that take their power from the same 5V supply as the digital stage - as this makes a clearly audible difference far greater than playing with the filters. If AutoMute is enabled you can detect when sound is playing by reading dac.automuted() Sample Rate is about the only thing I haven't put into the 9028/38 library (the 9018 library has it) - but I am happy to add it if you want it.
|
|
|
|
Twisted Pear Audio Support
»
Product Support
»
Digital
»
Buffalo DAC
»
NEW! Arduino class library for the ES9028/38 chip
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.