⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wm8753.c

📁 Embest IDE下s3c2440的测试工程
💻 C
📖 第 1 页 / 共 3 页
字号:
/*============================================================

	File Name: Iis.c
	Description: S3C2440A IIS controller Function Test
   	Version: 0.2 

   	History:
             0.0: 2002. 03. 06, Programming Start by SOP.
             0.1: 2004. 02. 04, Modified by Y. H. Lee.
		  - IIS Master Tx: Play Sample Wave File.
		  - IIS Master Rx: Record Sound using MIC and Play it.
		  - IIS maser clock selection (PCLK or MPLLin) is supported.
	      0.2: 2004. 04. 26, Modified by Y. H. Lee.
	         - Recording Sound via Line-In is available in the SMDK2440 base board (Rev 0.19).
	         		  
=============================================================*/

#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "profile.h"

#include "usbmain.h"
#include "usbout.h"
#include "usblib.h"
#include "2440usb.h"
#include "nand.h"
#include "iis.h"
#include "wm8753.h"

#define REC_LEN_IIS 0xfffff*2
#define PLAY_IIS    0
#define RECORD_MICIn  1
#define RECORD_LineIn 2 
 
#define L3C (1<<4)		  //GPB4 = L3CLOCK
#define L3D (1<<3)		  //GPB3 = L3DATA
#define L3M (1<<2)		  //GPB2 = L3MODE
//=================
//
//=====================
#define BIT0	0x0001
#define BIT1	1<<1
#define BIT2	0x0004
#define BIT3	1<<3
#define BIT4	1<<4
#define BIT5	0x0020
#define BIT6	0x0040
#define BIT7	0x0080
#define BIT8	0x0100
#define BIT9	0x0200
#define BIT10	0x0400
#define BIT11	0x0800
#define BIT12	0x1000
#define BIT13	0x2000
#define BIT14	0x4000
#define BIT15	0x8000

#define Set_i2c_SDA()  rGPBDAT |= BIT3
#define Set_i2c_SCL()  rGPBDAT |= BIT4
#define Clr_i2c_SDA()  rGPBDAT &= ~BIT3
#define Clr_i2c_SCL()  rGPBDAT &= ~BIT4

#define i2c_SDAHi()    (rGPBDAT & BIT3)
#define i2c_SDALo()    (!(rGPBDAT & BIT3))

#define i2c_SCLHi()    (rGPBDAT & BIT4)
#define i2c_SCLLo()    (!(rGPBDAT & BIT3))

#define PLL_N 0x7
#define PLL_K 0x23F548
#define WM8753_DEFAULT_HSRATE	48000
#define WM8753_DEFAULT_VSRATE	WM8753_VD48K

#define WM8753_I2S_8K		8//SADIV_513K
#define WM8753_I2S_12K		12//SADIV_702K
#define WM8753_I2S_16K		16//SADIV_1_026M
#define WM8753_I2S_22K		22//SADIV_1_405M
#define WM8753_I2S_44K		44//SADIV_2_836M
#define WM8753_I2S_48K		48//SADIV_3_058M
typedef enum i2c_direction
{ I2C_WRITE,
  I2C_READ
} I2C_Direction;

//==============================
//
//==============================
char mute = 1;
char which_Buf = 1;
char Rec_Done = 0;
char IIS_MasterClk_Sel = 0; 
static U8	hifi = 1;


unsigned char  *Buf,*_temp,*Buf2;
unsigned char *rec_buf = (unsigned char *)0x31000000;

unsigned int size, fs; 
unsigned int save_B, save_E, save_PB, save_PE;

extern U32 Hclk, Pclk;
extern U8 g_ucWave[155760];
float IIS_Codec_CLK;


void IIS_Port_Init(void);
void IIS_Port_Return(void);
void Download_Wave_File(void);
void Select_IIS_Master_CLK(void);
void IIS_RecSound_DMA1( int mode, U32 rec_size);
void IIS_PlayWave_DMA2(unsigned char *start_addr, U32 play_size);

void _WrL3Addr(U8 data);
void _WrL3Data(U8 data,int halt);
void Open_Wave_File(char *filename);

void Radio_IIS(void);

void __irq RxInt(void);
void __irq Muting(void);
void __irq DMA2_Done(void);
void __irq DMA1_Rec_Done(void);


//=============================
void SDA_pin_out(void);
void SDA_pin_in(void);
void Delay4us(void);
U8 i2c_Start(void);
void i2c_Stop(void);
U8 i2c_SendByte(U8 value, int direction);
U8 i2c_ReceiveByte(const U8 ack);
U8 i2c_BurstWrite(U8 count, U8 *buffer);
U8 i2c_BurstRead(U8 count, U8 * buffer);
U8 i2c_MasterStart(I2C_Direction direct, U8 addr);
int wm8753_i2c_write(unsigned char addr, unsigned char buffer1, unsigned short buffer2);

