一个 SPI 转串口驱动的优化

rel="File-List" href="file:///C:%5CDOCUME%7E1%5Czjujoe%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml">

一个 SPI 转串口驱动的优化

作者: zjujoe 转载请注明出处

Emailzjujoe@yahoo.com

BLOGhttp://blog.csdn.net/zjujoe

 

由于串口不够用,我们选用了 Exar 公司的 xr 20m 1172 SPI/I 2C 转串口芯片。考虑到速率问题(I 2c 较慢只有100k/400k两种模式),我们采用 SPI接口驱动该芯片。

 

花了两周的时间, 该芯片可以和 PC 通信了。最近应用组同事拿去连接一个加密芯片,发现不能正常工作。 该加密芯片提供的接口为 19200速率,8 位字节, 奇校验, 1位停止位,CTS/RTC 流控制。硬件同事仔细查看示波器,发现原来我们发出 0x94 时, 校验位时对时错。

 

考虑到我们的驱动程序确实也只是刚刚能够工作,应该有较大的优化空间, 决定对代码进行一定优化,以辅助问题解决。

 

首先写一个测试程序,该程序以 Cooked 模式, 8 位字节, 奇校验, 1位停止位, auto rts/cts 流控设置串口,然后写出一个字节 (0x55 或者 0x94)。然后恢复串口设置,最后退出。

优化1 提高 SPI 接口速率:

通过SPI 接口的时钟来提高 uart 寄存器速率。 Marvell 平台的 ssp 接口有一个分频器,系统有一个寄存器SSCR bit27控制分频器的输入是 26M 还是 13M 另外同一个寄存器里bit 8-bit19 控制分频数。 SPI输出频率为 ( 13M or 26M / SSCR[8-19] + 1

我们使用系统提供的 3.25M 时钟来计数,计算各种设置下 SPI 读写 uart 寄存器时间:

1)      缺省设置, SSCR[27] = 0, SSCR[8-19]= 0xf, 测量结果:

 

计数

time in uS

write

5a

27.69230769

read

52

25.23076923

2SSCR[27] = 0, SSCR[8-19]= 0x0, 测量结果:

 

计数

time in uS

write

19

7.692307692

read

14

6.153846154

3SSCR[27] = 1, SSCR[8-19]= 0x0, 测量结果:

 

计数

time in uS

write

17

7.076923077

read

12

5.538461538

性能大概提高了 4-5倍!

遗憾的是发现发送 0x94 正常,但是发送0x55 校验位时好时坏。

优化2 做寄存器 cache, 减少 SPI 读操作

Uart 寄存器的特殊之处在于它进行了地址复用:同一个地址对应了多个寄存器,到底是哪一个依赖于三个寄存器的内容:lcr, efr, mcr. 比如, lcr[7] == 1, lcr <> 0xbf 时, 地址 0x0 对应了 DLL 寄存器,在 lcr[7] == 1 时, 地址 0x0 对应了RHR/THR寄存器(读为 RHR, 写为 THR. 这样, 我们在进行读写寄存器时,需要频繁访问 lcr/efr/mcr, 对这三个寄存器进行缓冲可以减少 SPI接口访问, 提高读写效率。

优化前: 整个测试程序 SPI 读操作为: 103 次, 写操作为 240次。其中发送一个字符的 SPI 读操作为 15 次, 写操作为 26次。

优化后:整个测试程序 SPI 读操作为: 24 次, 写操作为 238次。其中发送一个字符的 SPI 读操作为 5 次, 写操作为 27次。

可见读操作大大减少了。写操作数基本不变。

遗憾的是问题依旧。

优化3 寄存器访问原子化

前面我们提过, 访问一个uart 寄存器可能需要先设置其它寄存器,这导致操作的原子性很难保证,另外,我们是通过 SPI 接口来读写 uart 寄存器的,这导致更加难以保证读写寄存器的原子性。 考虑到我们要在中断处理函数里访问 uart 寄存器,我们利用自旋锁来保证寄存器的原子性。

遗憾的是问题依旧。

优化4 进一步减少寄存器访问

跟踪系统寄存器访问发现, 我们目前不需要使用 IER:bit[4-7], ISR:bit[4/5], FCR :bit[4/5], MCR :bit[ 2/5/6 ], 对这些bit 访问需要更多的限制条件(EFR[4] == 1),事实上我们目前不需要。

所以我们修改这几个寄存器的访问限制, 从而节约寄存器访问。

优化后:整个测试程序 SPI 读操作为: 21 次, 写操作为 67次。其中发送一个字符的 SPI 读操作为 4 次, 写操作为 3次。

测试一下,发送 0x55 , 0x94 50次, 发现全部正确!

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值