浅探CS43131初始化

浅探CS43131初始化

CS43131,各大小尾巴的香饽饽IC,可惜就是初始化不好整。折腾出来了,作此文以作笔记。

寄存器读写

根据手册第61页,cs43131的寄存器地址是3bit的,还额外要一个控制字节
I2C写时序
I2C读时序

控制字节定义:
控制字节

通常情况下,这个字节设置为0x01即可

所以,寄存器读写部分的伪代码为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void cs43131_write_reg(uint32_t addr, uint8_t dat)
{
uint8_t addr_bit[5] = {0, 0, 0, 0x01,0x0};
addr_bit[0] = (addr >> 16) & 0xff;
addr_bit[1] = (addr >> 8) & 0xff;
addr_bit[2] = (addr) & 0xff;
//这里没[3],因为上面定义了
addr_bit[4] = dat;

iic_send_start(write_bit);
iic_send_data(addr_bit , 5);//注意这里一共5bit,比读取多1bit,多出来的是要写进寄存器的参数本身
iic_end();

}

void cs43131_read_reg(uint32_t addr, uint8_t *dst)
{

uint8_t addr_bit[4] = {0, 0, 0, 0x01};
addr_bit[0] = (addr >> 16) & 0xff;
addr_bit[1] = (addr >> 8) & 0xff;
addr_bit[2] = (addr) & 0xff;
//这里没[3],因为上面定义了

iic_send_start(write_bit);
iic_send_data(addr_bit , 4);
iic_send_start(read_bit);
iic_read(dst , 1);
iic_end();
}

初始化序列

直接上伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
cs43131_gpio_rst();//拉高复位脚(电平是1.8v)
delay_ms(10);//延时

//初始化晶振
// Configure XTAL driver
cs43131_write_reg(0x020052, 0x02); // Crystal Setting to 12.5ua
cs43131_write_reg(0x010006, 0x06); // Internal MCLK is expected to be 22.5792 MHz | RCO Mode
// cs43131_read_reg(xxx,&xxx);//clear any pending interrupts
// cs43131_write_reg(xxx,xxx);Enable XTAL interrupts
cs43131_write_reg(0x020000, 0xf6); // Power up XTAL

//初始化pll,根据手册第74页5.31.1节示例进行参考,pll数据参考手册第45页表4-5
/*
To power up the PLL, use the following default sequence:
1. Enable the PLL by clearing PDN_PLL.
2. Configure PLL_REF_PREDIV.
3. Configure PLL_OUT_DIV.
4. Configure the three fractional factor registers, PLL_DIV_FRAC.
5. Set the integer factor, PLL_DIV_INT, to the desired value.
6. Configure PLL_MODE and PLL_CAL_RATIO.
7. After properly unmasked (clearing PLL_READY_INT_MASK and PLL_ERROR_INT_MASK), PLL_READY_INT, and PLL_ERROR_INT are used to monitor if PLL has been successfully started.
8. Turn on the PLL by setting PLL_START.
*/

// Configure PLL
cs43131_write_reg(0x020000, 0xf2); // Power up XTAL | PLL
cs43131_write_reg(0x040002, 0x03); // PLL_REF_PREDIV = 8
cs43131_write_reg(0x030008, 0x0a); // PLL_OUT_DIV = 0x0a
cs43131_write_reg(0x030002, 0x80); // PLL_DIV_FRAC = 0x797680
cs43131_write_reg(0x030003, 0x76);
cs43131_write_reg(0x030004, 0x79);
cs43131_write_reg(0x030005, 0x45); // PLL_DIV_INT = 0x45
cs43131_write_reg(0x03001b, 0x01); // PLL_MODE = 1
cs43131_write_reg(0x03000a, 0x6f); // PLL_CAL_RATIO = 111
// cs43131_write_reg(xxx,xxx);//enable int

cs43131_write_reg(0x030001, 0x01); // PLL_START

//设置时钟输出,调试用,可去掉
// clk out
cs43131_write_reg(0x040004, 0x01); // source = pll | divide 2
cs43131_write_reg(0x020000, 0xf0); // Power up XTAL | PLL | CLKOUT

//设置内部数字核心使用pll输出频率
// Configure mclk to use pll
cs43131_write_reg(0x010006, 0x05); // Internal MCLK is expected to be 22.5792 MHz | PLL Mode

//初始化asp(音频串行接口)根据手册第74页5.31.1节示例进行参考
// Configure ASP interface.
cs43131_set_sample_rate(48000); // Serial Port Sample Rate = 48k
cs43131_set_sample_length(16); // Serial Port Sample Bit Size = 32bit