static U16 reg_cache[64] = {
	0x0008, 0x0000, 0x000a, 0x000a,
	0x0003, 0x0000, 0x0007, 0x01ff,
	0x01ff, 0x000f, 0x000f, 0x007b,
	0x0000, 0x0032, 0x0000, 0x00c3,
	0x00c3, 0x00c0, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0055, 
	0x0005, 0x0050, 0x0055, 0x0050,
	0x0055, 0x0050, 0x0055, 0x0079,
	0x0079, 0x0079, 0x0079, 0x0079,
	0x0000, 0x0000, 0x0000, 0x0000, 
	0x0097, 0x0097, 0x0000, 0x0004,
	0x0000, 0x0083, 0x0024, 0x01ba,
	0x0000, 0x0083, 0x0024, 0x01ba
};

static unsigned short	wav[600*1024];

static int wm8753_init_pll(void)
{
	U16 value;
#if 0	
	if (hifi) {
		/* set up N and K PLL divisor ratios */
		/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
		value = (PLL_N << 5) + ((PLL_K & 0x3c0000) >> 18);	
		if (wm8753_i2c_write(0x34, WM8753_PLL1CTL2, value) != 0)
			return -1;
		
		/* bits 8:0 = PLL_K[17:9] */
		value = (PLL_K & 0x03fe00) >> 9;
		if (wm8753_i2c_write(0x34, WM8753_PLL1CTL3, value) != 0)
			return -1;
		
		/* bits 8:0 = PLL_K[8:0] */
		value = PLL_K & 0x0001ff;
		if (wm8753_i2c_write(0x34, WM8753_PLL1CTL4, value) != 0)
			return -1;
		
		/* set PLL1 as input and enable */
		if (wm8753_i2c_write(0x34, WM8753_PLL1CTL1, 0x0027) != 0)
			return -1;
	}
	
	
	/* set up N and K PLL divisor ratios */
	/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
	value = (PLL_N << 5) + ((PLL_K & 0x3c0000) >> 18);	
	if (wm8753_i2c_write(0x34, WM8753_PLL2CTL2, value) != 0)
		return -1;
	
	/* bits 8:0 = PLL_K[17:9] */
	value = (PLL_K & 0x03fe00) >> 9;
	if (wm8753_i2c_write(0x34, WM8753_PLL2CTL3, value) != 0)
		return -1;
	
	/* bits 8:0 = PLL_K[8:0] */
	value = PLL_K & 0x0001ff;
	if (wm8753_i2c_write(0x34, WM8753_PLL2CTL4, value) != 0)
		return -1;
	
	/* set PLL2 as input and enable */
	if (wm8753_i2c_write(0x34, WM8753_PLL2CTL1, 0x0027) != 0)
		return -1;
	
	/* now enable the clock */
	if (wm8753_i2c_write(0x34, WM8753_CLOCK, WM8753_DEFAULT_VSRATE | 0x18) != 0)
		return -1;
		
	if (wm8753_i2c_write(0x34, WM8753_INCTL1, 0x0007) != 0)
		return -1;			
#endif
    	if (wm8753_i2c_write(0x34, WM8753_INCTL1, 0x0007) != 0)  //0x0007
return 0;
}

/*
 * Power up the codec
 */
static int wm8753_power_up(void)
{	
	U16 pwr = 0xf0;
	
	if (hifi)
		pwr |= 0xc;
	
	/* set Vmid to 5kOhm, enable VREF and VDAC */
	if (wm8753_i2c_write(0x34, WM8753_PWR1, 0x0100 | pwr) != 0)
		return -1;                    //--  0x100 | pwr
	
	/* enable MIC1 preamp, ALC mix and left ADC */
	if (wm8753_i2c_write(0x34, WM8753_PWR2, 0x01ff) != 0)	
		return -1;                    //0x0168
	
	/* enable LOUT 1, ROUT1, MONO1 */  //0x0184
	/* enable LOUT 1, ROUT1, MONO1 LOUT 2 ROUT2 */ //0x01E4
	if (wm8753_i2c_write(0x34, WM8753_PWR3, 0x01ff) != 0)
		return -1;                  //0x184 
		
	
	/* enable left, right mono mixer */
	if (wm8753_i2c_write(0x34, WM8753_PWR4, 0x000f) != 0)
		return -1;                      //0x000b
	
	/* let WM8753 powerup and then set Vmid to 50kOhm */
	Delay(10000);
	if (wm8753_i2c_write(0x34, WM8753_PWR1, pwr) != 0)
		return -1;
	
	return 0;
}

