📄 ds8007.lst
字号:
C51 COMPILER V8.08 DS8007 10/26/2007 09:32:25 PAGE 1
C51 COMPILER V8.08, COMPILATION OF MODULE DS8007
OBJECT MODULE PLACED IN DS8007.OBJ
COMPILER INVOKED BY: d:\Keil\C51\BIN\C51.EXE DS8007.c LARGE OMF2 OPTIMIZE(9,SIZE) BROWSE INCDIR(C:\Program Files\Keil\C5
-1\INC\Dallas) VARBANKING DEBUG
line level source
1 /*---------------------------------------------------------------------------
2 * Copyright (C) 2004 Dallas Semiconductor Corporation, All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of Dallas Semiconductor
23 * shall not be used except as stated in the Dallas Semiconductor
24 * Branding Policy.
25 * ---------------------------------------------------------------------------
26 */
27 /**
28 * \file ds8007.c
29 * \brief Interface library for Dallas Semiconductor's DS8007 smartcard interface chip
30 *
31 * This library contains routines required to communicate with smartcards
32 * via an DS8007 while conforming to:
33 * ISO 7816
34 * EMV 4.1
35 *
36 */
37
38 #include <stdio.h>
39 #include <string.h>
40
41 #include <reg5000.h>
42 #include <absacc.h>
43 #include "DS8007.h"
44
45 #define DEBUG 1
46
47 void clearATRstruct(struct ATR*);
48 int16_t dssc_ATRsequence(uint8_t);
49
50 uint8_t workingBuffer[512];
51 uint8_t ATRLength[CARD_SLOTS];
52 struct ATR lastATR[CARD_SLOTS];
53 uint8_t TMode[CARD_SLOTS]; // T=0 or T=1
54 uint32_t WWT[CARD_SLOTS]; // Work wait time
C51 COMPILER V8.08 DS8007 10/26/2007 09:32:25 PAGE 2
55 uint32_t CWT[CARD_SLOTS]; // Character wait time
56 uint32_t BWT[CARD_SLOTS]; // Block wait time
57 uint8_t EDCtype[CARD_SLOTS];
58 uint8_t NAD[CARD_SLOTS]; // Node address byte to use when communicating in T=1
59 uint8_t IFSC[CARD_SLOTS]; // Maximum segment length when sending to card in T=1
60 uint8_t currentSlot = 0;
61
62 /*
63 Dump formatted contents of ATR struct
64 */
65 void dumpATRStruct(struct ATR myatr)
66 {
67 1 int i;
68 1 printf("ATR\n");
69 1 printf("TS: %02bx\n",(uint8_t)myatr.TS);
70 1 printf("T0: %02bx\n",(uint8_t)myatr.T0);
71 1 for (i = 1;i < 8;i++)
72 1 {
73 2 if (myatr.TA[i] != -1)
74 2 printf("TA%d: %02bx\n",i,(uint8_t)myatr.TA[i]);
75 2 if (myatr.TB[i] != -1)
76 2 printf("TB%d: %02bx\n",i,(uint8_t)myatr.TB[i]);
77 2 if (myatr.TC[i] != -1)
78 2 printf("TC%d: %02bx\n",i,(uint8_t)myatr.TC[i]);
79 2 if (myatr.TD[i] != -1)
80 2 printf("TD%d: %02bx\n",i,(uint8_t)myatr.TD[i]);
81 2 }
82 1 for (i = 0;i < myatr.HistoricalLength;i++)
83 1 {
84 2 printf("%02bx ",myatr.Historical[i]);
85 2 }
86 1 printf("\n");
87 1 if (myatr.TCK != -1)
88 1 printf("TCK: %02bx\n",(uint8_t)myatr.TCK);
89 1
90 1 }
91
92 /*
93 Used to clear the ATR struct before card power up.
94 */
95 void clearATRStruct(struct ATR *myatr)
96 {
97 1 memset(myatr,0xFF,sizeof(struct ATR));
98 1 myatr->HistoricalLength = 0;
99 1 }
100
101 /*
102 CCITT CRC 16
103 X^16+X^12+X^5+1
104 Be sure to use 0xFFFF as initial crc value.
105 */
106 uint16_t update_crc(uint8_t value, uint16_t crc)
107 {
108 1 int i;
109 1
110 1 uint16_t newval = value << 8;
111 1
112 1 for (i = 0;i < 8;i++)
113 1 {
114 2 if ((crc ^ newval) & 0x8000)
115 2 {
116 3 crc <<= 1;
C51 COMPILER V8.08 DS8007 10/26/2007 09:32:25 PAGE 3
117 3 crc ^= 0x1021;
118 3 }
119 2 else
120 2 {
121 3 crc <<= 1;
122 3 }
123 2 newval <<= 1;
124 2 }
125 1 return crc;
126 1 }
127
128 /*
129 Read a byte from the UART or timeout after BWT (T=1), CWT (T=1) or WWT (T=0).
130 */
131 int16_t readByte()
132 {
133 1 uint8_t val;
134 1 uint32_t timeout;
135 1
136 1 while(!(dssc_readregister(MSR) & MSR_TBE_RBF_MASK))
137 1 {
138 2 val = dssc_readregister(USR);
139 2 if (val & USR_PE_MASK)
140 2 {
141 3 return ERR_RECEIVE_PARITY;
142 3 }
143 2 if (val & (USR_TOL3_MASK|USR_TOL2_MASK|USR_TOL1_MASK))
144 2 {
145 3 return ERR_RECEIVE_TIMEOUT;
146 3 }
147 2 }
148 1
149 1 // Read and store byte
150 1 val = dssc_readregister(URR);
151 1
152 1 if (TMode[currentSlot] == 0)
153 1 timeout = WWT[currentSlot]; // Use WWT for T=0
154 1 else
155 1 timeout = CWT[currentSlot]; // Use CWT for T=1
156 1
157 1 // Set up timer for 24 bit timer, start immediately
158 1 dssc_writeregister(TOC,0x00);
159 1 dssc_writeregister(TOR3,timeout >> 16);
160 1 dssc_writeregister(TOR2,timeout >> 8);
161 1 dssc_writeregister(TOR1,timeout);
162 1 dssc_writeregister(TOC,0x68);
163 1
164 1 return val;
165 1 }
166
167 /*
168 Write a byte and leave the DS8007 in transmit mode
169 */
170 void writeByte(uint8_t onebyte)
171 {
172 1 uint8_t val;
173 1 val = dssc_readregister(UCR1);
174 1 // set T bit
175 1 dssc_writeregister(UCR1,val | UCR1_T_R_MASK);
176 1 dssc_writeregister(UTR,onebyte);
177 1 // wait for byte to go out
178 1 while (!(dssc_readregister(USR) & USR_TBE_RBF_MASK));
C51 COMPILER V8.08 DS8007 10/26/2007 09:32:25 PAGE 4
179 1 }
180
181 /*
182 Write a byte and put the DS8007 in receive mode
183 */
184 void writeLastByte(uint8_t onebyte)
185 {
186 1 uint8_t val;
187 1 uint32_t timeout;
188 1
189 1 if (TMode[currentSlot] == 0)
190 1 timeout = WWT[currentSlot]; // Use WWT for T=0
191 1 else
192 1 timeout = BWT[currentSlot]; // Use BWT for T=1
193 1
194 1 // Set up timer for 24 bit timer, edge trigger start
195 1 dssc_writeregister(TOC,0x00);
196 1 dssc_writeregister(TOR3,timeout >> 16);
197 1 dssc_writeregister(TOR2,timeout >> 8);
198 1 dssc_writeregister(TOR1,timeout);
199 1 dssc_writeregister(TOC,0x7C);
200 1
201 1 val = dssc_readregister(UCR1);
202 1 // set LCT and T bit
203 1 dssc_writeregister(UCR1,val | (UCR1_T_R_MASK|UCR1_LCT_MASK));
204 1 dssc_writeregister(UTR,onebyte);
205 1 // wait for byte to go out
206 1 while (!(dssc_readregister(USR) & USR_TBE_RBF_MASK));
207 1 }
208
209 /*
210 Generate Error Data Check value depending on EDC type
211 */
212 uint16_t generateEDC(uint8_t type,uint8_t onebyte,uint16_t value)
213 {
214 1 if (type == EDC_TYPE_LRC)
215 1 {
216 2 return (value ^ onebyte);
217 2 }
218 1 else // type = CRC
219 1 {
220 2 return update_crc(onebyte,value);
221 2 }
222 1 }
223
224 /*
225 Send a T=1 formatted block.
226 Formats T=1 packet from raw input data. Length must already be
227 within the requirements of the destination smart card.
228 */
229 void sendBlock(uint8_t NAD,uint8_t PCB,int16_t length,uint8_t *buffer,uint8_t type)
230 {
231 1 int i;
232 1 uint16_t EDC;
233 1
234 1 if (type == EDC_TYPE_LRC)
235 1 {
236 2 EDC = 0;
237 2 }
238 1 else // type = CRC
239 1 {
240 2 EDC = 0xFFFF;
C51 COMPILER V8.08 DS8007 10/26/2007 09:32:25 PAGE 5
241 2 }
242 1
243 1 writeByte(NAD);
244 1 EDC = generateEDC(type,NAD,EDC);
245 1 writeByte(PCB);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -