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      Laurent Latil
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_i2c.c
30  * @brief PN532 driver using I2C bus.
31  */
32 
33 #ifdef HAVE_CONFIG_H
34 #  include "config.h"
35 #endif // HAVE_CONFIG_H
36 
37 #include "pn532_i2c.h"
38 
39 #include <stdio.h>
40 #include <inttypes.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <stdlib.h>
44 #include <time.h>
45 
46 #include <nfc/nfc.h>
47 
48 #include "drivers.h"
49 #include "nfc-internal.h"
50 #include "chips/pn53x.h"
51 #include "chips/pn53x-internal.h"
52 #include "buses/i2c.h"
53 
54 #define PN532_I2C_DRIVER_NAME "pn532_i2c"
55 
56 #define LOG_CATEGORY "libnfc.driver.pn532_i2c"
57 #define LOG_GROUP    NFC_LOG_GROUP_DRIVER
58 
59 // I2C address of the PN532 chip.
60 #define PN532_I2C_ADDR 0x24
61 
62 // Internal data structs
63 const struct pn53x_io pn532_i2c_io;
64 
65 struct pn532_i2c_data {
66   i2c_device dev;
67   volatile bool abort_flag;
68 };
69 
70 /* Delay for the loop waiting for READY frame (in ms) */
71 #define PN532_RDY_LOOP_DELAY 90
72 
73 const struct timespec rdyDelay = {
74   .tv_sec = 0,
75   .tv_nsec = PN532_RDY_LOOP_DELAY * 1000 * 1000
76 };
77 
78 /* Private Functions Prototypes */
79 
80 static nfc_device *pn532_i2c_open(const nfc_context *context, const nfc_connstring connstring);
81 
82 static void pn532_i2c_close(nfc_device *pnd);
83 
84 static int pn532_i2c_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
85 
86 static int pn532_i2c_ack(nfc_device *pnd);
87 
88 static int pn532_i2c_abort_command(nfc_device *pnd);
89 
90 static int pn532_i2c_wakeup(nfc_device *pnd);
91 
92 static int pn532_i2c_wait_rdyframe(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout);
93 
94 static size_t pn532_i2c_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len);
95 
96 
97 #define DRIVER_DATA(pnd) ((struct pn532_i2c_data*)(pnd->driver_data))
98 
99 /**
100  * @brief Scan all available I2C buses to find PN532 devices.
101  *
102  * @param context NFC context.
103  * @param connstrings array of 'nfc_connstring' buffer  (allocated by caller). It is used to store the
104  *      connection info strings of all I2C PN532 devices found.
105  * @param connstrings_len length of the connstrings array.
106  * @return number of PN532 devices found on all I2C buses.
107  */
108 static size_t
pn532_i2c_scan(const nfc_context * context,nfc_connstring connstrings[],const size_t connstrings_len)109 pn532_i2c_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
110 {
111   size_t device_found = 0;
112   i2c_device id;
113   char **i2cPorts = i2c_list_ports();
114   const char *i2cPort;
115   int iDevice = 0;
116 
117   while ((i2cPort = i2cPorts[iDevice++])) {
118     id = i2c_open(i2cPort, PN532_I2C_ADDR);
119     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find PN532 device on I2C bus %s.", i2cPort);
120 
121     if ((id != INVALID_I2C_ADDRESS) && (id != INVALID_I2C_BUS)) {
122       nfc_connstring connstring;
123       snprintf(connstring, sizeof(nfc_connstring), "%s:%s", PN532_I2C_DRIVER_NAME, i2cPort);
124       nfc_device *pnd = nfc_device_new(context, connstring);
125       if (!pnd) {
126         perror("malloc");
127         i2c_close(id);
128         iDevice = 0;
129         while ((i2cPort = i2cPorts[iDevice++])) {
130           free((void *)i2cPort);
131         }
132         free(i2cPorts);
133         return 0;
134       }
135       pnd->driver = &pn532_i2c_driver;
136       pnd->driver_data = malloc(sizeof(struct pn532_i2c_data));
137       if (!pnd->driver_data) {
138         perror("malloc");
139         i2c_close(id);
140         nfc_device_free(pnd);
141         iDevice = 0;
142         while ((i2cPort = i2cPorts[iDevice++])) {
143           free((void *)i2cPort);
144         }
145         free(i2cPorts);
146         return 0;
147       }
148       DRIVER_DATA(pnd)->dev = id;
149 
150       // Alloc and init chip's data
151       if (pn53x_data_new(pnd, &pn532_i2c_io) == NULL) {
152         perror("malloc");
153         i2c_close(DRIVER_DATA(pnd)->dev);
154         nfc_device_free(pnd);
155         iDevice = 0;
156         while ((i2cPort = i2cPorts[iDevice++])) {
157           free((void *)i2cPort);
158         }
159         free(i2cPorts);
160         return 0;
161       }
162 
163       // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
164       CHIP_DATA(pnd)->type = PN532;
165       // This device starts in LowVBat power mode
166       CHIP_DATA(pnd)->power_mode = LOWVBAT;
167 
168       DRIVER_DATA(pnd)->abort_flag = false;
169 
170       // Check communication using "Diagnose" command, with "Communication test" (0x00)
171       int res = pn53x_check_communication(pnd);
172       i2c_close(DRIVER_DATA(pnd)->dev);
173       pn53x_data_free(pnd);
174       nfc_device_free(pnd);
175       if (res < 0) {
176         continue;
177       }
178 
179       memcpy(connstrings[device_found], connstring, sizeof(nfc_connstring));
180       device_found++;
181 
182       // Test if we reach the maximum "wanted" devices
183       if (device_found >= connstrings_len)
184         break;
185     }
186   }
187   iDevice = 0;
188   while ((i2cPort = i2cPorts[iDevice++])) {
189     free((void *)i2cPort);
190   }
191   free(i2cPorts);
192   return device_found;
193 }
194 
195 /**
196  * @brief Close I2C connection to the PN532 device.
197  *
198  * @param pnd pointer on the device to close.
199  */
200 static void
pn532_i2c_close(nfc_device * pnd)201 pn532_i2c_close(nfc_device *pnd)
202 {
203   pn53x_idle(pnd);
204   i2c_close(DRIVER_DATA(pnd)->dev);
205 
206   pn53x_data_free(pnd);
207   nfc_device_free(pnd);
208 }
209 
210 /**
211  * @brief Open an I2C connection to the PN532 device.
212  *
213  * @param context NFC context.
214  * @param connstring connection info to the device  ( pn532_i2c:<i2c_devname> ).
215  * @return pointer to the device, or NULL in case of error.
216  */
217 static nfc_device *
pn532_i2c_open(const nfc_context * context,const nfc_connstring connstring)218 pn532_i2c_open(const nfc_context *context, const nfc_connstring connstring)
219 {
220   char *i2c_devname;
221   i2c_device i2c_dev;
222   nfc_device *pnd;
223 
224   int connstring_decode_level = connstring_decode(connstring, PN532_I2C_DRIVER_NAME, NULL, &i2c_devname, NULL);
225 
226   switch (connstring_decode_level) {
227     case 2:
228       break;
229     case 1:
230       break;
231     case 0:
232       return NULL;
233   }
234 
235   i2c_dev = i2c_open(i2c_devname, PN532_I2C_ADDR);
236 
237   if (i2c_dev == INVALID_I2C_BUS || i2c_dev == INVALID_I2C_ADDRESS) {
238     return NULL;
239   }
240 
241   pnd = nfc_device_new(context, connstring);
242   if (!pnd) {
243     perror("malloc");
244     i2c_close(i2c_dev);
245     return NULL;
246   }
247   snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_I2C_DRIVER_NAME, i2c_devname);
248 
249   pnd->driver_data = malloc(sizeof(struct pn532_i2c_data));
250   if (!pnd->driver_data) {
251     perror("malloc");
252     i2c_close(i2c_dev);
253     nfc_device_free(pnd);
254     return NULL;
255   }
256   DRIVER_DATA(pnd)->dev = i2c_dev;
257 
258   // Alloc and init chip's data
259   if (pn53x_data_new(pnd, &pn532_i2c_io) == NULL) {
260     perror("malloc");
261     i2c_close(i2c_dev);
262     nfc_device_free(pnd);
263     return NULL;
264   }
265 
266   // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
267   CHIP_DATA(pnd)->type = PN532;
268   // This device starts in LowVBat mode
269   CHIP_DATA(pnd)->power_mode = LOWVBAT;
270 
271   // empirical tuning
272   CHIP_DATA(pnd)->timer_correction = 48;
273   pnd->driver = &pn532_i2c_driver;
274 
275   DRIVER_DATA(pnd)->abort_flag = false;
276 
277   // Check communication using "Diagnose" command, with "Communication test" (0x00)
278   if (pn53x_check_communication(pnd) < 0) {
279     nfc_perror(pnd, "pn53x_check_communication");
280     pn532_i2c_close(pnd);
281     return NULL;
282   }
283 
284   pn53x_init(pnd);
285   return pnd;
286 }
287 
288 static int
pn532_i2c_wakeup(nfc_device * pnd)289 pn532_i2c_wakeup(nfc_device *pnd)
290 {
291   /* No specific.  PN532 holds SCL during wakeup time  */
292   CHIP_DATA(pnd)->power_mode = NORMAL; // PN532 should now be awake
293   return NFC_SUCCESS;
294 }
295 
296 #define PN532_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
297 
298 /**
299  * @brief Send data to the PN532 device.
300  *
301  * @param pnd pointer on the NFC device.
302  * @param pbtData buffer containing frame data.
303  * @param szData size of the buffer.
304  * @param timeout timeout before aborting the operation (in ms).
305  * @return NFC_SUCCESS if operation is successful, or error code.
306  */
307 static int
pn532_i2c_send(nfc_device * pnd,const uint8_t * pbtData,const size_t szData,int timeout)308 pn532_i2c_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
309 {
310   int res = 0;
311 
312   // Discard any existing data ?
313 
314   switch (CHIP_DATA(pnd)->power_mode) {
315     case LOWVBAT: {
316       /** PN532C106 wakeup. */
317       if ((res = pn532_i2c_wakeup(pnd)) < 0) {
318         return res;
319       }
320       // 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
321       if ((res = pn532_SAMConfiguration(pnd, PSM_NORMAL, 1000)) < 0) {
322         return res;
323       }
324     }
325     break;
326     case POWERDOWN: {
327       if ((res = pn532_i2c_wakeup(pnd)) < 0) {
328         return res;
329       }
330     }
331     break;
332     case NORMAL:
333       // Nothing to do :)
334       break;
335   };
336 
337   uint8_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };       // Every packet must start with "00 00 ff"
338   size_t szFrame = 0;
339 
340   if ((res = pn53x_build_frame(abtFrame, &szFrame, pbtData, szData)) < 0) {
341     pnd->last_error = res;
342     return pnd->last_error;
343   }
344 
345   res = i2c_write(DRIVER_DATA(pnd)->dev, abtFrame, szFrame);
346 
347   if (res < 0) {
348     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
349     pnd->last_error = res;
350     return pnd->last_error;
351   }
352 
353   uint8_t abtRxBuf[PN53x_ACK_FRAME__LEN];
354 
355   // Wait for the ACK frame
356   res = pn532_i2c_wait_rdyframe(pnd, abtRxBuf, sizeof(abtRxBuf), timeout);
357   if (res < 0) {
358     if (res == NFC_EOPABORTED) {
359       // Send an ACK frame from host to abort the command.
360       pn532_i2c_ack(pnd);
361     }
362     pnd->last_error = res;
363     return pnd->last_error;
364   }
365 
366   if (pn53x_check_ack_frame(pnd, abtRxBuf, res) == 0) {
367     // The PN53x is running the sent command
368   } else {
369     return pnd->last_error;
370   }
371   return NFC_SUCCESS;
372 }
373 
374 /**
375  * @brief Read data from the PN532 device until getting a frame with RDY bit set
376  *
377  * @param pnd pointer on the NFC device.
378  * @param pbtData buffer used to store the received frame data.
379  * @param szDataLen allocated size of buffer.
380  * @param timeout timeout delay before aborting the operation (in ms). Use 0 for no timeout.
381  * @return length (in bytes) of the received frame, or NFC_ETIMEOUT if timeout delay has expired,
382  *         NFC_EOPABORTED if operation has been aborted, NFC_EIO in case of IO failure
383  */
384 static int
pn532_i2c_wait_rdyframe(nfc_device * pnd,uint8_t * pbtData,const size_t szDataLen,int timeout)385 pn532_i2c_wait_rdyframe(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout)
386 {
387   bool done = false;
388   int res;
389 
390   struct timeval start_tv, cur_tv;
391   long long duration;
392 
393   // Actual I2C response frame includes an additional status byte,
394   // so we use a temporary buffer to read the I2C frame
395   uint8_t i2cRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN + 1];
396 
397   if (timeout > 0) {
398     // If a timeout is specified, get current timestamp
399     gettimeofday(&start_tv, NULL);
400   }
401 
402   do {
403     // Wait a little bit before reading
404     nanosleep(&rdyDelay, (struct timespec *) NULL);
405 
406     int recCount = i2c_read(DRIVER_DATA(pnd)->dev, i2cRx, szDataLen + 1);
407 
408     if (DRIVER_DATA(pnd)->abort_flag) {
409       // Reset abort flag
410       DRIVER_DATA(pnd)->abort_flag = false;
411 
412       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
413               "Wait for a READY frame has been aborted.");
414       return NFC_EOPABORTED;
415     }
416 
417     if (recCount <= 0) {
418       done = true;
419       res = NFC_EIO;
420     } else {
421       const uint8_t rdy = i2cRx[0];
422       if (rdy & 1) {
423         int copyLength;
424 
425         done = true;
426         res = recCount - 1;
427         copyLength = MIN(res, (int)szDataLen);
428         memcpy(pbtData, &(i2cRx[1]), copyLength);
429       } else {
430         /* Not ready yet. Check for elapsed timeout. */
431 
432         if (timeout > 0) {
433           gettimeofday(&cur_tv, NULL);
434           duration = (cur_tv.tv_sec - start_tv.tv_sec) * 1000000L
435                      + (cur_tv.tv_usec - start_tv.tv_usec);
436 
437           if (duration / 1000 > timeout) {
438             res = NFC_ETIMEOUT;
439             done = true;
440 
441             log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
442                     "timeout reached with no READY frame.");
443           }
444         }
445       }
446     }
447   } while (!done);
448 
449   return res;
450 }
451 
452 /**
453  * @brief Read a response frame from the PN532 device.
454  *
455  * @param pnd pointer on the NFC device.
456  * @param pbtData buffer used to store the response frame data.
457  * @param szDataLen allocated size of buffer.
458  * @param timeout timeout delay before aborting the operation (in ms). Use 0 for no timeout.
459  * @return length (in bytes) of the response, or NFC_ETIMEOUT if timeout delay has expired,
460  *         NFC_EOPABORTED if operation has been aborted, NFC_EIO in case of IO failure
461  */
462 static int
pn532_i2c_receive(nfc_device * pnd,uint8_t * pbtData,const size_t szDataLen,int timeout)463 pn532_i2c_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout)
464 {
465   uint8_t frameBuf[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
466   int frameLength;
467   int TFI_idx;
468   size_t len;
469 
470   frameLength = pn532_i2c_wait_rdyframe(pnd, frameBuf, sizeof(frameBuf), timeout);
471 
472   if (NFC_EOPABORTED == pnd->last_error) {
473     return pn532_i2c_ack(pnd);
474   }
475 
476   if (frameLength < 0) {
477     goto error;
478   }
479 
480   const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
481 
482   if (0 != (memcmp(frameBuf, pn53x_preamble, 3))) {
483     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
484     pnd->last_error = NFC_EIO;
485     goto error;
486   }
487 
488   if ((0x01 == frameBuf[3]) && (0xff == frameBuf[4])) {
489     uint8_t errorCode = frameBuf[5];
490     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Application level error detected  (%d)", errorCode);
491     pnd->last_error = NFC_EIO;
492     goto error;
493   } else if ((0xff == frameBuf[3]) && (0xff == frameBuf[4])) {
494     // Extended frame
495     len = (frameBuf[5] << 8) + frameBuf[6];
496 
497     // Verify length checksum
498     if (((frameBuf[5] + frameBuf[6] + frameBuf[7]) % 256) != 0) {
499       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Length checksum mismatch");
500       pnd->last_error = NFC_EIO;
501       goto error;
502     }
503     TFI_idx = 8;
504   } else {
505     // Normal frame
506 
507     len = frameBuf[3];
508 
509     // Verify length checksum
510     if ((uint8_t)(frameBuf[3] + frameBuf[4])) {
511       log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
512       pnd->last_error = NFC_EIO;
513       goto error;
514     }
515     TFI_idx = 5;
516   }
517 
518   if ((len - 2) > szDataLen) {
519     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
520     pnd->last_error = NFC_EIO;
521     goto error;
522   }
523 
524   uint8_t TFI = frameBuf[TFI_idx];
525   if (TFI != 0xD5) {
526     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "TFI Mismatch");
527     pnd->last_error = NFC_EIO;
528     goto error;
529   }
530 
531   if (frameBuf[TFI_idx + 1] != CHIP_DATA(pnd)->last_command + 1) {
532     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Command Code verification failed.  (got %d,  expected %d)",
533             frameBuf[TFI_idx + 1], CHIP_DATA(pnd)->last_command + 1);
534     pnd->last_error = NFC_EIO;
535     goto error;
536   }
537 
538   uint8_t DCS = frameBuf[TFI_idx + len];
539   uint8_t btDCS = DCS;
540 
541   // Compute data checksum
542   for (size_t i = 0; i < len; i++) {
543     btDCS += frameBuf[TFI_idx + i];
544   }
545 
546   if (btDCS != 0) {
547     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Data checksum mismatch  (DCS = %02x, btDCS = %d)", DCS, btDCS);
548     pnd->last_error = NFC_EIO;
549     goto error;
550   }
551 
552   if (0x00 != frameBuf[TFI_idx + len + 1]) {
553     log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Frame postamble mismatch  (got %d)", frameBuf[frameLength - 1]);
554     pnd->last_error = NFC_EIO;
555     goto error;
556   }
557 
558   memcpy(pbtData, &frameBuf[TFI_idx + 2], len - 2);
559 
560   /* The PN53x command is done and we successfully received the reply */
561   return len - 2;
562 error:
563   return pnd->last_error;
564 }
565 
566 /**
567  * @brief Send an ACK frame to the PN532 device.
568  *
569  * @param pnd pointer on the NFC device.
570  * @return NFC_SUCCESS on success, otherwise an error code
571  */
572 int
pn532_i2c_ack(nfc_device * pnd)573 pn532_i2c_ack(nfc_device *pnd)
574 {
575   return i2c_write(DRIVER_DATA(pnd)->dev, pn53x_ack_frame, sizeof(pn53x_ack_frame));
576 }
577 
578 /**
579  * @brief Abort any pending operation
580  *
581  * @param pnd pointer on the NFC device.
582  * @return NFC_SUCCESS
583  */
584 static int
pn532_i2c_abort_command(nfc_device * pnd)585 pn532_i2c_abort_command(nfc_device *pnd)
586 {
587   if (pnd) {
588     DRIVER_DATA(pnd)->abort_flag = true;
589   }
590   return NFC_SUCCESS;
591 }
592 
593 const struct pn53x_io pn532_i2c_io = {
594   .send       = pn532_i2c_send,
595   .receive    = pn532_i2c_receive,
596 };
597 
598 const struct nfc_driver pn532_i2c_driver = {
599   .name                             = PN532_I2C_DRIVER_NAME,
600   .scan_type                        = INTRUSIVE,
601   .scan                             = pn532_i2c_scan,
602   .open                             = pn532_i2c_open,
603   .close                            = pn532_i2c_close,
604   .strerror                         = pn53x_strerror,
605 
606   .initiator_init                   = pn53x_initiator_init,
607   .initiator_init_secure_element    = pn532_initiator_init_secure_element,
608   .initiator_select_passive_target  = pn53x_initiator_select_passive_target,
609   .initiator_poll_target            = pn53x_initiator_poll_target,
610   .initiator_select_dep_target      = pn53x_initiator_select_dep_target,
611   .initiator_deselect_target        = pn53x_initiator_deselect_target,
612   .initiator_transceive_bytes       = pn53x_initiator_transceive_bytes,
613   .initiator_transceive_bits        = pn53x_initiator_transceive_bits,
614   .initiator_transceive_bytes_timed = pn53x_initiator_transceive_bytes_timed,
615   .initiator_transceive_bits_timed  = pn53x_initiator_transceive_bits_timed,
616   .initiator_target_is_present      = pn53x_initiator_target_is_present,
617 
618   .target_init           = pn53x_target_init,
619   .target_send_bytes     = pn53x_target_send_bytes,
620   .target_receive_bytes  = pn53x_target_receive_bytes,
621   .target_send_bits      = pn53x_target_send_bits,
622   .target_receive_bits   = pn53x_target_receive_bits,
623 
624   .device_set_property_bool     = pn53x_set_property_bool,
625   .device_set_property_int      = pn53x_set_property_int,
626   .get_supported_modulation     = pn53x_get_supported_modulation,
627   .get_supported_baud_rate      = pn53x_get_supported_baud_rate,
628   .device_get_information_about = pn53x_get_information_about,
629 
630   .abort_command  = pn532_i2c_abort_command,
631   .idle           = pn53x_idle,
632   .powerdown      = pn53x_PowerDown,
633 };
634 
635