1 /*-
2  * Free/Libre Near Field Communication (NFC) library
3  *
4  * Libnfc historical contributors:
5  * Copyright (C) 2009      Roel Verdult
6  * Copyright (C) 2009-2013 Romuald Conty
7  * Copyright (C) 2010-2012 Romain Tartière
8  * Copyright (C) 2010-2013 Philippe Teuwen
9  * Copyright (C) 2012-2013 Ludovic Rousseau
10  * See AUTHORS file for a more comprehensive list of contributors.
11  * Additional contributors of this file:
12  * Copyright (C) 2013      Evgeny Boger
13  *
14  * This program is free software: you can redistribute it and/or modify it
15  * under the terms of the GNU Lesser General Public License as published by the
16  * Free Software Foundation, either version 3 of the License, or (at your
17  * option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful, but WITHOUT
20  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
22  * more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with this program.  If not, see <http://www.gnu.org/licenses/>
26  */
27 
28 /**
29  * @file pn532_spi.c
30  * @brief PN532 driver using SPI bus
31  */
32 
33 #ifdef HAVE_CONFIG_H
34 #  include "config.h"
35 #endif // HAVE_CONFIG_H
36 
37 #include "pn532_spi.h"
38 
39 #include <stdio.h>
40 #include <inttypes.h>
41 #include <string.h>
42 #include <nfc/nfc.h>
43 
44 #include "drivers.h"
45 #include "nfc-internal.h"
46 #include "chips/pn53x.h"
47 #include "chips/pn53x-internal.h"
48 #include "spi.h"
49 
50 #define PN532_SPI_DEFAULT_SPEED 1000000 // 1 MHz
51 #define PN532_SPI_DRIVER_NAME "pn532_spi"
52 #define PN532_SPI_MODE SPI_MODE_0
53 
54 #define LOG_CATEGORY "libnfc.driver.pn532_spi"
55 #define LOG_GROUP    NFC_LOG_GROUP_DRIVER
56 
57 #ifndef _WIN32
58 // Needed by sleep() under Unix
59 #  include <unistd.h>
60 #  include <time.h>
61 #  define msleep(x) do { \
62     struct timespec xsleep; \
63     xsleep.tv_sec = x / 1000; \
64     xsleep.tv_nsec = (x - xsleep.tv_sec * 1000) * 1000 * 1000; \
65     nanosleep(&xsleep, NULL); \
66   } while (0)
67 #else
68 // Needed by Sleep() under Windows
69 #  include <winbase.h>
70 #  define msleep Sleep
71 #endif
72 
73 // Internal data structs
74 const struct pn53x_io pn532_spi_io;
75 struct pn532_spi_data {
76   spi_port port;
77   volatile bool abort_flag;
78 };
79 
80 static const uint8_t pn532_spi_cmd_dataread = 0x03;
81 static const uint8_t pn532_spi_cmd_datawrite = 0x01;
82 
83 
84 // Prototypes
85 int     pn532_spi_ack(nfc_device *pnd);
86 int     pn532_spi_wakeup(nfc_device *pnd);
87 
88 #define DRIVER_DATA(pnd) ((struct pn532_spi_data*)(pnd->driver_data))
89 
90 static size_t
pn532_spi_scan(const nfc_context * context,nfc_connstring connstrings[],const size_t connstrings_len)91 pn532_spi_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
92 {
93   size_t device_found = 0;
94   spi_port sp;
95   char **acPorts = spi_list_ports();
96   const char *acPort;
97   int     iDevice = 0;
98 
99   while ((acPort = acPorts[iDevice++])) {
100     sp = spi_open(acPort);
101     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find PN532 device on SPI port: %s at %d Hz.", acPort, PN532_SPI_DEFAULT_SPEED);
102 
103     if ((sp != INVALID_SPI_PORT) && (sp != CLAIMED_SPI_PORT)) {
104       // Serial port claimed but we need to check if a PN532_SPI is opened.
105       spi_set_speed(sp, PN532_SPI_DEFAULT_SPEED);
106       spi_set_mode(sp, PN532_SPI_MODE);
107 
108       nfc_connstring connstring;
109       snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_SPI_DRIVER_NAME, acPort, PN532_SPI_DEFAULT_SPEED);
110       nfc_device *pnd = nfc_device_new(context, connstring);
111       if (!pnd) {
112         perror("malloc");
113         spi_close(sp);
114         iDevice = 0;
115         while ((acPort = acPorts[iDevice++])) {
116           free((void *)acPort);
117         }
118         free(acPorts);
119         return 0;
120       }
121       pnd->driver = &pn532_spi_driver;
122       pnd->driver_data = malloc(sizeof(struct pn532_spi_data));
123       if (!pnd->driver_data) {
124         perror("malloc");
125         spi_close(sp);
126         nfc_device_free(pnd);
127         iDevice = 0;
128         while ((acPort = acPorts[iDevice++])) {
129           free((void *)acPort);
130         }
131         free(acPorts);
132         return 0;
133       }
134       DRIVER_DATA(pnd)->port = sp;
135 
136       // Alloc and init chip's data
137       if (pn53x_data_new(pnd, &pn532_spi_io) == NULL) {
138         perror("malloc");
139         spi_close(DRIVER_DATA(pnd)->port);
140         nfc_device_free(pnd);
141         iDevice = 0;
142         while ((acPort = acPorts[iDevice++])) {
143           free((void *)acPort);
144         }
145         free(acPorts);
146         return 0;
147       }
148       // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
149       CHIP_DATA(pnd)->type = PN532;
150       // This device starts in LowVBat power mode
151       CHIP_DATA(pnd)->power_mode = LOWVBAT;
152 
153       DRIVER_DATA(pnd)->abort_flag = false;
154 
155       // Check communication using "Diagnose" command, with "Communication test" (0x00)
156       int res = pn53x_check_communication(pnd);
157       spi_close(DRIVER_DATA(pnd)->port);
158       pn53x_data_free(pnd);
159       nfc_device_free(pnd);
160       if (res < 0) {
161         continue;
162       }
163 
164       memcpy(connstrings[device_found], connstring, sizeof(nfc_connstring));
165       device_found++;
166 
167       // Test if we reach the maximum "wanted" devices
168       if (device_found >= connstrings_len)
169         break;
170     }
171   }
172   iDevice = 0;
173   while ((acPort = acPorts[iDevice++])) {
174     free((void *)acPort);
175   }
176   free(acPorts);
177   return device_found;
178 }
179 
180 struct pn532_spi_descriptor {
181   char *port;
182   uint32_t speed;
183 };
184 
185 static void
pn532_spi_close(nfc_device * pnd)186 pn532_spi_close(nfc_device *pnd)
187 {
188   pn53x_idle(pnd);
189 
190   // Release SPI port
191   spi_close(DRIVER_DATA(pnd)->port);
192 
193   pn53x_data_free(pnd);
194   nfc_device_free(pnd);
195 }
196 
197 static nfc_device *
pn532_spi_open(const nfc_context * context,const nfc_connstring connstring)198 pn532_spi_open(const nfc_context *context, const nfc_connstring connstring)
199 {
200   struct pn532_spi_descriptor ndd;
201   char *speed_s;
202   int connstring_decode_level = connstring_decode(connstring, PN532_SPI_DRIVER_NAME, NULL, &ndd.port, &speed_s);
203   if (connstring_decode_level == 3) {
204     ndd.speed = 0;
205     if (sscanf(speed_s, "%10"PRIu32, &ndd.speed) != 1) {
206       // speed_s is not a number
207       free(ndd.port);
208       free(speed_s);
209       return NULL;
210     }
211     free(speed_s);
212   }
213   if (connstring_decode_level < 2) {
214     return NULL;
215   }
216   if (connstring_decode_level < 3) {
217     ndd.speed = PN532_SPI_DEFAULT_SPEED;
218   }
219   spi_port sp;
220   nfc_device *pnd = NULL;
221 
222   log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s at %d Hz.", ndd.port, ndd.speed);
223   sp = spi_open(ndd.port);
224 
225   if (sp == INVALID_SPI_PORT)
226     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid SPI port: %s", ndd.port);
227   if (sp == CLAIMED_SPI_PORT)
228     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "SPI port already claimed: %s", ndd.port);
229   if ((sp == CLAIMED_SPI_PORT) || (sp == INVALID_SPI_PORT)) {
230     free(ndd.port);
231     return NULL;
232   }
233   spi_set_speed(sp, ndd.speed);
234   spi_set_mode(sp, PN532_SPI_MODE);
235 
236   // We have a connection
237   pnd = nfc_device_new(context, connstring);
238   if (!pnd) {
239     perror("malloc");
240     free(ndd.port);
241     spi_close(sp);
242     return NULL;
243   }
244   snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_SPI_DRIVER_NAME, ndd.port);
245   free(ndd.port);
246 
247   pnd->driver_data = malloc(sizeof(struct pn532_spi_data));
248   if (!pnd->driver_data) {
249     perror("malloc");
250     spi_close(sp);
251     nfc_device_free(pnd);
252     return NULL;
253   }
254   DRIVER_DATA(pnd)->port = sp;
255 
256   // Alloc and init chip's data
257   if (pn53x_data_new(pnd, &pn532_spi_io) == NULL) {
258     perror("malloc");
259     spi_close(DRIVER_DATA(pnd)->port);
260     nfc_device_free(pnd);
261     return NULL;
262   }
263   // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
264   CHIP_DATA(pnd)->type = PN532;
265   // This device starts in LowVBat mode
266   CHIP_DATA(pnd)->power_mode = LOWVBAT;
267 
268   // empirical tuning
269   CHIP_DATA(pnd)->timer_correction = 48;
270   pnd->driver = &pn532_spi_driver;
271 
272   DRIVER_DATA(pnd)->abort_flag = false;
273 
274   // Check communication using "Diagnose" command, with "Communication test" (0x00)
275   if (pn53x_check_communication(pnd) < 0) {
276     nfc_perror(pnd, "pn53x_check_communication");
277     pn532_spi_close(pnd);
278     return NULL;
279   }
280 
281   pn53x_init(pnd);
282   return pnd;
283 }
284 
285 static int
pn532_spi_read_spi_status(nfc_device * pnd)286 pn532_spi_read_spi_status(nfc_device *pnd)
287 {
288   static const uint8_t pn532_spi_statread_cmd = 0x02;
289 
290   uint8_t spi_status = 0;
291   int res = spi_send_receive(DRIVER_DATA(pnd)->port, &pn532_spi_statread_cmd, 1, &spi_status, 1, true);
292 
293 
294   if (res != NFC_SUCCESS) {
295     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Unable to read SPI status");
296     return res;
297   }
298 
299   return spi_status;
300 }
301 
302 int
pn532_spi_wakeup(nfc_device * pnd)303 pn532_spi_wakeup(nfc_device *pnd)
304 {
305   /* SPI wakeup is basically activating chipselect for several ms.
306    * To do so, we are sending harmless command at very low speed  */
307 
308   int res;
309   const uint32_t prev_port_speed  =  spi_get_speed(DRIVER_DATA(pnd)->port);
310 
311 
312 
313 
314   // Try to get byte from the SPI line. If PN532 is powered down, the byte will be 0xff (MISO line is high)
315   uint8_t spi_byte = 0;
316   res = spi_receive(DRIVER_DATA(pnd)->port, &spi_byte, 1, true);
317   if (res != NFC_SUCCESS) {
318     return res;
319   }
320 
321   log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Got %x byte from SPI line before wakeup", spi_byte);
322 
323   CHIP_DATA(pnd)->power_mode = NORMAL; // PN532 will be awake soon
324   msleep(1);
325 
326   if (spi_byte == 0xff) {
327     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Wakeup is needed");
328     spi_set_speed(DRIVER_DATA(pnd)->port, 5000); // set slow speed
329 
330     res = pn532_SAMConfiguration(pnd, PSM_NORMAL, 1000); // wakeup by sending SAMConfiguration, which works just fine
331 
332     spi_set_speed(DRIVER_DATA(pnd)->port, prev_port_speed);
333   }
334 
335 
336   return res;
337 }
338 
339 #define PN532_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
340 
341 
342 static int
pn532_spi_wait_for_data(nfc_device * pnd,int timeout)343 pn532_spi_wait_for_data(nfc_device *pnd, int timeout)
344 {
345   static const uint8_t pn532_spi_ready = 0x01;
346   static const int pn532_spi_poll_interval = 10; //ms
347 
348 
349   int timer = 0;
350 
351   int ret;
352   while ((ret = pn532_spi_read_spi_status(pnd)) != pn532_spi_ready) {
353     if (ret < 0) {
354       return ret;
355     }
356 
357     if (DRIVER_DATA(pnd)->abort_flag) {
358       DRIVER_DATA(pnd)->abort_flag = false;
359       return NFC_EOPABORTED;
360     }
361 
362     if (timeout > 0) {
363       timer += pn532_spi_poll_interval;
364       if (timer > timeout) {
365         return NFC_ETIMEOUT;
366       }
367 
368       msleep(pn532_spi_poll_interval);
369     }
370   }
371 
372   return NFC_SUCCESS;
373 }
374 
375 
376 static int
pn532_spi_receive_next_chunk(nfc_device * pnd,uint8_t * pbtData,const size_t szDataLen)377 pn532_spi_receive_next_chunk(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen)
378 {
379   // According to datasheet, the entire read operation should be done at once
380   // However, it seems impossible to do since the length of the frame is stored in the frame
381   // itself and it's impossible to manually set CS to low between two read operations
382 
383   // It's possible to read the response frame in a series of read operations, provided
384   // each read operation is preceded by SPI_DATAREAD byte from the host.
385 
386   // Unfortunately, the PN532 sends first byte of the second and successive response chunks
387   // at the same time as host sends SPI_DATAREAD byte
388 
389   // Many hardware SPI implementations are half-duplex, so it's became impossible to read this
390   // first response byte
391 
392   // The following hack is used here: we first try to receive data from PN532 without SPI_DATAREAD
393   // and then begin full-featured read operation
394 
395   // The PN532 does not shift the internal register on the receive operation, which allows us to read the whole response
396 
397   // The example transfer log is as follows:
398   // CS                  ..._/---\___________________________/---\________/------\_____________/-----\_________/---\____________/---...
399   // MOSI (host=>pn532)  ...       0x03 0x00 0x00 0x00 0x00        0x00            0x03  0x00          0x00          0x03  0x00
400   // MISO (pn532<=host)  ...       0x01 0x00 0xff 0x02 0xfe        0xd5            0xd5  0x15          0x16          0x16  0x00
401   // linux send/receive             s     r    r   r    r           r               s     r              r             s    r
402   //                                    |<--      data    -->|    |<-data->|           |<-data->|    |<-data->|           |<-data->|
403   //                               |<--    first chunk    -->|    |<--       second chunk    -->|    |<--    third chunk        -->|
404 
405   //  The response frame is 0x00 0xff 0x02 0xfe 0xd5 0x15 0x16 0x00
406 
407 
408   int res = spi_receive(DRIVER_DATA(pnd)->port, pbtData, 1, true);
409 
410   if (res != NFC_SUCCESS) {
411     return res;
412   }
413 
414   res = spi_send_receive(DRIVER_DATA(pnd)->port, &pn532_spi_cmd_dataread, 1, pbtData + 1, szDataLen - 1, true);
415 
416   return res;
417 }
418 
419 static int
pn532_spi_receive(nfc_device * pnd,uint8_t * pbtData,const size_t szDataLen,int timeout)420 pn532_spi_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout)
421 {
422   uint8_t  abtRxBuf[5];
423   size_t len;
424 
425   pnd->last_error = pn532_spi_wait_for_data(pnd, timeout);
426 
427   if (NFC_EOPABORTED == pnd->last_error) {
428     return pn532_spi_ack(pnd);
429   }
430 
431   if (pnd->last_error != NFC_SUCCESS) {
432     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to wait for SPI data. (RX)");
433     goto error;
434   }
435 
436   pnd->last_error = spi_send_receive(DRIVER_DATA(pnd)->port, &pn532_spi_cmd_dataread, 1, abtRxBuf , 4, true);
437 
438   if (pnd->last_error < 0) {
439     goto error;
440   }
441 
442   const uint8_t pn53x_long_preamble[3] = { 0x00, 0x00, 0xff };
443   if (0 == (memcmp(abtRxBuf, pn53x_long_preamble, 3))) {
444     // long preamble
445 
446     // omit first byte
447     for (size_t i = 0; i < 3; ++i) {
448       abtRxBuf[i] = abtRxBuf[i + 1];
449     }
450 
451     // need one more byte
452     pnd->last_error = pn532_spi_receive_next_chunk(pnd, abtRxBuf + 3, 1);
453     if (pnd->last_error != 0) {
454       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive one more byte for long preamble frame. (RX)");
455       goto error;
456     }
457   }
458 
459 
460   const uint8_t pn53x_preamble[2] = { 0x00, 0xff };
461   if (0 != (memcmp(abtRxBuf, pn53x_preamble, 2))) {
462     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", " preamble+start code mismatch");
463     pnd->last_error = NFC_EIO;
464     goto error;
465   }
466 
467   if ((0x01 == abtRxBuf[2]) && (0xff == abtRxBuf[3])) {
468     // Error frame
469     pn532_spi_receive_next_chunk(pnd, abtRxBuf, 3);
470 
471     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Application level error detected");
472     pnd->last_error = NFC_EIO;
473     goto error;
474   } else if ((0xff == abtRxBuf[2]) && (0xff == abtRxBuf[3])) {
475     // Extended frame
476     pnd->last_error = pn532_spi_receive_next_chunk(pnd, abtRxBuf, 3);
477 
478     if (pnd->last_error != 0) {
479       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
480       goto error;
481     }
482     // (abtRxBuf[0] << 8) + abtRxBuf[1] (LEN) include TFI + (CC+1)
483     len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2;
484     if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) {
485       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
486       pnd->last_error = NFC_EIO;
487       goto error;
488     }
489   } else {
490     // Normal frame
491     if (256 != (abtRxBuf[2] + abtRxBuf[3])) {
492       // TODO: Retry
493       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
494       pnd->last_error = NFC_EIO;
495       goto error;
496     }
497 
498     // abtRxBuf[3] (LEN) include TFI + (CC+1)
499     len = abtRxBuf[2] - 2;
500   }
501 
502   if (len > szDataLen) {
503     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
504     pnd->last_error = NFC_EIO;
505     goto error;
506   }
507 
508   // TFI + PD0 (CC+1)
509 
510   pnd->last_error = pn532_spi_receive_next_chunk(pnd, abtRxBuf, 2);
511 
512   if (pnd->last_error != 0) {
513     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
514     goto error;
515   }
516 
517   if (abtRxBuf[0] != 0xD5) {
518     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "TFI Mismatch");
519     pnd->last_error = NFC_EIO;
520     goto error;
521   }
522 
523   if (abtRxBuf[1] != CHIP_DATA(pnd)->last_command + 1) {
524     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Command Code verification failed");
525     pnd->last_error = NFC_EIO;
526     goto error;
527   }
528 
529   if (len) {
530     pnd->last_error = pn532_spi_receive_next_chunk(pnd, pbtData, len);
531 
532     if (pnd->last_error != 0) {
533       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
534       goto error;
535     }
536   }
537 
538   pnd->last_error = pn532_spi_receive_next_chunk(pnd, abtRxBuf, 2);
539 
540   if (pnd->last_error != 0) {
541     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
542     goto error;
543   }
544 
545   uint8_t btDCS = (256 - 0xD5);
546   btDCS -= CHIP_DATA(pnd)->last_command + 1;
547   for (size_t szPos = 0; szPos < len; szPos++) {
548     btDCS -= pbtData[szPos];
549   }
550 
551   if (btDCS != abtRxBuf[0]) {
552     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Data checksum mismatch");
553     pnd->last_error = NFC_EIO;
554     goto error;
555   }
556 
557   if (0x00 != abtRxBuf[1]) {
558     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
559     pnd->last_error = NFC_EIO;
560     goto error;
561   }
562   // The PN53x command is done and we successfully received the reply
563   return len;
564 error:
565   return pnd->last_error;
566 }
567 
568 static int
pn532_spi_send(nfc_device * pnd,const uint8_t * pbtData,const size_t szData,int timeout)569 pn532_spi_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
570 {
571   int res = 0;
572 
573   switch (CHIP_DATA(pnd)->power_mode) {
574     case LOWVBAT: {
575       /** PN532C106 wakeup. */
576       if ((res = pn532_spi_wakeup(pnd)) < 0) {
577         return res;
578       }
579       // According to PN532 application note, C106 appendix: to go out Low Vbat mode and enter in normal mode we need to send a SAMConfiguration command
580       if ((res = pn532_SAMConfiguration(pnd, PSM_NORMAL, 1000)) < 0) {
581         return res;
582       }
583     }
584     break;
585     case POWERDOWN: {
586       if ((res = pn532_spi_wakeup(pnd)) < 0) {
587         return res;
588       }
589     }
590     break;
591     case NORMAL:
592       // Nothing to do :)
593       break;
594   };
595 
596   uint8_t  abtFrame[PN532_BUFFER_LEN + 1] = { pn532_spi_cmd_datawrite, 0x00, 0x00, 0xff };       // SPI data transfer starts with DATAWRITE (0x01) byte,  Every packet must start with "00 00 ff"
597   size_t szFrame = 0;
598 
599   if ((res = pn53x_build_frame(abtFrame + 1, &szFrame, pbtData, szData)) < 0) {
600     pnd->last_error = res;
601     return pnd->last_error;
602   }
603 
604   res = spi_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame, true);
605   if (res != 0) {
606     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
607     pnd->last_error = res;
608     return pnd->last_error;
609   }
610 
611   res = pn532_spi_wait_for_data(pnd, timeout);
612   if (res != NFC_SUCCESS) {
613     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to wait for SPI data. (RX)");
614     pnd->last_error = res;
615     return pnd->last_error;
616   }
617 
618 
619 
620   uint8_t abtRxBuf[PN53x_ACK_FRAME__LEN];
621   res = spi_send_receive(DRIVER_DATA(pnd)->port, &pn532_spi_cmd_dataread, 1, abtRxBuf, sizeof(abtRxBuf), true);
622 
623   if (res != 0) {
624     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Unable to read ACK");
625     pnd->last_error = res;
626     return pnd->last_error;
627   }
628 
629   if (pn53x_check_ack_frame(pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) {
630     // The PN53x is running the sent command
631   } else {
632     return pnd->last_error;
633   }
634   return NFC_SUCCESS;
635 }
636 
637 
638 int
pn532_spi_ack(nfc_device * pnd)639 pn532_spi_ack(nfc_device *pnd)
640 {
641   const size_t ack_frame_len = (sizeof(pn53x_ack_frame) / sizeof(pn53x_ack_frame[0]));
642   uint8_t ack_tx_buf [1 + ack_frame_len];
643 
644   ack_tx_buf[0] = pn532_spi_cmd_datawrite;
645   memcpy(ack_tx_buf + 1, pn53x_ack_frame, ack_frame_len);
646 
647 
648   int res = spi_send(DRIVER_DATA(pnd)->port, ack_tx_buf, ack_frame_len + 1, true);
649   return res;
650 }
651 
652 static int
pn532_spi_abort_command(nfc_device * pnd)653 pn532_spi_abort_command(nfc_device *pnd)
654 {
655   if (pnd) {
656     DRIVER_DATA(pnd)->abort_flag = true;
657   }
658 
659   return NFC_SUCCESS;
660 }
661 
662 const struct pn53x_io pn532_spi_io = {
663   .send       = pn532_spi_send,
664   .receive    = pn532_spi_receive,
665 };
666 
667 const struct nfc_driver pn532_spi_driver = {
668   .name                             = PN532_SPI_DRIVER_NAME,
669   .scan_type                        = INTRUSIVE,
670   .scan                             = pn532_spi_scan,
671   .open                             = pn532_spi_open,
672   .close                            = pn532_spi_close,
673   .strerror                         = pn53x_strerror,
674 
675   .initiator_init                   = pn53x_initiator_init,
676   .initiator_init_secure_element    = pn532_initiator_init_secure_element,
677   .initiator_select_passive_target  = pn53x_initiator_select_passive_target,
678   .initiator_poll_target            = pn53x_initiator_poll_target,
679   .initiator_select_dep_target      = pn53x_initiator_select_dep_target,
680   .initiator_deselect_target        = pn53x_initiator_deselect_target,
681   .initiator_transceive_bytes       = pn53x_initiator_transceive_bytes,
682   .initiator_transceive_bits        = pn53x_initiator_transceive_bits,
683   .initiator_transceive_bytes_timed = pn53x_initiator_transceive_bytes_timed,
684   .initiator_transceive_bits_timed  = pn53x_initiator_transceive_bits_timed,
685   .initiator_target_is_present      = pn53x_initiator_target_is_present,
686 
687   .target_init           = pn53x_target_init,
688   .target_send_bytes     = pn53x_target_send_bytes,
689   .target_receive_bytes  = pn53x_target_receive_bytes,
690   .target_send_bits      = pn53x_target_send_bits,
691   .target_receive_bits   = pn53x_target_receive_bits,
692 
693   .device_set_property_bool     = pn53x_set_property_bool,
694   .device_set_property_int      = pn53x_set_property_int,
695   .get_supported_modulation     = pn53x_get_supported_modulation,
696   .get_supported_baud_rate      = pn53x_get_supported_baud_rate,
697   .device_get_information_about = pn53x_get_information_about,
698 
699   .abort_command  = pn532_spi_abort_command,
700   .idle           = pn53x_idle,
701   .powerdown      = pn53x_PowerDown,
702 };
703 
704