slvi驱动调试总结

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位传输

数据传输:SCL为高电平,SDA线若保持稳定,那么SDA上为传输数据bit;若SDA跳变,则 表示回话结束或开始。

slvi驱动调试总结_第1张图片


3.2 开始和结束信号
开始信号:SCL为高,SDA由高相低跳变,开始传输数据

结束信号:SCL为高,SDA由低相高跳变,结束传输数据

slvi驱动调试总结_第2张图片


3.3 I2C应答信号

Master每发送完8bit数据后等待Slave的ACK。即在第9个clock,若从I2C发ACK,SDA会被拉低。若无ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下图:

slvi驱动调试总结_第3张图片


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

slvi驱动调试总结_第4张图片


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步可以重复多次,即顺序读多个寄存器

slvi驱动调试总结_第5张图片


遇到问题:
主控设备通过I2C写NAU8810 codec的时候,发现写进去的值和读出来的值不同。向寄存器写如 0x15D,示波器抓图如下, 见图 3-5-1:
slvi驱动调试总结_第6张图片

读出来的值寄存器如下:

Read 总图 见图3-5-2
slvi驱动调试总结_第7张图片

Read 分解图3-5-3
slvi驱动调试总结_第8张图片
读出来的值是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平台继承过来的,咨询过技术支持,没有解释清楚,后续可以了解清楚。

你可能感兴趣的:(slvi驱动调试总结)