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

📄 codecs.c

📁 2.4G无线音箱的接收程序,采用ATMEGA8单片机和STS公司的无线模块完成
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*
* Purpose:      CODEC Functions
*
* Comment:	 	Type of codec can be set with the defines : CODEC_PCM3002 or
*				CODEC_WM8731
*				USE_DUAL_CODEC : if this define is set the interface B will also
*				be enabled.
*		 		VOLUME_DARR and VOLUME_CODEC defines if the volume on mu is
*				control using the codec or using the DARR79 volume registers.
*
* Creator:      Rob Lansbergen
*
* Version:		$Revision: 9 $
*
* File Name:	$Workfile: codecs.c $
*
* Author:		Rob Lansbergen
*
* Check in:		$Author: Chong.cheeleong $
*
* The information is provided 揳s is?without any express or implied warranty
* of any kind, * including warranties of merchantability, noninfringement of
* intellectual property, or fitness for any particular purpose. In no event sha
* Wireless Sound Solutions and/or its affiliate companies, or its suppliers be
* liable for any damages whatsoever arising out of the use of or inability to
* use the information or the materials. Wireless Sound Solutions, its affiliate
* companies, and its suppliers further do not warrant the accuracy or
* completeness of information, text, graphics, or other items contained within
* materials. Wireless Sound Solutions, Inc., may make changes to materials, or
* the products described within, at any time, without notice.
* ?007 Wireless Sound Solutions. All rights reserved. Wireless Sound Solutions
* STS and STS-wireless are trademarks of Wireless Sound Solutions.
******************************************************************************/
#include "defines.h"

unsigned char Wolfson_Slave_Address;
unsigned char Wireless_Codec_Select;
unsigned char prev_Sync_Stat = 0;

/* Local function declarations */
unsigned char 	Config_Codec_PCM3002	(void);
unsigned char 	Config_Codec_WM8731		(void);
unsigned char 	Config_Codec_CS4251 	(void);
unsigned char 	ConfigCodecSingle_WM8731(unsigned char Codec_A_B);
unsigned char 	Config_Codec_CS4341 	(void);

void          	Set_PCM3003       		(unsigned char address, int data);
unsigned char 	Set_WM8731        		(unsigned char address, int data);
unsigned char 	Set_CS4251       		(unsigned char address, int data);
unsigned char 	Set_CS4341       		(unsigned char address, int data);

void 			SetInVolume_PCM3002		(unsigned char Left_Right, unsigned char Volume);
void 			SetInVolume_WM8731		(unsigned char Left_Right, unsigned char Volume);
void 			SetInVolume_CS4251		(unsigned char Left_Right, unsigned char Volume);
void 			SetInVolume_CS4341		(unsigned char Left_Right, unsigned char Volume);

void 			SetVolume_PCM3002		(unsigned char Left_Right, unsigned char Volume);
void 			SetVolume_WM8731		(unsigned char Left_Right, unsigned char Volume);
void 			SetVolume_DARR80		(unsigned char Left_Right, unsigned char Volume);
void 			SetVolume_CS4251		(unsigned char Left_Right, unsigned char Volume);
void 			SetVolume_CS4341		(unsigned char Left_Right, unsigned char Volume);

extern char key_state; 
/******************************************************************************
*
* Function Name : Config Codec
*
* Purpose       : Config the codec to I2S 48 Khz
*
* Return value  : none
*
******************************************************************************/
unsigned char Config_Codec(void)
{
#ifdef CODEC_PCM3002
	return(Config_Codec_PCM3002());
#endif

#ifdef CODEC_WM8731
	return(Config_Codec_WM8731());
#endif

#ifdef CODEC_CS5341_WM8728
	return(0);
#endif

#ifdef CODEC_CS5368
	return(0);
#endif

#ifdef CODEC_CS4251
	return(Config_Codec_CS4251());
#endif
#ifdef CODEC_CS4341
	return(Config_Codec_CS4341());
#endif
}

