Open rupraph opened 11 years ago
I might be able to help a little more if you can provide me some details about what problem you are running into. Maybe some some schematics and code would give me a good starting point.
Without that, I can only say that I am using standard I2S protocol. I took a look at the datasheet of the WM8731 and it appears that it should work OK. Figure 27 on page 37 is representative of the mode that I used.
I'd try to start with the output only example I provided and try to match up the waveforms to the datasheet. If you can provide additional info I can take a look...
Ok, thx !
I am using with my due, a little proto board (from mikroe, "Audio Codec Board") with the wm8731 embedded on it.
My wiring for data transmission is done as this table :
MCU REF | FUNCTION | WM8731 PINS | DUE PINS | PROTO BOARD PIN NAMES |
PA14 | TK | BCLK | pin23 | SCK |
PA16 | TD | DACDAT | A0 | MOSI |
PA15 | TF | DACLRC | pin24 | DACLRC |
PB19 | RK | BCLK | A10 | SCK |
PB18 | RD | ADCDAT | A9 | MISO |
PB17 | RF | ADCLRC | A8 | ADCLRC |
To configure the wm8731, I use a library found here : https://github.com/hughpyle/machinesalem-arduino-libs/tree/master/WM8731
And to try to make this work, I started by using and modifying your example code by adding the setup for the wm8731 :
extern const int16_t sine[512];
uint16_t sineTblPtr; int16_t sign;
void setup() { sineTblPtr = 0; sign = 1;
unsigned char interface = WM8731_INTERFACE_FORMAT(I2S) | WM8731_INTERFACE_WORDLEN(bits32) | WM8731_INTERFACE_MASTER; WM8731.begin( low, WM8731_SAMPLING_RATE(hz48000), interface ); WM8731.setActive(); WM8731.set( WM8731_ANALOG,WM8731_ANALOG_DACSEL); WM8731.setOutputVolume(127);
HiFi.begin(); // Configure transmitter for 2 channels, external TK/TF clocks, 32 bit per // channel (data less than 32-bit is left justified in the 32 bit word, but // codec config needs 32 clocks per channel). HiFi.configureTx(HIFI_AUDIO_MODE_STEREO, HIFI_CLK_MODE_USE_EXT_CLKS, 32); // Register to be notified when the transmit register is ready for more data HiFi.onTxReady(codecTxReadyInterrupt); // Enable both receiver and transmitter. HiFi.enableTx(true); }
void loop() {}
void codecTxReadyInterrupt(HiFiChannelID_t channel)
{
HiFi.write((sign * sine[sineTblPtr])<<16);
if (channel == HIFI_CHANNEL_ID_2)
{
if (sineTblPtr == ((sizeof(sine)/sizeof(sine[0])) - 1))
{
sign *= -1;
sineTblPtr=0;
}
else
{
sineTblPtr++;
}
}
}
I verified that the library for controlling the wm8731 is working. I reached to toggle different function, but when I start to try to send data, I don't have anything. Moreover, I don't have a real scope, and so I can't mesure my data signals, I can only say if I have a signal or not. So, If you see a mistake somewhere, let me now !
Thanks
Seems pretty good at first glance. The HiFi code is straight out of the example and should work. I'd probably have to dive into the WM8731 library to see how it is configuring the part. You have verified that the WM8371 lib is working, but do you know if your code is setting all the registers appropriately? May need to pour through the datasheet and do some trial and error. Hard to confirm all this without a scope. You might be able to use another arduino or similar processor to measure frequency and see if the clocks from the codec are working.
Probably would be easier for me to understand if I had that board in hand, which I don't. Perhaps I'll try to order one... no promises though.
ok,
I already started to dig into the library and the datasheet, but until now, I didn't find the mistake.
I was thinking maybe about a timming problem in the I2C transmission. Indeed, I read that people from openmusiclabs had this problem, when trying to use the WM8731 with an AVR. Maybe it was beacause they didn't have the ssc on an AVR, but they had to cheat a little bit to get the right timmings...
While, I will try to check my data signals and see how it looks.
Thx
Hi Rupraph / Delsauce
Did you ever get the wm8731 Microe Proto board working with the DUE ? I have the same combination of hardware. It would be great if I don't have to try to re-invent the wheel !! :) I found the same library for control. I am confused as to which pins to use on the DUE for SSC I2S and how these pins are assigned in the sketch / library ! ?
I read you have to have the Microe Proto as master? since the Due can NOT create a master clock ?
any info would be great,
thanks,
ben
I am also working with WM8731. Did any body get it to work with your library and was able to access left_in and right_in and also left_out and right_out. Is there a hook up guide as to connect what to what?
hook up guide in other thread. WM8731 working now for me
WM8731 <-> ARDUINO DUE BCLK - Pin 3 <-> TK - Pin 7 DACDAT - Pin 4 <-> TD - Pin 78 DACLRC - Pin 5 <-> TF - Pin 8 BCLK - Pin 3 <-> RK - Pin 90 ADCDAT - Pin 6 <-> RD - Pin 89 ADCLRC - Pin 7 <-> RF - Pin 88
Hello, I am using the same setup with Arduino Due and mikroe audio codec board. I don't know yet how to setup Arduino for some things, so I am not sure how to use the pieces of code posted here for configuring WM8731 and using the HiFi library, and I am also having very difficult time asking Google the right questions. Is it possible to find a whole program that will compile and work if I have the correct libraries and connections set up?
Thank You
Hi,
Since there is no complete tutorial on WM8731 with Arduino DUE available to my knowledge so I don't think you will find a demo program.
I can only share a very old code that I had working, but it is full of other stuff, which will never compile if I give it as is.
If you manage to get the correct wiring, here is some of the setup code I used to get it working: The code below is only to help setting up things and writing values on the DAC output. You'll have to find a way to get your sound data somehow. Back then, I was using this method to generate signals : http://rcarduino.blogspot.com/2012/12/arduino-due-dds-part-1-sinewaves-and.html
----------Code pieces to configure and write on output ------- Declarations
----- Interrupt creation void codecTxReadyInterrupt(HiFiChannelID_t);
------Setup important steps //WM8731 CONFIG unsigned char interface = WM8731_INTERFACE_FORMAT(2) | WM8731_INTERFACE_WORDLEN(0);// data format interface |= WM8731_INTERFACE_MASTER; WM8731.begin(low, WM8731_SAMPLING_RATE(0), interface);//init at 48kHz
//set volume left Wire.beginTransmission(0x1a); Wire.write(0x04); Wire.write((uint8_t)LHPVOL); Wire.endTransmission(); //set volume right Wire.beginTransmission(0x1a); Wire.write(0x06); // right headphone out register Wire.write((uint8_t)RHPVOL); Wire.endTransmission(); // audio configuration Wire.beginTransmission(0x1a); Wire.write(0x0a); Wire.write((uint8_t)ADCHPD); Wire.endTransmission();
WM8731.setActive(); WM8731.set(WM8731_ANALOG, WM8731_ANALOG_DACSEL); WM8731.setActive(); WM8731.set(WM8731_DIGITAL, WM8731_DIGITAL_DEEMP(3) | WM8731_DIGITAL_ADCHPD); WM8731.set(WM8731_DIGITAL, 0); WM8731.set(WM8731_ANALOG, WM8731_ANALOG_DACSEL); delay(500); // important to wait some time to let the communication finish
//I2S CONFIG HiFi.begin(); delay(100); HiFi.configureTx(HIFI_AUDIO_MODE_MONO_RIGHT, HIFI_CLK_MODE_USE_EXT_CLKS, 32); HiFi.onTxReady(codecTxReadyInterrupt); HiFi.enableTx(true); delay(500); WM8731.setActive(); delay(500);
----- Write output in interrupt void codecTxReadyInterrupt(HiFiChannelID_t channel) { HiFi.write((output) << 16); //output is an int16_t for signed signals. Can also be an uint32_t }
Hi !
I can't make this library works with the wm8731 codec (configured as master in I2S). Can you describe me precisely the I2S protocol as you generate it, or can you comment a bit more your code, I don't understand enough what you did to be able to correct it, in case of any mistake.
Thx,
Rup