MickMad
Well-known member
Hey there, I've just tested the audio lib with the Mikroe proto board and the new PlayMidiTones sketch (which actually just plays sinewaves).
While reading through the code I discovered that the lib assumes that the ADC/DAC/CODEC on the I2S channel is in Slave mode, so I've added a #define and some #if blocks in the AudioI2S*put classes code to check wether the MCLK signal is external or internal and to set the appropriate registers to signal that.
in Audio.h, line 3
in Audio.h, line 337
in Audio.cpp, line 631
in Audio.cpp, line 1684
in Audio.cpp, line 1702
This last line is important, without it the WM8731 wouldn't start properly when activated.
It works, though there was a missing mysine.amplitude() call in the demo sketch and I lost half an hour just to find that The pins are exactly the same as the Audio Adaptor, minus MCLK which is not connected:
Audio Codec PROTO SCK -> Teensy 9 (I2S0_BCLK)
Audio Codec PROTO ADCL -> Teensy 12 (I2S0_RX_FS)
Audio Codec PROTO MISO -> Teensy 13 (I2S0_RXD0)
Audio Codec PROTO MOSI -> Teensy 22 (I2S0_TXD0)
Audio Codec PROTO DACL -> Teensy 23 (I2S0_TX_FS)
I've also noticed that the output frequency is slightly higher than the 440 Hz it should output.
I still gotta test the codec in input, will let you know.
I will probably make a pull request tomorrow, is it okay?
While reading through the code I discovered that the lib assumes that the ADC/DAC/CODEC on the I2S channel is in Slave mode, so I've added a #define and some #if blocks in the AudioI2S*put classes code to check wether the MCLK signal is external or internal and to set the appropriate registers to signal that.
in Audio.h, line 3
Code:
#define MCLK_IS_EXTERNAL 1
in Audio.h, line 337
Code:
bool disable(void) { return false; }
in Audio.cpp, line 631
Code:
void AudioOutputI2S::config_i2s(void)
{
SIM_SCGC6 |= SIM_SCGC6_I2S;
SIM_SCGC7 |= SIM_SCGC7_DMA;
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
// if either transmitter or receiver is enabled, do nothing
if (I2S0_TCSR & I2S_TCSR_TE) return;
if (I2S0_RCSR & I2S_RCSR_RE) return;
#if MCLK_IS_EXTERNAL
// Select input clock 0
// Configure to input the bit-clock from pin, bypasses the MCLK divider
I2S0_MCR = I2S_MCR_MICS(0);
I2S0_MDR = 0;
#else
// enable MCLK output
I2S0_MCR = I2S_MCR_MICS(3) | I2S_MCR_MOE;
I2S0_MDR = I2S_MDR_FRACT(1) | I2S_MDR_DIVIDE(16);
#endif
// configure transmitter
I2S0_TMR = 0;
I2S0_TCR1 = I2S_TCR1_TFW(1); // watermark at half fifo size
I2S0_TCR2 = I2S_TCR2_SYNC(0) | I2S_TCR2_BCP;
#if !MCLK_IS_EXTERNAL
I2S0_TCR2 |= I2S_TCR2_MSEL(1) | I2S_TCR2_BCD | I2S_TCR2_DIV(3);
#endif
I2S0_TCR3 = I2S_TCR3_TCE;
I2S0_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(15) | I2S_TCR4_MF
| I2S_TCR4_FSE | I2S_TCR4_FSP;
#if !MCLK_IS_EXTERNAL
I2S0_TCR4 |= I2S_TCR4_FSD;
#endif
I2S0_TCR5 = I2S_TCR5_WNW(15) | I2S_TCR5_W0W(15) | I2S_TCR5_FBT(15);
// configure receiver (sync'd to transmitter clocks)
I2S0_RMR = 0;
I2S0_RCR1 = I2S_RCR1_RFW(1);
I2S0_RCR2 = I2S_RCR2_SYNC(1) | I2S_TCR2_BCP;
#if !MCLK_IS_EXTERNAL
I2S0_RCR2 |= I2S_RCR2_MSEL(1) | I2S_RCR2_BCD | I2S_RCR2_DIV(3);
#endif
I2S0_RCR3 = I2S_RCR3_RCE;
I2S0_RCR4 = I2S_RCR4_FRSZ(1) | I2S_RCR4_SYWD(15) | I2S_RCR4_MF
| I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
#if !MCLK_IS_EXTERNAL
I2S0_RCR4 |= I2S_RCR4_FSD;
#endif
I2S0_RCR5 = I2S_RCR5_WNW(15) | I2S_RCR5_W0W(15) | I2S_RCR5_FBT(15);
// configure pin mux for 3 clock signals
CORE_PIN23_CONFIG = PORT_PCR_MUX(6); // pin 23, PTC2, I2S0_TX_FS (LRCLK)
CORE_PIN9_CONFIG = PORT_PCR_MUX(6); // pin 9, PTC3, I2S0_TX_BCLK
CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK
}
in Audio.cpp, line 1684
Code:
bool AudioControlWM8731::enable(void)
{
Wire.begin();
delay(5);
//write(WM8731_REG_RESET, 0);
#if MCLK_IS_EXTERNAL
write(WM8731_REG_INTERFACE, 0x42); // I2S, 16 bit, MCLK master
#else
write(WM8731_REG_INTERFACE, 0x02); // I2S, 16 bit, MCLK slave
#endif
write(WM8731_REG_SAMPLING, 0x20); // 256*Fs, 44.1 kHz, MCLK/1
in Audio.cpp, line 1702
Code:
write(WM8731_REG_POWERDOWN, 0x00); // codec powerdown
This last line is important, without it the WM8731 wouldn't start properly when activated.
It works, though there was a missing mysine.amplitude() call in the demo sketch and I lost half an hour just to find that The pins are exactly the same as the Audio Adaptor, minus MCLK which is not connected:
Audio Codec PROTO SCK -> Teensy 9 (I2S0_BCLK)
Audio Codec PROTO ADCL -> Teensy 12 (I2S0_RX_FS)
Audio Codec PROTO MISO -> Teensy 13 (I2S0_RXD0)
Audio Codec PROTO MOSI -> Teensy 22 (I2S0_TXD0)
Audio Codec PROTO DACL -> Teensy 23 (I2S0_TX_FS)
I've also noticed that the output frequency is slightly higher than the 440 Hz it should output.
I still gotta test the codec in input, will let you know.
I will probably make a pull request tomorrow, is it okay?