/******************************************************************************
*
* Function Name : SetVolume
*
* Purpose       : Set Volume
*
* arguments	: Left_Right
*		  0 is Left
*         1 is Right
*		  Volume is a value from 0 to 0xFF
* Return value  : none
*
******************************************************************************/
void SetVolume(unsigned char Left_Right, unsigned char Volume)
{
#ifdef VOLUME_DARR
	SetVolume_DARR80(Left_Right, Volume);
#endif

#ifdef CODEC_PCM3002
	#ifdef VOLUME_CODEC
		SetVolume_PCM3002(Left_Right, Volume);
	#endif
#endif

#ifdef CODEC_WM8731
	#ifdef VOLUME_CODEC
		SetVolume_WM8731(Left_Right, Volume);
	#endif
#endif

#ifdef CODEC_CS5341_WM8728
#endif

#ifdef CODEC_CS5368
#endif

#ifdef CODEC_WM8731
	#ifdef VOLUME_CODEC
		SetVolume_CS4251(Left_Right, Volume);
	#endif
#endif

#ifdef CODEC_CS4251
	#ifdef VOLUME_CODEC
		SetVolume_CS4251(Left_Right, Volume);
	#endif
#endif
#ifdef CODEC_CS4341
	#ifdef VOLUME_CODEC
		SetVolume_CS4341(Left_Right, 0x00);
	#endif
#endif

}


/******************************************************************************
*
* Function Name : SetInVolume
*
* Purpose       : Set Volume
*
* arguments	: Left_Right
*		  0 is Left
*         1 is Right
*		  Volume is a value from 0 to 0xff
* Return value  : none
*
******************************************************************************/
void SetInVolume(unsigned char Left_Right, unsigned char Volume)
{
#ifdef CODEC_PCM3002
	SetInVolume_PCM3002(Left_Right, Volume);
#endif

#ifdef CODEC_WM8731
	SetInVolume_WM8731(Left_Right, Volume);
#endif

#ifdef CODEC_CS5341_WM8728
#endif

#ifdef CODEC_CS5368
#endif

#ifdef CODEC_CS4251
	SetInVolume_CS4251(Left_Right, Volume);
#endif

#ifdef CODEC_CS4341
	SetInVolume_CS4341(Left_Right, 0x00);
#endif

}


//==============================================================================================

/*********************/
/*** CODEC_PCM3002 ***/
/*********************/
void Set_PCM3003 (unsigned char address, int data)
{
#ifdef CODEC_PCM3002
	unsigned char i;
	unsigned int tmp16;

	tmp16 = ((address & 0x03) << 9) + (data & 0x1FF); /* set Registers Address */

	PCM_ML_HIGH;
	PCM_MC_HIGH;
	PCM_ML_LOW;

	for (i = 0; i < 16; i++)
	{
		PCM_MC_LOW;

		if (tmp16 & 0x8000) {PCM_MD_HIGH;}
		else                {PCM_MD_LOW;}

		tmp16 = tmp16 << 1;
		PCM_MC_HIGH;
	}

	PCM_MC_LOW;
	PCM_ML_HIGH;
#endif
}

void SetInVolume_PCM3002(unsigned char Left_Right, unsigned char Volume)
{
	//Set_PCM3003(Left_Right & 0x01, Volume | 0x100);
}

void SetVolume_PCM3002(unsigned char Left_Right, unsigned char Volume)
{
	//Set_PCM3003(Left_Right & 0x01, Volume | 0x100);
}

unsigned char Config_Codec_PCM3002(void)
{
#ifdef CODEC_PCM3002
	RESET_CODEC_OFF;

	if (Use_ModuleMode == MU)
		Set_PCM3003(2, 0x100 | 2);
	else
		Set_PCM3003(2, 0x40 | 2);

	Set_PCM3003(0x03, 0x0000E); /* Set to I2S */
	//Set_PCM3003(0x00, 0x100 | START_UP_VOLUME);
	//Set_PCM3003(0x01, 0x100 | START_UP_VOLUME);

#endif
	return (0);
}

