📄 pcdutils.lst
字号:
191 }
192
193 }
194 WriteRawRC(RegPage,oldPageSelect | 0x80);
195 }
196 }
197
198 //////////////////////////////////////////////////////////////////////
199 // W R I T E A P C D C O M M A N D
200 ///////////////////////////////////////////////////////////////////////
201 char PcdSingleResponseCmd(unsigned char cmd,
202 volatile unsigned char* send,
203 volatile unsigned char* rcv,
204 volatile MfCmdInfo *info)
205 {
206 char status = MI_OK;
207 char tmpStatus ;
208 unsigned char lastBits;
209
210 unsigned char irqEn = 0x00;
211 unsigned char waitFor = 0x00;
212 unsigned char timerCtl = 0x00;
213
214 WriteRC(RegInterruptEn,0x7F); // disable all interrupts
215 WriteRC(RegInterruptRq,0x7F); // reset interrupt requests
216 WriteRC(RegCommand,PCD_IDLE); // terminate probably running command
217
218 FlushFIFO(); // flush FIFO buffer
219
220 // save info structures to module pointers
221 MpIsrInfo = info;
222 MpIsrOut = send;
223 MpIsrIn = rcv;
224
225 // initialising the ISR-Function pointer for mifare
226 // protocol - do this after initialising the MpXXXX variables
227 PcdIsrFct = SingleResponseIsr;
228
229 info->irqSource = 0x0; // reset interrupt flags
230
231 READER_INT_ENABLE;
232
233 // depending on the command code, appropriate interrupts are enabled (irqEn)
C51 COMPILER V6.12 PCDUTILS 08/18/2008 15:29:35 PAGE 5
234 // and the commit interrupt is choosen (waitFor).
235 switch(cmd)
236 {
237 case PCD_IDLE: // nothing else required
238 irqEn = 0x00;
239 waitFor = 0x00;
240 break;
241 case PCD_WRITEE2: // LoAlert and TxIRq
242 irqEn = 0x11;
243 waitFor = 0x10;
244 break;
245 case PCD_READE2: // HiAlert, LoAlert and IdleIRq
246 irqEn = 0x07;
247 waitFor = 0x04;
248 break;
249 case PCD_LOADCONFIG: // IdleIRq and LoAlert
250 case PCD_LOADKEYE2: // IdleIRq and LoAlert
251 case PCD_AUTHENT1: // IdleIRq and LoAlert
252 irqEn = 0x05;
253 waitFor = 0x04;
254 break;
255 case PCD_CALCCRC: // LoAlert and TxIRq
256 irqEn = 0x11;
257 waitFor = 0x10;
258 break;
259 case PCD_AUTHENT2: // IdleIRq
260 irqEn = 0x04;
261 waitFor = 0x04;
262 break;
263 case PCD_RECEIVE: // HiAlert and IdleIRq
264 info->nBitsReceived = -(ReadRC(RegBitFraming) >> 4);
265 irqEn = 0x06;
266 waitFor = 0x04;
267 break;
268 case PCD_LOADKEY: // IdleIRq
269 irqEn = 0x05;
270 waitFor = 0x04;
271 break;
272 case PCD_TRANSMIT: // LoAlert and IdleIRq
273 irqEn = 0x05;
274 waitFor = 0x04;
275 break;
276 case PCD_TRANSCEIVE: // TxIrq, RxIrq, IdleIRq and LoAlert
277 info->nBitsReceived = -(ReadRC(RegBitFraming) >> 4);
278 irqEn = 0x3D;
279 waitFor = 0x04;
280 break;
281 default:
282 status = MI_UNKNOWN_COMMAND;
283 }
284 if (status == MI_OK)
285 {
286 // Initialize uC Timer for global Timeout management
287 irqEn |= 0x20; // always enable timout irq
288 waitFor |= 0x20; // always wait for timeout
289
290 GT_vInitTmr(TIMER_3,0x87); // initialise and start
291 GT_vLoadTmr(TIMER_3,0xF00); // guard timer for reader
292
293 GT_vInitTmr(TIMER_4,0x04); // initialise and start
294 GT_vLoadTmr(TIMER_4,0x01); // processing time counter
295 // 6.4 us resolution - max 420 ms
C51 COMPILER V6.12 PCDUTILS 08/18/2008 15:29:35 PAGE 6
296
297 LED_ON;
298 WriteRC(RegInterruptEn,irqEn | 0x80); //necessary interrupts are enabled // count up from 1
299
300 GT_vStartTmr(TIMER_3); // start timer 3
301 GT_vStartTmr(TIMER_4); // start timer 4
302
303 WriteRC(RegCommand,cmd); //start command
304
305 // wait for commmand completion
306 // a command is completed, if the corresponding interrupt occurs
307 // or a timeout is signaled
308
309 while (!(MpIsrInfo->irqSource & waitFor
310 || T3IR)); // wait for cmd completion or timeout
311
312 WriteRC(RegInterruptEn,0x7F); // disable all interrupts
313 WriteRC(RegInterruptRq,0x7F); // clear all interrupt requests
314 SetBitMask(RegControl,0x04); // stop timer now
315
316 GT_vStopTmr(TIMER_4);
317 GT_vStopTmr(TIMER_3);
318 LED_OFF;
319
320 T3IR = 0;
321 WriteRC(RegCommand,PCD_IDLE); // reset command register
322
323 if (!(MpIsrInfo->irqSource & waitFor)) // reader has not terminated
324 { // timer 3 expired
325 status = MI_ACCESSTIMEOUT;
326 }
327 else
328 status = MpIsrInfo->status; // set status
329
330 if (status == MI_OK) // no timeout error occured
331 {
332 if ((tmpStatus = (ReadRC(RegErrorFlag) & 0x17))) // error occured
333 {
334 if (tmpStatus & 0x01) // collision detected
335 {
336 info->collPos = ReadRC(RegCollPos); // read collision position
337 status = MI_COLLERR;
338 }
339 else
340 {
341 info->collPos = 0;
342 if (tmpStatus & 0x02) // parity error
343 {
344 status = MI_PARITYERR;
345 }
346 }
347 if (tmpStatus & 0x04) // framing error
348 {
349 status = MI_FRAMINGERR;
350 }
351 if (tmpStatus & 0x10) // FIFO overflow
352 {
353 FlushFIFO();
354 status = MI_OVFLERR;
355 }
356 if (tmpStatus & 0x08) // CRC error
357 {
C51 COMPILER V6.12 PCDUTILS 08/18/2008 15:29:35 PAGE 7
358 status = MI_CRCERR;
359 }
360 if (status == MI_OK)
361 status = MI_NY_IMPLEMENTED;
362 // key error occures always, because of
363 // missing crypto 1 keys loaded
364 }
365 // if the last command was TRANSCEIVE, the number of
366 // received bits must be calculated - even if an error occured
367 if (cmd == PCD_TRANSCEIVE || cmd == PCD_RECEIVE)
368 {
369 // number of bits in the last byte
370 lastBits = ReadRC(RegSecondaryStatus) & 0x07;
371 if (lastBits)
372 info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits;
373 else
374 info->nBitsReceived += info->nBytesReceived * 8;
375 }
376 }
377 else
378 {
379 info->collPos = 0x00;
380 }
381 }
382
383 READER_INT_DISABLE;
384
385 PcdIsrFct = EmptyPcdIsrFct; // reset the ISR-Function pointer to
386 // an empty function body
387 // do this before clearing the Mp XXXX variables
388
389 MpIsrInfo = 0; // reset interface variables for ISR
390 MpIsrOut = 0;
391 MpIsrIn = 0;
392 return status;
393 }
C51 COMPILATION COMPLETE. 0 WARNING(S), 6 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -