FM1702这款芯片的操作可以通过SPI串口,也可以通过并口。在我们的设计中,是通过SPI串口进行操作的。所以在硬件电路搭建好了之后,首先要做的是调试SPI接口。我们所用的控制芯片是STM32F103C8TL,其中集成了SPI接口,对其进行操作就是进行一些设置,然后读写缓冲区,标志位,片选信号线。在程序中设置如下:
SCK,MISO,MOSI对应芯片上的引脚设为推挽复用,
RST,NSS对应的芯片上的引脚设为推挽输出,
设置SPI端口:方向,为双向全双工;模式,主模式;数据大小,8bits;NSS为高时钟电平为高;在NSS有效后第二个周期数据有效;发送或者接受的第1比特为8bits中的最高位;循环纠正码为7。
ST芯片上的SPI端口设定好之后,就是进行SPI端口调试,这个模块的调试,我们是费了一些周折的,先是直接连上FM1702芯片,发送数据并接收数据,结果总是令人沮丧,这是第一步,SPI口没有调通,之后的操作都不能进行。后来改了一下,接上Flash来调试SPI端口,由于开发平台是ST的一个开发板,把以前一个废板子,上面有Flash的,通过飞线将对应端口连接起来,结果受到废板子电路的影响,高低电平都无法稳定得到,然后换了一个有Flash的废板子,就可以了,这个大概是侥幸吧。
让我觉得欣慰的是,在两天内,我就完成了对AT45DB161这个Flash存储器的读写操作的程序,当然是在借鉴别人的一些程序的基础上。让我有点纳闷,并且有点出乎我的意料的是,SPI端口的读操作,并不是我分析出来的那样:
先让NSS有效(低)并保持有效,然后发送一个地址命令(1byte),接着检测接收缓冲器的标识位,有效以后读取缓冲区的值,然后将NSS无效。这个流程是我分析出来的,但是这样是不对的,因为这样无法读出数据,读出来的数据也是不对的。
在我参考、学习了好几个SPI操作程序之后,我发现了正确的读操作流程,1,让NSS有效(低)并保持有效;2,发送一个无效字节(DUMMY),3,检测接收缓冲器的标示位,有效后读取接收缓冲区的数据。4,让NSS无效(高)。而正确的发送一个字节操作流程为1,让NSS有效(低)并保持有效;2,发送一个命令或者数据;3,检测接收缓冲器的标志位,有效后读取数据(1byte);4,让NSS无效(高)。其中读操作的第二步,是为了给SPI端口提供时钟,而写操作的第3步好似多余,因为读出的数据是无效数据。
不管怎样,经过折腾,把SPI接口的操作调试通过了。紧接着做的工作就是调试FM1702的读写,参看了文档之后,发送地址,数据,发送地址,接收数据,主要是对FM1702中的FIFO进行读写,对Command寄存器进行读写,以及对一些寄存器进行设置。
测试这些寄存器通过之后,写好一个初始化FM1702的程序进行设置。设置好了以后,就要通过FM1702对卡片(FM1208)进行操作,1,寻卡;2,防冲突;3,选卡;这三步执行成功就会选定一张卡接下来的操作就是针对这张卡的。在第2步中,会获得卡片的序列号,这个序列号是生产卡片时就确定了的。
接着是Rats和PPS命令,这两条命令通过之后就进入了MF,MF是默认的一个文件夹,将CPU卡内的64k空间当做一个文件夹便于管理操作。之后的操作就是建立文件夹(应用),然后建立文件,添加记录等的操作。
在发送命令对卡进行操作时,有个问题然我很头痛,直到最后才解决,那就是发送命令等待返回值,有时候是操作失败,没有成功,那么可以继续发送,但是我并不知道怎样去判断该等待多长时间才去读取返回值,在调试的过程中,(1)如果把它设为死循环,只要没有得到相应的相应,就一直发送,结果这样很不好,假如在寻卡时失败,或者发送命令有误,那么程序无法跳出。(2)又试着把延迟设置得比较小,因为这样可以让系统反应快一点,有错就重新来过,但是有些命令,(如创建文件,添加记录)执行正确之后,需要很长时间才能有返回值,还没有到执行结束,由于延迟不够,就判定执行失败了,又重新发命令,结果是一直都操作失败。后来我发现,(3)可以通过检测FM1702的一个寄存器(中断请求寄存器)的值来判断是否完成了接受返回值。不能进行的操作是,等待期间读取FIFO的值,或者FIFO长度。这样还是有(1)中的问题,当一开始没有卡,而后来有卡时就没有办法检测到,所以在(3)的基础上添加一个延迟判别,到达一定延迟时间还没有返回正确值就判定命令执行失败,再重新发送。这个问题在调试的过程中让我吃尽苦头,有时候都不知道是这个地方的问题,最后终于解决,心中也有那么一点的成就感。
还有一些问题,是在复旦微电子那边的技术支持(唐工)的帮助下解决的,主要是后面建立钱包,管理钱包,充值,消费程序调试的时候,有一个问题,困扰了几天,在调试初始化圈存命令时,总是返回69 85,使用条件不满足,唐工帮我看了好久,排除了各种权限问题,还是不行,后来我仔细看文档,发现其中说钱包文件的标识符要设为00 02,改过来之后就执行成功了;还有一个问题也是让我很困扰,在调试圈存命令时,总是返回6901,一开始,唐工告诉我要建立一个应用公共基本数据文件,并且往里面添加记录,当我把这个完成(其实也不简单,这个文件是线路保护的二进制文件,添加记录也是一件麻烦的事情)之后,圈存命令返回值还是6901,后来在我都觉得没有希望的时候,唐工帮我仔细分析了我的操作流程,发现问题就在初始化圈存之后,卡片的状态发生了改变,我仔细检查,发现有一个获取随机数的命令,改过来之后,调试成功了,心中又是一阵欢喜。就这样,后面的消费指令也顺利调试通过了。