Type-A Anticollision with RUL SDK Transparent Mode API
This is an example app to resolve the UIDs of 2 Type-A cards in the field. More than 2 cards are not supported.
Anticollision loop flow:
Field ON → WUPA → CL-1(collision) → SELECT card A → HALT A
→ REQA → CL-1(no collision) → SELECT card B → HALT B
→ REQA → timeout (no cards) → Field OFF → Field ON → WUPA → ...
Notes:
HALT after SELECT (ptx_Example_TransparentMode_Halt) — sends [0x50][0x00] with CRC to the selected card. Per ISO 14443-3A the card enters HALT state and sends no response (timeout is normal). The card will now ignore the next REQA.
REQA instead of WUPA for subsequent passes (sUsedWUPA flag) — after field-on, the first activation uses WUPA (0x52) to wake all cards including halted. Every subsequent activation in the same field-on cycle uses REQA (0x26), which only wakes non-halted cards. This is what makes halted cards stay silent.
No field reset between cards — after HALT the state goes straight back to DemoAppState_WUPA (which now sends REQA). The field stays on. When REQA gets no response (all cards halted), the existing timeout path sets DemoAppState_SetStateOff, which turns the field off and back on, resets sUsedWUPA = false, and the full cycle restarts with WUPA.
Source file:
/*c
---------------------------------------------------------------
SPDX-License-Identifier: BSD-3-Clause
Copyright (c) 2025, Renesas Electronics Corporation and/or its affiliates
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of Renesas nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Renesas "AS IS" AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL RENESAS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------
Project : PTX2xxR/W
Module : SDK Example (Transparent Mode)
File : EXAMPLES/ptx_Example_TransparentMode/ptx_Example_TransparentMode.c
Description : This application example demonstrates how to use the Transparent-Mode API.
It performs standard activation procedures for each technology type (A, B, F, V)
*/
/*
* ####################################################################################################################
* INCLUDES
* ####################################################################################################################
*/
#include "ptx_ExampleApplication.h"
#include "ptx_Status.h"
#include "ptx_RUL.h"
#include "ptx_Utils_AppParameters.h"
#include "ptx_Utils_Print.h"
#include "ptx_Utils_VersionInfo.h"
#include "ptx_Utils_CardInfo.h"
#include "ptx_TransparentMode.h"
#if defined(PTX_APP_DIVERSITY_WIN)
#include <wincon.h>
#endif
#if defined(PTX_APP_DIVERSITY_LINUX)
#include <stdlib.h>
#include <signal.h>
#endif
#if defined(PTX_ENABLE_BOARD_EVK)
#include "ptx_EVK_Peripherals.h"
#endif
#include <stdbool.h>
/*
* ####################################################################################################################
* DEFINES / TYPES / CONSTANTS
* ####################################################################################################################
*/
/* Device Name used during RUL-initialization. Only used for Desktop-OS versions like Windows or Linux. Can be omitted for MCU platforms. */
static const char *EXAMPLE_DEVICE_NAME = "COM4";
/* Device Name Length. See above. */
static const uint16_t EXAMPLE_DEVICE_NAME_LEN = 4u;
#if defined(PTX_ENABLE_SPI)
/* Interface Type for the connection to the PTX2xxX chips. */
static const ptx_HAL_Interface_Type_t EXAMPLE_INTERFACE_TYPE = HAL_Interface_Type_SPI;
#elif PTX_ENABLE_I2C
/* Interface Type for the connection to the PTX2xxX chips. */
static const ptx_HAL_Interface_Type_t EXAMPLE_INTERFACE_TYPE = HAL_Interface_Type_I2C;
#elif PTX_ENABLE_UART
/* Interface Type for the connection to the PTX2xxX chips. */
static const ptx_HAL_Interface_Type_t EXAMPLE_INTERFACE_TYPE = HAL_Interface_Type_UART;
#else
/* Interface Type for the connection to the PTX2xxX chips. */
static const ptx_HAL_Interface_Type_t EXAMPLE_INTERFACE_TYPE = HAL_Interface_Type_SPI;
#endif
#if defined(PTX_ENABLE_BOARD_EVK)
/* Interface Driver Port implementation type for the connection to the PTX2xxX chips. */
static const ptx_HAL_DRV_Interface_Port_Type_t EXAMPLE_INTERFACE_PORT_TYPE = HAL_DRV_Interface_Port_Type_Evk;
#else
/* Interface Driver Port implementation type for the connection to the PTX2xxX chips. */
static const ptx_HAL_DRV_Interface_Port_Type_t EXAMPLE_INTERFACE_PORT_TYPE = HAL_DRV_Interface_Port_Type_Default;
#endif
/* Interface Driver Port implementation ID for the connection to the PTX2xxX chips. */
static const uint8_t EXAMPLE_INTERFACE_PORT_ID = 0;
/* Requested number of hardware timer instances. */
static const uint8_t EXAMPLE_NUMBER_OF_TIMERS = 2;
/* Application specific Exit-Flag (controllable by the user on Windows-/Linux-platforms via Ctrl-C). */
static volatile int gExit = 0;
#if defined(PTX_ENABLE_BOARD_EVK)
/* Corresponds to the voltage on the DC/DC converter on the PTX2xxW Boards. E.g. a value of 330 corresponds to 3.3V. */
static const uint16_t EVK_DEFAULT_VOLTAGE = 500u;
#endif
/* Waiting time after a loop of the example. */
static const uint32_t PTX_EXAMPLE_TRANSPARENT_MODE_LOOP_SLEEP_MS = 500u;
/* Maximum RF timeout. */
static const uint32_t PTX_EXAMPLE_TRANSPARENT_MODE_RF_TIMEOUT_MS = 100u;
/* Sleep time after turning field on (can be adjusted - depending on used RF-technology after field on). */
static const uint16_t PTX_EXAMPLE_TRANSPARENT_MODE_FIELD_ON_SLEEP_MS = 50u;
/* Required minimum sleep time after turning field off. */
static const uint16_t PTX_EXAMPLE_TRANSPARENT_MODE_FIELD_OFF_SLEEP_MS = 10u;
/* Maximum buffer size. */
#define PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE 255u
/* ISO 14443-3A Protocol Constants */
#define ISO14443A_CMD_WUPA 0x52U /* Wake-Up All command */
#define ISO14443A_CMD_REQA 0x26U /* Request Command type A */
#define ISO14443A_CMD_SEL_CL1 0x93U /* SELECT command for Cascade Level 1 */
#define ISO14443A_CMD_SEL_CL2 0x95U /* SELECT command for Cascade Level 2 */
#define ISO14443A_CASCADE_TAG 0x88U /* Cascade Tag (UID continues in next level) */
#define ISO14443A_CMD_SELECT_BYTE 0x70U /* PAD0/NVB byte value for SELECT command */
#define ISO14443A_CMD_HALT 0x50U /* HALT/Deselect command (MSB) */
#define ISO14443A_CMD_HALT_LSB 0x00U /* HALT/Deselect command (LSB) */
#define ISO14443A_SAK_UID_NOT_COMPLETE 0x04U /* SAK bit 2: UID not complete flag */
#define ISO14443A_NVB_BITS_MASK 0x07U /* NVB lower nibble for partial bits (0-7) */
/* Fully-reconstructed 4-byte UID + BCC for the most recent cascade level (CL-1 or CL-2). */
static uint8_t sUIDWithXOR[5] = {0};
/* Accumulated final UID bytes across all cascade levels (up to 10 bytes). */
static uint8_t sFullUID[10] = {0};
static uint8_t sFullUIDLen = 0U;
/* SEL byte used for the SELECT command: 0x93 after CL-1, 0x95 after CL-2. */
static uint8_t sSelectSelByte = 0x93U;
/* true = field just turned on, send WUPA (0x52) to wake all PICCs incl. halted.
* false = at least one card already handled this cycle, send REQA (0x26) so
* halted PICCs stay silent and a new card can be selected. */
static bool sUsedWUPA = false;
/*
* ####################################################################################################################
* INTERNAL FUNCTIONS DECLARATIONS / HELPERS
* ####################################################################################################################
*/
static ptx_Status_t ptx_RunDemoApplication(ptx_RUL_t *rul);
static ptx_Status_t ptx_Example_TransparentMode_SetStateOn(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState);
static ptx_Status_t ptx_Example_TransparentMode_SetStateOff(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState);
static ptx_Status_t ptx_Example_TransparentMode_WUPA(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams);
static ptx_Status_t ptx_Example_TransparentMode_CL1(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams);
static ptx_Status_t ptx_Example_TransparentMode_Select(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams);
static ptx_Status_t ptx_Example_TransparentMode_Halt(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams);
static ptx_Status_t ptx_Example_TransparentMode_CL2(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams);
static ptx_Status_t ptx_RunAntiCollision(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams, uint8_t selByte);
static ptx_Status_t ptx_ProcessState_SystemError(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_RUL_Status_Params_t *statusInfoParam);
static ptx_Status_t ptx_ProcessState_RestartSystem(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState);
static uint8_t buildNvbByte(uint8_t completeBytesInFrame, uint8_t bitsKnown);
#if PTX_APP_DIVERSITY_WIN
/*
* Add a platform dependent handler for a console event.
* It is used to catch the user key press application-quit event Ctrl-C.
*/
BOOL WINAPI ConsoleHandler(DWORD dwType);
BOOL WINAPI ConsoleHandler(DWORD dwType)
{
if (dwType == CTRL_C_EVENT)
{
ptx_Utils_Print("Application interrupted by user\n");
gExit = 1;
}
return TRUE;
}
#endif
#if defined(PTX_APP_DIVERSITY_LINUX)
/*
* Add a platform dependent handler for a console event.
* It is used to catch the user key press application-quit event Ctrl-C.
*/
static void handler(int sig)
{
if (sig == SIGINT)
{
ptx_Utils_Print("Application interrupted by user\n");
gExit = 1;
}
else
{
exit(sig);
}
}
#endif
/*
* ####################################################################################################################
* APPLICATION ENTRY / INTERNAL FUNCTIONS / CALLBACKS
* ####################################################################################################################
*/
#if defined(PTX_PLATFORM_MCU)
int ptx_App_Entry(void)
#else
int main(int argc, char **argv)
#endif
{
/*
* Define platform dependent console handler function to handle application quit event: key press Ctrl-C.
*/
#if defined(PTX_APP_DIVERSITY_WIN)
SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE);
#elif defined(PTX_APP_DIVERSITY_LINUX)
signal(SIGINT, handler);
#endif
ptx_Status_t status;
/* Demo Application Parameters */
ptx_Utils_AppParams_t app_params;
/* Main API component */
ptx_RUL_t rul = {0};
ptx_RUL_InitParams_t rul_init_params = {0};
/* Other components */
ptx_RUL_DeactivateParams_t deact_params = {0};
ptx_Utils_Print("***********************************************************\n");
ptx_Utils_Print("**** Transparent Mode Example %s ****\n", PTX_DEMO_VERSION);
ptx_Utils_Print("***********************************************************\n");
/* Initialize demo application parameters with default values. */
(void)memcpy(&app_params.DeviceName[0], EXAMPLE_DEVICE_NAME, EXAMPLE_DEVICE_NAME_LEN);
app_params.DeviceNameLen = EXAMPLE_DEVICE_NAME_LEN;
#if defined(PTX_PLATFORM_OS)
/* Load application parameters from command-line (if provided), otherwise use default values. */
ptx_Utils_AppParameters_Load((uint32_t)argc, argv, &app_params);
#endif
/* Initialize Main RUL API Component.
*
* Note: The used Host-Interface i.e. the HAL-component and the Logging-component (if used) get selected via the Build-process (see User Manual)
* and get also initialized during the next call to "ptx_RUL_Init".
*/
rul_init_params.InterfaceInitParams.InterfaceName = (uint8_t*)&app_params.DeviceName[0];
rul_init_params.InterfaceInitParams.InterfaceNameLen = app_params.DeviceNameLen;
rul_init_params.InterfaceInitParams.InterfaceType = EXAMPLE_INTERFACE_TYPE;
rul_init_params.InterfaceInitParams.InterfacePortType = EXAMPLE_INTERFACE_PORT_TYPE;
rul_init_params.InterfaceInitParams.InterfacePortID = EXAMPLE_INTERFACE_PORT_ID;
rul_init_params.InterfaceInitParams.NumberOfTimers = EXAMPLE_NUMBER_OF_TIMERS;
status = ptx_RUL_Init(&rul, &rul_init_params);
if (PTX_STATUS_SUCCESS == status)
{
ptx_Utils_Print("RUL SW-Stack successfully initialized!\n");
#if defined(PTX_ENABLE_BOARD_EVK)
/*
* Allocate the RUL Peripherals data structure.
* This component is needed for operation of the PTX2xxR/W EVK.
* It controls additional circuitry on the PCB like a DC/DC converter,
* an (optional) on-PCB temperature sensor as well as (optional) power sensors.
*/
ptx_EVK_Peripherals_t peripherals;
memset(&peripherals, 0, sizeof(ptx_EVK_Peripherals_t));
if (PTX_STATUS_SUCCESS == status)
{
/* Initialize the RUL Peripherals component. */
status = ptx_EVK_Peripherals_Init(&peripherals);
}
if (PTX_STATUS_SUCCESS == status)
{
/* Set the DC/DC converter to the default voltage of 5.0 Volts. */
status = ptx_EVK_Peripherals_DCDC_SetVoltage(&peripherals.Dcdc, EVK_DEFAULT_VOLTAGE);
}
#endif
/* Initialize the Hardware by
* - downloading the Firmware-image and starting execution,
* - initializing the hardware / firmware,
* - downloading the default RF-configuration,
* - changing into READY-state.
*/
status = ptx_RUL_InitHardware(&rul);
if (PTX_STATUS_SUCCESS == status)
{
ptx_Utils_Print("PTX Hardware-/-Chip successfully initialized!\n");
/* Print HW-Info and all available Stack-revisions */
status = ptx_Utils_VersionInfo_Print_Revision(&rul);
if (PTX_STATUS_SUCCESS == status)
{
status = ptx_RunDemoApplication(&rul);
ptx_Utils_Print("Demo Application completed with Status %04X!\n", status);
}
else
{
ptx_Utils_Print("Print Status/Revision information failed with Error-Status %04X!\n", status);
}
}
else
{
ptx_Utils_Print("Hardware initialization failed with Error-Status %04X!\n", status);
}
}
else
{
ptx_Utils_Print("RUL-Stack initialization failed with Error-Status %04X!\n", status);
}
/* Switch RF-Field off (independent of previous state) */
deact_params.Type = ptx_RUL_DeactivateType_Generic;
deact_params.State = ptx_RUL_DeactivateState_Idle;
(void)ptx_RUL_Deactivate(&rul, &deact_params);
/* De-initialize the RUL API Component (independent of previous state) */
status = ptx_RUL_DeInit(&rul);
if (PTX_STATUS_SUCCESS == status)
{
ptx_Utils_Print("RUL-Stack successfully de-initialized!\n");
}
else
{
ptx_Utils_Print("RUL-Stack de-initialization failed with Error-Status %04X!\n", status);
}
#if defined(PTX_PLATFORM_OS)
(void)argc;
(void)argv;
#endif
return 0;
}
static ptx_Status_t ptx_RunDemoApplication(ptx_RUL_t *rul)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
ptx_DemoAppState_t demo_state = DemoAppState_SetStateOn;
ptx_RUL_Status_Params_t status_info = {0};
/* Transparent Mode Add-on API component */
ptx_TransparentMode_t tm = {0};
ptx_TransparentMode_InitParams_t init_params = {0};
ptx_TransparentMode_RFParams_t rfParams = {0};
ptx_TransparentMode_ExchangeParams_t exchangeParams = {0};
uint8_t rx[PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE];
uint8_t tx[PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE];
exchangeParams.TxData = tx;
exchangeParams.RxData = rx;
rfParams.Tech = ptx_TransparentMode_RF_Tech_A;
rfParams.RxRate = ptx_TransparentMode_RF_Bitrate_106;
rfParams.TxRate = ptx_TransparentMode_RF_Bitrate_106;
rfParams.ResLimit = 1U;
if (PTX_COMP_CHECK(rul, Comp_RUL))
{
init_params.Rul = rul;
init_params.UseDefaultConfigForFieldOffState = 0;
status = ptx_TransparentMode_Open(&tm, &init_params);
ptx_Utils_Print("Opening Transparent Mode completed with Status %04X!\n", status);
if (PTX_STATUS_SUCCESS == status)
{
do
{
/* Check regularly for System-state/-health (e.g. temperature/over-current errors etc.) */
status_info.Type = ptx_RUL_StatusType_System;
status = ptx_RUL_GetStatusInfo(rul, &status_info);
if (PTX_STATUS_SUCCESS == status)
{
if (ptx_RUL_StatusInfoSystem_OK != status_info.Info.System)
{
demo_state = DemoAppState_SystemError;
}
}
if (PTX_STATUS_SUCCESS == status)
{
switch (demo_state)
{
case DemoAppState_SetStateOn:
{
status = ptx_Example_TransparentMode_SetStateOn(&tm, &demo_state);
ptx_Utils_Print("Turning Field ON completed with Status %04X!\n", status);
(void)ptx_RUL_Sleep(rul, PTX_EXAMPLE_TRANSPARENT_MODE_FIELD_ON_SLEEP_MS);
break;
}
case DemoAppState_WUPA:
{
status = ptx_Example_TransparentMode_WUPA(&tm, &demo_state, &rfParams, &exchangeParams);
ptx_Utils_Print("WUPA/REQA completed with Status %04X!\n", status);
break;
}
case DemoAppState_CL1:
{
status = ptx_Example_TransparentMode_CL1(&tm, &demo_state, &rfParams, &exchangeParams);
ptx_Utils_Print("CL-1 completed with Status %04X!\n", status);
break;
}
case DemoAppState_Select:
{
status = ptx_Example_TransparentMode_Select(&tm, &demo_state, &rfParams, &exchangeParams);
ptx_Utils_Print("Select completed with Status %04X!\n", status);
break;
}
case DemoAppState_CL2:
{
status = ptx_Example_TransparentMode_CL2(&tm, &demo_state, &rfParams, &exchangeParams);
ptx_Utils_Print("CL-2 completed with Status %04X!\n", status);
break;
}
case DemoAppState_Halt:
{
status = ptx_Example_TransparentMode_Halt(&tm, &demo_state, &rfParams, &exchangeParams);
ptx_Utils_Print("Halt completed with Status %04X!\n", status);
break;
}
case DemoAppState_SetStateOff:
{
status = ptx_Example_TransparentMode_SetStateOff(&tm, &demo_state);
ptx_Utils_Print("Turning Field OFF completed with Status %04X!\n", status);
(void)ptx_RUL_Sleep(rul, PTX_EXAMPLE_TRANSPARENT_MODE_FIELD_OFF_SLEEP_MS);
ptx_Utils_Print("Sequence over, waiting %lu ms.\n", PTX_EXAMPLE_TRANSPARENT_MODE_LOOP_SLEEP_MS);
(void)ptx_RUL_Sleep(rul, PTX_EXAMPLE_TRANSPARENT_MODE_LOOP_SLEEP_MS);
break;
}
case DemoAppState_SystemError:
{
status = ptx_ProcessState_SystemError(&tm, &demo_state, &status_info);
break;
}
case DemoAppState_Exit:
{
/* Nothing to do here */
break;
}
default:
{
ptx_Utils_Print("Invalid Application-State detected!\n");
demo_state = DemoAppState_Exit;
break;
}
}
/* RF-Errors can happen in this demo application (e.g. desired card not present / used) - expected, just reset status */
status = ptx_Utils_Check_Rf_Error(status);
}
/*
* NOTE: This required for to this demo application only! Please use your own
* error handling for your application!
*
* In case of an PTX_STATUS_E_NSC_SYSTEM error, we can safely reset the status
* and set it to PTX_STATUS_SUCCESS. We also need to set the demo_state to the
* DemoAppState_SystemError to check for the error during the next iteration of
* the program loop.
*/
if (PTX_STATUS_E_NSC_SYSTEM == status)
{
demo_state = DemoAppState_SystemError;
status = PTX_STATUS_SUCCESS;
}
}
while ((PTX_STATUS_SUCCESS == status) && (DemoAppState_Exit != demo_state) && (0 == gExit));
(void)ptx_TransparentMode_Close(&tm);
}
ptx_Utils_Print("Exiting Demo-Application...\n");
}
return status;
}
static ptx_Status_t ptx_Example_TransparentMode_SetStateOn(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
if ((NULL != tm) && (NULL != appState))
{
status = ptx_TransparentMode_SetState(tm, ptx_TransparentMode_State_RF_On);
sUsedWUPA = false;
*appState = DemoAppState_WUPA;
}
return status;
}
static ptx_Status_t ptx_Example_TransparentMode_SetStateOff(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
if ((NULL != tm) && (NULL != appState))
{
status = ptx_TransparentMode_SetState(tm, ptx_TransparentMode_State_RF_Off);
*appState = DemoAppState_SetStateOn;
}
return status;
}
static ptx_Status_t ptx_Example_TransparentMode_WUPA(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
/* Prepare RFParams and exchange parameters required for a successful data exchange. */
rfParams->Flags = (uint8_t)(0x00 | PTX_TRANSPARENT_MODE_FLAGS_TX_PARITY | PTX_TRANSPARENT_MODE_FLAGS_RX_PARITY);
rfParams->RxBitOffset = 0;
exchangeParams->TxLength = PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE;
memset(exchangeParams->TxData, 0, sizeof(uint8_t)*exchangeParams->TxLength);
exchangeParams->NrTxBits = 0;
exchangeParams->RxLength = PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE;
memset(exchangeParams->RxData, 0, sizeof(uint8_t)*exchangeParams->RxLength);
exchangeParams->NrResidualRxBits = 0;
exchangeParams->TimeoutMS = PTX_EXAMPLE_TRANSPARENT_MODE_RF_TIMEOUT_MS;
/* First activation after field-on: WUPA wakes all PICCs including halted ones.
* Subsequent activations: REQA so already-halted PICCs stay silent. */
bool useWUPA = !sUsedWUPA;
sUsedWUPA = true;
exchangeParams->TxData[0] = useWUPA ? ISO14443A_CMD_WUPA : ISO14443A_CMD_REQA;
exchangeParams->TxLength = 1;
exchangeParams->NrTxBits = 7;
ptx_Utils_Print("%s: ", useWUPA ? "WUP-A" : "REQ-A");
ptx_Utils_Print_Buffer(&exchangeParams->TxData[0], (uint16_t)exchangeParams->TxLength, 1U, 0);
status = ptx_TransparentMode_Exchange(tm, rfParams, exchangeParams);
if (PTX_STATUS_SUCCESS == status)
{
/* A clean ATQA means exactly one PICC responded (no bit collision). Proceed to
* anti-collision regardless of byte count — CL-1 will validate the card is there. */
ptx_Utils_Print("ATQA (len=%lu): ", exchangeParams->RxLength);
ptx_Utils_Print_Buffer(&exchangeParams->RxData[0], (uint16_t)exchangeParams->RxLength, 1U, 0);
*appState = DemoAppState_CL1;
}
else if (PTX_STATUS_E_NSC_COLLISION == status || PTX_STATUS_E_NSC_RESIDUAL_BITS == status)
{
/* Multiple PICCs responded simultaneously — proceed to anti-collision to resolve. */
ptx_Utils_Print("ATQA collision (status=%04X), proceeding to CL-1\n", status);
status = PTX_STATUS_SUCCESS;
*appState = DemoAppState_CL1;
}
else
{
/* Timeout = no more cards in the field; any other error = hard fault. */
ptx_Utils_Print("WUPA/REQA exchange failed with status %04X\n", status);
*appState = DemoAppState_SetStateOff;
}
return status;
}
/*
* Build the NVB (Number of Valid Bits) byte per ISO 14443-3A §6.4.2.
* completeBytesInFrame: complete bytes in the TX frame including SEL and NVB (minimum 2).
* bitsKnown: partial bits in the next UID byte (0..7). Passing 8 triggers promotion
* (completeBytesInFrame+1, bitsKnown=0) to keep the lower nibble in range.
*/
static uint8_t buildNvbByte(uint8_t completeBytesInFrame, uint8_t bitsKnown)
{
if (8U == bitsKnown)
{
completeBytesInFrame++;
bitsKnown = 0U;
}
return (uint8_t)((completeBytesInFrame << 4U) | (bitsKnown & ISO14443A_NVB_BITS_MASK));
}
/*
* ISO 14443-3A anti-collision loop.
* selByte: 0x93 = CL-1, 0x95 = CL-2.
* On success sUIDWithXOR holds the 4 UID bytes + BCC for this cascade level,
* and *appState is set to DemoAppState_Select.
* On failure *appState is set to DemoAppState_SetStateOff.
*/
static ptx_Status_t ptx_RunAntiCollision(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState,
ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams,
uint8_t selByte)
{
/* 32 possible single-bit deepenings + 1 final clean-response read = 33 iterations max. */
#define PTX_ANTICOLL_MAX_ITER 33U
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
if ((NULL == tm) || (NULL == appState))
{
return status;
}
uint8_t completeBytesKnown = 0U; /* fully-known UID bytes accumulated so far (0..4) */
uint8_t bitsKnown = 0U; /* partial bits known in the next UID byte (0..7) */
uint8_t knownUIDBytes[4] = {0U, 0U, 0U, 0U};
uint8_t knownPartialByte = 0U;
bool resolved = false;
status = PTX_STATUS_SUCCESS;
for (uint8_t iteration = 0U; iteration < PTX_ANTICOLL_MAX_ITER; iteration++)
{
/* Build anti-collision TX frame */
rfParams->Flags = (uint8_t)(PTX_TRANSPARENT_MODE_FLAGS_TX_PARITY | PTX_TRANSPARENT_MODE_FLAGS_RX_PARITY);
rfParams->RxBitOffset = bitsKnown;
exchangeParams->TxData[0] = selByte;
exchangeParams->TxData[1] = buildNvbByte(2U + completeBytesKnown, bitsKnown);
memcpy(&exchangeParams->TxData[2], knownUIDBytes, completeBytesKnown);
if (bitsKnown > 0U)
{
exchangeParams->TxData[2U + completeBytesKnown] = knownPartialByte;
exchangeParams->TxLength = 3U + completeBytesKnown;
}
else
{
exchangeParams->TxLength = 2U + completeBytesKnown;
}
exchangeParams->NrTxBits = bitsKnown;
exchangeParams->RxLength = PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE;
memset(exchangeParams->RxData, 0, sizeof(uint8_t) * PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE);
exchangeParams->TimeoutMS = PTX_EXAMPLE_TRANSPARENT_MODE_RF_TIMEOUT_MS;
ptx_Utils_Print("AntiColl TX (iter=%u NVB=%02X): ", (unsigned int)iteration, exchangeParams->TxData[1]);
ptx_Utils_Print_Buffer(&exchangeParams->TxData[0], (uint16_t)exchangeParams->TxLength, 1U, 0);
status = ptx_TransparentMode_Exchange(tm, rfParams, exchangeParams);
if (PTX_STATUS_SUCCESS == status)
{
/* Collision-free response: reconstruct the full UID+BCC into sUIDWithXOR */
uint8_t expectedRx = (uint8_t)(5U - completeBytesKnown);
if ((uint32_t)expectedRx != exchangeParams->RxLength)
{
ptx_Utils_Print("AntiColl: unexpected RxLength %lu (expected %u)\n",
exchangeParams->RxLength, (unsigned int)expectedRx);
status = PTX_STATUS_E_GEN_INTERNAL;
*appState = DemoAppState_SetStateOff;
break;
}
memcpy(&sUIDWithXOR[0], knownUIDBytes, completeBytesKnown);
if (bitsKnown > 0U)
{
/* RxData[0] has zeros in bits 0..bitsKnown-1 (hardware RxBitOffset padding)
* and received data in bits bitsKnown..7. OR with knownPartialByte to complete. */
sUIDWithXOR[completeBytesKnown] = knownPartialByte | exchangeParams->RxData[0];
memcpy(&sUIDWithXOR[completeBytesKnown + 1U], &exchangeParams->RxData[1], expectedRx - 1U);
}
else
{
memcpy(&sUIDWithXOR[completeBytesKnown], &exchangeParams->RxData[0], expectedRx);
}
uint8_t bcc = (uint8_t)(sUIDWithXOR[0] ^ sUIDWithXOR[1] ^ sUIDWithXOR[2] ^ sUIDWithXOR[3]);
if (bcc != sUIDWithXOR[4])
{
ptx_Utils_Print("AntiColl: BCC mismatch (computed %02X, received %02X)\n", bcc, sUIDWithXOR[4]);
status = PTX_STATUS_E_GEN_INTERNAL;
*appState = DemoAppState_SetStateOff;
break;
}
ptx_Utils_Print("AntiColl UID+BCC: ");
ptx_Utils_Print_Buffer(&sUIDWithXOR[0], 5U, 1U, 0);
*appState = DemoAppState_Select;
resolved = true;
break;
}
else if (PTX_STATUS_E_NSC_COLLISION == status || PTX_STATUS_E_NSC_RESIDUAL_BITS == status)
{
/* NrResidualRxBits: number of valid bits in the collision byte (0..7).
* RxLength: 1-indexed position of the collision byte in the received stream. */
uint8_t collBitPos = exchangeParams->NrResidualRxBits;
uint32_t collRxLen = exchangeParams->RxLength;
ptx_Utils_Print("AntiColl collision iter=%u: collRxLen=%lu collBitPos=%u",
(unsigned int)iteration, collRxLen, (unsigned int)collBitPos);
ptx_Utils_Print(" RX: ");
ptx_Utils_Print_Buffer(&exchangeParams->RxData[0], (uint16_t)exchangeParams->RxLength, 1U, 0);
if ((collRxLen < 1U) || ((completeBytesKnown + (uint8_t)(collRxLen - 1U)) >= 5U))
{
ptx_Utils_Print("AntiColl: collision position out of UID range\n");
status = PTX_STATUS_E_GEN_INTERNAL;
*appState = DemoAppState_SetStateOff;
break;
}
/* Accumulate complete UID bytes received before the collision byte */
if (bitsKnown > 0U)
{
if (collRxLen > 1U)
{
/* Complete the partial byte: known low bits OR received high bits */
knownUIDBytes[completeBytesKnown] = knownPartialByte | exchangeParams->RxData[0];
completeBytesKnown++;
/* Copy any further complete bytes (RxData[1..collRxLen-2]) */
uint32_t furtherComplete = collRxLen - 2U;
memcpy(&knownUIDBytes[completeBytesKnown], &exchangeParams->RxData[1], furtherComplete);
completeBytesKnown += (uint8_t)furtherComplete;
bitsKnown = 0U;
}
/* else collRxLen==1: collision within the partial byte — no new complete bytes */
}
else
{
uint32_t newComplete = collRxLen - 1U;
memcpy(&knownUIDBytes[completeBytesKnown], &exchangeParams->RxData[0], newComplete);
completeBytesKnown += (uint8_t)newComplete;
}
/* Build the next knownPartialByte with explicit probe bit.
* The probe bit is always set explicitly — never inherited from the
* collision byte (whose bit at the collision position is unreliable).
* Probing the 0-branch first gives deterministic depth-first resolution. */
uint8_t collByte;
uint8_t validMask;
if (bitsKnown > 0U)
{
/* collRxLen==1: collision within the partial byte continuation in RxData[0].
* Bits 0..bitsKnown-1 come from knownPartialByte; bits bitsKnown..collBitPos-1
* from RxData[0]. Mask keeps only the valid bits 0..collBitPos-1. */
collByte = exchangeParams->RxData[0];
validMask = (collBitPos > 0U) ? (uint8_t)((1U << collBitPos) - 1U) : 0U;
knownPartialByte = (knownPartialByte | collByte) & validMask;
}
else
{
collByte = exchangeParams->RxData[collRxLen - 1U];
validMask = (collBitPos > 0U) ? (uint8_t)((1U << collBitPos) - 1U) : 0U;
knownPartialByte = collByte & validMask;
}
/* Set probe bit = 0 explicitly (0-branch first) */
knownPartialByte &= ~(uint8_t)(1U << collBitPos);
bitsKnown = collBitPos + 1U;
/* Promote if the partial byte is now fully specified (NVB overflow fix) */
if (8U == bitsKnown)
{
knownUIDBytes[completeBytesKnown] = knownPartialByte;
completeBytesKnown++;
bitsKnown = 0U;
knownPartialByte = 0U;
}
status = PTX_STATUS_SUCCESS; /* consume the collision; loop continues */
}
else
{
ptx_Utils_Print("AntiColl exchange failed (iter=%u) status=%04X\n",
(unsigned int)iteration, status);
*appState = DemoAppState_SetStateOff;
break;
}
}
if ((!resolved) && (PTX_STATUS_SUCCESS == status))
{
ptx_Utils_Print("AntiColl: exceeded maximum iterations (%u)\n", PTX_ANTICOLL_MAX_ITER);
status = PTX_STATUS_E_GEN_INTERNAL;
*appState = DemoAppState_SetStateOff;
}
return status;
}
static ptx_Status_t ptx_Example_TransparentMode_CL1(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams)
{
sSelectSelByte = ISO14443A_CMD_SEL_CL1;
ptx_Status_t status = ptx_RunAntiCollision(tm, appState, rfParams, exchangeParams, ISO14443A_CMD_SEL_CL1);
if (PTX_STATUS_SUCCESS == status)
{
/* Populate sFullUID. When sUIDWithXOR[0]==Cascade Tag, bytes 1..3 are
* the first three bytes of a 7- or 10-byte UID; CL-2 will append the rest. */
if (ISO14443A_CASCADE_TAG == sUIDWithXOR[0])
{
sFullUID[0] = sUIDWithXOR[1];
sFullUID[1] = sUIDWithXOR[2];
sFullUID[2] = sUIDWithXOR[3];
sFullUIDLen = 3U;
}
else
{
memcpy(&sFullUID[0], &sUIDWithXOR[0], 4U);
sFullUIDLen = 4U;
}
ptx_Utils_Print("CL-1 resolved, partial UID (%u bytes): ", (unsigned int)sFullUIDLen);
ptx_Utils_Print_Buffer(&sFullUID[0], (uint16_t)sFullUIDLen, 1U, 0);
}
return status;
}
static ptx_Status_t ptx_Example_TransparentMode_Select(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
if ((NULL == tm) || (NULL == appState))
{
return status;
}
rfParams->RxBitOffset = 0U;
rfParams->Flags = (uint8_t)(PTX_TRANSPARENT_MODE_FLAGS_TX_CRC | PTX_TRANSPARENT_MODE_FLAGS_RX_CRC |
PTX_TRANSPARENT_MODE_FLAGS_TX_PARITY | PTX_TRANSPARENT_MODE_FLAGS_RX_PARITY);
/* sSelectSelByte is set by CL-1 or CL-2 before transitioning to Select */
exchangeParams->TxData[0] = sSelectSelByte;
exchangeParams->TxData[1] = ISO14443A_CMD_SELECT_BYTE;
/* sUIDWithXOR holds the correctly reconstructed 4-byte UID + BCC for this cascade level */
memcpy(&exchangeParams->TxData[2], &sUIDWithXOR[0], 5U);
exchangeParams->TxLength = 7U;
exchangeParams->NrTxBits = 0U;
exchangeParams->RxLength = PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE;
memset(exchangeParams->RxData, 0, sizeof(uint8_t) * exchangeParams->RxLength);
exchangeParams->TimeoutMS = PTX_EXAMPLE_TRANSPARENT_MODE_RF_TIMEOUT_MS;
ptx_Utils_Print("Select (SEL=%02X): ", sSelectSelByte);
ptx_Utils_Print_Buffer(&exchangeParams->TxData[0], (uint16_t)exchangeParams->TxLength, 1U, 0);
status = ptx_TransparentMode_Exchange(tm, rfParams, exchangeParams);
if (PTX_STATUS_SUCCESS == status)
{
if (1U != exchangeParams->RxLength)
{
ptx_Utils_Print("Select: unexpected SAK length %lu\n", exchangeParams->RxLength);
status = PTX_STATUS_E_GEN_INTERNAL;
*appState = DemoAppState_SetStateOff;
}
else
{
uint8_t sak = exchangeParams->RxData[0];
ptx_Utils_Print("SAK: %02X\n", sak);
if (0U != (sak & ISO14443A_SAK_UID_NOT_COMPLETE))
{
/* ISO 14443-3A §6.4.3: SAK bit 2 set means UID not complete — run CL-2 */
ptx_Utils_Print("SAK indicates UID not complete, running CL-2\n");
*appState = DemoAppState_CL2;
}
else
{
ptx_Utils_Print("Activation complete. Full UID (%u bytes): \t", (unsigned int)sFullUIDLen);
ptx_Utils_Print_Buffer(&sFullUID[0], (uint16_t)sFullUIDLen, 1U, 0);
*appState = DemoAppState_Halt;
}
}
}
else
{
ptx_Utils_Print("Select failed with Error-Status %04X!\n", status);
*appState = DemoAppState_SetStateOff;
}
return status;
}
static ptx_Status_t ptx_Example_TransparentMode_CL2(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams)
{
sSelectSelByte = ISO14443A_CMD_SEL_CL2;
ptx_Status_t status = ptx_RunAntiCollision(tm, appState, rfParams, exchangeParams, ISO14443A_CMD_SEL_CL2);
if (PTX_STATUS_SUCCESS == status)
{
/* sUIDWithXOR now holds the CL-2 UID payload (4 bytes + BCC).
* Append the real UID bytes (skip BCC at index 4) to sFullUID. */
if (ISO14443A_CASCADE_TAG == sUIDWithXOR[0])
{
/* Cascade Tag in CL-2: 10-byte UID, need CL-3 (not implemented) */
ptx_Utils_Print("CL-2: cascade tag detected (10-byte UID not supported)\n");
sFullUID[3] = sUIDWithXOR[1];
sFullUID[4] = sUIDWithXOR[2];
sFullUID[5] = sUIDWithXOR[3];
sFullUIDLen = 6U;
}
else
{
sFullUID[3] = sUIDWithXOR[0];
sFullUID[4] = sUIDWithXOR[1];
sFullUID[5] = sUIDWithXOR[2];
sFullUID[6] = sUIDWithXOR[3];
sFullUIDLen = 7U;
}
ptx_Utils_Print("CL-2 resolved, partial UID (%u bytes): ", (unsigned int)sFullUIDLen);
ptx_Utils_Print_Buffer(&sFullUID[0], (uint16_t)sFullUIDLen, 1U, 0);
}
return status;
}
static ptx_Status_t ptx_Example_TransparentMode_Halt(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_TransparentMode_RFParams_t *rfParams, ptx_TransparentMode_ExchangeParams_t *exchangeParams)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
if ((NULL == tm) || (NULL == appState))
{
return status;
}
rfParams->RxBitOffset = 0U;
/* TX_CRC required by ISO 14443-3A; no RX_CRC because HALT elicits no response */
rfParams->Flags = (uint8_t)(PTX_TRANSPARENT_MODE_FLAGS_TX_CRC |
PTX_TRANSPARENT_MODE_FLAGS_TX_PARITY |
PTX_TRANSPARENT_MODE_FLAGS_RX_PARITY);
exchangeParams->TxData[0] = ISO14443A_CMD_HALT;
exchangeParams->TxData[1] = ISO14443A_CMD_HALT_LSB;
exchangeParams->TxLength = 2U;
exchangeParams->NrTxBits = 0U;
exchangeParams->RxLength = PTX_EXAMPLE_TRANSPARENT_MODE_MAX_BUFFER_SIZE;
memset(exchangeParams->RxData, 0, sizeof(uint8_t) * exchangeParams->RxLength);
exchangeParams->TimeoutMS = PTX_EXAMPLE_TRANSPARENT_MODE_RF_TIMEOUT_MS;
ptx_Utils_Print("HALT -> ");
ptx_Utils_Print_Buffer(&sFullUID[0], (uint16_t)sFullUIDLen, 1U, 0);
(void)ptx_TransparentMode_Exchange(tm, rfParams, exchangeParams);
/* ISO 14443-3A: a valid HALT receives no response; any status is acceptable here */
/* After HALT, cards that were not selected are in IDLE state (ISO 14443-3A: a PICC
* in READY that receives a SELECT with a non-matching UID transitions to IDLE).
* Send REQA to wake them from IDLE to READY before the next anti-collision round. */
*appState = DemoAppState_WUPA;
return PTX_STATUS_SUCCESS;
}
static ptx_Status_t ptx_ProcessState_SystemError(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState, ptx_RUL_Status_Params_t *statusInfoParam)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
if ((NULL != tm) && (NULL != appState) && (NULL != statusInfoParam))
{
status = PTX_STATUS_SUCCESS;
/* System-Errors-/-Warnings are critical and needs to be resolved at integration-/application-level.
* There can be multiple root causes those errors/warnings, but in most cases they are related
* the Hardware-environment (e.g. PCB, component issues etc.).
*/
if (ptx_RUL_StatusInfoSystem_ErrorOvercurrent == statusInfoParam->Info.System)
{
ptx_Utils_Print("WARNING - Overcurrent Limiter activated!\n");
*appState = DemoAppState_Exit;
}
if (ptx_RUL_StatusInfoSystem_ErrorTemperature == statusInfoParam->Info.System)
{
ptx_Utils_Print("WARNING - Temperature Limiter activated!\n");
status = ptx_ProcessState_RestartSystem(tm, appState);
}
if (ptx_RUL_StatusInfoSystem_NSCReset == statusInfoParam->Info.System)
{
ptx_Utils_Print("WARNING - Unexpected System Reset - exiting Application!\n");
*appState = DemoAppState_Exit;
}
}
return status;
}
static ptx_Status_t ptx_ProcessState_RestartSystem(ptx_TransparentMode_t *tm, ptx_DemoAppState_t *appState)
{
ptx_Status_t status = PTX_STATUS_E_GEN_INVALID_PARAMETER;
if ((NULL != tm) && (NULL != appState))
{
do
{
/* Wait for 1s to give the chip time to cool down, after that time try to initialize the system again */
status = ptx_RUL_Sleep(tm->Rul, 1000u);
if (PTX_STATUS_SUCCESS == status)
{
status = ptx_RUL_InitHardware(tm->Rul);
}
}
while (status != PTX_STATUS_SUCCESS);
if (PTX_STATUS_SUCCESS == status)
{
status = ptx_TransparentMode_ResetState(tm);
}
if (PTX_STATUS_SUCCESS == status)
{
*appState = DemoAppState_SetStateOn;
}
}
return status;
}Header file:
/*
---------------------------------------------------------------
SPDX-License-Identifier: BSD-3-Clause
Copyright (c) 2025, Renesas Electronics Corporation and/or its affiliates
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of Renesas nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Renesas "AS IS" AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL RENESAS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------
Project : PTX2xxR/W
Module : SDK Example (Transparent Mode)
File : EXAMPLES/ptx_Example_TransparentMode/ptx_ExampleApplication.h
Description : This application example demonstrates how to use the Transparent-Mode API.
It performs standard activation procedures for each technology type (A, B, F, V)
*/
/**
* \addtogroup TRANSPARENT_MODE SDK_EXAMPLES.
*
* @{
*/
#if !defined(_PTX_SDK_EXAMPLE_TRANSPARENT_MODE_H_)
#define _PTX_SDK_EXAMPLE_TRANSPARENT_MODE_H_
#if defined(__cplusplus)
extern "C" {
#endif
/*
* ####################################################################################################################
* INCLUDES
* ####################################################################################################################
*/
/*
* ####################################################################################################################
* DEFINES / CONSTANTS
* ####################################################################################################################
*/
/**
* \brief Version number of current Demo-Application.
*/
const char *PTX_DEMO_VERSION = "V1.0";
/*
* ####################################################################################################################
* TYPES
* ####################################################################################################################
*/
/**
* \brief Demo-Application States.
*/
typedef enum ptx_DemoAppState
{
DemoAppState_SetStateOn, /**< Switches System into Transparent Mode. */
DemoAppState_SetStateOff, /**< Switches System back to Idle Mode. */
DemoAppState_WUPA, /**< Performs WUPA command using Transparent Mode. */
DemoAppState_CL1, /**< Resolve CL-1 collision using Transparent Mode. */
DemoAppState_CL2, /**< Resolve CL-2 collision (7/10-byte UID). */
DemoAppState_Select, /**< Select card using Transparent Mode. */
DemoAppState_Halt, /**< HALT selected card so it ignores REQA. */
DemoAppState_SystemError, /**< Critical (System-)Error occurred. */
DemoAppState_Exit, /**< Stop Demo-Application (no specific reason)). */
} ptx_DemoAppState_t;
/*
* ####################################################################################################################
* API FUNCTIONS
* ####################################################################################################################
*/
#if defined(PTX_PLATFORM_MCU)
int ptx_App_Entry(void);
#endif
#if defined(__cplusplus)
}
#endif
#endif /* Guard */
/** @} */
Console output:
***********************************************************
**** Transparent Mode Example V1.0 ****
***********************************************************
RUL SW-Stack successfully initialized!
PTX Hardware-/-Chip successfully initialized!
***********************************************************
**************** Revision Information *********************
***********************************************************
C-Stack Revision.......: v01.02.00
FW-Code Revision.......: 0x347E
RF-Config Version......: 0x29
HW Version.............: 0xAA
Platform Revision......: 941F00D53
Local Changes..........: no
***********************************************************
Opening Transparent Mode completed with Status 0000!
Turning Field ON completed with Status 0000!
WUP-A: 52
ATQA (len=2): 4400
WUPA/REQA completed with Status 0000!
AntiColl TX (iter=0 NVB=20): 9320
AntiColl collision iter=0: collRxLen=3 collBitPos=0 RX: 88047F
AntiColl TX (iter=1 NVB=41): 9341880400
AntiColl UID+BCC: 8804326DD3
CL-1 resolved, partial UID (3 bytes): 04326D
CL-1 completed with Status 0000!
Select (SEL=93): 93708804326DD3
SAK: 04
SAK indicates UID not complete, running CL-2
Select completed with Status 0000!
AntiColl TX (iter=0 NVB=20): 9520
AntiColl UID+BCC: 2AC55F8030
CL-2 resolved, partial UID (7 bytes): 04326D2AC55F80
CL-2 completed with Status 0000!
Select (SEL=95): 95702AC55F8030
SAK: 20
Activation complete. Full UID (7 bytes): 04326D2AC55F80
Select completed with Status 0000!
HALT -> 04326D2AC55F80
Halt completed with Status 0000!
REQ-A: 26
ATQA (len=2): 4400
WUPA/REQA completed with Status 0000!
AntiColl TX (iter=0 NVB=20): 9320
AntiColl UID+BCC: 88045D4392
CL-1 resolved, partial UID (3 bytes): 045D43
CL-1 completed with Status 0000!
Select (SEL=93): 937088045D4392
SAK: 04
SAK indicates UID not complete, running CL-2
Select completed with Status 0000!
AntiColl TX (iter=0 NVB=20): 9520
AntiColl UID+BCC: 2AC55F8030
CL-2 resolved, partial UID (7 bytes): 045D432AC55F80
CL-2 completed with Status 0000!
Select (SEL=95): 95702AC55F8030
SAK: 20
Activation complete. Full UID (7 bytes): 045D432AC55F80
Select completed with Status 0000!
HALT -> 045D432AC55F80
Halt completed with Status 0000!
REQ-A: 26
WUPA/REQA exchange failed with status 0101
WUPA/REQA completed with Status 0101!
Turning Field OFF completed with Status 0000!
Sequence over, waiting 500 ms.