Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18108
  • 博文数量: 4
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 67
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-21 10:04
文章分类

全部博文(4)

文章存档

2013年(4)

我的朋友

分类: Android平台

2013-12-26 15:02:06

IC读卡芯片是一个完全单芯片、低成本、低功耗、功能强大的智能读卡器。它具有多种用来减少功耗的模式以及宽的电源电压范围,使之非常适合使用在便携式 设备中。由于具有特殊的多用途硬件,小嵌入式软件程序能够控制市场上的大部份卡。

由于我们产品的串口都已经被占用,IC读卡芯片支持非标准I2C方式访问数据,所以我们改用I2C方式。CPUI2C有标准I2CGPIO I2C两种方式。由于IC读卡芯片的I2C协议不是标准I2C,需要进行修改。所以我们选择从GPIO I2C方式中进行简单修改以支持ALPAR协议访问格式。

下面是ALPAR协议格式:
由上图可知,协议发送或接收的数据长度在数据的第二第三字节定义。因此,我们只需要在读取数据过程中先得出数据长度即可。

以下部分是修改的代码, +为添加部分:


  1. Index: include/linux/i2c.h
  2. ===================================================================
  3. --- include/linux/i2c.h    (版本 986)
  4. +++ include/linux/i2c.h    (版本 988)
  5. @@ -90,6 +90,12 @@
  6.                   u8 command, u8 *values);
  7.  extern s32 i2c_smbus_write_block_data(struct i2c_client *client,
  8.                   u8 command, u8 length, const u8 *values);
  9. +/*
  10. +*    iUnin add for tda8029 ALPAR protocol. by yang.yuanming.
  11. +*    data: ACK(1) + length(2) + code(1) + data(n) +LRC(1) = n+5     n=0~506
  12. +*/
  13. +extern s32 i2c_smbus_read_alpar_data(struct i2c_client *client, u8 *values);
  14. +extern s32 i2c_smbus_write_alpar_data(struct i2c_client *client, u8 length, const u8 *values);
  15.  /* Returns the number of read bytes */
  16.  extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client,
  17.                       u8 command, u8 length, u8 *values);
  18. @@ -511,6 +517,7 @@
  19.  #define I2C_M_IGNORE_NAK    0x1000    /* if I2C_FUNC_PROTOCOL_MANGLING */
  20.  #define I2C_M_NO_RD_ACK        0x0800    /* if I2C_FUNC_PROTOCOL_MANGLING */
  21.  #define I2C_M_RECV_LEN        0x0400    /* length will be first received byte */
  22. +#define I2C_M_ALPAR_RECV_LEN        0x0200    /* length will be n2&0xFF+n3+5 received byte */
  23.      __u16 len;        /* msg length                */
  24.      __u8 *buf;        /* pointer to msg data            */
  25.  };
  26. @@ -566,6 +573,18 @@
  27.               /* and one more for user-space compatibility */
  28.  };
  29.  
  30. +/*
  31. +*    iUnin add for tda8029 ALPAR protocol. by yang.yuanming.
  32. +*    data: ACK(1) + length(2) + code(1) + data(n) +LRC(1) = n+5     n=0~506
  33. +*/
  34. +#define I2C_SMBUS_ALPAR_MAX    512    /* As specified in SMBus standard */
  35. +union i2c_alpar_data {
  36. +    __u8 byte;
  37. +    __u16 word;
  38. +    __u8 block[I2C_SMBUS_ALPAR_MAX]; /* block[0] is used for length */
  39. +             /* and one more for user-space compatibility */
  40. +};
  41. +
  42.  /* i2c_smbus_xfer read or write markers */
  43.  #define I2C_SMBUS_READ    1
  44.  #define I2C_SMBUS_WRITE    0
  45. @@ -581,5 +600,5 @@
  46.  #define I2C_SMBUS_I2C_BLOCK_BROKEN 6
  47.  #define I2C_SMBUS_BLOCK_PROC_CALL 7        /* SMBus 2.0 */
  48.  #define I2C_SMBUS_I2C_BLOCK_DATA 8
  49. -
  50. +#define I2C_SMBUS_ALPAR_DATA     9
  51.  #endif /* _LINUX_I2C_H */
  52. Index: drivers/i2c/i2c-core.c
  53. ===================================================================
  54. --- drivers/i2c/i2c-core.c    (版本 986)
  55. +++ drivers/i2c/i2c-core.c    (版本 988)
  56. @@ -1803,6 +1803,70 @@
  57.  }
  58.  EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
  59.  
  60. +
  61. +/*
  62. +*    iUnin add for tda8029 ALPAR protocol. by yang.yuanming.
  63. +*    data: ACK(1) + length(2) + code(1) + data(n) +LRC(1) = n+5    
  64. +*/
  65. +s32 i2c_smbus_read_alpar_data(struct i2c_client *client, u8 *values)
  66. +{
  67. +    union i2c_alpar_data data;
  68. +    int status;
  69. +    unsigned char msgbuf0[I2C_SMBUS_ALPAR_MAX];
  70. +    int num = 1;
  71. +    struct i2c_msg msg[1] = {{ client->addr, client->flags | I2C_M_RD, 0, msgbuf0 }
  72. +     };
  73. +
  74. +    int i, alpar_len;
  75. +    u8 partial_pec = 0;
  76. +
  77. +    msg[0].flags |= I2C_M_ALPAR_RECV_LEN;
  78. +    msg[0].len = 5; /* block length will be added by the underlying bus driver */
  79. +
  80. +    status = i2c_transfer(client->adapter, msg, num);
  81. +    if (status < 0)
  82. +        return status;
  83. +
  84. +    /* Check PEC if last message is a read */
  85. +    if (i && (msg[num-1].flags & I2C_M_RD)) {
  86. +        status = i2c_smbus_check_pec(partial_pec, &msg[num-1]);
  87. +        if (status < 0)
  88. +            return status;
  89. +    }
  90. +
  91. +    alpar_len = (msgbuf0[1]*256 +msgbuf0[2] + 5);
  92. +    for (i = 0; i < alpar_len; i++)
  93. +        data.block[i] = msgbuf0[i];            
  94. +    
  95. +    memcpy(values, &data.block[0], alpar_len);
  96. +
  97. +    return alpar_len;
  98. +}
  99. +EXPORT_SYMBOL(i2c_smbus_read_alpar_data);
  100. +
  101. +/*
  102. +*    iUnin add for tda8029 ALPAR protocol. by yang.yuanming.
  103. +*    data: ACK(1) + length(2) + code(1) + data(n) +LRC(1) = n+5    
  104. +*/
  105. +s32 i2c_smbus_write_alpar_data(struct i2c_client *client, u8 length, const u8 *values)
  106. +{
  107. +    int status;
  108. +
  109. +    if (length > I2C_SMBUS_ALPAR_MAX)
  110. +        length = I2C_SMBUS_ALPAR_MAX;
  111. +
  112. +    struct i2c_msg msg[1] = {{ client->addr, 0, length, values }
  113. +     };
  114. +
  115. +    status = i2c_transfer(client->adapter, msg, 1);
  116. +    if (status < 0)
  117. +        return status;
  118. +
  119. +    return 0;
  120. +}
  121. +EXPORT_SYMBOL(i2c_smbus_write_alpar_data);
  122. +
  123. +
  124.  /* Simulate a SMBus command using the i2c protocol
  125.     No checking of parameters is */
  126.  static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
  127. Index: drivers/i2c/algos/i2c-algo-bit.c
  128. ===================================================================
  129. --- drivers/i2c/algos/i2c-algo-bit.c    (版本 986)
  130. +++ drivers/i2c/algos/i2c-algo-bit.c    (版本 988)
  131. @@ -417,6 +417,25 @@
  132.          temp++;
  133.          count--;
  134.  
  135. +    /*
  136. +    *    iUnin add for tda8029 ALPAR protocol. by yang.yuanming.
  137. +    *    data: ACK(1) + length(2) + code(1) + data(n) +LRC(1) = n+5    
  138. +    */
  139. +        if ((rdcount == 2 || rdcount == 3) && (flags & I2C_M_ALPAR_RECV_LEN)) {
  140. +            /* The original count value accounts for the extra
  141. +             bytes, that is, either 1 for a regular transaction,
  142. +             or 2 for a PEC transaction. */
  143. +             if(rdcount == 2){
  144. +                count += (inval*256);
  145. +                msg->len += (inval*256);
  146. +             }
  147. +             if(rdcount == 3){
  148. +                count += inval;
  149. +                msg->len += inval;
  150. +             }            
  151. +            
  152. +        }    
  153. +        
  154.          /* Some SMBus transactions require that we receive the
  155.           transaction length as the first read byte. */
  156.          if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) {
在完成协议小小修改部分后,IC读卡芯片驱动则相对简单了。真正的工作在上层的各种IC卡的协议访问过程。这就是下部分的事情了。。。


阅读(1187) | 评论(0) | 转发(0) |
0

上一篇:NV12T转换成NV12算法公式

下一篇:没有了

给主人留下些什么吧!~~