|
How to init IIS and IIC to make wm8960 chip play wav file
[复制链接]
How to init IIS and IIC to make wm8960 chip play wav file
pin -> signalsAudio_Xi2sSCLK0 [13]Audio_Xi2sCDCLK0 [13]Audio_Xi2sLRCK0 [13]Audio_Xi2sSDO0_0 [1]Audio_Xi2sSDI0 [1]Xi2s0SCLK GPI[0] Xi2s0CDCLK GPI[1] Xi2s0LRCK GPI[2] Xi2s0SDI GPI[3] Xi2s0SDO[0] GPI[4] Xi2s0SDO[1] GPI[5] Xi2s0SDO[2] GPI[6] GPICON 0xE020_0220 GPIDAT 0xE020_0224 GPIPUD 0xE020_0228 GPIDRV 0xE020_022C SFR of GPIO and IISGPIOPort Group GPI Control Register (GPICON, R/W, Address = 0xE020_0220) GPICON Bit Description Initial State GPICON[6] [27:24] 0010 = I2S_0_SDO[2] 0010 GPICON[5] [23:20] 0010 = I2S_0_SDO[1] 0010 GPICON[4] [19:16] 0010 = I2S_0_SDO[0] 0011 = PCM_0_SOUT 0010 GPICON[3] [15:12] 0010 = I2S_0_SDI 0011 = PCM_0_SIN 0010 GPICON[2] [11:8] 0010 = I2S_0_LRCK 0011 = PCM_0_FSYNC 0010 GPICON[1] [7:4] 0010 = I2S_0_CDCLK 0011 = PCM_0_EXTCLK 0010 GPICON[0] [3:0] 0010 = I2S_0_SCLK 0011 = PCM_0_SCLK 0010 IISRegister Address IISCON 0xEEE3_0000 IISMOD 0xEEE3_0004 IISFIC 0xEEE3_0008 IISPSR 0xEEE3_000C IISTXD 0xEEE3_0010 IISRXD 0xEEE3_0014 IISFICS 0xEEE3_0018 IISTXDS 0xEEE3_001C IIC SignalsXi2cSCL0Xi2cSDA0XI2C0SDA XI2C0SCL Xi2c0SDA GPD1[0] I2C0_SDA Xi2c0SCL GPD1[1] I2C0_SCL GPD1CON[1] [7:4] 0000 = Input 0001 = Output 0010 = I2C0_SCL 0011 ~ 1110 = Reserved 1111 = GPD1_INT[1] 0000 GPD1CON[0] [3:0] 0000 = Input 0001 = Output 0010 = I2C0_SDA 0011 ~ 1110 = Reserved 1111 = GPD1_INT[0] 0000 uboot 启动后,IIS 寄存器的配置值:[FriendlyLEG-TINY210]# md 0xeee30000eee30000: 00000000 00000000 00000000 00000000 ................eee30010: 00000000 此处死机Linux 启动后,IIS 寄存器的配置值:[root@FriendlyARM /tmp]# ./sfr 0xeee30000 256addr = 0xeee30000, size = 256 SFR addr = 0xeee30000, size = 0x100eee30000 : 8050cc91 100 40 0 eee30010 : 0 0 0 0 eee30020 : 0 0 7fff0000 0 eee30030 : 0 0 0 0 Linux 上运行 QTopia 视频播放程序 之后再次查看 IIS 配置值:[ 54.517075] ASoC_mini210: SCLK=67738000 PSR=6 RCLK=11289600 RFS=256 BFS=32[root@FriendlyARM /]# ./sfr 0xeee30000 64addr = 0xeee30000, size = 64SFR addr = 0xeee30000, size = 0x40eee30000 : 8050c185 600 3f40 8500eee30010 : 0 0 0 0eee30020 : 0 0 7fff0000 0结论: 播放 44.1Khz wav 时,BFS = 32fs, RFS = 256fs, RCLK = 44.1*256 = 11289600, PSR = 6 (5+1), SCLK = 67.738Mhz此时查看 EPLL 配置,发现 0xa8430303 -> EPLL = 67Mhz ,说明 Linux 使用 EPLL 作为 IIS 的输入时钟[root@FriendlyARM /]# ./sfr 0xe0100000 100 e0100100 : a07d0301 0 a29b0c01 0e0100110 : a8430303 bcee 0 0e0100120 : a06c0603 0 0 0e0100130 : 0 0 0 0e0100140 : 0 0 0 0e0100150 : 0 0 0 0e0100160 : 0 0 0 0e0100170 : 0 0 0 0e0100180 : 0 0 0 0begin to write vmem+4总结 IIS 时钟产生过程// IIS clock init // step 1: EPLL output 67.7Mhz (see p361 of s5pv210.pdf) // EPLL_CON0/ EPLL_CON1, R/W, Address = 0xE010_0110/0xE010_0114) // FOUT = (MDIV+K/65536) X FIN / (PDIV X 2SDIV) // Fout = (0x43+0.7)*24M / (3*2^3) = 80*24M/24 = 67.7Mhz#define EPLL_CON0 (*(volatile unsigned int *)0xe0100110)#define EPLL_CON1 (*(volatile unsigned int *)0xe0100114) EPLL_CON0 = 0xa8430303; // MPLL_FOUT = 67.7Mhz EPLL_CON1 = 0xbcee; // from linux kernel setting // step 2: MUX_EPLL = 1 -> SCLK_EPLL = 67.7Mhz (see p361 of s5pv210.pdf) // CLK_SRC0, R/W, Address = 0xE010_0200 // 0xe0100200: 10001111 // EPLL_SEL [8] Control MUXEPLL (0:FINPLL, 1:FOUTEPLL) #define CLK_SRC0 (*(volatile unsigned int *)0xE0100200) CLK_SRC0 = 0x10001111; // step 3: Mux_I2S AUDIO subsystem clock selection (see P1868 P1875 of s5pv210.pdf)#define CLK_CON (*(volatile unsigned int *)0xEEE10000) CLK_CON = 0x1; // 1 = FOUT_EPLL MUXI2S_A 00 = Main CLK // IIS SFRs // step 4: Divider of IIS (67.7 -> 11.289Mhz) // N + 1 = (67.7Mhz) / (256 * 44.1Khz) = 5.99 // IISCDCLK 11.289Mhz = 44.1K * 256fs // IISSCLK 1.4112Mhz = 44.1K * 32fs // IISLRCLK 44.1Khz N = 5; IISPSR = 1<<15 | N<<8;下一步解决 IIC 和 WM8960 驱动/* IIC bus - SCL & SDA 2 signals -> GPD1_0 & GDP1_1 -> GPD0CON */void IIC_init(void){ // set GPIO pin function as IICSCL, IICSDA GPD1CON |= 0x22; //GPD1CON[1] 0010 = I2C0_SCL , GPD1CON[0] 0010 = I2C0_SDA GPD1PUD |= 0x5; //Pull-down enable // Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16 IICCON = (1<<7) | (0<<6) | (1<<5) | (0xf); // Enable IIC bus //IICADD = 0x10; // no use if s5pv210 is a IIC master IICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)} IIC master 工作模式下写 WM8960 的接口 IIC_write/* slave_addr -> WM8960 device addr; addr -> WM8960 reg addr, data -> value */void IIC_write(int slave_addr, int addr, int data){ IICDS = slave_addr; IICSTAT = 0xf0; while ((IICCON & 0x10) == 0); // INT while ((IICSTAT & 0x1)); // ACK // 7 bit addr & 9 bit data IICDS = addr<<1 | ((data>>8) & 0x0001); IICCON = 0xaf; while ((IICCON & 0x10) == 0); // INT while ((IICSTAT & 0x1)); // ACK IICDS = (data & 0x00FF); IICCON = 0xaf; while ((IICCON & 0x10) == 0); // INT while ((IICSTAT & 0x1)); // ACK IICSTAT = 0xd0; // stop write IICCON = 0xaf; return;}WM8960 初始化配置/* 0x34 is WM8960 IIC slave address */void WM8960_init(void){#define WM8960_DEVICE_ADDR 0x34 // reset IIC_write(WM8960_DEVICE_ADDR, 0xf, 0x0); // power1 2 3 IIC_write(WM8960_DEVICE_ADDR, 0x19, 1<<8 | 1<<7 | 1<<6); IIC_write(WM8960_DEVICE_ADDR, 0x1a, 1<<8 | 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3); IIC_write(WM8960_DEVICE_ADDR, 0x2F, 1<<3 | 1<<2); // clock IIC_write(WM8960_DEVICE_ADDR, 0x4, 0x0); // CLKSEL = 0 : no PLL -> SYSCLK using MCLK // no mute ok IIC_write(WM8960_DEVICE_ADDR, 0x5, 0x0); // set no mute //IIC_write(WM8960_DEVICE_ADDR, 0x5, 0x08); // set mute // audio interface IIC_write(WM8960_DEVICE_ADDR, 0x7, 0x2); // 00 = 16bits, 10 = IIS format // volume +6db ok IIC_write(WM8960_DEVICE_ADDR, 0x2, 0xFF | 0x100); // WM8960_LOUT1 IIC_write(WM8960_DEVICE_ADDR, 0x3, 0xFF | 0x100); // WM8960_ROUT1 IIC_write(WM8960_DEVICE_ADDR, 0xa, 0xFF | 0x100); // Left DAC volume IIC_write(WM8960_DEVICE_ADDR, 0xb, 0xFF | 0x100); // Right DAC volume // mixer control IIC_write(WM8960_DEVICE_ADDR, 0x22, 1<<8 | 1<<7); // Left output mixer control IIC_write(WM8960_DEVICE_ADDR, 0x25, 1<<8 | 1<<7); // Right output mixer control return;}
|
|