Slvi驱动调试总结
本篇是继音频基本知识介绍后,4G项目中调试过程中遇到的一些问题总结
好奇是进步的原动力
目录
Slvi驱动调试总结 1
1 模拟spi通信问题 3
2 msleep和mdelay 3
2-1 系统资源 3
2-2 时间控制精度 3
3 I2C通信问题 4
3.1 I2C位传输 4
3.2 开始和结束信号 4
3.3 I2C应答信号 4
3.4 I2C写寄存器 4
3.5 I2C读寄存器 5
4 定时器使用 8
5 中断上下两部问题 9
6 nau8810芯片pcm数据,si_3217x芯片中注意事项 10
1 模拟spi通信问题
Spi 是 Serial Peripheral interface的缩写,即串行外围设备接口。
通信接口包括,
MISO:主设备数据输入,从设备数据输出。Master input,Slave Output
MOSI:主设备数据输出,从设备数据输入。Master Output,Slave Input
SCLK:时钟信号,由主设备产生
CS:从设备片选信号,由主设备控制。当从设备的片选被拉低的时候,才能从SPI总线上获取数据信息
根据SPI被配置成主或者从模式,MIMO和MOSI引脚的功能会自动改变,实现发送和接收的切换
遇到问题:
使用模拟spi读写寄存器,数据异常。写的数据不对。
问题排查:
模拟spi 读写reg后需要一个delay的时间,否则读写数据会异常。
2 msleep和mdelay
它们都有延时的作用,但是有很大的区别:
2-1 系统资源
mdelay 占用cpu资源,其他功能此时无法使用cpu
msleep 不占用cpu资源,其他功能模块可以使用cpu
2-2 时间控制精度
Mdelay时间控制是精确的,可以到ms级别,例如mdelay(2),则实际等待也是2ms
Msleep时间控制刻度已10ms为单位,例如msleep(2),实际要休眠10ms以上。因为调用的线程会休眠,休眠10ms后,依据线程优先级,可能依然不能立刻执行,所以,一般会大于10ms。
遇到问题:
Spi延时中分别使用mdelay和msleep,效果完全不同,使用msleep加载驱动的patch,速度非常慢。更换mdelay后,速度快了,但是会消耗更多的cpu资源。
3 I2C通信问题
I2C协议,2条双向串行线,一条数据线SDA,一条时钟线SCL。
3.1 I2C位传输
3.2 开始和结束信号
开始信号:SCL为高,SDA由高相低跳变,开始传输数据
3.3 I2C应答信号
3.4 I2C写寄存器
1. Master发起START
2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
3. Slave发送ACK
4. Master发送reg addr(8bit),等待ACK
5. Slave发送ACK
6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
7. Slave发送ACK
8. 第6步和第7步可以重复多次,即顺序写多个寄存器
3.5 I2C读寄存器
1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
2. Slave发送ACK
3. Master发送reg addr(8bit),等待ACK
4. Slave发送ACK
5. Master发起START
6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
7. Slave发送ACK
8. Slave发送data(8bit),即寄存器里的值
9. Master发送ACK
10. 第8步和第9步可以重复多次,即顺序读多个寄存器
主控设备通过I2C写NAU8810 codec的时候,发现写进去的值和读出来的值不同。向寄存器写如 0x15D,示波器抓图如下, 见图 3-5-1:
读出来的值寄存器如下:
Read 总图 见图3-5-2
Read 分解图3-5-3
读出来的值是0x101,后来排查才发现I2C写数据没有按照芯片的协议处理,上面介绍的是通用协议,但是不同的芯片厂商可能不同。例如nau8810芯片:
Nau8810 I2C写reg协议如下:
注意:此处数据是9位的而寄存器只有7位,数据为的最高位放在了control Register Address传输。发现这一点问题就解决了。
4 定时器使用
调试过程中遇到一个问题:上层设置生成ACK的握手音,波形要求如下:
首先生成1400Hz的tone音 100ms,然后停止100ms,再生成2300Hz的tone音100ms。问题的难点在于在1400Hz的tone音和2300Hz的tone音时间间隔要求为100ms,偏差在上下3%。如果上层做这个任务,控制的精度达不到要求。所以在底层使用定时器处理,使用方法:
1、 注册定时A
init_timer();
2、注册任务队列B
INIT_WORK();
3、 添加定时器
Add_timer();
当定时器时间到后,会执行软中断中向定时器注册的function,在此function中调度任务队列中的函数,任务队列完成不同的需要功能。
5 中断上下两部问题
又想让中断服务程序尽量快地执行,同时又想让程序完成尽可能多的工作,这两个目标显然是有矛盾的,基于这样的矛盾,我们把中断服务程序划分为两个部分:上半部(top half)和下半部(bottom half)。
1, 上半部:接收到一个中断就马上开始执行,具有严格的时限要求,比如 对硬件设备的响应和对硬件进行复位,这些工作都是在所有中断被禁止 的情况下完成的。中断服务程序是上半部。
2,下半部:没有特别严格的时限要求,允许稍后完成的工作被划分到下半部来做。一般来说中断服务程序返回的时候会立刻执行下半部。
中断活动的全过程大致为:copy from: http://cache.baiducontent.com/c? ... 2b000179ca&p1=1
1、中断请求:中断事件一旦发生或者中断条件一旦构成,中断源提交“申请报告”,与请求CPU暂时放下目前的工作而转为中断源作为专项服务
2、中断屏蔽:虽然中断源提交了“申请报告”,但是,是否得到CPU的响应,还要取决于“申请报告”是否能够通过2道或者3道“关卡”(中断屏蔽)送达CPU(相应的中断屏蔽位等于1,为关卡放行;反之相应的中断屏蔽位等于0,为关卡禁止通行);
3、中断响应:如果一路放行,则CPU响应中断后,将被打断的工作断点记录下来(把断点地址保护到堆栈),挂起“不再受理其他申请报告牌”(清除全局中断标志位GIE=0),跳转到中断服务子程序
4、保护现场:在处理新任务时可能破坏原有的工作现场,所以需要对工作现场和工作环境进行适当保护;
5、调查中断源:检查“申请报告”是由哪个中断源提交的,以便作出有针对性的服务;
6、中断处理:开始对查明的中断源进行有针对性的中断服务;
7、清除标志:在处理完毕相应的任务之后,需要进行撤消登记(清除中断标志),以避免造成重复响应;
8、恢复现场:恢复前面曾经被保护起来的工作现场,以便继续执行被中断的工作;
9、中断返回:将被打断的工作断点找回来(从堆栈中恢复断点地址),并摘下“不再受理其他申请报告牌”(GIE=1),继续执行原先被打断的工作
中断服务子程序中:
A、中断程序不能向用户空间发送或者接收数据
B、不能做任何可能发生休眠的操作,wait_event,或者 锁住信号量
C、不能调用schdule函数.
中断中不能读写spi设备,可以放在中断下半部做spi读写的操作。
1、 上半部要求尽量快,增加系统的吞吐量。
2、 下半部一般有软中断、tasklet、工作队列等处理方法。
6 nau8810芯片pcm数据,si_3217x芯片中注意事项
问题 nau8810有噪音:
问题分析:噪音的原因是4线的pcm有两条是数据线,一根dataIn,一根dataOut, 由于没有加载中控的音频模块,hisi主控没有配置内部codec,有脏数据直接输出到codec,导致噪音问题.
解决方法:直接关闭nau8810的pcm 数据输入/输出模块的电源。
问题 si3217x中问题:
1、 生成2300Hz tone音问题。
按照芯片厂商提供的软件生成2300Hz的tone音是不对的,软件计算中有问题。后续按照手册中提供的公式,手动计算出应该配置到寄存器的值。具体算法代码中有描述,不再赘述。
2、 配置ram寄存器
严格按照芯片手册提供的方法配置该ram寄存器,代码中有详细的描述,不再赘述。另外就是74号reg寄存器的配置,技术支持给的值不太对,需要修改成代码中的值。
3、 疑惑的问题
关于中断寄存器17、18、20 reg寄存器的用法,现有代码是直接从mtk平台继承过来的,咨询过技术支持,没有解释清楚,后续可以了解清楚。
本篇是继音频基本知识介绍后,4G项目中调试过程中遇到的一些问题总结
好奇是进步的原动力
目录
Slvi驱动调试总结 1
1 模拟spi通信问题 3
2 msleep和mdelay 3
2-1 系统资源 3
2-2 时间控制精度 3
3 I2C通信问题 4
3.1 I2C位传输 4
3.2 开始和结束信号 4
3.3 I2C应答信号 4
3.4 I2C写寄存器 4
3.5 I2C读寄存器 5
4 定时器使用 8
5 中断上下两部问题 9
6 nau8810芯片pcm数据,si_3217x芯片中注意事项 10
1 模拟spi通信问题
Spi 是 Serial Peripheral interface的缩写,即串行外围设备接口。
通信接口包括,
MISO:主设备数据输入,从设备数据输出。Master input,Slave Output
MOSI:主设备数据输出,从设备数据输入。Master Output,Slave Input
SCLK:时钟信号,由主设备产生
CS:从设备片选信号,由主设备控制。当从设备的片选被拉低的时候,才能从SPI总线上获取数据信息
根据SPI被配置成主或者从模式,MIMO和MOSI引脚的功能会自动改变,实现发送和接收的切换
遇到问题:
使用模拟spi读写寄存器,数据异常。写的数据不对。
问题排查:
模拟spi 读写reg后需要一个delay的时间,否则读写数据会异常。
2 msleep和mdelay
它们都有延时的作用,但是有很大的区别:
2-1 系统资源
mdelay 占用cpu资源,其他功能此时无法使用cpu
msleep 不占用cpu资源,其他功能模块可以使用cpu
2-2 时间控制精度
Mdelay时间控制是精确的,可以到ms级别,例如mdelay(2),则实际等待也是2ms
Msleep时间控制刻度已10ms为单位,例如msleep(2),实际要休眠10ms以上。因为调用的线程会休眠,休眠10ms后,依据线程优先级,可能依然不能立刻执行,所以,一般会大于10ms。
遇到问题:
Spi延时中分别使用mdelay和msleep,效果完全不同,使用msleep加载驱动的patch,速度非常慢。更换mdelay后,速度快了,但是会消耗更多的cpu资源。
3 I2C通信问题
I2C协议,2条双向串行线,一条数据线SDA,一条时钟线SCL。
3.1 I2C位传输
数据传输:SCL为高电平,SDA线若保持稳定,那么SDA上为传输数据bit;若SDA跳变,则 表示回话结束或开始。
3.2 开始和结束信号
开始信号:SCL为高,SDA由高相低跳变,开始传输数据
结束信号:SCL为高,SDA由低相高跳变,结束传输数据
3.3 I2C应答信号
Master每发送完8bit数据后等待Slave的ACK。即在第9个clock,若从I2C发ACK,SDA会被拉低。若无ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下图:
3.4 I2C写寄存器
1. Master发起START
2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
3. Slave发送ACK
4. Master发送reg addr(8bit),等待ACK
5. Slave发送ACK
6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
7. Slave发送ACK
8. 第6步和第7步可以重复多次,即顺序写多个寄存器
9. Master发起STOP
3.5 I2C读寄存器
1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
2. Slave发送ACK
3. Master发送reg addr(8bit),等待ACK
4. Slave发送ACK
5. Master发起START
6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
7. Slave发送ACK
8. Slave发送data(8bit),即寄存器里的值
9. Master发送ACK
10. 第8步和第9步可以重复多次,即顺序读多个寄存器
主控设备通过I2C写NAU8810 codec的时候,发现写进去的值和读出来的值不同。向寄存器写如 0x15D,示波器抓图如下, 见图 3-5-1:
![](https://i-blog.csdnimg.cn/blog_migrate/a71647933fe25b9a33cdc2cf26efdbc3.png)
读出来的值寄存器如下:
Read 总图 见图3-5-2
![](https://i-blog.csdnimg.cn/blog_migrate/eac7278e7aaec6d1a33367466c7b4685.png)
Read 分解图3-5-3
![](https://i-blog.csdnimg.cn/blog_migrate/91b0c2dab452c4cda92fda20710c8d96.png)
读出来的值是0x101,后来排查才发现I2C写数据没有按照芯片的协议处理,上面介绍的是通用协议,但是不同的芯片厂商可能不同。例如nau8810芯片:
Nau8810 I2C写reg协议如下:
注意:此处数据是9位的而寄存器只有7位,数据为的最高位放在了control Register Address传输。发现这一点问题就解决了。
4 定时器使用
调试过程中遇到一个问题:上层设置生成ACK的握手音,波形要求如下:
首先生成1400Hz的tone音 100ms,然后停止100ms,再生成2300Hz的tone音100ms。问题的难点在于在1400Hz的tone音和2300Hz的tone音时间间隔要求为100ms,偏差在上下3%。如果上层做这个任务,控制的精度达不到要求。所以在底层使用定时器处理,使用方法:
1、 注册定时A
init_timer();
2、注册任务队列B
INIT_WORK();
3、 添加定时器
Add_timer();
当定时器时间到后,会执行软中断中向定时器注册的function,在此function中调度任务队列中的函数,任务队列完成不同的需要功能。
5 中断上下两部问题
又想让中断服务程序尽量快地执行,同时又想让程序完成尽可能多的工作,这两个目标显然是有矛盾的,基于这样的矛盾,我们把中断服务程序划分为两个部分:上半部(top half)和下半部(bottom half)。
1, 上半部:接收到一个中断就马上开始执行,具有严格的时限要求,比如 对硬件设备的响应和对硬件进行复位,这些工作都是在所有中断被禁止 的情况下完成的。中断服务程序是上半部。
2,下半部:没有特别严格的时限要求,允许稍后完成的工作被划分到下半部来做。一般来说中断服务程序返回的时候会立刻执行下半部。
中断活动的全过程大致为:copy from: http://cache.baiducontent.com/c? ... 2b000179ca&p1=1
1、中断请求:中断事件一旦发生或者中断条件一旦构成,中断源提交“申请报告”,与请求CPU暂时放下目前的工作而转为中断源作为专项服务
2、中断屏蔽:虽然中断源提交了“申请报告”,但是,是否得到CPU的响应,还要取决于“申请报告”是否能够通过2道或者3道“关卡”(中断屏蔽)送达CPU(相应的中断屏蔽位等于1,为关卡放行;反之相应的中断屏蔽位等于0,为关卡禁止通行);
3、中断响应:如果一路放行,则CPU响应中断后,将被打断的工作断点记录下来(把断点地址保护到堆栈),挂起“不再受理其他申请报告牌”(清除全局中断标志位GIE=0),跳转到中断服务子程序
4、保护现场:在处理新任务时可能破坏原有的工作现场,所以需要对工作现场和工作环境进行适当保护;
5、调查中断源:检查“申请报告”是由哪个中断源提交的,以便作出有针对性的服务;
6、中断处理:开始对查明的中断源进行有针对性的中断服务;
7、清除标志:在处理完毕相应的任务之后,需要进行撤消登记(清除中断标志),以避免造成重复响应;
8、恢复现场:恢复前面曾经被保护起来的工作现场,以便继续执行被中断的工作;
9、中断返回:将被打断的工作断点找回来(从堆栈中恢复断点地址),并摘下“不再受理其他申请报告牌”(GIE=1),继续执行原先被打断的工作
中断服务子程序中:
A、中断程序不能向用户空间发送或者接收数据
B、不能做任何可能发生休眠的操作,wait_event,或者 锁住信号量
C、不能调用schdule函数.
中断中不能读写spi设备,可以放在中断下半部做spi读写的操作。
1、 上半部要求尽量快,增加系统的吞吐量。
2、 下半部一般有软中断、tasklet、工作队列等处理方法。
6 nau8810芯片pcm数据,si_3217x芯片中注意事项
问题 nau8810有噪音:
问题分析:噪音的原因是4线的pcm有两条是数据线,一根dataIn,一根dataOut, 由于没有加载中控的音频模块,hisi主控没有配置内部codec,有脏数据直接输出到codec,导致噪音问题.
解决方法:直接关闭nau8810的pcm 数据输入/输出模块的电源。
问题 si3217x中问题:
1、 生成2300Hz tone音问题。
按照芯片厂商提供的软件生成2300Hz的tone音是不对的,软件计算中有问题。后续按照手册中提供的公式,手动计算出应该配置到寄存器的值。具体算法代码中有描述,不再赘述。
2、 配置ram寄存器
严格按照芯片手册提供的方法配置该ram寄存器,代码中有详细的描述,不再赘述。另外就是74号reg寄存器的配置,技术支持给的值不太对,需要修改成代码中的值。
3、 疑惑的问题
关于中断寄存器17、18、20 reg寄存器的用法,现有代码是直接从mtk平台继承过来的,咨询过技术支持,没有解释清楚,后续可以了解清楚。