cryptnox-sdk-esp32 1.0.0
ESP32 SDK for Cryptnox Hardware Wallet
Loading...
Searching...
No Matches
PN532 NFC driver

Low-level PN532 driver (SPI + I²C, ESP-IDF). More...

Classes

struct  pn532_config_t
 Compile-time configuration passed to pn532_init. More...
struct  pn532_t
 Opaque-like runtime state for a single PN532 instance. More...

Macros

#define PN532_MIFARE_ISO14443A   (0x00U)
 Baud-rate selector for ISO 14443-A (Mifare) cards passed to pn532_read_passive_target_id.
#define PN532_MAX_APDU_LEN   (252U)
 Maximum APDU payload length accepted by pn532_send_apdu.
#define PN532_I2C_ADDRESS   (0x24U)
 7-bit I²C slave address of the PN532 (fixed in hardware).

Enumerations

enum  pn532_transport_t { PN532_TRANSPORT_SPI , PN532_TRANSPORT_I2C }
 Physical bus used to communicate with the PN532. More...

Functions

esp_err_t pn532_init (pn532_t *dev, const pn532_config_t *config)
 Initialise the PN532 and bring it to a ready state.
uint32_t pn532_get_firmware_version (pn532_t *dev)
 Query the PN532 firmware version.
bool pn532_sam_config (pn532_t *dev)
 Configure the PN532's Security Access Module (SAM).
uint32_t pn532_read_passive_target_id (pn532_t *dev, uint8_t cardbaudrate)
 Scan for a passive ISO 14443-A card and return its UID.
bool pn532_send_apdu (pn532_t *dev, const uint8_t *apdu, uint8_t apdu_len, uint8_t *response, uint16_t *response_len)
 Exchange a single ISO-DEP APDU with the currently selected card.
bool pn532_release_target (pn532_t *dev)
 Release the currently selected NFC target.

Detailed Description

Low-level PN532 driver (SPI + I²C, ESP-IDF).

Macro Definition Documentation

◆ PN532_I2C_ADDRESS

#define PN532_I2C_ADDRESS   (0x24U)

7-bit I²C slave address of the PN532 (fixed in hardware).

Definition at line 63 of file pn532.h.

Referenced by pn532_init_i2c().

◆ PN532_MAX_APDU_LEN

#define PN532_MAX_APDU_LEN   (252U)

Maximum APDU payload length accepted by pn532_send_apdu.

Constrained so that the PN532 InDataExchange frame LEN field (8-bit) never overflows: cmd_total_len = apdu_len + 2 ≤ 254, frame_len = 255.

Definition at line 60 of file pn532.h.

Referenced by pn532_send_apdu().

◆ PN532_MIFARE_ISO14443A

#define PN532_MIFARE_ISO14443A   (0x00U)

Baud-rate selector for ISO 14443-A (Mifare) cards passed to pn532_read_passive_target_id.

Definition at line 54 of file pn532.h.

Referenced by PN532Adapter::inListPassiveTarget(), and Pn532NfcTransport::inListPassiveTarget().

Enumeration Type Documentation

◆ pn532_transport_t

Physical bus used to communicate with the PN532.

Value Bus Typical use
PN532_TRANSPORT_SPI SPI ESP32-S3 dev kit + Keyestudio breakout
PN532_TRANSPORT_I2C I²C Cheap Yellow Display (CN1 connector)
Enumerator
PN532_TRANSPORT_SPI 

SPI master via ESP-IDF spi_master driver.

PN532_TRANSPORT_I2C 

I²C master via ESP-IDF v5.x i2c_master driver.

Definition at line 76 of file pn532.h.

Function Documentation

◆ pn532_get_firmware_version()

uint32_t pn532_get_firmware_version ( pn532_t * dev)

Query the PN532 firmware version.

Sends the GetFirmwareVersion command (0x02) and reads the response. Also serves as a FIFO-drain step after init to prevent stale bytes from confusing subsequent command sequences.

Parameters
[in]devInitialised device handle.
Returns
Packed 32-bit version word: (IC << 24) | (Ver << 16) | (Rev << 8) | Support, or 0 on communication failure.
See also
pn532_init

