Cosmetic changes from review of last pull request

This commit is contained in:
Gregory Nutt 2016-01-17 14:52:11 -06:00
parent 81fe265502
commit 63301fe213
5 changed files with 226 additions and 135 deletions

View File

@ -59,8 +59,8 @@ config WL_NRF24L01_RXFIFO_LEN
Length of the software based fifo used to store content of
received messages.
endif
endif
endif # WL_NRF24L01_RXSUPPORT
endif # WL_NRF24L01
config WL_PN532
bool "pn532 NFC-chip support"
@ -91,10 +91,4 @@ config WL_PN532_DEBUG_RX
default n
depends on WL_PN532_DEBUG
endif
endif # WL_PN532

View File

@ -1,7 +1,7 @@
############################################################################
# drivers/wireless/Make.defs
#
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
# Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
/****************************************************************************
* include/wireless/pn532.h
*
* Copyright(C) 2012,2013,2016 Offcode Ltd. All rights reserved.
* Copyright(C) 2012, 2013, 2016 Offcode Ltd. All rights reserved.
* Authors: Janne Rosberg <janne@offcode.fi>
* Teemu Pirinen <teemu@offcode.fi>
* Juho Grundström <juho@offcode.fi>
@ -63,7 +63,7 @@
# define pn532dbg(x...)
# else
# define pn532dbg (void)
# endif
# endif
#endif
#ifdef CONFIG_WL_PN532_DEBUG_TX
@ -97,11 +97,22 @@ static void pn532_unlock(FAR struct spi_dev_s *spi);
/* Character driver methods */
static int _open(FAR struct file *filep);
static int _close(FAR struct file *filep);
static int _open(FAR struct file *filep);
static int _close(FAR struct file *filep);
static ssize_t _read(FAR struct file *, FAR char *, size_t);
static ssize_t _write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
static int _ioctl(FAR struct file *filep,int cmd,unsigned long arg);
static ssize_t _write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static int _ioctl(FAR struct file *filep,int cmd,unsigned long arg);
static uint8_t pn532_checksum(uint8_t value);
static uint8_t pn532_data_checksum(uint8_t *data, int datalen);
int pn532_read(struct pn532_dev_s *dev, uint8_t *buff, uint8_t n);
/* IRQ Handling TODO:
static int pn532_irqhandler(FAR int irq, FAR void *context, FAR void* dev);
static inline int pn532_attachirq(FAR struct pn532_dev_s *dev, xcpt_t isr);
*/
/****************************************************************************
* Private Data
@ -118,17 +129,15 @@ static const struct file_operations g_pn532fops =
#ifndef CONFIG_DISABLE_POLL
,0
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
,0
#endif
};
static uint8_t pn532_checksum(uint8_t value);
static uint8_t pn532_data_checksum(uint8_t *data, int datalen);
int pn532_read(struct pn532_dev_s *dev, uint8_t *buff, uint8_t n);
/* IRQ Handling TODO:
static int pn532_irqhandler(FAR int irq, FAR void *context, FAR void* dev);
static inline int pn532_attachirq(FAR struct pn532_dev_s *dev, xcpt_t isr);
*/
static const uint8_t pn532ack[] =
{
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00
};
/****************************************************************************
* Private Functions
@ -142,7 +151,6 @@ static void pn532_lock(FAR struct spi_dev_s *spi)
SPI_SETMODE(spi, SPIDEV_MODE0);
SPI_SETBITS(spi, -8);
SPI_SETFREQUENCY(spi, CONFIG_PN532_SPI_FREQ);
}
#endif
@ -159,6 +167,7 @@ static inline void pn532_configspi(FAR struct spi_dev_s *spi)
/* Configure SPI for the PN532 module.
* As we own the SPI bus this method is called just once.
*/
SPI_SETMODE(spi, SPIDEV_MODE0);
SPI_SETBITS(spi, -8);
SPI_SETFREQUENCY(spi, CONFIG_PN532_SPI_FREQ);
@ -223,7 +232,6 @@ static uint8_t pn532_data_checksum(uint8_t *data, int datalen)
return pn532_checksum(sum);
}
bool pn532_rx_frame_is_valid(struct pn532_frame *f, bool check_data)
{
uint8_t chk;
@ -235,7 +243,9 @@ bool pn532_rx_frame_is_valid(struct pn532_frame *f, bool check_data)
}
if (f->tfi != PN532_PN532TOHOST)
return false;
{
return false;
}
chk = pn532_checksum(f->len);
if (chk != f->lcs)
@ -247,7 +257,8 @@ bool pn532_rx_frame_is_valid(struct pn532_frame *f, bool check_data)
if (check_data)
{
chk = pn532_data_checksum(&f->tfi, f->len);
if (chk != f->data[f->len-1]) {
if (chk != f->data[f->len-1])
{
pn532dbg("Frame data checksum failed: calc=0x%X != 0x%X", chk, f->data[f->len-1]);
return false;
}
@ -272,11 +283,20 @@ static uint8_t pn532_status(struct pn532_dev_s *dev)
return rs;
}
/**
* Blocks until Data frame available from chip.
/****************************************************************************
* Name: pn532_wait_rx_ready
*
* @return 0 for OK. -ETIMEDOUT if no data available
*/
* Description:
* Blocks until Data frame available from chip.
*
* Input Parameters:
* dev
* timeout
*
* Returned Value:
* 0 for OK. -ETIMEDOUT if no data available
*
****************************************************************************/
static int pn532_wait_rx_ready(struct pn532_dev_s *dev, int timeout)
{
@ -289,7 +309,8 @@ static int pn532_wait_rx_ready(struct pn532_dev_s *dev, int timeout)
sem_timedwait(dev->sem_rx, &ts);
#endif
// TODO: Handle Exception bits 2, 3
/* TODO: Handle Exception bits 2, 3 */
while (pn532_status(dev) != PN532_SPI_READY)
{
if (--timeout == 0x00)
@ -297,22 +318,32 @@ static int pn532_wait_rx_ready(struct pn532_dev_s *dev, int timeout)
pn532dbg("wait RX timeout!\n");
return -ETIMEDOUT;
}
usleep(1000);
}
dev->state = PN532_STATE_DATA_READY;
return ret;
}
/****************************************************************************
* Name: pn532_writecommand
*
* Description:
* Helper for debug/testing
*
* Input Parameters:
*
* Returned Value:
*
****************************************************************************/
#if 0
/* Helper for debug/testing */
static void pn532_writecommand(struct pn532_dev_s *dev, uint8_t cmd)
{
char cmd_buffer[16];
struct pn532_frame *f = (struct pn532_frame *) cmd_buffer;
pn532_frame_init(f, cmd);
pn532_frame_finish(f);
@ -327,16 +358,22 @@ static void pn532_writecommand(struct pn532_dev_s *dev, uint8_t cmd)
pn532_unlock(dev->spi);
tracetx("command sent", (uint8_t *) f, FRAME_SIZE(f));
}
#endif
/**
* RAW Read data from chip.
* @note this DON'T wait if data is available!
/****************************************************************************
* Name: pn532_read
*
*/
* Description:
* RAW Read data from chip.
* NOTE: This WON'T wait if data is available!
*
* Input Parameters:
*
* Returned Value:
*
****************************************************************************/
int pn532_read(struct pn532_dev_s *dev, uint8_t *buff, uint8_t n)
{
pn532_lock(dev->spi);
@ -362,14 +399,20 @@ int pn532_read_more(struct pn532_dev_s *dev, uint8_t *buff, uint8_t n)
return n;
}
static const uint8_t pn532ack[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
/**
* @brief Read Ack responce from device
/****************************************************************************
* Name: pn532_read_ack
*
* @return 0 = NOK, 1 = OK
**/
* Description:
* Read Ack responce from device
*
* Input Parameters:
* dev
*
* Returned Value:
* 0 = NOK, 1 = OK
*
****************************************************************************/
int pn532_read_ack(struct pn532_dev_s *dev)
{
int res = 0;
@ -380,7 +423,9 @@ int pn532_read_ack(struct pn532_dev_s *dev)
if (memcmp(&ack, &pn532ack, 6) == 0x00)
{
res = 1;
} else {
}
else
{
pn532dbg("ACK NOK");
res = 0;
}
@ -388,18 +433,24 @@ int pn532_read_ack(struct pn532_dev_s *dev)
return res;
}
/****************************************************************************
* Name: pn532_write_frame
*
* Description:
* Write frame to chip. Also waits and reads ACK frame from chip.
*
* Construct frame with
* pn532_frame_init(), pn532_frame_finish()
*
* Input Parameters:
* dev - Device instance
* f - Pointer to start frame
*
* Returned Value:
* 0 for OK, negative for error
*
****************************************************************************/
/**
* @brief Write frame to chip
* also waits and reads ACK frame from chip.
*
* construct frame with
* pn532_frame_init(), pn532_frame_finish()
*
* @param dev device instance
* @param f pointer to start frame
* @return 0 for OK, negative for error
*/
int pn532_write_frame(struct pn532_dev_s *dev, struct pn532_frame *f)
{
int res = OK;
@ -414,7 +465,8 @@ int pn532_write_frame(struct pn532_dev_s *dev, struct pn532_frame *f)
pn532_unlock(dev->spi);
tracetx("WriteFrame", (uint8_t *) f, FRAME_SIZE(f));
// wait ACK frame
/* Wait ACK frame */
res = pn532_wait_rx_ready(dev, 30);
if (res == OK)
{
@ -428,16 +480,15 @@ int pn532_write_frame(struct pn532_dev_s *dev, struct pn532_frame *f)
return res;
}
int pn532_read_frame(struct pn532_dev_s *dev, struct pn532_frame *f, int max_size)
{
int res = -EIO;
/* wait for frame available */
/* Wait for frame available */
if ((res = pn532_wait_rx_ready(dev, 100)) == OK)
{
/* read header */
/* Read header */
pn532_read(dev, (uint8_t *) f, sizeof(struct pn532_frame));
if (pn532_rx_frame_is_valid(f, false))
@ -446,6 +497,7 @@ int pn532_read_frame(struct pn532_dev_s *dev, struct pn532_frame *f, int max_siz
{
return -EINVAL;
}
pn532_read_more(dev, &f->data[0], f->len);
/* TODO: optimize frame integrity check...
@ -463,7 +515,6 @@ int pn532_read_frame(struct pn532_dev_s *dev, struct pn532_frame *f, int max_siz
return res;
}
bool pn532_set_config(struct pn532_dev_s *dev, uint8_t flags)
{
char cmd_buffer[2+7];
@ -491,19 +542,22 @@ int pn532_sam_config(struct pn532_dev_s *dev, struct pn_sam_settings_s *settings
{
char cmd_buffer[4+7];
struct pn532_frame *f = (struct pn532_frame *) cmd_buffer;
int res;
pn532_frame_init(f, PN532_COMMAND_SAMCONFIGURATION);
f->data[1] = PN532_SAM_NORMAL_MODE;
f->data[2] = 0x14; /* Timeout LSB=50ms 0x14*50ms = 1sec */
f->data[3] = 0x01; /* P-70, IRQ enabled */
f->data[2] = 0x14; /* Timeout LSB=50ms 0x14*50ms = 1sec */
f->data[3] = 0x01; /* P-70, IRQ enabled */
if (settings) {
if (settings)
{
/* TODO: !!! */
}
f->len += 3;
pn532_frame_finish(f);
int res = -EIO;
res = -EIO;
if (pn532_write_frame(dev, f) == OK)
{
@ -511,14 +565,15 @@ int pn532_sam_config(struct pn532_dev_s *dev, struct pn_sam_settings_s *settings
{
tracerx("sam config response", (uint8_t *) f->data, 3);
if (f->data[0] == PN532_COMMAND_SAMCONFIGURATION + 1)
res = OK;
{
res = OK;
}
}
}
return res;
}
int pn532_get_fw_version(struct pn532_dev_s *dev,
struct pn_firmware_version *fv)
{
@ -543,6 +598,7 @@ int pn532_get_fw_version(struct pn532_dev_s *dev,
{
memcpy(fv, fw, sizeof(struct pn_firmware_version));
}
res = OK;
}
}
@ -551,8 +607,6 @@ int pn532_get_fw_version(struct pn532_dev_s *dev,
return res;
}
int pn532_write_gpio(struct pn532_dev_s *dev, uint8_t p3, uint8_t p7)
{
uint8_t cmd_buffer[3+7];
@ -571,7 +625,9 @@ int pn532_write_gpio(struct pn532_dev_s *dev, uint8_t p3, uint8_t p7)
tracetx("Resp:", cmd_buffer, 10);
pn532dbg("TFI=%x, data0=%X", f->tfi, f->data[0]);
if ((f->tfi == PN532_PN532TOHOST) && (f->data[0] == PN532_COMMAND_WRITEGPIO+1))
res = OK;
{
res = OK;
}
}
return res;
@ -610,6 +666,7 @@ uint32_t pn532_write_passive_data(struct pn532_dev_s *dev, uint8_t address,
}
}
}
return res;
}
@ -650,6 +707,7 @@ uint32_t pn532_read_passive_data(struct pn532_dev_s *dev, uint8_t address,
}
}
}
return res;
}
@ -688,7 +746,8 @@ uint32_t pn532_read_passive_target_id(struct pn532_dev_s *dev, uint8_t baudrate)
pn532dbg("idlen:0x%x ", t->nfcid_len);
/* generate 32bit cid from id (could be longer)
* HACK: Using only top 4 bytes */
* HACK: Using only top 4 bytes.
*/
for (i = 0; i < 4 /*t->nfcid_len*/; i++)
{
@ -696,6 +755,7 @@ uint32_t pn532_read_passive_target_id(struct pn532_dev_s *dev, uint8_t baudrate)
cid |= t->nfcid_data[i];
}
}
res = cid;
}
}
@ -737,18 +797,29 @@ bool pn532_set_rf_config(struct pn532_dev_s *dev, struct pn_rf_config_s *conf)
if (pn532_rx_frame_is_valid(f, true))
{
if (f->data[0] == PN532_COMMAND_RFCONFIGURATION + 1)
res = true;
{
res = true;
}
}
}
return res;
}
/****************************************************************************
* Name: pn532_attachirq
*
* Description:
* IRQ handling TODO:
*
* Input Parameters:
*
* Returned Value:
*
****************************************************************************/
#if 0
/* IRQ handling TODO: */
static inline int pn532_attachirq(FAR struct pn532_dev_s *dev, xcpt_t isr)
static inline int (FAR struct pn532_dev_s *dev, xcpt_t isr)
{
return dev->config->irqattach(dev,isr);
}
@ -821,13 +892,13 @@ static int _close(FAR struct file *filep)
#ifdef CONFIG_PM
if(dev->pm_level >= PM_SLEEP)
{
// priv->config->reset(0);
//priv->config->reset(0);
}
#endif
return OK;
}
/****************************************************************************
* Name: _read
*
@ -851,8 +922,10 @@ static ssize_t _read(FAR struct file *filep, FAR char *buffer, size_t buflen)
dev = inode->i_private;
uint32_t id = pn532_read_passive_target_id(dev, PN532_MIFARE_ISO14443A);
if (id != 0xFFFFFFFF) {
if (buffer) {
if (id != 0xFFFFFFFF)
{
if (buffer)
{
return snprintf(buffer, buflen, "0X%X", id);
}
}
@ -905,6 +978,7 @@ static int _ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (tag_data)
{
/* HACK: get rid of previous command */
if (dev->state == PN532_STATE_CMD_SENT)
{
if (pn532_wait_rx_ready(dev, 1))
@ -928,6 +1002,7 @@ static int _ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (tag_data)
{
/* HACK: get rid of previous command */
if (dev->state == PN532_STATE_CMD_SENT)
{
if (pn532_wait_rx_ready(dev, 1))
@ -1020,11 +1095,11 @@ static int _ioctl(FAR struct file *filep, int cmd, unsigned long arg)
* Register the PN532 character device as 'devpath'
*
* Input Parameters:
* devpath - The full path to the driver to register.
* E.g., "/dev/nfc0"
* spi - An instance of the SPI interface to use to communicate with
* PN532.
* config - chip config
* devpath - The full path to the driver to register.
* E.g., "/dev/nfc0"
* spi - An instance of the SPI interface to use to communicate with
* PN532.
* config - chip config
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/wireless/pn532.h
*
* Copyright(C) 2012,2013,2016 Offcode Ltd. All rights reserved.
* Copyright(C) 2012, 2013, 2016 Offcode Ltd. All rights reserved.
* Authors: Janne Rosberg <janne@offcode.fi>
* Teemu Pirinen <teemu@offcode.fi>
* Juho Grundström <juho@offcode.fi>
@ -35,35 +35,39 @@
*
****************************************************************************/
#ifndef __DRIVERS_WIRELESS_PN532_H
#define __DRIVERS_WIRELESS_PN532_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/spi/spi.h>
#include <nuttx/wqueue.h>
#include <nuttx/wireless/pn532.h>
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
#define PN532_PREAMBLE 0x00
#define PN532_STARTCODE1 0x00
#define PN532_STARTCODE2 0xFF
#define PN532_POSTAMBLE 0x00
#define PN532_PREAMBLE 0x00
#define PN532_STARTCODE1 0x00
#define PN532_STARTCODE2 0xFF
#define PN532_POSTAMBLE 0x00
#define PN532_SOF 0xFF00
#define PN532_SOF 0xFF00
#define PN532_HOSTTOPN532 0xD4
#define PN532_PN532TOHOST 0xD5
#define PN532_HOSTTOPN532 0xD4
#define PN532_PN532TOHOST 0xD5
#define PN532_SPI_STATREAD 0x02
#define PN532_SPI_DATAWRITE 0x01
#define PN532_SPI_DATAREAD 0x03
#define PN532_SPI_READY 0x01
#define PN532_SPI_STATREAD 0x02
#define PN532_SPI_DATAWRITE 0x01
#define PN532_SPI_DATAREAD 0x03
#define PN532_SPI_READY 0x01
/* PN532 Commands */
@ -102,38 +106,49 @@
#define PN532_WAKEUP 0x55
#define PN532_SAM_NORMAL_MODE 0x01
#define PN532_SAM_VIRTUAL_CARD 0x02
#define PN532_SAM_WIRED_CARD 0x03
#define PN532_SAM_DUAL_CARD 0x04
#define PN532_SAM_NORMAL_MODE 0x01
#define PN532_SAM_VIRTUAL_CARD 0x02
#define PN532_SAM_WIRED_CARD 0x03
#define PN532_SAM_DUAL_CARD 0x04
#ifndef CONFIG_PN532_SPI_FREQ
# define CONFIG_PN532_SPI_FREQ (5000000)
#endif
struct pn532_frame {
/****************************************************************************
* Public Types
****************************************************************************/
struct pn532_frame
{
uint8_t preamble; /* 0x00 */
uint16_t start_code; /* 0x00FF (BE) -> 0xFF00 (LE) */
uint16_t start_code; /* 0x00FF (BE) -> 0xFF00 (LE) */
uint8_t len; /* 1 byte indicating the number of bytes in
* the data field */
uint8_t lcs; /* 1 Packet Length Checksum LCS byte that satisfies
* the relation: Lower byte of [LEN + LCS] = 00h */
uint8_t tfi; /* Frame idenfifier 0xD4, 0xD5 */
uint8_t tfi; /* Frame idenfifier 0xD4, 0xD5 */
uint8_t data[]; /* LEN-1 bytes of Packet Data Information.
* The first byte PD0 is the Command Code */
} packed_struct;
struct pn_poll_response {
struct pn_poll_response
{
uint8_t nbtg;
uint8_t tg;
uint8_t target_data[];
} packed_struct;
struct pn_target_type_a {
struct pn_target_type_a
{
uint16_t sens_res;
uint8_t sel_res;
uint8_t nfcid_len;
uint8_t nfcid_data[];
} packed_struct;
struct pn_firmware_version {
struct pn_firmware_version
{
uint8_t ic;
uint8_t ver;
uint8_t rev;
@ -142,14 +157,15 @@ struct pn_firmware_version {
struct pn532_dev_s
{
uint8_t state;
uint8_t state;
FAR struct spi_dev_s *spi; /* SPI interface */
FAR struct pn532_config_s *config; /* Board configuration data */
};
#ifndef CONFIG_PN532_SPI_FREQ
#define CONFIG_PN532_SPI_FREQ (5000000)
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
bool pn532_set_config(struct pn532_dev_s *dev, uint8_t flags);
#endif /* __DRIVERS_WIRELESS_PN532_H */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* include/wireless/nfc.h
* include/wireless/pn532.h
*
* Copyright(C) 2012,2013,2016 Offcode Ltd. All rights reserved.
* Copyright(C) 2012, 2013, 2016 Offcode Ltd. All rights reserved.
* Authors: Janne Rosberg <janne@offcode.fi>
* Teemu Pirinen <teemu@offcode.fi>
* Juho Grundström <juho@offcode.fi>
@ -52,7 +52,7 @@
* Pre-Processor Definitions
****************************************************************************/
#define PN532_MIFARE_ISO14443A (0x00)
#define PN532_MIFARE_ISO14443A (0x00)
/* IOCTL Commands ***********************************************************/
@ -66,6 +66,10 @@
#define PN532IOC_READ_TAG_DATA _WLIOC_USER(0x0008)
#define PN532IOC_WRITE_TAG_DATA _WLIOC_USER(0x0009)
/****************************************************************************
* Public Types
****************************************************************************/
enum pn532_state_E
{
PN532_STATE_NOT_INIT,
@ -74,23 +78,19 @@ enum pn532_state_E
PN532_STATE_DATA_READY,
};
/****************************************************************************
* Global Data
****************************************************************************/
struct pn532_dev_s;
struct pn532_config_s
{
int (*reset)(uint8_t enable);
/* external CS, if NULL then SPIDEV_WIRELESS CS is used */
/* External CS, if NULL then SPIDEV_WIRELESS CS is used */
int (*select)(struct pn532_dev_s *dev, bool sel);
int (*irqattach)(void* dev, xcpt_t isr);
};
enum PN_SAM_MODE {
enum PN_SAM_MODE
{
PN_SAM_NORMAL_MODE = 0x01,
PN_SAM_VIRTUAL_CARD,
PN_SAM_WIRED_CARD,
@ -104,7 +104,8 @@ struct pn_sam_settings_s
uint8_t irq_en; /* If 1 - enable P-70, IRQ */
};
enum PN_RF_CONFIG_ITEM {
enum PN_RF_CONFIG_ITEM
{
PN_RF_CONFIG_RF_FIELD = 0x01,
PN_RF_CONFIG_VARIOUS_TIMINGS = 0x02,
@ -114,9 +115,9 @@ enum PN_RF_CONFIG_ITEM {
struct pn_rf_config_s
{
uint8_t cfg_item; /* Item */
uint8_t data_size; /* number of config items */
uint8_t config[11]; /* Item config data */
uint8_t cfg_item; /* Item */
uint8_t data_size; /* number of config items */
uint8_t config[11]; /* Item config data */
};
struct pn_mifare_tag_data_s
@ -125,9 +126,14 @@ struct pn_mifare_tag_data_s
uint8_t address;
};
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C" {
extern "C"
{
#else
#define EXTERN extern
#endif
@ -148,8 +154,8 @@ extern "C" {
*
****************************************************************************/
EXTERN int pn532_register(FAR const char *devpath, FAR struct spi_dev_s *spi,
FAR struct pn532_config_s *config);
int pn532_register(FAR const char *devpath, FAR struct spi_dev_s *spi,
FAR struct pn532_config_s *config);
#undef EXTERN
#ifdef __cplusplus