SED-A9C主板PS/2接口的实现

时间:2022-10-03 05:59:26

摘要:本文介绍基于EP9315处理器开发的SED-A9C主板PS/2键盘接口的实现方法,对Cirrus Logic公司的在Linux操作系统下的PS/2键盘驱动程序进行分析,找出相应的漏洞,并给予解决。

关键词:Linux;ARM;嵌入式操作系统;SPI;PS/2

引言

EP931x是Cirrus Logic公司推出的基于ARM920T的片上系统,它广泛应用于数字媒体服务器播放器、遥控系统、GPS定位设备等领域。

深圳桑达龙金商业机器有限公司开发的基于EP9315处理器的SED-A9C主板,全面支持Linux2.6.8、eCos 2.0、5.0等操作系统,在原有公开的Linux/WinCE的基础上,根据自身的硬件特性进行相应的驱动程序开发,形成一个完整的SED―A9C主板嵌入式操作系统。

PS/2是A9C主板的主要接口之一,本文介绍基于EP9315处理器的SED-A9C主板PS/2键盘接口实现方法。

键盘协议

PS/2设备(下面简称设备)按照一种双向同步串行协议进行通讯。设备可以发送数据到主机,主机也可以发送数据到设备,但主机在总线上具有优先权,它可以在任何时候抑制来自于设备的通讯,只要把时钟拉低即可。

从设备发送到主机的数据在时钟信号的下降沿被读取,从主机发送到设备的数据在上升沿被读取。不管通讯的方向怎样,设备总是产生时钟信号。如果主机要发送数据,它必须首先告诉设备开始产生时钟信号。最大的时钟频率是33kHz,而且大多数设备工作在10kHz~20kHz。

数据由11~12位组成。这些位如下:1个起始位总是为0;8个数据位低位在前;1个奇校验位;1个停止位总是为1;1个应答位仅在主机对设备的通讯中。

如果数据位中包含偶数个1,校验位就置1;如果数据位中包含奇数个1,校验位就置0。数据位中1的个数加上校验位总是为奇数(奇校验),主要用来进行错误检测。

当主机发送数据给设备时,设备回送一个握手信号来应答数据包已经收到,这个位不会出现在设备发送数据到主机的过程中。

设备到主机的通讯过程

数据和时钟线都是集电极开路结构。当设备等待发送数据时,它首先检查时钟线以确认它是否是高电平。如果不是,那么是主机抑制了通讯,设备必须缓冲任何要发送的数据直到重新获得总线的控制权。如果时钟线是高电平,设备就可以开始发送数据。

上面提及的设备使用一种每帧包含11位的串行协议,且1个起始位总是为0;8个数据位低位在前;1个奇校验位;1个停止位总是为1。

数据的每位在时钟的下降沿被主机读入。

主机到设备的通讯

由于设备总是产生时钟信号,如果主机要发送数据,它必须首先把时钟和数据线设置为请求“发送状态”,通过下拉时钟线至少100μs来抑制通讯;通过下拉数据线来应用请求发送,然后释放时钟。

设备应该在不超过10ms的间隔内检查这个状态。当设备检测到这个状态,它才开始产生时钟信号,并且时钟脉冲标记下输入八个数据位和一个停止位。主机仅当时钟线为低的时候改变数据线,而数据在时钟脉冲的上升沿被锁存。这与设备到主机通讯的过程正好相反。

在停止位发送完毕后,设备要应答接收到的数据,把数据线拉低并产生最后一个时钟脉冲。如果主机在第11个时钟脉冲后不释放数据线,设备将继续产生时钟脉冲直到数据线被释放(设备将产生一个错误)。

主机可以在第11个时钟脉冲前中止一次传送,只需下拉时钟线至少100μs。

图1以单独的时序表示了由主机产生的信号及由PS/2设备产生的信号。注意应答位时序的改变,此时表现为数据的改变发生在时钟线为高的时候。

硬件实现

SED-A9C主板采用EP9315嵌入式处理器,再加上一些芯片来实现特有的功能。

EP9315内嵌有SPI(串口外设接口)接口,也称为SSP,支持以主模式和从模式与外设的同步串行通信。

软件实现

SED-A9C嵌入式主板上运行Linux 2.6.20操作系统。由于PS/2的硬件只能实现键盘设备到主机的通讯,下面着重介绍驱动程序的实现过程。

EP9315中SSPCR0控制寄存器配置为:MotorolaSPI格式,11位数据位(1位开始位、8位数据位、1位奇校验位、1位停止位)。

SSPCR1控制寄存器配置为从模式,同步串口允许,接收中断允许,溢出中断禁止。

SSPDR是16位宽度的数据寄存器,当读该寄存器时是在访问接收FIFO,当写该寄存器时是在访问发送FIFO。

SSPSR为只读状态寄存器,可查询接收/发送FIFO和工作忙状态。

SSPIIR中断标识寄存器,可以查询到中断的类型。

对于接收中断,并不是SPI每接收一个来自键盘的数据都会产生一个中断,中断条件是接收FIFO中不少于4个数据。

目前Cirrus Logic的SPI键盘驱动程序中,取SPI接收数据有2个中断,一个中断是sPI本身的接收中断,当接收FIFO超过4个数据时,会产生中断,这样SPI接收中断程序会去读SPI接收FIFO的数据。但由于EP9315的SPI接收中断设计本身的限制,当接收FIFO中有数据,但又不足4个时,不会发生中断。为了避免上面的实时性不足,驱动程序又设置了1个20ms定时器,定时器是每隔20ms执行一个程序,查询接收FIFO中是否有数据,从而实现实时取接收数据的目的。

SPI接收中断和定时器程序都是调用一个程序ReadIntoBufferO来实现取SPI接收FIFO中的数据,ReadIntoBufferO子程序会读SPI接收FIFO中的数据,并保存在一个uiKeyBuffer[256]的环形数组缓存区中,在这种设计方法下,SPI中断程序和定时器程序有可能会同时调用ReadIntoBuffer()程序,发生“重入”问题,从而使数据不正确。但当键盘快速输入时会产生误码或丢码现象。

图2是Cirrus Logic公司SPI接收中断程序、定时器程序和ReadIntoBuffer()程序的框图。

针对这种情况,我们在程序上做了改进,当发生SPI接收中断时,说明接收FIFO中至少有4个键盘数据,为了避免sPI接口再次接收到数据从而造成接收FIFO溢出,在接收中断程序中通过EGPIO14输出高电平使时钟保持低电平来抑制键盘的发送,不调用ReadIntoB uffer()子程序,取SPI数据的工作由定时器程序执行,从而解决“重入”问题。图3是修改后的SPI接收中断程序和定时器程序的框图。

经测试,PC键盘数据接收正常,应用在POS机上也正确无误。

结语

本文介绍的设计方法成功应用在SED-A9C主板的开发中,目前SED-A9C主板已应用在桑达POS机及北京地铁10号线广告上。

上一篇:RFID印刷电路板跟踪技术探析 下一篇:通过电路仿真降低无线回程成本