Definition at line 718 of file pn532.c.

References pn532_buffer_equal(), PN532_BYTE_SHIFT_BITS, PN532_CMD_TIMEOUT_MS, PN532_FIRMWARE_CMD_LEN, PN532_FIRMWARE_HDR_LEN, PN532_FIRMWARE_RESP_LEN, PN532_FIRMWAREVERSION, PN532_FW_IC_OFFSET, PN532_FW_REV_OFFSET, PN532_FW_SUPPORT_OFFSET, PN532_FW_VER_OFFSET, PN532_LOG_TAG, pn532_response_fw, read_data(), and send_command_check_ack().

Referenced by pn532_init(), PN532Adapter::printFirmwareVersion(), and Pn532NfcTransport::printFirmwareVersion().

◆ pn532_init()

esp_err_t pn532_init ( pn532_t * dev,
const pn532_config_t * config )

Initialise the PN532 and bring it to a ready state.

Performs the full transport-specific bring-up:

  • SPI: configures the SPI device, runs the wake-up byte sequence, sends a sacrificial pn532_sam_config (absorbs the post-power-on latency), then confirms readiness with pn532_get_firmware_version.
  • I²C: configures the I²C bus and device, sends two SAMConfig frames to recover from Soft-Power-Down if the PN532 was already powered, then confirms readiness with pn532_get_firmware_version.
Parameters
[out]devDevice state structure to populate. Must remain valid for the lifetime of all subsequent calls on this device.
[in]configTransport and pin configuration. Caller may free or reuse this after pn532_init returns.
Returns
ESP_OK on success, an esp_err_t error code otherwise.
Note
The return value of the internal firmware-version and sacrificial SAMConfig calls is intentionally ignored; they are used purely for timing and FIFO-drain purposes.
Examples
BasicUsage/main/main.cpp, Connect/main/main.cpp, Sign/main/main.cpp, UsdcSigning/main/main.cpp, and VerifyPin/main/main.cpp.

Definition at line 657 of file pn532.c.

References pn532_get_firmware_version(), pn532_init_i2c(), pn532_init_spi(), PN532_LOG_TAG, pn532_sam_config(), PN532_SYNC_DELAY_MS, PN532_TRANSPORT_I2C, pn532_config_t::transport, and pn532_t::transport.

Referenced by app_main(), and PN532Adapter::begin().

◆ pn532_read_passive_target_id()

uint32_t pn532_read_passive_target_id ( pn532_t * dev,
uint8_t cardbaudrate )

Scan for a passive ISO 14443-A card and return its UID.

Sends InListPassiveTarget (0x4A) with maxTargets = 1. Blocks until a card is found or the command times out inside the PN532 firmware.

Parameters
[in]devInitialised device handle.
[in]cardbaudrateBaud-rate selector; use PN532_MIFARE_ISO14443A for standard Mifare / ISO 14443-A cards.
Returns
32-bit packed card UID (UID bytes packed MSB-first), or 0 if no card was found or a communication error occurred.
Note
UIDs longer than 4 bytes are truncated to the most-significant 32 bits.

Definition at line 775 of file pn532.c.

References PN532_BYTE_SHIFT_BITS, PN532_CMD_TIMEOUT_MS, PN532_INLISTPASSIVETARGET, PN532_PASSIVE_CMD_LEN, PN532_PASSIVE_EXPECTED_TARGETS, PN532_PASSIVE_MAX_TARGETS, PN532_PASSIVE_NUM_TARGETS_OFFSET, PN532_PASSIVE_RESP_LEN, PN532_PASSIVE_UID_DATA_OFFSET, PN532_PASSIVE_UID_LEN_OFFSET, read_data(), and send_command_check_ack().

Referenced by PN532Adapter::inListPassiveTarget(), and Pn532NfcTransport::inListPassiveTarget().

◆ pn532_release_target()

bool pn532_release_target ( pn532_t * dev)

Release the currently selected NFC target.

Sends InRelease (0x52) so the PN532 drops the logical target and is ready to list a new one. Should be called after finishing a card session before the next pn532_read_passive_target_id.

