foreword
In the recent project development, it is necessary to control the volume of the AV side. Since the AV volume control gpio of the main control side is multiplexed as other function ports, an IC has to be added to control the volume output. Here, the M62429L volume control IC is used.
1. Overview of M62429 volume ic
M62429L is a two-channel electronic volume controller chip controlled by serial data, allowing each channel to be controlled independently, the volume is 0dB~ -83dB, and each level can be controlled by 1dB.
1.1 ic pins and their functions
The hardware pin diagram is as follows:
The pin functions are defined as follows:
The volume signal is input to VIN1 or VIN2 and output from VOUT1 or VOUT2 after internal circuit processing;
1.2 Control data format
One frame of control data is 10bit, bit0 selects the channel to be controlled, bit1 selects several channels to control, bit2-bit8 is the data to control the volume, bit9-bit10 is high level 1 by default.
1.2.1 Volume control data bit2-bit8
The volume control data is divided into two parts, which can be understood in this way, D2-D6 control large steps, as can be seen from the table, each group of data interval is 4dB, D7-D8 control small steps, 0~3dB.
For example, if you set the volume to -7dB, then D2-D6 should be set to -4dB (00101), D7-D8 should be set to -3dB (00), and so on, the minimum volume can be set to -83dB, The maximum volume is 0dB.
1.3 Control signal timing diagram
After talking about the data format, the next step is to understand the timing of clock and data. The CLOCK and DATA pins usually lead to two gpio pins from the master control terminal. According to these two gpio to simulate the timing for data transmission, simulate the timing of the clock It should be noted that its minimum clock period is 4us; as can be seen from the figure below, the data sent by bit0-bit10 will be read by ic when the rising edge of the clock, and it should be noted that the bit is read on the rising edge After the data, pull the bit data to low level 0 before the falling edge, because ic will read the trigger signal when the clock is on the falling edge, if the signal read on the falling edge is high level 1, it means a frame of data ( D0-D10) transmission is completed, so after the data reading of D10 is completed, the data line remains high to indicate that the data transmission is completed.
2. Software driver control ic
The software driver is relatively simple. You can list the control data of D2-D6 and D7-D8 in the form of an array, and then integrate it into a frame of data according to the set real volume and send it.
The parameter track_set in the M62429L_data function: selects the D0-bit channel, ctrl_set: controls the number of channels, vol: sets the volume (0~100), first converts vol to a number in the range 0-87 in the function, and then goes to the index Which value corresponds to the two arrays, and finally, it is shifted and integrated into a set of data.
The M62429L_send_data function is the sent data, clock and data timing.
#define DATA_D0_0 0x0 //track1
#define DATA_D0_1 0x1 //track2
#define DATA_D1_0 (0x0 <<1) //all ctrl
#define DATA_D1_1 (0x1 <<1) //one ctrl
#define DATA_D9_D10 (0x11 <<9)
int8_t data_d6_d2[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15}; //-& ~ 0db
int8_t data_d8_d7[] = {0x0,0x1,0x2,0x3}; //-3db ~ 0db
void M62429L_gpio_init()
{
gpio_configure(PINPAD_T14, GPIO_DIR_OUTPUT); //clk
gpio_configure(PINPAD_T19, GPIO_DIR_OUTPUT); //data
gpio_set_output(PINPAD_T14,0);
gpio_set_output(PINPAD_T19,0);
}
void M62429L_set_clk(bool value)
{
gpio_set_output(PINPAD_T14,value);
}
void M62429L_set_data(bool value)
{
gpio_set_output(PINPAD_T19,value);
}
int16_t M62429L_data(bool track_set,bool ctrl_set,int8_t vol)
{
int16_t vol_data = 0x00;
int8_t data8_2[2]={0};
if(track_set){
vol_data |= DATA_D0_1;
}
if(ctrl_set){
vol_data |= DATA_D1_1;
}
vol = vol * 87 / 100;
data8_2[0] = vol /4;
data8_2[1] = vol %4;
vol_data = vol_data | (data_d6_d2[data8_2[0]] <<2) | (data_d8_d7[data8_2[1]] <<7) | DATA_D9_D10;
printf("vol:%d,data[0]:%d,data[1]:%d,vol_data:%d\n",vol,data8_2[0],data8_2[1],vol_data);
return vol_data;
}
void M62429L_send_data(bool track_set,bool ctrl_set,int8_t vol)
{
int16_t vol_data = 0;
bool data_bit = 0;
vol_data = M62429L_data(track_set,ctrl_set,vol);
for(int i=0; i<=9;i++){
data_bit = (vol_data>>i)&0x1;
M62429L_set_clk(0);
usleep(10);
M62429L_set_data(data_bit);
usleep(10);
M62429L_set_clk(1);
usleep(10);
M62429L_set_data(0);
usleep(10);
}
M62429L_set_clk(0);
usleep(10);
M62429L_set_data(1);
usleep(10);
M62429L_set_clk(1);
usleep(10);
M62429L_set_clk(0);
usleep(10);
}