一个 SPI 转串口驱动的优化

一个 SPI 转串口驱动的优化

作者: zjujoe 转载请注明出处

Email zjujoe@yahoo.com

BLOG http://blog.csdn.net/zjujoe

 

由于串口不够用,我们选用了 Exar 公司的 xr20m1172 SPI/I2C 转串口芯片。考虑到速率问题( I2c 较慢只有 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

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

 

计数

time in uS

write

19

7.692307692

read

14

6.153846154

3 SSCR[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 次, 发现全部正确!

 

<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData("text"); if (text && text.length>300) { text = text + "/r/n/n本文来自CSDN博客,转载请标明出处:" + location.href; clipboardData.setData("text", text); } }, 100); } } </script> <script class="blogstory">function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:黑体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimHei; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:"Century Gothic"; panose-1:2 11 5 2 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@黑体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} h3 {mso-style-next:正文; margin-top:13.0pt; margin-right:0cm; margin-bottom:13.0pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:173%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:3; font-size:16.0pt; font-family:"Times New Roman"; mso-font-kerning:1.0pt;} h4 {mso-style-next:正文; margin-top:14.0pt; margin-right:0cm; margin-bottom:14.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:156%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:4; font-size:14.0pt; font-family:Arial; mso-fareast-font-family:黑体; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:913003993; mso-list-type:hybrid; mso-list-template-ids:-710929446 -1551737860 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-text:"%1/)"; mso-level-tab-stop:18.0pt; mso-level-number-position:left; margin-left:18.0pt; text-indent:-18.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->

一个 SPI 转串口驱动的优化

作者: zjujoe 转载请注明出处

Email zjujoe@yahoo.com

BLOG http://blog.csdn.net/zjujoe

 

由于串口不够用,我们选用了 Exar 公司的 xr20m1172 SPI/I2C 转串口芯片。考虑到速率问题( I2c 较慢只有 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

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

 

计数

time in uS

write

19

7.692307692

read

14

6.153846154

3 SSCR[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 次, 发现全部正确!

 

 

 

From Vendor:

We are glad to hear that the problem has disappeared. However, as we have mentioned in our previous e-mail, you should make sure that the Transmitter is empty before changing LCR.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值