static int wm8753_power_down()
{
	if ((wm8753_i2c_write(0x34, WM8753_PWR1, 0x0100) != 0) &&
		(wm8753_i2c_write(0x34, WM8753_PWR2, 0x0000) != 0) &&
		(wm8753_i2c_write(0x34, WM8753_PWR3, 0x0000) != 0) &&
		(wm8753_i2c_write(0x34, WM8753_PWR4, 0x0000) != 0)) {
			Uart_Printf("could not powerdown WM8753");
			return -1;
		}
	return 0;
}

/*
 * Set WM8753 ADC and DAC sample rates and
 * enable SSP port 2 at the correct speed.
 * 
 * returns sample rate on success, else error.
 */
static U16 wm8753_read_reg_cache(U8 reg)
{
	return reg_cache[reg - 1];
}

static int wm8753_i2s_open(int speed)
{
	//	CKEN |= CKEN8_I2S;
	rCLKCON |= (1<<17);
	
/*
	SACR0 |= SACR0_RFTH(14) | SACR0_TFTH(1) | SACR0_BCKD;
	SACR1 &= ~(SACR1_DRPL | SACR1_DREC | SACR1_AMSL);
	SAIMR |= SAIMR_RFS | SAIMR_TFS;
	SADIV = speed;
	SACR0 |= SACR0_ENB;
*/
	return 0;
}

static void wm8753_i2s_close()
{
	//	SACR0 &= ~SACR0_ENB;
	//	CKEN &= ~CKEN8_I2S;
		rCLKCON &=~(1<<17);
		rIISCON  &=~(1<<0);
		
}

/*
void ssp_enable(void)
{
	Ser4SSCR0 |= SSCR0_SSE;
}
*/
static int wm8753_set_adcdac_rate(int val)
{
	int ret = val;
	U16 clock;
	
	clock = wm8753_read_reg_cache(WM8753_CLOCK) & 0x3f;
	
	switch (val) {
		case 8000: /* ADC/DAC 8kHz */
			if (wm8753_i2c_write(0x34, WM8753_SRATE1, WM8753_A8D8) != 0)
				ret = -1;
			if (wm8753_i2c_write(0x34, WM8753_CLOCK, WM8753_VD8K | clock) !=0)
				ret = -1;
//			if (wm8753_psp_open(WM8753_SSP_8K) != 0)
//				ret = -1;
			if (hifi)
				wm8753_i2s_open(WM8753_I2S_8K);
			break;
		case 12000:	 /* ADC/DAC 12kHz */
			if (wm8753_i2c_write(0x34, WM8753_SRATE1, WM8753_A12D12) != 0)
				ret = -1;
			if (wm8753_i2c_write(0x34, WM8753_CLOCK, WM8753_VD12K | clock) !=0)
				ret = -1;
//			if (wm8753_psp_open(WM8753_SSP_12K) != 0)
//				ret = -1;
			if (hifi)
				wm8753_i2s_open(WM8753_I2S_12K);
			break;
		case 16000:	 /* ADC/DAC 16kHz */
			if (wm8753_i2c_write(0x34, WM8753_SRATE1, WM8753_A16D16) != 0)
				ret = -1;
			if (wm8753_i2c_write(0x34, WM8753_CLOCK, WM8753_VD16K | clock) !=0)
				ret = -1;
//			if (wm8753_psp_open(WM8753_SSP_16K) != 0)
//				ret = -1;
			if (hifi)
				wm8753_i2s_open(WM8753_I2S_16K);
			break;
		case 24000:	 /* ADC/DAC 24kHz - Voice DAC only*/
			if (wm8753_i2c_write(0x34, WM8753_SRATE1, WM8753_A24D24) != 0)
				ret = -1;
			if (wm8753_i2c_write(0x34, WM8753_CLOCK, WM8753_VD24K | clock) !=0)
				ret = -1;
//			if (wm8753_psp_open(WM8753_SSP_24K) != 0)
//				ret = -1;
			break;		
		case 48000:	 /* ADC/DAC 48kHz */
			if (wm8753_i2c_write(0x34, WM8753_SRATE1, WM8753_A48D48) != 0)
				ret = -1;
			if (wm8753_i2c_write(0x34, WM8753_CLOCK, WM8753_VD48K | clock) !=0)
				ret = -1;
//			if (wm8753_psp_open(WM8753_SSP_48K) != 0)
//				ret = -1;
			if (hifi)
				wm8753_i2s_open(WM8753_I2S_48K);
			break;
		default:
			/* desired rate is not permitted */
			ret = -1;
			break;
	}	
	
//	if (ret != -1)
//		ssp_enable(&wm8753_codec.ssp);
		
	return ret;
}