cs43131_write_reg(0x01000d, 0x00); // When in Master Mode, serial port clocks are active.

cs43131_write_reg(0x040018, 0x0c); // ASP Master Mode | ASP SCLK Inverted
cs43131_write_reg(0x040019, 0x0a); // ASP LRCK fixed 50/50 duty cycle | ASP frame start delay = 1

cs43131_write_reg(0x050000, 0x00); // ASP Rx channel n location. Start on SCLK 0
cs43131_write_reg(0x050001, 0x00);

cs43131_write_reg(0x05000A, 0x07); // 32 bits | Input channel data is propagated to the internal data path | L/R
cs43131_write_reg(0x05000B, 0x0f);

//初始化dsd,由于用不上,所以没写
// Configure DSD

//初始化pcm处理核心,根据手册第74页5.31.1节示例进行参考
// Configure PCM
cs43131_set_filter(0x00); // PCM Filter
cs43131_set_vol(0x10); // PCM Volume
cs43131_write_reg(0x090003, 0x0f); // This mute and unmute is controlled by PCM_SZC | Volume setting of both channels are controlled by PCM_VOLUME_A. PCM_VOLUME_B is ignored | PCM_SZC = Soft ramp
cs43131_write_reg(0x090004, 0x00); // PCM Path Signal Control 2 invert polarity & copy data(all disable)

cs43131_write_reg(0x020000, 0xb0); // Power up ASP | XTAL | PLL | CLKOUT

//初始化耳机放大器,根据手册第74页5.31.1节示例进行参考
// Configure HP
cs43131_write_reg(0x080000, 0x10); // HP Output Control 1 Output full scale voltage is at 1 V
cs43131_write_reg(0x0b0000, 0x00); // High voltage mode enable | Fixed, Mode 0 (±VP_LDO)

//免噗噗声参数,参考手册67页表5.8.1
cs43131_write_reg(0x010010, 0x99); // pop free setting
cs43131_write_reg(0x080032, 0x20);

//打开耳机电源
cs43131_write_reg(0x020000, 0xA0); // Power up HP | ASP | XTAL | PLL | CLKOUT

delay_ms(22);

//免噗噗声参数,参考手册67页表5.8.1
cs43131_write_reg(0x010010, 0x00); // pop free setting Restore
cs43131_write_reg(0x080032, 0x00);

// cs43131_write_reg(0x080000, 0x10); // HP Output Control 1
// cs43131_write_reg(0x090000, 0x02); // PCM Filter
//取消静音
cs43131_set_mute(0); // disable mute

上面代码用到的中间函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

//设置音量
void cs43131_set_vol(uint8_t vol)
{
cs43131_write_reg(0x090001, vol); // PCM Volume
cs43131_write_reg(0x090002, vol);
}

//设置静音
void cs43131_set_mute(uint8_t m)
{
uint8_t tmp = 0;
cs43131_read_reg(0x090003, &tmp);
if (m)
{
tmp = tmp | 0b00000011; // set bit[1:0] to 0b11
}
else
{
tmp = tmp & ~(0b00000011); // set bit[1:0] to 0b00
}
cs43131_write_reg(0x090003, tmp);
}

//设置采样位深
void cs43131_set_sample_length(uint8_t bps)
{
uint8_t reg = 0x00;
switch (bps)
{
case 32:
reg = 0;
break;
case 24:
reg = 1;
break;
case 16:
reg = 2;
break;
case 8:
reg = 3;
break;

default:
LOG_ERROR(TAG, "sample length %d error", bps);
break;
}
cs43131_write_reg(0x01000c, reg);
}

//设置采样率
void cs43131_set_sample_rate(uint32_t sr)
{
uint8_t reg = 0x00;
switch (sr)
{
case 32000:
reg = 0;
break;
case 44100:
reg = 1;
break;
case 48000:
reg = 2;
break;
case 88200:
reg = 3;
break;
case 96000:
reg = 4;
break;
case 176400:
reg = 5;
break;
case 192000:
reg = 6;
break;
case 352800:
reg = 7;
break;
case 384000:
reg = 8;
break;

default:
LOG_ERROR(TAG, "sample rate %ld error", sr);
break;
}
cs43131_write_reg(0x01000b, reg);
}

//设置滤波器寄存器
void cs43131_set_filter(uint8_t m)
{
cs43131_write_reg(0x090000, m);
}

理论上,硬件没问题,跑完序列就能出声了

作者

【社区】UM4I

发布于

2024-01-19

更新于

2024-12-07

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×