中级会员
- 积分
- 222
- 金钱
- 222
- 注册时间
- 2020-7-6
- 在线时间
- 54 小时
|
53金钱
本帖最后由 akes 于 2020-8-29 22:15 编辑
初学IMX6ULL,没买LCD屏幕,想着用以前的spi接口的LCD屏幕显示QT程序,开始试着写LCD驱动
写完清屏函数时,对ECSPI通讯速度产生了疑问,开始试着解答,但没有成功,
期待以后出现大神前来解答,另一方面,也是给自己以后复习用
下面的讲解如有错误还望多多指教
内核用的是原子的4.19.35版本,yocto rootfs
LCD屏幕分辨率240*320,RGB565,写一次屏幕要发送150kb数据( 320 * 240 * 2 )
设备树初始化和驱动都设置的SPI时钟是 60 MHz
ecspi1设备树
驱动初始化
理论上,写入150kb需要的时间是 0.02 秒,但实际花费时间是0.122秒
清屏函数和程序输出结果如下
驱动清屏函数
程序输出
这么慢根本不能忍,现在考虑的可能的原因是,ECSPI的时钟没有达到 60Mhz ,发送之间存在时间间隔
想到的解决方法是去阅读spi驱动源码,看看寄存器的值是不是理想的,
寄存器还好,阅读linux源码还没干过,心里没底,幸好原子哥在教程里把源码路径都放出来了 linux源码 / drivers / spi / spi-imx.c,还讲解了一部分
修改spi-imx.c 在函数里加入 printk("函数名称") ,编译内核重启,看看清屏时到底调用了什么函数 (第二天才想到这法子)
结果发现每次清屏都会调用这四个函数
mx51_ecspi_config
mx51_ecspi_clkdiv
mx51_ecspi_trigger
mx51_setup_wml
花了个下午去阅读这几个函数,操作寄存器用的是 writel 函数,和原子教程里点亮LED的一样,寄存器地址通过 spi_imx->base + 偏移值来指定,如写入ECSPIx_CONREG 就是 writel( val , spi_imx->base + 0x08 )
因为清屏时发送的数据非常长,所以ecspi驱动就开启了DMA传输,原来我用正点原子早期发布的根文件系统是没有DMA的配置文件的,换成了yocto rootfs 的就OK了
回到spi-imx.c文件,都能直接操作寄存器,检查时钟源的寄存器,检查分频的寄存器不就能知道答案了?
实际用 printk 发送出来的 ECSPIx_CONREG 寄存器的值表示,没有分频,
于是只能去查看时钟配置的寄存器 ECSPIx_PERIODREG
结果 printk 打印出来的是 0 ,意味着这个ECSPI并在拉低 CS 引脚后不等待,时钟源是 正常的SCLK 时钟,发送间隔时间为 0 ,
如果直接自己在这写入寄存器确保分频为1,发送间隔时间为0会怎么样?结果也能用,但速度没变化
致此,我知道的伎俩都用完了,并没有得到答案。如果手头有示波器就能好好看看到底发生了什么了,或者试试裸机开发,但那就得花上更多的时间去弄寄存器了,所以搁置。
原子哥的书籍里提到IMX6U可以达到几十MHz,手册里也说到可以达到60MHz,时钟树里的图像表明最高速度是 528_PLL / 8 ,有66MHz
但现在的效果实在算是比较差的了,还有可能是 ECSPI 驱动里某些地方花了时间,或者DMA配置不正确,等着原子哥什么时候讲讲了
|
最佳答案
查看完整内容[请看2#楼]
LCD清屏速度慢的问题解决了,真是出乎意料,昨天看源码时发现 spi_transfer 可以覆盖初始化驱动时设置的部分内容,如通讯速度,单次发送的长度等,所以刚刚改清屏函数,效果真是令人惊讶
清屏代码 和 输出结果 如下
设置 spi_transger 结构体的单次发送长度为 32 位,清屏的时间是27ms左右,理论上可以达到 30帧 左右的刷新速度,
屏幕单像素是 RGB565,还需要稍微处理下 u16 与 u32 的转换就能正确显示颜色
准 ...
|