static int wm8753_init(void)
{
	int ret = 0;
/*
while(1){
	Set_i2c_SCL();
	Delay4us();
	Clr_i2c_SCL();
	Delay4us();
}

while(1){
wm8753_power_up();
}
*/	/* power up the device */
	if ((ret = wm8753_power_up()) != 0) {
		ret = -1;
		goto out;
	}
	
	/* start adc/dac clocks */
	if ((ret = wm8753_init_pll()) != 0) {
		Uart_Printf("could not initialise PLL's\n");
		ret = -1;
		goto out;
	}
	
	/* set up GPIO and alternate functions for SSP2/I2S 
	set_GPIO_mode(GPIO13_SSP2TX_MD);
	set_GPIO_mode(GPIO22_SSP2CLK_MD);
	set_GPIO_mode(GPIO86_SSP2RX_MD); // not sure of correct GPIO for SSP2 RX
	set_GPIO_mode(GPIO88_SSP2FRM_MD);
	
	if (hifi) {
		set_GPIO_mode(GPIO29_SDATA_IN_I2S_MD);
		set_GPIO_mode(28 | GPIO_ALT_FN_1_OUT);
		set_GPIO_mode(GPIO30_SDATA_OUT_I2S_MD);
		set_GPIO_mode(GPIO31_SYNC_I2S_MD);
	}
*/	
	/* set up default ADC/DAC sample rate */
	if ((ret = wm8753_set_adcdac_rate(WM8753_DEFAULT_HSRATE)) != WM8753_DEFAULT_HSRATE) {
		Uart_Printf("could not set WM8753 sample rate to %d", WM8753_DEFAULT_HSRATE);
		ret = -1;
		goto out;
	}
	
	/* set up ADC mode */
	ret = wm8753_i2c_write(0x34, WM8753_ADC, 0x001c);
		
	/* set up sample rate mode 87*/ 
	ret += wm8753_i2c_write(0x34, WM8753_SRATE2, 0x0097);
	
	/* set up PCM digital interface format and master mode */
	ret += wm8753_i2c_write(0x34, WM8753_PCM, 0x0063);
	

	/* set up PCM digital interface as output */
	ret += wm8753_i2c_write(0x34, WM8753_IOCTL, 0x0003);
	                                           //0x0003
	ret += wm8753_i2c_write(0x34, WM8753_INCTL1, 0x0000);  //0x0007
	
	/* set up default input audio paths, enable MIC1 */
	ret += wm8753_i2c_write(0x34, WM8753_INCTL2, 0x0000);
	                                        //0x0002 ----hxm
	
	/* set up analog mono mix using LADC  */
//	ret += wm8753_i2c_write(0x34, WM8753_ADCIN, 0x0011);
	                                             //0x0010 ---hxm
	
	/* set up left input PGA */
	ret += wm8753_i2c_write(0x34, WM8753_LINVOL, 0x011c);
	
	
	/* set up default output audio paths, enable left out 1 */
//	ret += wm8753_i2c_write(0x34, WM8753_LOUTM1, 0x0103);
	ret += wm8753_i2c_write(0x34, WM8753_LOUTM1, 0x0180);
	
	/* set up default output audio paths, enable rightt out 1 */
//	ret += wm8753_i2c_write(0x34, WM8753_ROUTM1, 0x0103);
	ret += wm8753_i2c_write(0x34, WM8753_ROUTM1, 0x0180);

	/* set up default output audio paths, enable left out 2 */
//	ret += wm8753_i2c_write(0x34, WM8753_LOUTM2, 0x0103);
	ret += wm8753_i2c_write(0x34, WM8753_LOUTM2, 0x0180);
	
	/* set up default output audio paths, enable rightt out 2 */
//	ret += wm8753_i2c_write(0x34, WM8753_ROUTM2, 0x0103);
	ret += wm8753_i2c_write(0x34, WM8753_ROUTM2, 0x0100);
    
    ret += wm8753_i2c_write(0x34, WM8753_LOUT2V, 0x017F);	/* set up default output audio paths, enable right out 2 */
	ret += wm8753_i2c_write(0x34, WM8753_ROUT2V, 0x017F);	/* set up default output audio paths, enable right out 2 */
	/*ROUT2INV enable*/
	
	ret +=wm8753_i2c_write(0x34, WM8753_OUTCTL, 0x0106);


	/* set up default output audio paths, enable mono 1 */
	ret += wm8753_i2c_write(0x34, WM8753_MOUTM2, 0x005a);
	
	/* hifi stuff */
	if (hifi == 0) 
		goto out;
	
	/* enable hifi DAC */
	ret += wm8753_i2c_write(0x34, WM8753_HIFI, 0x0002);
	
	/* enable Left mixer */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -