Line No. | Rev | Author | Line |
---|---|---|---|
1 | 32 | kaklik | /******************************************************************** |
2 | FileName: SCpic18.c |
||
3 | Dependencies: See INCLUDES section |
||
4 | Processor: PIC18 Microcontrollers |
||
5 | Hardware: This demo is natively intended to be used on LPC & HPC Exp board. |
||
6 | This demo can be modified for use on other hardware platforms. |
||
7 | Complier: Microchip C18 (for PIC18) |
||
8 | Company: Microchip Technology, Inc. |
||
9 | |||
10 | Software License Agreement: |
||
11 | |||
12 | The software supplied herewith by Microchip Technology Incorporated |
||
13 | (the Company) for its PIC® Microcontroller is intended and |
||
14 | supplied to you, the Companys customer, for use solely and |
||
15 | exclusively on Microchip PIC Microcontroller products. The |
||
16 | software is owned by the Company and/or its supplier, and is |
||
17 | protected under applicable copyright laws. All rights are reserved. |
||
18 | Any use in violation of the foregoing restrictions may subject the |
||
19 | user to criminal sanctions under applicable laws, as well as to |
||
20 | civil liability for the breach of the terms and conditions of this |
||
21 | license. |
||
22 | |||
23 | THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES, |
||
24 | WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED |
||
25 | TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||
26 | PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, |
||
27 | IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR |
||
28 | CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
||
29 | |||
30 | ******************************************************************** |
||
31 | File Description: |
||
32 | |||
33 | Change History: |
||
34 | Rev Description |
||
35 | ---- ----------------------------------------- |
||
36 | 1.0 Initial release |
||
37 | 1.01 Cleaned up unnecessary variables |
||
38 | ********************************************************************/ |
||
39 | |||
40 | #include <p18cxxx.h> |
||
41 | #include "stdio.h" |
||
42 | #include "Smart Card/pps18.h" |
||
43 | #include "string.h" |
||
44 | #include "GenericTypeDefs.h" |
||
45 | #include "Smart Card/SCpic18.h" |
||
46 | #include "sc_config.h" |
||
47 | |||
48 | unsigned int gBitTimeDelay; |
||
49 | unsigned int bitTime; |
||
50 | unsigned int initialBaudReg; |
||
51 | unsigned long scReferenceClock; |
||
52 | |||
53 | unsigned long baudRate; |
||
54 | |||
55 | //////////////////////////////////////// |
||
56 | // Generate delay in microsec resolution |
||
57 | // 0 - 2 us |
||
58 | // 1 - 3 us |
||
59 | // 10 - 12 us |
||
60 | // ... |
||
61 | //////////////////////////////////////// |
||
62 | void WaitMicroSec( WORD microSec ) |
||
63 | { |
||
64 | while( microSec ) |
||
65 | { |
||
66 | Nop(); |
||
67 | microSec--; |
||
68 | } |
||
69 | } |
||
70 | |||
71 | void WaitMilliSec( WORD ms ) |
||
72 | { |
||
73 | while( ms-- ) |
||
74 | WaitMicroSec( 800 ); |
||
75 | } |
||
76 | |||
77 | /////////////////////////////////// |
||
78 | // precalculate 1 bit time microsec used for Delay counter |
||
79 | |||
80 | |||
81 | //////////////////////////////////////////////////// |
||
82 | //////////////////////////////////////////////////// |
||
83 | void SCdrv_SendTxData( BYTE data ) |
||
84 | { |
||
85 | BYTE txRetryCounter = 0; |
||
86 | BOOL noError = TRUE; |
||
87 | |||
88 | //calculate parity |
||
89 | _asm |
||
90 | swapf data,0,0 //reducing byte to nibble |
||
91 | xorwf data,0,0 |
||
92 | addlw 0x41 // bit 1 becomes B0^B1 and bit 7 becomes B6^B7 |
||
93 | iorlw 0x7C // for carry propagation from bit 1 to bit 7 |
||
94 | addlw 2 // Done! the parity bit is bit 7 of W |
||
95 | _endasm |
||
96 | |||
97 | TXSTAbits.TX9D = WREG >> 7; //copy calc parity bit to the transmitter |
||
98 | |||
99 | TXREG = data; |
||
100 | TXSTAbits.TXEN = 1; |
||
101 | |||
102 | while( !TXSTAbits.TRMT ) //wait for Tx Complete |
||
103 | { |
||
104 | Nop(); |
||
105 | } |
||
106 | |||
107 | TXSTAbits.TXEN = 0; |
||
108 | |||
109 | //turn off uart |
||
110 | RCSTAbits.SPEN = 0; |
||
111 | |||
112 | if( !SCdrv_GetRxPinData() ) // The Receiver did not like our data. it is pulling line low |
||
113 | { // to indicate PE or FR errors |
||
114 | noError = FALSE; |
||
115 | |||
116 | RCSTAbits.SPEN = 1; |
||
117 | |||
118 | //now retransmit the data |
||
119 | if( txRetryCounter < 5 ) |
||
120 | { |
||
121 | txRetryCounter++; |
||
122 | SCdrv_SendTxData(data); |
||
123 | } |
||
124 | } |
||
125 | |||
126 | if( noError ) //no error detected |
||
127 | txRetryCounter = 0; |
||
128 | |||
129 | RCSTAbits.SPEN = 1; |
||
130 | |||
131 | if( RCSTA & 0x6 ) //FERR or OERR occured |
||
132 | { |
||
133 | RCSTAbits.CREN = 0; //clear error flags |
||
134 | RCSTAbits.CREN = 1; |
||
135 | } |
||
136 | |||
137 | while(1) // remove rx data recvd from our Tx line |
||
138 | { |
||
139 | BYTE temp; |
||
140 | if( PIR1bits.RCIF ) |
||
141 | { |
||
142 | temp = RCREG; |
||
143 | } |
||
144 | else |
||
145 | break; |
||
146 | } |
||
147 | } |
||
148 | |||
149 | ///////////////////////////////////////////// |
||
150 | ///////////////////////////////////////////// |
||
151 | BOOL SCdrv_GetRxData( BYTE* pDat, unsigned long nTrys ) |
||
152 | { |
||
153 | //wait for data byte |
||
154 | while( !(PIR1 & 0x20) ) |
||
155 | { |
||
156 | if( nTrys-- == 0 ) |
||
157 | return FALSE; |
||
158 | } |
||
159 | |||
160 | //calculate parity |
||
161 | _asm |
||
162 | swapf RCREG,0,0 //reducing byte to nibble |
||
163 | xorwf RCREG,0,0 |
||
164 | addlw 0x41 // bit 1 becomes B0^B1 and bit 7 becomes B6^B7 |
||
165 | iorlw 0x7C // for carry propagation from bit 1 to bit 7 |
||
166 | addlw 2 // Done! the parity bit is bit 7 of W |
||
167 | RLNCF WREG,0,0 //rotate left W reg |
||
168 | xorwf RCSTA,0,0 |
||
169 | _endasm |
||
170 | |||
171 | if( WREG & 1 ) //Parity Error detected |
||
172 | { |
||
173 | RCSTAbits.SPEN = 0; |
||
174 | SCdrv_TxPin_Direction(0); //pull it low to tell the card that there was error receiving data |
||
175 | |||
176 | WaitMicroSec(gBitTimeDelay ); |
||
177 | |||
178 | SCdrv_TxPin_Direction(1); //release line. Card should retransmit now. |
||
179 | |||
180 | RCSTAbits.SPEN = 1; |
||
181 | return SCdrv_GetRxData( pDat, nTrys ); //Read the data from retransmission |
||
182 | } |
||
183 | |||
184 | *pDat = RCREG; |
||
185 | return TRUE; |
||
186 | } |
||
187 | |||
188 | |||
189 | /////////////////////////////////////////////////// |
||
190 | ////////////////////////////////////////////////// |
||
191 | void SCdrv_SetBRG( BYTE speedCode ) |
||
192 | { |
||
193 | float factorD = 1; |
||
194 | unsigned int factorF = 372; |
||
195 | BYTE tempCode; |
||
196 | unsigned int baudReg; |
||
197 | |||
198 | tempCode = speedCode & 0x0F; |
||
199 | |||
200 | // Calculate Factor 'D' from TA1 value |
||
201 | switch(tempCode) |
||
202 | { |
||
203 | case 0x00: |
||
204 | case 0x07: |
||
205 | case 0x01: |
||
206 | break; |
||
207 | |||
208 | case 0x02: |
||
209 | factorD = 2; |
||
210 | break; |
||
211 | |||
212 | case 0x03: |
||
213 | factorD = 4; |
||
214 | break; |
||
215 | |||
216 | case 0x04: |
||
217 | factorD = 8; |
||
218 | break; |
||
219 | |||
220 | case 0x05: |
||
221 | factorD = 16; |
||
222 | break; |
||
223 | |||
224 | case 0x06: |
||
225 | factorD = 32; |
||
226 | break; |
||
227 | |||
228 | case 0x08: |
||
229 | factorD = 12; |
||
230 | break; |
||
231 | |||
232 | case 0x09: |
||
233 | factorD = 20; |
||
234 | break; |
||
235 | |||
236 | case 0x0A: |
||
237 | factorD = 0.5; |
||
238 | break; |
||
239 | |||
240 | case 0x0B: |
||
241 | factorD = 0.25; |
||
242 | break; |
||
243 | |||
244 | case 0x0C: |
||
245 | factorD = 0.125; |
||
246 | break; |
||
247 | |||
248 | case 0x0D: |
||
249 | factorD = 0.0625; |
||
250 | break; |
||
251 | |||
252 | case 0x0E: |
||
253 | factorD = 0.03125; |
||
254 | break; |
||
255 | |||
256 | case 0x0F: |
||
257 | factorD = 0.015625; |
||
258 | break; |
||
259 | } |
||
260 | |||
261 | // If you are not using internal clock in Smart Card & are |
||
262 | // using external clock to drive Smart Card than calculate |
||
263 | // factor 'F' from TA1 value |
||
264 | #ifdef ENABLE_SC_EXTERNAL_CLOCK |
||
265 | |||
266 | tempCode = (speedCode & 0xF0) >> 4; |
||
267 | |||
268 | // Calculate Factor 'F' from TA1 value |
||
269 | switch(tempCode) |
||
270 | { |
||
271 | case 0x00: |
||
272 | case 0x07: |
||
273 | case 0x08: |
||
274 | case 0x0E: |
||
275 | case 0x0F: |
||
276 | break; |
||
277 | |||
278 | case 0x01: |
||
279 | factorF = 372; |
||
280 | break; |
||
281 | |||
282 | case 0x02: |
||
283 | factorF = 558; |
||
284 | break; |
||
285 | |||
286 | case 0x03: |
||
287 | factorF = 744; |
||
288 | break; |
||
289 | |||
290 | case 0x04: |
||
291 | factorF = 1116; |
||
292 | break; |
||
293 | |||
294 | case 0x05: |
||
295 | factorF = 1488; |
||
296 | break; |
||
297 | |||
298 | case 0x06: |
||
299 | factorF = 1860; |
||
300 | break; |
||
301 | |||
302 | case 0x09: |
||
303 | factorF = 512; |
||
304 | break; |
||
305 | |||
306 | case 0x0A: |
||
307 | factorF = 768; |
||
308 | break; |
||
309 | |||
310 | case 0x0B: |
||
311 | factorF = 1024; |
||
312 | break; |
||
313 | |||
314 | case 0x0C: |
||
315 | factorF = 1536; |
||
316 | break; |
||
317 | |||
318 | case 0x0D: |
||
319 | factorF = 2048; |
||
320 | break; |
||
321 | } |
||
322 | |||
323 | if(tempCode == 0x00) // If internal clock used in Smart Card |
||
324 | { |
||
325 | baudReg = (unsigned int)(FCY/(9600 * factorD) - 1); |
||
326 | SPBRG = (unsigned char)baudReg; |
||
327 | SPBRGH = (unsigned char)(baudReg >> 8); |
||
328 | } |
||
329 | else // If externa; clock used to drive Smart Card |
||
330 | { |
||
331 | baudRate = (scReferenceClock * factorD)/factorF; |
||
332 | baudReg = (unsigned int)((FCY/baudRate) - 1); |
||
333 | SPBRG = (unsigned char)baudReg; |
||
334 | SPBRGH = (unsigned char)(baudReg >> 8); |
||
335 | } |
||
336 | |||
337 | #else // If internal clock used in Smart Card |
||
338 | |||
339 | baudReg = (unsigned char)(FCY/(9600 * factorD) - 1); |
||
340 | SPBRG = (unsigned char)baudReg; |
||
341 | SPBRGH = (unsigned char)(baudReg >> 8); |
||
342 | |||
343 | #endif |
||
344 | |||
345 | //recalculate bit time |
||
346 | gBitTimeDelay = baudReg; |
||
347 | gBitTimeDelay *= bitTime; //micro sec for 1 bit @ 9.6kbps |
||
348 | gBitTimeDelay /= initialBaudReg; |
||
349 | } |
||
350 | |||
351 | /////////////////////////////////////////////////// |
||
352 | ////////////////////////////////////////////////// |
||
353 | void SCdrv_CloseUART(void) |
||
354 | { |
||
355 | SCdrv_DisableClock(); //turn off Clock |
||
356 | RCSTAbits.SPEN = 0; //turn off UART |
||
357 | RCSTAbits.CREN = 0; |
||
358 | } |
||
359 | |||
360 | |||
361 | /////////////////////////////////////////////////// |
||
362 | ////////////////////////////////////////////////// |
||
363 | void SCdrv_InitUART(void) |
||
364 | { |
||
365 | unsigned int power2Value = 1; |
||
366 | BYTE power2temp; |
||
367 | |||
368 | SCdrv_PowerPin_Direction(0); //set RB0 as output to power the Smart Card |
||
369 | SCdrv_ResetPin_Direction(0); //set RB4 as output for Smart Card Reset Pin |
||
370 | SCdrv_CardPresent_Direction(1); //RB3 Input Card Present |
||
371 | SCdrv_SimPresent_Direction(1); //RB1 Input Card Present |
||
372 | |||
373 | SCdrv_SetTxPinData(0); |
||
374 | SCdrv_TxPin_Direction(1); // TX1 also act as gpio to pull the line low |
||
375 | SCdrv_RxPin_Direction(1); |
||
376 | |||
377 | SCdrv_EnableCardSimPresentPinPullUp(); //enable pull up, active low |
||
378 | |||
379 | SCdrv_SetSwitchCardPower(0); //Turn off power to smart card |
||
380 | SCdrv_SetSwitchCardReset(0); //keep card in reset state |
||
381 | |||
382 | // Set the clock value that you want to trigger the smart card. |
||
383 | // Dont enable the clock,only set it. |
||
384 | Scdrv_ClockSet(); |
||
385 | |||
386 | power2temp = REF_CLOCK_POWER2_VALUE; |
||
387 | |||
388 | while(power2temp--) |
||
389 | { |
||
390 | power2Value = power2Value * (BYTE)2; |
||
391 | } |
||
392 | |||
393 | scReferenceClock = REF_CLOCK_CIRCUIT_INPUT_CLK/(power2Value + REF_CLOCK_DIVISOR_VALUE); |
||
394 | |||
395 | baudRate = scReferenceClock/(unsigned int)372; |
||
396 | |||
397 | initialBaudReg = ((FCY/baudRate) - 1); |
||
398 | SPBRG = (unsigned char)initialBaudReg; |
||
399 | SPBRGH = (unsigned char)(initialBaudReg >> 8); |
||
400 | bitTime = (1000000UL)/baudRate + 1; |
||
401 | |||
402 | gBitTimeDelay = initialBaudReg; |
||
403 | gBitTimeDelay *= bitTime; //micro sec for 9.6k baud |
||
404 | gBitTimeDelay /= initialBaudReg; |
||
405 | |||
406 | TXSTAbits.TX9 = 1; //select 9 bit transmission |
||
407 | TXSTAbits.SYNC = 0; //Async mode |
||
408 | TXSTAbits.BRGH = 1; |
||
409 | BAUDCONbits.BRG16 = 1; |
||
410 | |||
411 | RCSTAbits.CREN = 1; |
||
412 | RCSTAbits.RX9 = 1; |
||
413 | } |
||
414 | |||
415 |
Powered by WebSVN v2.8.3