Parameters
[in]devInitialised device handle.
Returns
true if the PN532 acknowledged the release successfully, false on communication failure.

Definition at line 875 of file pn532.c.

References PN532_CMD_TIMEOUT_MS, PN532_EXCHANGE_STATUS_OFFSET, PN532_EXCHANGE_STATUS_OK, PN532_EXCHANGE_TG, PN532_INRELEASE, PN532_INRELEASE_CMD_LEN, PN532_INRELEASE_RESP_LEN, read_data(), and send_command_check_ack().

Referenced by PN532Adapter::resetReader(), and Pn532NfcTransport::resetReader().

◆ pn532_sam_config()

bool pn532_sam_config ( pn532_t * dev)

Configure the PN532's Security Access Module (SAM).

Sends the SAMConfiguration command (0x14) with Normal Mode, a 1-second timeout, and IRQ enabled. Must be called (at least once) before listing passive targets or exchanging APDUs.

pn532_init already issues this command internally; application code calls it again via CW_NfcTransport::begin() / Pn532NfcTransport::begin.

Parameters
[in]devInitialised device handle.
Returns
true on success (PN532 acknowledged and returned response code 0x15), false on timeout or unexpected response.

Definition at line 752 of file pn532.c.

References PN532_CMD_TIMEOUT_MS, PN532_SAM_CMD_LEN, PN532_SAM_NORMAL_MODE, PN532_SAM_RESP_CODE, PN532_SAM_RESP_CODE_OFFSET, PN532_SAM_RESP_LEN, PN532_SAM_TIMEOUT, PN532_SAM_USE_IRQ, PN532_SAMCONFIGURATION, read_data(), and send_command_check_ack().

Referenced by Pn532NfcTransport::begin(), and pn532_init().

◆ pn532_send_apdu()

bool pn532_send_apdu ( pn532_t * dev,
const uint8_t * apdu,
uint8_t apdu_len,
uint8_t * response,
uint16_t * response_len )

Exchange a single ISO-DEP APDU with the currently selected card.

Wraps the PN532 InDataExchange command (0x40). Handles both normal PN532 frames (LEN ≤ 255) and extended frames (LEN > 255) transparently; the frame format is detected from the response header.

Parameters
[in]devInitialised device handle.
[in]apduAPDU command bytes (must not be NULL).
[in]apdu_lenLength of apdu; must be ≤ PN532_MAX_APDU_LEN.
[out]responseCaller-allocated buffer for the card's DataOut.
[in,out]response_lenIn: capacity of response in bytes. Out: number of DataOut bytes actually written.
Returns
true on success (PN532 error byte = 0x00), false on a PN532 transport error, a card-level error, or if apdu_len exceeds PN532_MAX_APDU_LEN.
Warning
response must be large enough to hold the full DataOut; if capacity is exceeded the copy is silently truncated to *response_len.
See also
pn532_release_target

Definition at line 805 of file pn532.c.

References PN532_APDU_TIMEOUT_MS, PN532_EXCHANGE_CMD_OVERHEAD, PN532_EXCHANGE_DATA_OFFSET, PN532_EXCHANGE_FRAME_MAX, PN532_EXCHANGE_LEN_BIAS, PN532_EXCHANGE_LEN_OFFSET, PN532_EXCHANGE_STATUS_OFFSET, PN532_EXCHANGE_STATUS_OK, PN532_EXCHANGE_TG, PN532_EXT_EXCHANGE_DATA_OFFSET, PN532_EXT_EXCHANGE_ERR_OFFSET, PN532_EXT_FRAME_INDICATOR, PN532_EXT_FRAME_LENHI_OFFSET, PN532_EXT_FRAME_LENLO_OFFSET, PN532_INDATAEXCHANGE, PN532_LOG_TAG, PN532_MAX_APDU_LEN, read_data_apdu_frame(), and send_command_check_ack().

Referenced by PN532Adapter::sendAPDU(), Pn532NfcTransport::sendAPDU(), PN532Adapter::sendAPDULarge(), and Pn532NfcTransport::sendAPDULarge().