/*
Wolfson WM8805 Digital Receiver SPI routines, extract
coded by sumotoy
NOTES:
WM8805 it's actually one of the best digital audio receiver chip around
but it's far to be perfect, for example it's not easy to get exaustive
infos about it's current working audio link connection. For example I cannot find a way
to determine if it's linked to 48K or 44.1K since the 2 freq are identified
with the same register out. To determine if chip it's linked or not to an audio stream, best
way to me it's check the GPO1 pin of WM chip and only then send queries to it
for read registers and check the quality and all infos.
WM8805 can communicate via I2C or SPI, the 2 ways are slight different (check
datasheet) and need slight different pin setup.
The following routines are for SPI and I checked and are working on
a ATMEGA1284P (arduino ide 1.0.3) If you need help with WM8805 circuit
I can post my setup for SPI and I2C.
*/
/* ----------------------WM8805 ------------------*/
#define WMRST 0x00
#define DEVID2 0x01
#define DEVREV 0x02
#define PLL1 0x03
#define PLL2 0x04
#define PLL3 0x05
#define PLL4 0x06
#define PLL5 0x07
#define PLL6 0x08
#define SPDMODE 0x09
#define INTMASK 0x0A
#define INTSTAT 0x0B
#define SPDSTAT 0x0C
#define RXCHAN1 0x0D
#define RXCHAN2 0x0E
#define RXCHAN3 0x0F
#define RXCHAN4 0x10
#define RXCHAN5 0x11
#define SDPTX1 0x12
#define SDPTX2 0x13
#define SDPTX3 0x14
#define SDPTX4 0x15
#define SDPTX5 0x16
#define GPO01 0x17
#define GPO23 0x18
#define GPO45 0x19
#define GPO67 0x1A
#define AIFTX 0x1B
#define AIFRX 0x1C
#define SPDXR1 0x1D
#define PWRDN 0x1E
//related to cpu
#define WMCS 10 //cs pin cpu side
byte wm_PLL6 = 0b00011000;
byte wm_PWRDN = 0b00000000;
//powerup chip
void WMPowerUp(){
WMwrite(PWRDN,wm_PWRDN);
}
//enable/disable I2S interface
void WMI2SInterface(byte state){
if (state){
WMwrite(PWRDN,0x00);//power up I2S interface on WM8805
}
else {
WMwrite(PWRDN,0x10);//power down I2S interface on WM8805
}
}
//write to wm8805
void WMwrite(byte reg, byte data){
digitalWrite(WMCS,LOW);
//Bit 7 t 0
SPI.transfer(reg &= ~(1<<7));
SPI.transfer(data);
// stop transmitting
digitalWrite(WMCS, HIGH);
}
//read from wm8805
int WMread(byte reg){
digitalWrite(WMCS,LOW);
//bit 7 to 1
SPI.transfer(reg |= (1<<7));
int _data = SPI.transfer(0x0);
digitalWrite(WMCS,HIGH);
return _data;
}
//select source (I know this is the worst way
//to do but easy to understand)
void WMsource(byte src)
{
switch(src){
case 0://000
bitClear(wm_PLL6,0);
bitClear(wm_PLL6,1);
bitClear(wm_PLL6,2);
break;
case 1://001
bitSet(wm_PLL6,0);
bitClear(wm_PLL6,1);
bitClear(wm_PLL6,2);
break;
case 2://010
bitClear(wm_PLL6,0);
bitSet(wm_PLL6,1);
bitClear(wm_PLL6,2);
break;
case 3://011
bitSet(wm_PLL6,0);
bitSet(wm_PLL6,1);
bitClear(wm_PLL6,2);
break;
case 4://100
bitClear(wm_PLL6,0);
bitClear(wm_PLL6,1);
bitSet(wm_PLL6,2);
break;
case 5://101
bitSet(wm_PLL6,0);
bitClear(wm_PLL6,1);
bitSet(wm_PLL6,2);
break;
case 6://110
bitClear(wm_PLL6,0);
bitSet(wm_PLL6,1);
bitSet(wm_PLL6,2);
break;
case 7://111
bitSet(wm_PLL6,0);
bitSet(wm_PLL6,1);
bitSet(wm_PLL6,2);
break;
}
WMwrite(PLL6,wm_PLL6);
}
/*
Example:
WMwrite(WMRST,0x00);//reset
WMwrite(SPDXR1,B1000011);//reset
//wait a little, wm it's slow to initialize
WMwrite(SPDMODE,0xF4);//SPDIF modes (coax/TTL)
WMwrite(SDPTX1,0x04);//SPDIF TX copyright = no
WMwrite(SDPTX4,0x31);//SPDIF TX source
WMwrite(GPO01,0x7A);//GPO Config - GPO0 = DEEMPH; GPO1 = UNLOCK// NEW!
WMwrite(AIFTX,0x0A);//AIF TX = 24-bit I2S
WMwrite(AIFRX,0x4A);//AIF = master mode
WMsource(1);//select input 1
WMwrite(PWRDN,wm_PWRDN);
//check if chip it's connected
if (WMread(DEVID2) == 0x88) it's connected and working
*/