EM9X60利用串口实现ISO7816的方法

 2012-3-29         

        英利EM9160、EM9460系列产品,均以丰富的串口资源为特色,已大量地应用于工业环境中,特别是在电力系统中应用。最近公司即将推出一款新的产品EM9560工控主板,该主板是是以EM9460工控主板为基础,并针对客户应用的需求,增加了更多通用数字IO,该产品继续保持了Linux操作系统作为客户应用程序的软件平台。这三款主板均具备6个串口,其中的4个串口可支持ISO7816,用户可以通过简单的设置,即可将异步串口转换为符合ISO7816的接口,从而方便地实现和各种智能卡之间的通讯。本文将详细介绍在EM9160、EM9460、EM9560工控主板上设置ISO7816的方法。

 

1、ISO7816接口资源配置
        可支持ISO7816的串口资源包括:ttyS2 + GPIO14、ttyS4 + GPIO15、ttyS5 + GPIO15、ttyS6 + GPIO15,其中的GPIO14和GPIO15分别作为ISO7816的工作时钟输出,需要注意的是ttyS4、ttyS5、ttyS6这三个串口共用的是一个工作时钟输出,如果需要同时使用的话,要求波特率是一致的。以下为资源列表:

 

串口

管脚配置

备注

ttyS2

  TXD:半双工数据线
  RXD:复位输出控制   低电平有效
  GPIO14:作为SCK   输出频率与波特率等参数有关

ttyS4

  TXD:半双工数据线
  RXD:复位输出控制   低电平有效
  GPIO15:作为SCK   输出频率与波特率等参数有关

ttyS5

  TXD:半双工数据线
  RXD:复位输出控制   低电平有效
  GPIO15:作为SCK   输出频率与波特率等参数有关

ttyS6

  TXD:半双工数据线
  RXD:复位输出控制   低电平有效
  GPIO15:作为SCK   输出频率与波特率等参数有关

 

        其中ttyS4-ttyS6缺省为TTL电平,所以建议客户首选其中之一作为ISO7816接口。ttyS2缺省出厂配置为RS232电平,如果选择了该串口,需要特别通知我们公司在出厂时将该串口设置为TTL电平。一旦GPIO14、GPIO15作为ISO7816的工作时钟,就不能再做其他用途使用。

 

2、硬件接口电路

 

 

        需要注意的是我们将串口的RXD作为对ISO7816接口的复位信号,相应的在串口驱动中已实现了该功能,在后续应用程序介绍中会介绍对ISO7816进行复位的方法。

 

3、应用程序设置方法
        对于ISO7816设置我们已经在底层的串口驱动中完全实现,因此上层的应用程序在进行ISO7816设置、通讯时,和使用标准的串口方法是类似的。也是按照标准的方式打开串口,只是在设置串口的通讯参数时增加对ISO7816的设置即可,然后就可以按照串口数据收发的标准方式进行ISO7816的数据读写,只是需要注意的是ISO7816的半双工通讯模式。

 

        根据ISO7816协议类型以及帧应答规范,所定义的ISO7816的相关参数均定义在我们公司提到个em9x60_drivers.h文件中。

        #define EM9X60_ISO7816_T0 (1 << 27) // D27 of termios.c_cflag
        #define EM9X60_ISO7816_T1 (1 << 26) // D26 of termios.c_cflag
        #define EM9X60_ISO7816_RXD_RESET(1 << 23) // D23 of termios.c_cflag
        #define EM9X60_ISO7816_MODE (EM9X60_ISO7816_T0 | EM9X60_ISO7816_T1)

 

        设置这些参数的方法和标准设置串口的波特率等其他通讯参数一样,直接调用标准函数tcsetattr( )就可完成。如:

 

        int enable_iso7816(pport_info p_info)
        {
                struct termios cur_opt;
                int status;

                tcgetattr(p_info->port_fd,&cur_opt);

                // 修改模式,启动iso7816复位操作
                cur_opt.c_cflag |= ( EM9X60_ISO7816_T0 | EM9X60_ISO7816_RXD_RESET );
                status = tcsetattr(p_info->port_fd,TCSANOW,&cur_opt);
                if(status != 0)
                {
                        perror('Cannot set the serial port parameters');
                        return -1; 
                }

                // 修改模式,进入iso7816
                cur_opt.c_cflag &= ~EM9X60_ISO7816_RXD_RESET;
                status = tcsetattr(p_info->port_fd,TCSANOW,&cur_opt);
                if(status != 0)
                {
                        perror('Cannot set the serial port parameters');
                        return -1;
                }
                return status;
        }