SCI7816.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. #include <stdarg.h>
  2. #include "yc11xx.h"
  3. #include "SCI7816.h"
  4. #include "yc11xx_uart.h"
  5. #include "yc11xx_gpio.h"
  6. #define SCI7816_BUF_SIZE 128
  7. unsigned char sci7816_rx_buf[SCI7816_BUF_SIZE];
  8. unsigned char sci7816_tx_buf[SCI7816_BUF_SIZE];
  9. #define SCI7816_CLK_IO 19 //4 //29
  10. #define SCI7816_RESET_IO 24 //2 //28
  11. #define SCI7816_DATA_IO 25 //26
  12. #define SCI7816_VCC_IO 27 //0 //27
  13. #define SCI7816_RESET_IO_HIGH GPIO_SetGpioMultFunction(SCI7816_RESET_IO, GPCFG_OUTPUT_HIGH)
  14. #define SCI7816_RESET_IO_LOW GPIO_SetGpioMultFunction(SCI7816_RESET_IO, GPCFG_OUTPUT_LOW)
  15. #define SCI7816_DATA_IO_RX GPIO_SetGpioMultFunction(SCI7816_DATA_IO, GPCFG_UART_RXD)
  16. #define SCI7816_DATA_IO_TX GPIO_SetGpioMultFunction(SCI7816_DATA_IO, GPCFG_UART_TXD)
  17. #define SCI7816_VCC_IO_HIGH GPIO_SetGpioMultFunction(SCI7816_VCC_IO, GPCFG_OUTPUT_HIGH)
  18. #define SCI7816_VCC_IO_LOW GPIO_SetGpioMultFunction(SCI7816_VCC_IO, GPCFG_OUTPUT_LOW)
  19. void sci7816_clk_enable(void)
  20. {
  21. GPIO_SetGpioMultFunction(SCI7816_CLK_IO, GPCFG_PWM_OUT0);
  22. HWRITE(CORE_CLKOFF+1, 0);
  23. HWRITE(CORE_PWM0_PCNT, 2);
  24. HWRITE(CORE_PWM0_NCNT, 2);
  25. HWRITE(CORE_PWM0_CTRL, 0X30);
  26. }
  27. void sci7816_clk_disable(void)
  28. {
  29. GPIO_SetGpioMultFunction(SCI7816_CLK_IO, GPCFG_OUTPUT_LOW);
  30. HWRITE(CORE_PWM0_CTRL, 0X00);
  31. }
  32. void sci7816_io_init(void)
  33. {
  34. HWRITE(CORE_UART_CTRL, 0x00);
  35. //sysclk/186 = 129075
  36. HWRITEW(CORE_UART_BAUD, 0x8000|4463); //3.57 115200 4 129075 372 //186
  37. HWRITEW(CORE_UART_RX_SADDR, sci7816_rx_buf);
  38. HWRITEW(CORE_UART_RX_EADDR, sci7816_rx_buf+SCI7816_BUF_SIZE-1);
  39. HWRITEW(CORE_UART_RX_RPTR, sci7816_rx_buf);
  40. HWRITEW(CORE_UART_TX_SADDR, sci7816_tx_buf);
  41. HWRITEW(CORE_UART_TX_EADDR, sci7816_tx_buf+SCI7816_BUF_SIZE-1);
  42. HWRITEW(CORE_UART_TX_WPTR, sci7816_tx_buf);
  43. HWRITE(CORE_UART_CTRL, 0xc5);
  44. }
  45. void sci7816_delay_ms(unsigned int time)
  46. {
  47. unsigned int num,j;
  48. for (num = 0; num <time; num++)
  49. {
  50. for (j = 0; j < 4000; j++);
  51. }
  52. }
  53. void sci7816_delay_etu(unsigned int time)
  54. {
  55. unsigned int num,j;
  56. for (num = 0; num <time; num++)
  57. {
  58. for (j = 0; j < 400; j++);
  59. }
  60. }
  61. void SCI7816_Power_Off(void)
  62. {
  63. SCI7816_RESET_IO_LOW;
  64. sci7816_clk_disable();
  65. HWRITE(CORE_UART_CTRL, 0xc4); //¹Ø±Õ´®¿Ú¹¦ÄÜ
  66. GPIO_SetGpioMultFunction(SCI7816_DATA_IO, GPCFG_OUTPUT_LOW);
  67. SCI7816_VCC_IO_LOW;
  68. }
  69. uint8_t sci7816_rec(unsigned char *buf, unsigned char num)
  70. {
  71. uint8_t ret = 0;
  72. while (!ret)
  73. {
  74. ret = USART_ReadDatatoBuff(UARTA, buf, num);
  75. }
  76. return ret;
  77. }
  78. void sci7816_send(unsigned char *buf, unsigned char num)
  79. {
  80. uint32_t WPtr = 0;
  81. uint16_t i = 0;
  82. GPIO_SetGpioMultFunction(SCI7816_DATA_IO, GPCFG_UART_TXD);
  83. sci7816_delay_etu(1);
  84. for (i=0; i<num; i++)
  85. {
  86. USART_SendDataFromBuff(UARTA, buf+i, 1);
  87. sci7816_delay_etu(1);
  88. }
  89. GPIO_SetGpioMultFunction(SCI7816_DATA_IO, GPCFG_UART_RXD);
  90. }
  91. uint8_t esam_rec_atr(uint8_t *atr, uint16_t *num)
  92. {
  93. uint8_t logsize = 0;
  94. uint8_t txnum = 0;
  95. uint8_t td1flag = 0;
  96. uint8_t recnum = 0;
  97. sci7816_rec(atr, 2);
  98. if (atr[0] == 0x3b)
  99. {
  100. logsize = atr[1] & 0x0f;
  101. if (atr[1] & 0x80) //TD
  102. {
  103. txnum++;
  104. }
  105. if (atr[1] & 0x40) //TC
  106. {
  107. txnum++;
  108. }
  109. if (atr[1] & 0x20) //TB
  110. {
  111. txnum++;
  112. }
  113. if (atr[1] & 0x10) //TA
  114. {
  115. txnum++;
  116. }
  117. if (txnum > 0)
  118. {
  119. sci7816_rec(atr+2, txnum);
  120. }
  121. recnum = 2 + txnum;
  122. if (td1flag == 1)
  123. {
  124. txnum = 0;
  125. if (atr[recnum-1] & 0x80) //TD
  126. {
  127. txnum++;
  128. }
  129. if (atr[recnum-1] & 0x40) //TC
  130. {
  131. txnum++;
  132. }
  133. if (atr[recnum-1] & 0x20) //TB
  134. {
  135. txnum++;
  136. }
  137. if (atr[recnum-1] & 0x10) //TA
  138. {
  139. txnum++;
  140. }
  141. if (txnum > 0)
  142. {
  143. sci7816_rec(atr+recnum, txnum);
  144. }
  145. recnum += txnum;
  146. }
  147. sci7816_rec(atr+recnum, logsize);
  148. *num = recnum+logsize;
  149. return 0;
  150. }
  151. return 1;
  152. }
  153. uint8_t SCI7816_Reset (uint8_t *presp ,uint8_t respbufsize, uint16_t *prespsize)
  154. {
  155. uint8_t data[2] = {0xaa,0x55};
  156. SCI7816_VCC_IO_LOW;
  157. SCI7816_RESET_IO_LOW;
  158. SCI7816_VCC_IO_HIGH;
  159. sci7816_clk_enable();
  160. sci7816_delay_ms(10);
  161. sci7816_io_init();
  162. SCI7816_RESET_IO_HIGH;
  163. GPIO_SetGpioMultFunction(SCI7816_DATA_IO, GPCFG_UART_RXD);
  164. sci7816_delay_ms(5);
  165. return esam_rec_atr(presp, prespsize);
  166. }
  167. uint16_t ISO7816_TPDU_T0(uint8_t *pCommand, uint16_t CommandLength,
  168. uint8_t *pResponse, uint16_t *pResponseLength)
  169. {
  170. uint8_t sw1, Ins;
  171. uint16_t p3;
  172. uint16_t ret , tmpRecLen=0, tmpSendOffset;
  173. tmpRecLen =0;
  174. if((NULL == pCommand) || (NULL == pResponse)||
  175. (CommandLength < 4)|| (NULL == pResponseLength))
  176. {
  177. return ISO7816_PARA_ERROR;
  178. }
  179. if(CommandLength == 4)
  180. {
  181. //case1
  182. pCommand[4] = 0;
  183. }
  184. Ins = pCommand[1];
  185. sci7816_send(pCommand, 5);
  186. pResponse[tmpRecLen] = ISO7816_NULL_T0;
  187. do
  188. {
  189. sci7816_rec(&pResponse[tmpRecLen], 1);
  190. }while(pResponse[tmpRecLen] == ISO7816_NULL_T0);
  191. sw1 = pResponse[0];
  192. p3 = pCommand[4];
  193. tmpSendOffset = 5;
  194. do
  195. {
  196. if( (0x60 == (sw1 & 0xF0)) || (0x90 == (sw1 & 0xF0)) )
  197. {
  198. tmpRecLen++;
  199. sci7816_rec(&pResponse[tmpRecLen++], 1);
  200. *pResponseLength = tmpRecLen;
  201. return OK;
  202. }
  203. if(Ins == sw1)
  204. {
  205. if(5 == CommandLength)
  206. {
  207. sci7816_rec(&pResponse[tmpRecLen], p3 + 2 - tmpRecLen);
  208. *pResponseLength = p3 + 2;
  209. return OK;
  210. }
  211. else
  212. { //case 3 case4
  213. sci7816_send(pCommand + tmpSendOffset, p3);
  214. pResponse[tmpRecLen] = ISO7816_NULL_T0;
  215. do
  216. {
  217. ret = sci7816_rec(&pResponse[tmpRecLen], 1);
  218. }while(pResponse[tmpRecLen] == ISO7816_NULL_T0);
  219. tmpRecLen++;
  220. ret = sci7816_rec(&pResponse[tmpRecLen++], 1);
  221. *pResponseLength = tmpRecLen;
  222. return OK;
  223. }
  224. }
  225. else if (sw1 == (uint8_t)(~Ins))
  226. {
  227. if(5 == CommandLength)
  228. {
  229. //case 2
  230. ret = sci7816_rec(&pResponse[tmpRecLen++], 1);
  231. if(tmpRecLen >= (p3 + 2))
  232. {
  233. *pResponseLength = tmpRecLen;
  234. return OK;
  235. }
  236. ret = sci7816_rec(&pResponse[tmpRecLen], 1);
  237. sw1 = pResponse[tmpRecLen];
  238. }
  239. else
  240. { //case 3 case4
  241. if(p3)
  242. {
  243. sci7816_send(pCommand + tmpSendOffset, 1);
  244. tmpSendOffset++;
  245. p3--;
  246. do
  247. {
  248. ret = sci7816_rec(&pResponse[tmpRecLen], 1);
  249. }while(pResponse[tmpRecLen] == ISO7816_NULL_T0);
  250. sw1 = pResponse[tmpRecLen];
  251. continue;
  252. }
  253. else
  254. {
  255. do
  256. {
  257. ret = sci7816_rec(&pResponse[tmpRecLen], 1);
  258. }while(pResponse[tmpRecLen] == ISO7816_NULL_T0);
  259. sw1 = pResponse[tmpRecLen++];
  260. ret = sci7816_rec(pResponse + 1, 1);
  261. *pResponseLength = 2;
  262. return OK;
  263. }
  264. }
  265. }
  266. else
  267. {
  268. return ISO7816_PROCEDURE_INS_ERROR;
  269. }
  270. }while(1);
  271. }
  272. uint16_t ISO7816_Dispose_CMD(uint8_t *pCmd, uint16_t CmdLen, uint8_t *pResp, uint16_t *pRespLen)
  273. {
  274. uint16_t ret;
  275. uint16_t tmpRespLen,tmpCmdLen;
  276. uint16_t tmpOffset;
  277. uint8_t tmpCMDBuf[5];
  278. uint8_t tmpRECBuf[286];
  279. uint8_t tmp61Flag;
  280. uint8_t lenflag = 0;
  281. tmpOffset = 0;
  282. tmp61Flag = 0;
  283. tmpCmdLen = CmdLen;
  284. memcpy(tmpCMDBuf,pCmd,5);
  285. ret = ISO7816_TPDU_T0(pCmd, tmpCmdLen, tmpRECBuf + tmpOffset, &tmpRespLen);
  286. tmpOffset +=tmpRespLen;
  287. while(1)
  288. {
  289. if(tmpRespLen>=2)
  290. {
  291. if(tmpRECBuf[tmpOffset-2] == 0x61)
  292. {
  293. lenflag = 1;
  294. tmpCMDBuf[0] = 0;
  295. tmpCMDBuf[1] = 0xC0;
  296. tmpCMDBuf[2] = 0;
  297. tmpCMDBuf[3] = 0;
  298. tmpCMDBuf[4] = tmpRECBuf[tmpOffset-1];
  299. tmpOffset -= 2;
  300. ret = ISO7816_TPDU_T0(tmpCMDBuf, 5, tmpRECBuf + tmpOffset, &tmpRespLen);
  301. tmp61Flag = 1;
  302. tmpOffset +=tmpRespLen;
  303. continue;
  304. }
  305. else if(tmpRECBuf[tmpOffset-2] == 0x6C)
  306. {
  307. lenflag = 1;
  308. tmpCMDBuf[4] = tmpRECBuf[tmpOffset-1];
  309. tmpOffset -= 2;
  310. ret = ISO7816_TPDU_T0(tmpCMDBuf, 5, tmpRECBuf + tmpOffset, &tmpRespLen);
  311. tmpOffset +=tmpRespLen;
  312. continue;
  313. }
  314. else if((tmpRECBuf[tmpOffset-2] == 0x90) && (tmpRECBuf[tmpOffset-1] == 0x00))
  315. {
  316. break;
  317. }
  318. //date
  319. else if((tmpRECBuf[tmpOffset-2] == 0x62) || (tmpRECBuf[tmpOffset-2] == 0x63) || ( (tmpRECBuf[tmpOffset-2] & 0xF0) == 0x90 ) )
  320. {
  321. if(tmp61Flag==1)
  322. {
  323. break;
  324. }
  325. if((CmdLen > 5) &&(tmpCMDBuf[1] == 0xA4)) //case 3 or 4
  326. {
  327. lenflag = 1;
  328. tmpCMDBuf[0] = 0;
  329. tmpCMDBuf[1] = 0xC0;
  330. tmpCMDBuf[2] = 0;
  331. tmpCMDBuf[3] = 0;
  332. tmpCMDBuf[4] = 0;
  333. tmpOffset-=2;
  334. ret = ISO7816_TPDU_T0(tmpCMDBuf, 5, tmpRECBuf + tmpOffset, &tmpRespLen);
  335. tmpOffset +=tmpRespLen;
  336. continue;
  337. }
  338. else
  339. {
  340. break;
  341. }
  342. }
  343. else
  344. {
  345. break;
  346. }
  347. }
  348. else
  349. {
  350. break;
  351. }
  352. }//end while
  353. // if (lenflag)
  354. // {
  355. // memcpy(pResp,tmpRECBuf+2,tmpOffset-2);
  356. // *pRespLen = tmpOffset - 2;
  357. // }
  358. // else
  359. {
  360. memcpy(pResp,tmpRECBuf,tmpOffset);
  361. *pRespLen = tmpOffset;
  362. }
  363. return OK;
  364. }
  365. uint8_t SCI7816_CosOperation(uint8_t *pcmd, uint16_t cmdsize, uint8_t getrespfalg, uint8_t *presp,
  366. uint16_t respbufsize, uint16_t *prespsize)
  367. {
  368. if (getrespfalg == ESAM_GET_RESP)
  369. {
  370. return ISO7816_Dispose_CMD(pcmd, cmdsize, presp, prespsize);
  371. }
  372. else
  373. {
  374. return ISO7816_TPDU_T0(pcmd, cmdsize, presp, prespsize);
  375. }
  376. }