//==============================================================================================

/********************/
/*** CODEC_WM8731 ***/
/********************/
unsigned char Set_WM8731 (unsigned char address, int data)
{
	unsigned char I2C_error = 0;

	/* Warning, disable unit before configuring */

	/* Wolfson register map */
	/* address part 7 bits  */
	/* data part 9 bits     */

	/* i2c_map = 7 bits address + MSB bit of Wolfson data */
	/* i2c_data = lower 8 bits of Wolfson data            */

	if (Wireless_Codec_Select == 0)
	{
		i2cSlaveAddress	= Wolfson_Slave_Address; /* Address of Wolfson */
		I2C_error = I2C_Write_Byte((address << 1) + ((data >> 8) & 0x01), data & 0xFF);
		/* switch back to org i2c slave address */
		i2cSlaveAddress = I2C_SLAVE_ADDRESS;
	}
	else /* codec on MU side is programm by CU using the wireless I2C mechanism */
	{
		TX_Data_send_array[0] = MSG_TYPE_WRITE_WITHOUT_ACK + 4;
		TX_Data_send_array[1] = IMSL_ADDR;
		TX_Data_send_array[2] = Wolfson_Slave_Address;		// Slave Address
		TX_Data_send_array[3] = (address << 1) + ((data >> 8) & 0x01);
		TX_Data_send_array[4] = 1;		// Amount of I2C Words
		TX_Data_send_array[5] = data & 0xff;
		Send_Message(STR_A, 2049); /* Magic number!!! */
	}
	return (I2C_error);
}


void SetInVolume_WM8731(unsigned char Left_Right, unsigned char Volume)
{
	if ((Left_Right == 0x00) || (Left_Right == 0x01))
	{
		Wolfson_Slave_Address = 0x34;
		Set_WM8731(0x00 + (Left_Right), Volume >> 3); /* volume is 8->5 bit */
	}
	#ifdef USE_DUAL_CODEC
	else /* 0x02 & 0x03 stript down to 0x00 and 0x01 */
	{
		Wolfson_Slave_Address = 0x36; /* Codec B */
		Set_WM8731(0x00 + (Left_Right & 0x01), Volume >> 3); /* volume is 8->5 bit */
		Wolfson_Slave_Address = 0x34;
	}
	#endif /* USE_DUAL_CODEC */
}


void SetVolume_WM8731(unsigned char Left_Right, unsigned char Volume)
{
	if ((Left_Right == 0x00) || (Left_Right == 0x01))
	{
		Wolfson_Slave_Address = 0x34;
		Set_WM8731(0x02 + (Left_Right & 0x01), Volume >> 1); /* volume is 8->7 bit */
	}
	#ifdef USE_DUAL_CODEC
		else
		{
			Wolfson_Slave_Address = 0x36; /* Codec B */
			Set_WM8731(0x02 + (Left_Right & 0x01), Volume >> 1); /* volume is 8->7 bit */
			Wolfson_Slave_Address = 0x34;
		}
	#endif /* END USE_DUAL_CODEC */	
}


unsigned char Config_Codec_WM8731(void)
{
	unsigned char I2C_error = 0;

	I2C_error = ConfigCodecSingle_WM8731(0); /* Inteface A */
	#ifdef USE_DUAL_CODEC
		I2C_error = ConfigCodecSingle_WM8731(1); /* Inteface B */
	#endif

	#ifdef VOLUME_DARR
		/* set darr to start-up volume, with IB the max setting is 126 because of clipping signals */
		SetVolume_DARR80(0, START_UP_VOLUME);
		SetVolume_DARR80(1, START_UP_VOLUME);
		SetVolume_DARR80(2, START_UP_VOLUME);
		SetVolume_DARR80(3, START_UP_VOLUME);
	#endif

	return (I2C_error);
}

