PT2313驱动(i2c通信)

/*****************************************************************************
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_

 

你可能感兴趣的:(驱动,单片机,算法)