Hack a DAC project for Audio Techole/Prozor register data handling

Hi

So this project started because I have recently moved from Win to Linux and I was convinced that the bit rate of my SPDIF was running lower than it should.

I couldn't find a decent DAC for less than £100 that would offer me a read out of the sample rate and or bit rate. So I purchased a £10 job off Amazon and decided to try and make it talk.

After a few issues I can now talk to the DAC chip over I2C. But there are many registers and I am wondering how's best that I should handle the data.

So for example I might request data from register 0B and then receive the contents back say 0x27 (0100111) now each bit points to various states of the device, such as for example the bit rate. So expanded it would look like:

My issue is I cant decide how best to handle this as there are around 8 registers in total.
My thinking is to use the bitRead function and seperate the bits out then test them should they be a 1 or a 0 and ouput that to serial as a state

Like (this is rough)

If((bitRead(1, 8) == 1){
Serial.println("96khz RX")
}
else {
Serial.println("Less than 96Khz RX")

if((bitRead(1, 7) == 0){
Serial.println("Digital Silence")    
}
else {
Serial.println("No Silence")
}

etc..

Or do I seperate the bits and put them in to an array and then mask them and test that way? So many ways to do this but what is the best practice?

This is rough! but it does work and is only for testing! I do get the full read outs by walking through the various registers which has lead to me proving my SPDIF on linux is running at 48khz instead of 192khz but thats another project/headache. I am planning on adding an LCD screen so I get the readouts once I can figure out how is best to handle the data.

Thanks

Hi, @blaze101101
Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".

This will help with advice on how to present your code and problems.

Can you please post link to data/specs of the DAC?
What would you call a "decent DAC"?

What model Arduino are you using?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Hi

Oh no... Im not falling for that one lol

But I did want a chip that had an interface I could communicate with and these are not expensive so wouldn't bother me if i broke it. I am using an esp8266.

Here is the dac sheet:
MS8416

Here is the rough as toast project thrown together last night on the box it arrived in:

Thanks

If You would read the entire byte a 48 kHz it will almost be like 384 kHz bitrate.

Here is the setup code I wrote for the DAC which gets it working

It sets up the DAC MUX input/Serial audio bit rate to the serial audio chip, sets the correct Clock components and will produce sound. Once a signal is fed in to the DAC via optical or Coax then the other registers will populate with the information available on the datasheet.

#include <Wire.h>

void setup() {
  Wire.begin();

  Serial.begin(9600);
  while (!Serial);
  Serial.println("\DAC Talker");
}
#define CHIP_ADDRESS_WRITE 0x10
#define CHIP_ADDRESS_READ  0x10
byte REGISTER_ADDRESS = 0x00;

void loop() {
//REGISTER_ADDRESS ++;

//Setup the DAC so to accept input on SPDIF MUX as per PCB, only needs doing once and taking out of loop
Serial.println("\First Byte Sending Register 0");
Wire.beginTransmission(CHIP_ADDRESS_WRITE);
Wire.write(0x00);
Wire.write(0x00);
Wire.endTransmission();
delay(500); // Wait 5

Serial.println("\First Byte Sending Register 1");
Wire.beginTransmission(CHIP_ADDRESS_WRITE);
Wire.write(0x01);
Wire.write(0x00);
Wire.endTransmission();
delay(500); // Wait 5

Serial.println("\First Byte Sending Register 2");
Wire.beginTransmission(CHIP_ADDRESS_WRITE);
Wire.write(0x02);
Wire.write(0x80);
Wire.endTransmission();
delay(500); // Wait 5

Serial.println("\First Byte Sending Register 4");
Wire.beginTransmission(CHIP_ADDRESS_WRITE);
Wire.write(0x04);
Wire.write(0x80);
Wire.endTransmission();
delay(500); // Wait 5

Serial.println("\First Byte Sending Register 5");
Wire.beginTransmission(CHIP_ADDRESS_WRITE);
Wire.write(0x05);
Wire.write(0xC0);
Wire.endTransmission();
delay(500); // Wait 5

// End of DAC init

// Walk through registers
Serial.println("\Requesting Data...");
Wire.beginTransmission(CHIP_ADDRESS_READ);
Wire.write(0x0B);
//Wire.write(REGISTER_ADDRESS);
Wire.endTransmission();
Wire.requestFrom(CHIP_ADDRESS_READ, 1); // We want one byte
//uint8_t val = Wire.read();
byte valb = Wire.read();

Serial.println("\Register...");
Serial.println("");
Serial.println(REGISTER_ADDRESS, HEX);
Serial.println("\Value Read...");
Serial.println("");
//Serial.println(val);
Serial.println("\Value Read...Hex");
Serial.println("");
Serial.println(valb, HEX);
Serial.println(valb, BIN);
delay(500); // Wait 5

}

Hi

Oh no not reading the entire byte of audio, comms is over i2c and the DAC IC responds in time with arduino clock (DAC is slave dev)
Audio is dealt with only by the DAC, DAC simply has 8 or so registers of 1 byte that i need to process in some sort of way but there are many choices how to do it

Ta

Your original main question depends so much on the overall structure of your code. Since what you posted might, or might not reflect your final structure, it is difficult to answer.

Register values that don't change for the lifetime of the program, could be read once and assigned to a parameters struct for example. But if any bits change you are probably better to sample them in line, however if you want to be really "cool" you could wrap those bit tests in functions.

My $0.02

Hi
The idea is at some point I will write the code for a 20x4 LCD and display DAC status on there. I suppose what I am wondering is how I can best extract the bits i need from each byte read from the DAC and then set a condition to be true or false.
Its more a question of data handling as opposed to how I choose to display the result.

So for example the dac gives me 1101100 maybe I want to know the value of position 3, which could be say an CRC error condition. So I could use the bitRead function and find position 3 which in this example is a 1. Then I might want to serial print "Error":"True" or "Error":"False" depending on if its a 1 or 0.
That code is simple, but is it the best way? thats why I reached out on how other people handle this type of data who have more experience than me or if anyone can throw any ideas out there that would be more efficent than my ideas so far.
Thats a lot of "if" statements. Assuming there are 8 bits in each of the 8 registers I will be writing a lot of lines out, well 64. Suppose its managable.

Sounds reasonable to me. What is the problem? Have a look at the Arduino core or almost any hardware library. It's full of stuff like that.

Hi

No problem I suspect you're right and I had a feeling this was the best approach. I just threw this together:

if((bitRead(valb, 0) == 1)){
  Serial.println("Sample Rate >88Khz");
}
else{
  Serial.println("Sample Rate <88Khz");
}

Seems to work OK

Well suspect rest of my day is going to be spent writing out lines.

Ta

If you require a printout, you're stuck with those lines anyway, no matter how you read the registers.