/* Power down Registers bit address */
#define LINEIN_ON   0x00
#define LINEIN_OFF  0x01
#define MIC_ON      0x00
#define MIC_OFF     0x02
#define ADC_ON      0x00
#define ADC_OFF     0x04
#define DAC_ON      0x00
#define DAC_OFF     0x08
#define LINEOUT_ON  0x00
#define LINEOUT_OFF 0x10
#define OSC_ON      0x00
#define OSC_OFF     0x20
#define CLKOUT_ON   0x00
#define CLKOUT_OFF  0x40
#define POWER_ON    0x00
#define POWER_OFF   0x80

unsigned char ConfigCodecSingle_WM8731(unsigned char Codec_A_B)
{
	unsigned char I2C_error = 0;

	if (Codec_A_B == 0) Wolfson_Slave_Address = 0x34;
	else                Wolfson_Slave_Address = 0x36;

	I2C_error += Set_WM8731(0, 0x17); /* LinVol Left  17 is 0 db versterking */
	I2C_error += Set_WM8731(1, 0x17); /* LinVol Right 17 is 0 db versterking */
	I2C_error += Set_WM8731(2, 0x7F); /* HPVol Left */
	I2C_error += Set_WM8731(3, 0x7F); /* HPVol Right */
	I2C_error += Set_WM8731(4, 0x12); /* Analog audio path control */
	I2C_error += Set_WM8731(5, 0x01); /* Digital audio path control */

	if (Use_ModuleMode == MU)
	{
		if (Codec_A_B == 0)
		{
			#ifdef USE_DUAL_CODEC
				I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_ON|MIC_OFF|DAC_ON|ADC_ON|LINEOUT_ON|LINEIN_ON);
			#else
				I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_OFF|MIC_OFF|DAC_ON|ADC_OFF|LINEOUT_ON|LINEIN_OFF);
			#endif
		}
		if (Codec_A_B != 0)
			I2C_error += Set_WM8731(6, OSC_OFF|POWER_ON|CLKOUT_OFF|MIC_OFF|DAC_ON|ADC_ON|LINEOUT_ON);
	}
	else
	{
		/* if bit 6 is set the ADC does not work anymore (according to the data sheet this bit should be set. */
		/* Keep LINEOUT_ON also on CU because this helps VMID to get to the correct value faster */
		if (Codec_A_B == 0)
		{
			#ifdef	USE_DUAL_CODEC
				I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_ON|ADC_ON|DAC_ON|LINEOUT_ON);
			#else
				I2C_error += Set_WM8731(6, POWER_ON|OSC_ON|CLKOUT_OFF|ADC_ON|DAC_OFF|LINEOUT_ON|LINEIN_ON);
			#endif
		}
		if (Codec_A_B != 0)
			I2C_error += Set_WM8731(6, OSC_OFF|POWER_ON|CLKOUT_OFF|MIC_OFF|DAC_ON|ADC_ON|LINEOUT_ON);
	}

	if (Codec_A_B == 0) I2C_error += Set_WM8731(7, 0x4A); /* Master */
	else                I2C_error += Set_WM8731(7, 0x0A); /* Slave  */

	
	if (Use_SPDIF) I2C_error += Set_WM8731(8, 0x00); /* codecs are not used, set 12MHz clock undivided to DARR79 */
	else
	{
		#ifdef USE_WM8731_12Mhz
			I2C_error += Set_WM8731(8, 0x5D); /* half Sampling control : use USB mode (12MHZ/250=48KHz) */
		#else
			if (Codec_A_B == 0) I2C_error += Set_WM8731(8, 0x5c); /* half Clock output(Div intclock) */
		  	else                I2C_error += Set_WM8731(8, 0x1c); /* receive halve clock but still use 96 kHZ   */
		#endif
	}

⌨️ 快捷键说明

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