/*****************************************************************************
FileName : pt2313.c
Function : PT2313音频驱动
Author : mike
Email : [email protected]
Version : V1.0
Date : 2019-08-25
Note :
*****************************************************************************/
#include "include.h"
#include "pt2313.h"
#if USE_PT2313_EN
pt2313_type pt2313_ctl;
u8 I2C_Buffer[17];
const u8 ToneTbl[BAS_TRE_MAX+1]= // 高低音值
{
/*
0x00,//-14dB
0x01,//-12dB
0x02,//-10dB
0x03,//-8dB
0x04,//-6dB
0x05,//-4dB
0x06,//-2dB
0x07,//0dB
//0xff,//0dB--0x07和0xff都是0db
0x0e,//2//2dB
0x0d,//4//4dB
0x0c,//6dB
0x0b,//8dB
0x0a,//10dB
0x09,//12dB
0x08,//14dB
*/
0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,
0x05,0x06,0x06,0x07,0x07,0xff,0x0e,0x0e,0x0d,0x0d,
0x0c,0x0c,0x0b,0x0b,0x0a,0x0a,0x09,0x09,0x08,0x08,
0x0c,
};
/* 音效 */
const u8 SoundEffect[5][2]=
{
/* bass treble effect */
{0x0e,0x0d}, /* 02db 04db pop 流行 */
{0x0e,0x0e}, /* 02db 02db clas 古典 */
{0x0c,0x07}, /* 06db 00db rock 摇滚 */
{0x0a,0x0e}, /* 10db 02db jazz 爵士 */
{0x07,0x07}, /* 00db 00db normal正常 */
};
const u8 MasterVolTbl[MAIN_VOL_MAX+1]= /*step:1.25db 音量值 */
{
/* 0x3f,//-78.75dB
0x3c,//-75.00dB
0x3a,//-72.50dB
0x38,//-70.00dB
0x36,//-67.50dB
0x34,//-65.00dB
0x32,//-62.50dB
0x30,//-60.00dB
0x2e,//-57.50dB
0x2c,//-55.00dB
0x2a,//-52.50dB
0x28,//-50.00dB
0x26,//-47.50dB
0x24,//-45.00dB
0x22,//-42.50dB
*/
/*
0x3f,//-78.75dB
0x20,//-40.00dB
0x1e,//-37.50dB
0x1c,//-35.00dB
0x1a,//-32.50dB
0x18,//-30.00dB
0x16,//-27.50dB
0x14,//-25.00dB
0x12,//-22.50dB
0x10,//-20.00dB
0x0e,//-17.50dB
0x0c,//-15.00dB
0x0a,//-12.50dB
0x08,//-10.00dB
0x06,//-7.50dB
0x04,//-5.00dB
0x02,//-2.50dB
0x00,//-0.00dB*/
63, 62, 61, 60, 59, 58, 57, 56, 55, 54,
53, 52, 51, 50, 49, 48, 47, 46, 45, 44,
43, 42, 41, 40, 39, 38, 37, 36, 35, 34,
33, 32, 31, 30, 29, 28, 27, 26, 25, 24,
23, 22, 21, 20, 19, 18, 17, 16, 15, 14,
13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
};
const u8 BalanceFaderTbl[13][2]=
{
//rear front……fader
//right left ……balance
{0x06,0x00},
{0x05,0x00},
{0x04,0x00},
{0x03,0x00},
{0x02,0x00},
{0x01,0x00},
{0x00,0x00},
{0x00,0x01},
{0x00,0x02},
{0x00,0x03},
{0x00,0x04},
{0x00,0x05},
{0x00,0x06},
};
const u8 ATT_TBL[13]=
{
0x00,
0x03,
0x06,
0x09,
0x0c,
0x0f,
0x1f,
0x1f,
0x1f,
0x1f,
0x1f,
0x1f,
0x1f,
};
//1us Delay
void iic_delay(void)
{
delay_us(10);
}
//2us Delay
void iic_delay_2(void)
{
delay_us(20);
}
void iic_start(void)
{
IIC_DATA_CLK_OUT();
IIC_DATA_CLK_HIGH();
iic_delay();
IIC_DATA_LOW();
iic_delay();
IIC_CLK_LOW();
}
//结束一次IIC通信
void iic_stop(void)
{
IIC_DATA_OUT();
IIC_DATA_LOW();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_DATA_HIGH();
}
//IIC总线发送1byte
void iic_sendbyte(u8 val)
{
u8 i;
IIC_DATA_OUT();
for (i=8; i!=0; i--) {
if (val & BIT(7)) {
IIC_DATA_HIGH();
} else {
IIC_DATA_LOW();
}
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_CLK_LOW();
val <<= 1;
}
}
//IIC总线接收1byte
u8 iic_getbyte(void)
{
u8 i;
u8 val = 0;
IIC_DATA_IN();
for (i=8; i!=0; i--) {
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
val <<= 1;
if (IIC_DATA_IS_HIGH()) {
val |= BIT(0);
}
IIC_CLK_LOW();
}
return val;
}
//IIC总线发送ACK
void iic_sendack(void)
{
IIC_DATA_OUT();
IIC_DATA_LOW();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_CLK_LOW();
}
//IIC总线发送NACK
void iic_sendnack(void)
{
IIC_DATA_OUT();
IIC_DATA_HIGH();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_CLK_LOW();
}
//IIC总线获取ACK状态
bool iic_getack(void)
{
bool ack = false;
IIC_DATA_IN();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
if (!IIC_DATA_IS_HIGH()) {
//printf("t\n");
ack = true;
}
IIC_CLK_LOW();
// printf("f\n");
return ack;
}
/*************************** PT2313 控制 ***************************/
static u8 I2C_Write_Byte(u8 data)
{
//int ret = 0;
//ret = i2c_master_send(g_pt2313_Dev->client, &data, sizeof(data));
//if(ret == 0)
// printk(" --> Fun: %s, Line: %05d i2c_master_send failure!! <--\n",
__func__, __LINE__);
iic_start();
iic_sendbyte(PT2313_Addr);
iic_getack();
iic_sendbyte(data); //音量 Volume 0~60
iic_getack();
iic_stop();
return 0;
}
void I2C_Write(u8 device_addr,u8 *buf,u8 num)
{
u8 i;
for(i = 0; i < num; i ++)
{
//DEBUGOUT("I2C_Write_Byte = 0X%X", *buf);
I2C_Write_Byte(*buf++);
}
}
/* 音频通道切换 */
void AudioSwitch(u8 channel)
{
u8 temp = 0;
channel > 3 ? channel = 3 : channel;
//DEBUGOUT("Audio Channel = %d ", channel);
switch(channel)
{
case 1:
temp = SwitchCtrlCmd | Stereo1;
temp |= PT2313_GAIN_DEFAULE;
break;
case 2:
temp = SwitchCtrlCmd | Stereo2;
temp |= PT2313_GAIN_DEFAULE;
break;
case 3:
temp = SwitchCtrlCmd | Stereo3;
temp |= PT2313_GAIN_DEFAULE;
break;
default:
temp = SwitchCtrlCmd | Stereo1;
temp |= PT2313_GAIN_DEFAULE;
break;
}
if(pt2313_ctl.LoudnessSta == OFF)
temp |= LOUDOFF;
else
temp |= LOUDON;
I2C_Buffer[0] = temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
}
/* 低音控制 */
void BassControl(void)
{
u8 temp;
if(pt2313_ctl.EQ == USER) // 设置指定值
{
ISVal(pt2313_ctl.BassVal, ToneTbl); // 超限控制
temp = ToneTbl[pt2313_ctl.BassVal];
}
else
{
pt2313_ctl.EQ --;
ISVal(pt2313_ctl.EQ, SoundEffect); // 超限控制
temp = SoundEffect[pt2313_ctl.EQ][0]; // 设置指定音效
}
I2C_Buffer[0] = BassCtrlCmd | temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
}
/* 高音控制 */
void TrebleControl(void)
{
u8 temp;
if(pt2313_ctl.EQ == USER)
{
ISVal(pt2313_ctl.TrebleVal, ToneTbl); // 超限控制
temp = ToneTbl[pt2313_ctl.TrebleVal];
}
else
{
pt2313_ctl.EQ --;
ISVal(pt2313_ctl.EQ, SoundEffect); // 超限控制
temp = SoundEffect[pt2313_ctl.EQ][1];
}
I2C_Buffer[0] = TreblwCtrlCmd | temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
}
/* 平衡音量控制 */
void BalanceFaderControl(void)
{
u8 temp;
u8 BR;// balance right 平衡右
u8 BL;// balance left 平衡左
u8 FF;// balance front 平衡前
u8 FR;// balance rear 平衡后
// 超限判断
ISVal(pt2313_ctl.BalVal, BalanceFaderTbl); // 超限控制
ISVal(pt2313_ctl.FadeVal, BalanceFaderTbl); // 超限控制
BR = BalanceFaderTbl[pt2313_ctl.BalVal][0];
FF = BalanceFaderTbl[pt2313_ctl.FadeVal][1];
BL = BalanceFaderTbl[pt2313_ctl.BalVal][1];
FR = BalanceFaderTbl[pt2313_ctl.FadeVal][0];
//front vol
temp = ATT_TBL[FF+BR];
I2C_Buffer[0] = ATTFRCtrlCmd | temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
temp = ATT_TBL[FF+BL];
I2C_Buffer[0] = ATTFLCtrlCmd | temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
//rear vol
temp = ATT_TBL[FR+BL];
I2C_Buffer[0] = ATTRRCtrlCmd | temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
temp = ATT_TBL[FR+BR];
I2C_Buffer[0] = ATTRLCtrlCmd | temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
}
/* 主音量控制 */
void MasterVolControl(u8 Val)
{
u8 temp;
ISVal(Val, MasterVolTbl);
temp = MasterVolTbl[Val];
I2C_Buffer[0] = VolCtrlCmd | temp;
I2C_Write(PT2313_Addr,I2C_Buffer,1);
BalanceFaderControl();
}
/* 静音控制 */
void AudioMute(char MuteOn)
{
if(MuteOn) // 静音
{
//DEBUGOUT("Mute on...");
I2C_Buffer[0] = ATTRLCtrlCmd | 0x1f;
I2C_Write(PT2313_Addr, I2C_Buffer,1);
I2C_Buffer[0] = ATTRRCtrlCmd | 0x1f;
I2C_Write(PT2313_Addr, I2C_Buffer,1);
I2C_Buffer[0] = ATTFLCtrlCmd | 0x1f;
I2C_Write(PT2313_Addr, I2C_Buffer,1);
I2C_Buffer[0] = ATTFRCtrlCmd | 0x1f;
I2C_Write(PT2313_Addr, I2C_Buffer,1);
}
else
{
//DEBUGOUT("Mute off...");
BassControl();
TrebleControl();
BalanceFaderControl();
MasterVolControl(pt2313_ctl.MasterVolVal);
}
}
void set_pt2313_channel(u8 channel)
{
AudioSwitch(channel); // 设置音频输入通道
}
void pt2313_set_volume(u8 val) // 设置音量
{
pt2313_ctl.MasterVolVal = val;
MasterVolControl(val);
}
void pt2313_set_treble(u8 val) // 设置高音
{
pt2313_ctl.TrebleVal = val;
TrebleControl();
//param_music_treb_write(); //记忆高音值
}
void pt2313_set_bass(u8 val) // 设置低音
{
pt2313_ctl.BassVal = val;
BassControl();
//param_music_bass_write(); //记忆低音值
}
void pt2313_init(void)
{
pt2313_ctl.LoudnessSta = ON;
pt2313_ctl.EQ = USER;
pt2313_ctl.MasterVolVal = 5; // 开机默认音量
pt2313_ctl.FadeVal= 6; // 增益
pt2313_ctl.BalVal = 6; // 均衡
AudioSwitch(PT2313_MAIN_CH); // 设置音频输入通道
BassControl(); // 设置低音
TrebleControl(); // 设置高音
MasterVolControl(pt2313_ctl.MasterVolVal); // 设置默认音量
BalanceFaderControl(); // 设置左右平衡
}
#endif // USE_PT2313_EN
/*****************************************************************************
FileName : pt2313.h
Function : PT2313音频驱动
Author : mike
Email : [email protected]
Version : V1.0
Date : 2019-08-25
Note :
*****************************************************************************/
#ifndef _PT2313_H_
#define _PT2313_H_
#if USE_PT2313_EN
#define ON 1
#define OFF 0
#define PT2313_Addr 0x88 // 芯片地址
#define Stereo1 0x00 // 音源通道选择
#define Stereo2 0x01
#define Stereo3 0x02
#define Stereo4 0x03
#define VolCtrlCmd 0x00 // 控制命令
#define ATTRLCtrlCmd 0xc0
#define ATTRRCtrlCmd 0xe0
#define ATTFLCtrlCmd 0x80
#define ATTFRCtrlCmd 0xa0
#define SwitchCtrlCmd 0x40
#define BassCtrlCmd 0x60
#define TreblwCtrlCmd 0x70
#define GAIN0 0x18 //0dB
#define GAIN1 0x10 //0.75dB
#define GAIN2 0x08 //7.5dB
#define GAIN3 0x00 //12.25dB
#define LOUDON 0x00
#define LOUDOFF 0x04
#define Volume_Default 45//10 // 默认值
#define Treble_Default 20//7
#define Bass_Default 20//7
#define Vol_Max_Val 60//20
#define MAIN_VOL_MAX 60 //主音量最大值
#define MAIN_VOL_DEFAULT 45 //主音量默认值
#define BAS_TRE_MAX 30 //高低音最大值
#define BAS_TRE_DEFAULT 20 //高低音默认值
#define USER 0x00 // 音效
#define POP 0x01
#define CLAS 0x02
#define ROCK 0x03
#define JAZZ 0x04
#define NORMAL 0x05
// 极限控制,用于判断指定值是否超过一维数组大小,若超过则修改成数组大小
#define GETARRSIZE(arr) ((sizeof(arr)/sizeof(arr[0])))
#define ISVal(variable, _arr) (variable > GETARRSIZE(_arr) - 1 ? variable = GETARRSIZE(_arr) - 1 : variable)
#define PT2313_MAIN_CH Stereo4 //BT/MUSIC/FM通道
#define PT2313_AUX_CH Stereo2 //AUX通道
#define PT2313_MUTE_CH Stereo1 //静音---设置到空的通道
#define PT2313_GAIN_DEFAULE GAIN3 //默认增益12.25dB
#define IIC_DATA 2 //PB2
#define IIC_CLK 1 //PB1
#define DATA_DE GPIOBDE
#define CLK_DE GPIOBDE
#define DATA_DIR GPIOBDIR
#define CLK_DIR GPIOBDIR
#define DATA_PU GPIOBPU
#define CLK_PU GPIOBPU
#define DATA_PORT GPIOB
#define CLK_PORT GPIOB
#define IIC_DATA_CLK_OUT() DATA_DE |= BIT(IIC_DATA);CLK_DE |= BIT(IIC_CLK);\
DATA_PU &= ~BIT(IIC_DATA);CLK_PU &= ~BIT(IIC_CLK);\
DATA_DIR &= ~BIT(IIC_DATA);DATA_DIR &= ~BIT(IIC_CLK);delay_us(10);
#define IIC_DATA_IN() DATA_DIR |= BIT(IIC_DATA);DATA_PU |= BIT(IIC_DATA);
#define IIC_DATA_OUT() DATA_PU |= BIT(IIC_DATA); DATA_DIR &= ~BIT(IIC_DATA);
#define IIC_DATA_CLK_HIGH() DATA_PORT |= BIT(IIC_DATA);DATA_PORT |= BIT(IIC_CLK);
#define IIC_DATA_HIGH() DATA_PORT |= BIT(IIC_DATA);
#define IIC_DATA_LOW() DATA_PORT &= ~BIT(IIC_DATA);
#define IIC_CLK_HIGH() CLK_PORT |= BIT(IIC_CLK);
#define IIC_CLK_LOW() CLK_PORT &= ~BIT(IIC_CLK);
#define IIC_DATA_IS_HIGH() (DATA_PORT & BIT(IIC_DATA))
typedef struct
{
u8 CrtAudioCh; //音频通道
u8 LoudnessSta; //响度
u8 MasterVolVal;//主音量
//u8 TempVolVal; //
u8 TrebleVal; //高音
u8 BassVal; //低音
u8 FadeVal; //增益
u8 BalVal; //均衡
u8 EQ; //EQ
} pt2313_type;
extern pt2313_type pt2313_ctl;
void set_pt2313_channel(u8 channel);
void pt2313_set_volume(u8 val);
void pt2313_set_treble(u8 val);
void pt2313_set_bass(u8 val);
void pt2313_init(void);
#endif USE_PT2313_EN
#endif //#ifndef _PT2313_H_