diff options
56 files changed, 21553 insertions, 0 deletions
diff --git a/pn54x/Android.bp b/pn54x/Android.bp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pn54x/Android.bp diff --git a/pn54x/Android.mk b/pn54x/Android.mk new file mode 100644 index 0000000..21d4f19 --- /dev/null +++ b/pn54x/Android.mk @@ -0,0 +1,105 @@ +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#variables for NFC_NXP_CHIP_TYPE +PN547C2 := 1 +PN548C2 := 2 +PN551 := 3 +PN553 := 4 +NQ110 := $PN547C2 +NQ120 := $PN547C2 +NQ210 := $PN548C2 +NQ220 := $PN548C2 +#NXP PN547 Enable +ifeq ($(PN547C2),1) +D_CFLAGS += -DPN547C2=1 +endif +ifeq ($(PN548C2),2) +D_CFLAGS += -DPN548C2=2 +endif +ifeq ($(PN551),3) +D_CFLAGS += -DPN551=3 +endif +ifeq ($(PN553),4) +D_CFLAGS += -DPN553=4 +endif + +#### Select the CHIP #### +ifneq ($(filter pn547 nq110 nq120,$(BOARD_NFC_CHIPSET)),) +NXP_CHIP_TYPE := $(PN547C2) +else ifneq ($(filter pn548 nq210 nq220,$(BOARD_NFC_CHIPSET)),) +NXP_CHIP_TYPE := $(PN548C2) +else ifeq ($(BOARD_NFC_CHIPSET),pn551) +NXP_CHIP_TYPE := $(PN551) +else ifeq ($(BOARD_NFC_CHIPSET),pn553) +NXP_CHIP_TYPE := $(PN553) +endif + +ifeq ($(NXP_CHIP_TYPE),$(PN547C2)) +D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN547C2 +else ifeq ($(NXP_CHIP_TYPE),$(PN548C2)) +D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN548C2 +else ifeq ($(NXP_CHIP_TYPE),$(PN551)) +D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN551 +else ifeq ($(NXP_CHIP_TYPE),$(PN553)) +D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN553 +else +D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN553 +endif + +ifneq ($(BOARD_NFC_HAL_SUFFIX),) + HAL_SUFFIX := $(BOARD_NFC_HAL_SUFFIX) +else + HAL_SUFFIX := $(TARGET_DEVICE) +endif + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := nfc_nci.$(HAL_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_SRC_FILES := \ + $(call all-c-files-under, common) \ + $(call all-c-files-under, dnld) \ + $(call all-c-files-under, hal) \ + $(call all-c-files-under, log) \ + $(call all-c-files-under, self-test) \ + $(call all-c-files-under, tml) \ + $(call all-c-files-under, utils) \ + $(call all-cpp-files-under, utils) \ + nfc_nci.c + +LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libhardware + +LOCAL_CFLAGS := $(D_CFLAGS) +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/utils \ + $(LOCAL_PATH)/inc \ + $(LOCAL_PATH)/common \ + $(LOCAL_PATH)/dnld \ + $(LOCAL_PATH)/hal \ + $(LOCAL_PATH)/log \ + $(LOCAL_PATH)/tml \ + $(LOCAL_PATH)/self-test \ + +LOCAL_CFLAGS += -DANDROID \ + -DNXP_UICC_ENABLE -DNXP_HW_SELF_TEST +LOCAL_CFLAGS += -DNFC_NXP_HFO_SETTINGS=FALSE +#LOCAL_CFLAGS += -DFELICA_CLT_ENABLE + + +# +# nfc_nci.$(HAL_SUFFIX) +# +include $(BUILD_SHARED_LIBRARY) diff --git a/pn54x/common/phNfcCommon.h b/pn54x/common/phNfcCommon.h new file mode 100644 index 0000000..638a133 --- /dev/null +++ b/pn54x/common/phNfcCommon.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * OSAL header files related to memory, debug, random, semaphore and mutex + * functions. + */ + +#ifndef PHNFCCOMMON_H +#define PHNFCCOMMON_H + +/* +************************* Include Files **************************************** +*/ + +#include <phDal4Nfc_messageQueueLib.h> +#include <phNfcCompId.h> +#include <phNfcStatus.h> +#include <phOsalNfc_Timer.h> +#include <pthread.h> +#include <semaphore.h> + +#define FW_DLL_ROOT_DIR "/system/vendor/firmware/" +#define FW_DLL_EXTENSION ".so" + +#if (NFC_NXP_CHIP_TYPE == PN548C2) + +/* Actual FW library name*/ +#define FW_LIB_PATH FW_DLL_ROOT_DIR "libpn548ad_fw" FW_DLL_EXTENSION +/* Restore Corrupted PLL Setttings/etc */ +#define PLATFORM_LIB_PATH \ + FW_DLL_ROOT_DIR "libpn548ad_fw_platform" FW_DLL_EXTENSION +/* Upgrade the public Key */ +#define PKU_LIB_PATH FW_DLL_ROOT_DIR "libpn548ad_fw_pku" FW_DLL_EXTENSION +#elif (NFC_NXP_CHIP_TYPE == PN551) +/* Actual FW library name*/ +#define FW_LIB_PATH FLASH_CONF_ROOT_DIR "libpn551_fw" FW_DLL_EXTENSION +/* Restore Corrupted PLL Settings/etc */ +#define PLATFORM_LIB_PATH \ + FW_DLL_ROOT_DIR "libpn551_fw_platform" FW_DLL_EXTENSION +/* Upgrade the public Key */ +#define PKU_LIB_PATH FW_DLL_ROOT_DIR "libpn551_fw_pku" FW_DLL_EXTENSION +#elif (NFC_NXP_CHIP_TYPE == PN553) +/* Actual FW library name*/ +#define FW_LIB_PATH FLASH_CONF_ROOT_DIR "libpn553_fw" FW_DLL_EXTENSION +/* Restore Corrupted PLL Settings/etc */ +#define PLATFORM_LIB_PATH \ + FW_DLL_ROOT_DIR "libpn553_fw_platform" FW_DLL_EXTENSION +/* Upgrade the public Key */ +#define PKU_LIB_PATH FW_DLL_ROOT_DIR "libpn553_fw_pku" FW_DLL_EXTENSION +#else +/* Actual FW library name*/ +#define FW_LIB_PATH FW_DLL_ROOT_DIR "libpn547_fw" FW_DLL_EXTENSION +/* Restore Corrupted PLL Settings/etc */ +#define PLATFORM_LIB_PATH \ + FW_DLL_ROOT_DIR "libpn547_fw_platform" FW_DLL_EXTENSION +/* Upgrade the public Key */ +#define PKU_LIB_PATH FW_DLL_ROOT_DIR "libpn547_fw_pku" FW_DLL_EXTENSION +#endif + +#if (NFC_NXP_CHIP_TYPE == PN548C2) +#define COMPILATION_MW "PN548C2" +#elif (NFC_NXP_CHIP_TYPE == PN551) +#define COMPILATION_MW "PN551" +#elif (NFC_NXP_CHIP_TYPE == PN553) +#define COMPILATION_MW "PN553" +#else +#define COMPILATION_MW "PN547C2" +#endif + +/* HAL Version number (Updated as per release) */ +#define NXP_MW_VERSION_MAJ (3U) +#define NXP_MW_VERSION_MIN (5U) + +/* + ***************************************************************** + *********** System clock source selection configuration ******** + ***************************************************************** + */ + +#define CLK_SRC_UNDEF 0 +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 +#define CLK_SRC_PADDIRECT 3 + +/*Extern crystal clock source*/ +/* Use one of CLK_SRC_<value> */ +#define NXP_SYS_CLK_SRC_SEL CLK_SRC_PLL +/*Direct clock*/ + +/* + ***************************************************************** + *********** System clock frequency selection configuration **************** + * If Clk_Src is set to PLL, make sure to set the Clk_Freq also* + ***************************************************************** + */ +#define CLK_FREQ_UNDEF 0 +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 + +/* Set to one of CLK_FREQ_<value> */ +#define NXP_SYS_CLK_FREQ_SEL CLK_FREQ_19_2MHZ + +#define CLK_TO_CFG_DEF 1 +#define CLK_TO_CFG_MAX 6 +/* + * information to configure OSAL + */ +typedef struct phOsalNfc_Config { + uint8_t* pLogFile; /* Log File Name*/ + uintptr_t dwCallbackThreadId; /* Client ID to which message is posted */ +} phOsalNfc_Config_t, *pphOsalNfc_Config_t /* Pointer to #phOsalNfc_Config_t */; + +/* + * Deferred call declaration. + * This type of API is called from ClientApplication (main thread) to notify + * specific callback. + */ +typedef void (*pphOsalNfc_DeferFuncPointer_t)(void*); + +/* + * Deferred message specific info declaration. + */ +typedef struct phOsalNfc_DeferedCallInfo { + pphOsalNfc_DeferFuncPointer_t pDeferedCall; /* pointer to Deferred callback */ + void* pParam; /* contains timer message specific details*/ +} phOsalNfc_DeferedCallInfo_t; + +/* + * States in which a OSAL timer exist. + */ +typedef enum { + eTimerIdle = 0, /* Indicates Initial state of timer */ + eTimerRunning = 1, /* Indicate timer state when started */ + eTimerStopped = 2 /* Indicates timer state when stopped */ +} phOsalNfc_TimerStates_t; /* Variable representing State of timer */ + +/* + **Timer Handle structure containing details of a timer. + */ +typedef struct phOsalNfc_TimerHandle { + uint32_t TimerId; /* ID of the timer */ + timer_t hTimerHandle; /* Handle of the timer */ + /* Timer callback function to be invoked */ + pphOsalNfc_TimerCallbck_t Application_callback; + void* pContext; /* Parameter to be passed to the callback function */ + phOsalNfc_TimerStates_t eState; /* Timer states */ + /* Osal Timer message posted on User Thread */ + phLibNfc_Message_t tOsalMessage; + /* Deferred Call structure to Invoke Callback function */ + phOsalNfc_DeferedCallInfo_t tDeferedCallInfo; + /* Variables for Structure Instance and Structure Ptr */ +} phOsalNfc_TimerHandle_t, *pphOsalNfc_TimerHandle_t; + +#endif /* PHOSALNFC_H */ diff --git a/pn54x/common/phNfcCompId.h b/pn54x/common/phNfcCompId.h new file mode 100644 index 0000000..9930e0c --- /dev/null +++ b/pn54x/common/phNfcCompId.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * NFC Component ID Values - Used for Function Return Codes + */ + +#ifndef PHNFCCOMPID_H +#define PHNFCCOMPID_H + +/* + * Component IDs + * + * IDs for all NFC components. Combined with the Status Code they build the + * value (status) + * returned by each function. + * + * ID Number Spaces: + * - 01..1F: HAL + * - 20..3F: NFC-MW (Local Device) + * - 40..5F: NFC-MW (Remote Device) + * . + * + * The value CID_NFC_NONE does not exist for Component IDs. Do not use + * this value except + * for NFCSTATUS_SUCCESS. The enumeration function uses CID_NFC_NONE + * to mark unassigned "References". + */ +/* Unassigned or doesn't apply (see #NFCSTATUS_SUCCESS) */ +#define CID_NFC_NONE 0x00 +#define CID_NFC_TML 0x01 /* Transport Mapping Layer */ +#define CID_NFC_LLC 0x07 /* Logical Link Control Layer */ +/* NFC Controller(NFCC) Interface Layer */ +#define CID_NFC_NCI 0x08 +/* Firmware Download Management Layer */ +#define CID_NFC_DNLD 0x09 +#define CID_NFC_HAL 0x10 /* Hardware Abstraction Layer */ +/* Operating System Abstraction Layer*/ +#define CID_NFC_OSAL CID_NFC_NONE +#define CID_FRI_NFC_OVR_HAL 0x20 /* NFC-Device, HAL-based */ +#define CID_FRI_NFC_NDEF_RECORD 0x22 /* NDEF Record Tools Library. */ +#define CID_FRI_NFC_NDEF_MAP 0x23 /* NDEF Mapping. */ +#define CID_FRI_NFC_NDEF_REGISTRY 0x24 /* NDEF_REGISTRY. */ +/* Automatic Device Discovery. */ +#define CID_FRI_NFC_AUTO_DEV_DIS 0x25 +#define CID_FRI_NFC_NDEF_SMTCRDFMT 0x26 /* Smart Card Formatting */ +#define CID_NFC_LIB 0x30 /* NFC Library Layer*/ +/* The maximum CID value that is defined. */ +#define CID_MAX_VALUE 0xF0 +/* Logical Link Control Protocol */ +#define CID_FRI_NFC_LLCP 0x40 +#define CID_FRI_NFC_LLCP_TRANSPORT 0x50 +#define CID_FRI_NFC_LLCP_MAC 0x60 + +#endif /* PHNFCCOMPID_H */ diff --git a/pn54x/common/phNfcStatus.h b/pn54x/common/phNfcStatus.h new file mode 100644 index 0000000..f3aa51a --- /dev/null +++ b/pn54x/common/phNfcStatus.h @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * NFC Status Values - Function Return Codes + */ + +#ifndef PHNFCSTATUS_H +#define PHNFCSTATUS_H + +#include <phNfcTypes.h> + +/* Internally required by PHNFCSTVAL. */ +#define PHNFCSTSHL8 (8U) +/* Required by PHNFCSTVAL. */ +#define PHNFCSTBLOWER ((NFCSTATUS)(0x00FFU)) + +/* + * NFC Status Composition Macro + * + * This is the macro which must be used to compose status values. + * + * phNfcCompID Component ID, as defined in phNfcCompId.h . + * phNfcStatus Status values, as defined in phNfcStatus.h . + * + * The macro is not required for the NFCSTATUS_SUCCESS value. + * This is the only return value to be used directly. + * For all other values it shall be used in assignment and conditional + * statements, e.g.: + * NFCSTATUS status = PHNFCSTVAL(phNfcCompID, phNfcStatus); ... + * if (status == PHNFCSTVAL(phNfcCompID, phNfcStatus)) ... + */ +#define PHNFCSTVAL(phNfcCompID, phNfcStatus) \ + (((phNfcStatus) == (NFCSTATUS_SUCCESS)) \ + ? (NFCSTATUS_SUCCESS) \ + : ((((NFCSTATUS)(phNfcStatus)) & (PHNFCSTBLOWER)) | \ + (((uint16_t)(phNfcCompID)) << (PHNFCSTSHL8)))) + +/* + * PHNFCSTATUS + * Get grp_retval from Status Code + */ +#define PHNFCSTATUS(phNfcStatus) ((phNfcStatus)&0x00FFU) +#define PHNFCCID(phNfcStatus) (((phNfcStatus)&0xFF00U) >> 8) + +#define PHNFC_I2C_FRAGMENT_SIZE 512 +/* + * Status Codes + * + * Generic Status codes for the NFC components. Combined with the Component ID + * they build the value (status) returned by each function. + * Example: + * grp_comp_id "Component ID" - e.g. 0x10, plus + * status code as listed in this file - e.g. 0x03 + * result in a status value of 0x0003. + */ + +/* + * The function indicates successful completion + */ +#define NFCSTATUS_SUCCESS (0x0000) + +/* + * The function indicates successful completion + */ +#define NFCSTATUS_OK (NFCSTATUS_SUCCESS) + +/* + * At least one parameter could not be properly interpreted + */ +#define NFCSTATUS_INVALID_PARAMETER (0x0001) + +/* + * The buffer provided by the caller is too small + */ +#define NFCSTATUS_BUFFER_TOO_SMALL (0x0003) + +/* + * Device specifier/handle value is invalid for the operation + */ +#define NFCSTATUS_INVALID_DEVICE (0x0006) + +/* + * The function executed successfully but could have returned + * more information than space provided by the caller + */ +#define NFCSTATUS_MORE_INFORMATION (0x0008) + +/* + * No response from the remote device received: Time-out + */ +#define NFCSTATUS_RF_TIMEOUT (0x0009) + +/* + * RF Error during data transaction with the remote device + */ +#define NFCSTATUS_RF_ERROR (0x000A) + +/* + * Not enough resources Memory, Timer etc(e.g. allocation failed.) + */ +#define NFCSTATUS_INSUFFICIENT_RESOURCES (0x000C) + +/* + * A non-blocking function returns this immediately to indicate + * that an internal operation is in progress + */ +#define NFCSTATUS_PENDING (0x000D) + +/* + * A board communication error occurred + * (e.g. Configuration went wrong) + */ +#define NFCSTATUS_BOARD_COMMUNICATION_ERROR (0x000F) + +/* + * Invalid State of the particular state machine + */ +#define NFCSTATUS_INVALID_STATE (0x0011) + +/* + * This Layer is Not initialized, hence initialization required. + */ +#define NFCSTATUS_NOT_INITIALISED (0x0031) + +/* + * The Layer is already initialized, hence initialization repeated. + */ +#define NFCSTATUS_ALREADY_INITIALISED (0x0032) + +/* + * Feature not supported + */ +#define NFCSTATUS_FEATURE_NOT_SUPPORTED (0x0033) + +/* The Unregistration command has failed because the user wants to unregister + * on + * an element for which he was not registered + */ +#define NFCSTATUS_NOT_REGISTERED (0x0034) + +/* The Registration command has failed because the user wants to register on + * an element for which he is already registered + */ +#define NFCSTATUS_ALREADY_REGISTERED (0x0035) + +/* Single Tag with Multiple + Protocol support detected */ +#define NFCSTATUS_MULTIPLE_PROTOCOLS (0x0036) + +/* + * Feature not supported + */ +#define NFCSTATUS_MULTIPLE_TAGS (0x0037) + +/* + * A DESELECT event has occurred + */ +#define NFCSTATUS_DESELECTED (0x0038) + +/* + * A RELEASE event has occurred + */ +#define NFCSTATUS_RELEASED (0x0039) + +/* + * The operation is currently not possible or not allowed + */ +#define NFCSTATUS_NOT_ALLOWED (0x003A) + +/* + * FW version error while performing FW download, + * FW major version mismatch (cannot downgrade FW major version) or FW version + * already upto date + * User may be trying to flash Mobile FW on top of Infra FW, which is not + * allowed + * Download appropriate version of FW + */ +#define NFCSTATUS_FW_VERSION_ERROR (0x003C) + +/* + * The system is busy with the previous operation. + */ +#define NFCSTATUS_BUSY (0x006F) + +/* NDEF Mapping error codes */ + +/* The remote device (type) is not valid for this request. */ +#define NFCSTATUS_INVALID_REMOTE_DEVICE (0x001D) + +/* Read operation failed */ +#define NFCSTATUS_READ_FAILED (0x0014) + +/* + * Write operation failed + */ +#define NFCSTATUS_WRITE_FAILED (0x0015) + +/* Non Ndef Compliant */ +#define NFCSTATUS_NO_NDEF_SUPPORT (0x0016) + +/* Could not proceed further with the write operation: reached card EOF*/ +#define NFCSTATUS_EOF_NDEF_CONTAINER_REACHED (0x001A) + +/* Incorrect number of bytes received from the card*/ +#define NFCSTATUS_INVALID_RECEIVE_LENGTH (0x001B) + +/* The data format/composition is not understood/correct. */ +#define NFCSTATUS_INVALID_FORMAT (0x001C) + +/* There is not sufficient storage available. */ +#define NFCSTATUS_INSUFFICIENT_STORAGE (0x001F) + +/* The Ndef Format procedure has failed. */ +#define NFCSTATUS_FORMAT_ERROR (0x0023) + +/* The NCI Cedit error */ +#define NFCSTATUS_CREDIT_TIMEOUT (0x0024) + +/* + * Response Time out for the control message(NFCC not responded) + */ +#define NFCSTATUS_RESPONSE_TIMEOUT (0x0025) + +/* + * Device is already connected + */ +#define NFCSTATUS_ALREADY_CONNECTED (0x0026) + +/* + * Device is already connected + */ +#define NFCSTATUS_ANOTHER_DEVICE_CONNECTED (0x0027) + +/* + * Single Target Detected and Activated + */ +#define NFCSTATUS_SINGLE_TAG_ACTIVATED (0x0028) + +/* + * Single Target Detected + */ +#define NFCSTATUS_SINGLE_TAG_DISCOVERED (0x0029) + +/* + * Secure element Detected and Activated + */ +#define NFCSTATUS_SECURE_ELEMENT_ACTIVATED (0x0028) + +/* + * Unknown error Status Codes + */ +#define NFCSTATUS_UNKNOWN_ERROR (0x00FE) + +/* + * Status code for failure + */ +#define NFCSTATUS_FAILED (0x00FF) + +/* + * The function/command has been aborted + */ +#define NFCSTATUS_CMD_ABORTED (0x0002) + +/* + * No target found after poll + */ +#define NFCSTATUS_NO_TARGET_FOUND (0x000A) + +/* Attempt to disconnect a not connected remote device. */ +#define NFCSTATUS_NO_DEVICE_CONNECTED (0x000B) + +/* External RF field detected. */ +#define NFCSTATUS_EXTERNAL_RF_DETECTED (0x000E) + +/* Message is not allowed by the state machine + * (e.g. configuration went wrong) + */ +#define NFCSTATUS_MSG_NOT_ALLOWED_BY_FSM (0x0010) + +/* + * No access has been granted + */ +#define NFCSTATUS_ACCESS_DENIED (0x001E) + +/* No registry node matches the specified input data. */ +#define NFCSTATUS_NODE_NOT_FOUND (0x0017) + +/* The current module is busy ; one might retry later */ +#define NFCSTATUS_SMX_BAD_STATE (0x00F0) + +/* The Abort mechanism has failed for unexpected reason: user can try again*/ +#define NFCSTATUS_ABORT_FAILED (0x00F2) + +/* The Registration command has failed because the user wants to register as + * target + * on a operating mode not supported + */ +#define NFCSTATUS_REG_OPMODE_NOT_SUPPORTED (0x00F5) + +/* + * Shutdown in progress, cannot handle the request at this time. + */ +#define NFCSTATUS_SHUTDOWN (0x0091) + +/* + * Target is no more in RF field + */ +#define NFCSTATUS_TARGET_LOST (0x0092) + +/* + * Request is rejected + */ +#define NFCSTATUS_REJECTED (0x0093) + +/* + * Target is not connected + */ +#define NFCSTATUS_TARGET_NOT_CONNECTED (0x0094) + +/* + * Invalid handle for the operation + */ +#define NFCSTATUS_INVALID_HANDLE (0x0095) + +/* + * Process aborted + */ +#define NFCSTATUS_ABORTED (0x0096) + +/* + * Requested command is not supported + */ +#define NFCSTATUS_COMMAND_NOT_SUPPORTED (0x0097) + +/* + * Tag is not NDEF compilant + */ +#define NFCSTATUS_NON_NDEF_COMPLIANT (0x0098) + +/* + * Not enough memory available to complete the requested operation + */ +#define NFCSTATUS_NOT_ENOUGH_MEMORY (0x001F) + +/* + * Indicates incoming connection + */ +#define NFCSTATUS_INCOMING_CONNECTION (0x0045) + +/* + * Indicates Connection was successful + */ +#define NFCSTATUS_CONNECTION_SUCCESS (0x0046) + +/* + * Indicates Connection failed + */ +#define NFCSTATUS_CONNECTION_FAILED (0x0047) + +#endif /* PHNFCSTATUS_H */ diff --git a/pn54x/common/phNfcTypes.h b/pn54x/common/phNfcTypes.h new file mode 100644 index 0000000..d80ad50 --- /dev/null +++ b/pn54x/common/phNfcTypes.h @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PHNFCTYPES_H +#define PHNFCTYPES_H + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifndef TRUE +#define TRUE (0x01) /* Logical True Value */ +#endif +#ifndef FALSE +#define FALSE (0x00) /* Logical False Value */ +#endif +typedef uint8_t utf8_t; /* UTF8 Character String */ +typedef uint8_t bool_t; /* boolean data type */ +typedef uint16_t NFCSTATUS; /* Return values */ +#define STATIC static + +#define PHNFC_MAX_UID_LENGTH 0x0AU /* Maximum UID length expected */ +/* Maximum ATR_RES (General Bytes) length expected */ +#define PHNFC_MAX_ATR_LENGTH 0x30U +#define PHNFC_NFCID_LENGTH 0x0AU /* Maximum length of NFCID 1.3*/ +#define PHNFC_ATQA_LENGTH 0x02U /* ATQA length */ + +/* + * NFC Data structure + */ +typedef struct phNfc_sData { + uint8_t* buffer; /* Buffer to store data */ + uint32_t length; /* Buffer length */ +} phNfc_sData_t; + +/* + * Possible Hardware Configuration exposed to upper layer. + * Typically this should be port name (Ex:"COM1","COM2") to which PN54X is + * connected. + */ +typedef enum { + ENUM_LINK_TYPE_COM1, + ENUM_LINK_TYPE_COM2, + ENUM_LINK_TYPE_COM3, + ENUM_LINK_TYPE_COM4, + ENUM_LINK_TYPE_COM5, + ENUM_LINK_TYPE_COM6, + ENUM_LINK_TYPE_COM7, + ENUM_LINK_TYPE_COM8, + ENUM_LINK_TYPE_I2C, + ENUM_LINK_TYPE_SPI, + ENUM_LINK_TYPE_USB, + ENUM_LINK_TYPE_TCP, + ENUM_LINK_TYPE_NB +} phLibNfc_eConfigLinkType; + +/* + * Deferred message. This message type will be posted to the client application + * thread + * to notify that a deferred call must be invoked. + */ +#define PH_LIBNFC_DEFERREDCALL_MSG (0x311) + +/* + * Deferred call declaration. + * This type of API is called from ClientApplication ( main thread) to notify + * specific callback. + */ +typedef void (*pphLibNfc_DeferredCallback_t)(void*); + +/* + * Deferred parameter declaration. + * This type of data is passed as parameter from ClientApplication (main thread) + * to the + * callback. + */ +typedef void* pphLibNfc_DeferredParameter_t; + +/* + * Possible Hardware Configuration exposed to upper layer. + * Typically this should be at least the communication link (Ex:"COM1","COM2") + * the controller is connected to. + */ +typedef struct phLibNfc_sConfig { + uint8_t* pLogFile; /* Log File Name*/ + /* Hardware communication link to the controller */ + phLibNfc_eConfigLinkType nLinkType; + /* The client ID (thread ID or message queue ID) */ + uintptr_t nClientId; +} phLibNfc_sConfig_t, *pphLibNfc_sConfig_t; + +/* + * NFC Message structure contains message specific details like + * message type, message specific data block details, etc. + */ +typedef struct phLibNfc_Message { + uint32_t eMsgType; /* Type of the message to be posted*/ + void* pMsgData; /* Pointer to message specific data block in case any*/ + uint32_t Size; /* Size of the datablock*/ +} phLibNfc_Message_t, *pphLibNfc_Message_t; + +/* + * Deferred message specific info declaration. + * This type of information is packed as message data when + * PH_LIBNFC_DEFERREDCALL_MSG + * type message is posted to message handler thread. + */ +typedef struct phLibNfc_DeferredCall { + pphLibNfc_DeferredCallback_t pCallback; /* pointer to Deferred callback */ + pphLibNfc_DeferredParameter_t pParameter; /* pointer to Deferred parameter */ +} phLibNfc_DeferredCall_t; + +/* + * Definitions for supported protocol + */ +typedef struct phNfc_sSupProtocol { + unsigned int MifareUL : 1; /* Protocol Mifare Ultra Light or any NFC Forum + Type-2 tags */ + unsigned int MifareStd : 1; /* Protocol Mifare Standard. */ + unsigned int ISO14443_4A : 1; /* Protocol ISO14443-4 Type A. */ + unsigned int ISO14443_4B : 1; /* Protocol ISO14443-4 Type B. */ + unsigned int ISO15693 : 1; /* Protocol ISO15693 HiTag. */ + unsigned int Felica : 1; /* Protocol Felica. */ + unsigned int NFC : 1; /* Protocol NFC. */ + unsigned int Jewel : 1; /* Protocol Innovision Jewel Tag. or Any T1T*/ + unsigned int + Desfire : 1; /*TRUE indicates specified feature (mapping + or formatting)for DESFire tag supported else not supported.*/ + unsigned int Kovio : 1; /* Protocol Kovio Tag*/ + unsigned int HID : 1; /* Protocol HID(Picopass) Tag*/ + unsigned int Bprime : 1; /* Protocol BPrime Tag*/ + unsigned int EPCGEN2 : 1; /* Protocol EPCGEN2 Tag*/ +} phNfc_sSupProtocol_t; + +/* + * Enumerated MIFARE Commands + */ + +typedef enum phNfc_eMifareCmdList { + phNfc_eMifareRaw = 0x00U, /* This command performs raw transcations */ + phNfc_eMifareAuthentA = 0x60U, /* This command performs an authentication with + KEY A for a sector. */ + phNfc_eMifareAuthentB = 0x61U, /* This command performs an authentication with + KEY B for a sector. */ + phNfc_eMifareRead16 = 0x30U, /* Read 16 Bytes from a Mifare Standard block */ + phNfc_eMifareRead = 0x30U, /* Read Mifare Standard */ + phNfc_eMifareWrite16 = 0xA0U, /* Write 16 Bytes to a Mifare Standard block */ + phNfc_eMifareWrite4 = 0xA2U, /* Write 4 bytes. */ + phNfc_eMifareInc = 0xC1U, /* Increment */ + phNfc_eMifareDec = 0xC0U, /* Decrement */ + phNfc_eMifareTransfer = 0xB0U, /* Transfer */ + phNfc_eMifareRestore = 0xC2U, /* Restore. */ + phNfc_eMifareReadSector = 0x38U, /* Read Sector. */ + phNfc_eMifareWriteSector = 0xA8U, /* Write Sector. */ + /* Above commands could be used for preparing raw command but below one can + not be */ + phNfc_eMifareReadN = 0x01, /* Proprietary Command */ + phNfc_eMifareWriteN = 0x02, /* Proprietary Command */ + phNfc_eMifareSectorSel = 0x03, /* Proprietary Command */ + phNfc_eMifareAuth = 0x04, /* Proprietary Command */ + phNfc_eMifareProxCheck = 0x05, /* Proprietary Command */ + phNfc_eMifareInvalidCmd = 0xFFU /* Invalid Command */ +} phNfc_eMifareCmdList_t; + +/* + * Information about ISO14443A + */ +typedef struct phNfc_sIso14443AInfo { + uint8_t Uid[PHNFC_MAX_UID_LENGTH]; /* UID information of the TYPE A + * Tag Discovered */ + uint8_t UidLength; /* UID information length */ + uint8_t + AppData[PHNFC_MAX_ATR_LENGTH]; /* Application data information of the + 1 * tag discovered (= Historical bytes for + * type A) */ + uint8_t AppDataLength; /* Application data length */ + uint8_t Sak; /* SAK information of the TYPE A + * Tag Discovered */ + uint8_t AtqA[PHNFC_ATQA_LENGTH]; /* ATQA informationof the TYPE A + * Tag Discovered */ + uint8_t MaxDataRate; /* Maximum data rate supported + * by the tag Discovered */ + uint8_t Fwi_Sfgt; /* Frame waiting time and start up + * frame guard */ +} phNfc_sIso14443AInfo_t; + +/* Remote device information structure */ +typedef union phNfc_uRemoteDevInfo { + phNfc_sIso14443AInfo_t Iso14443A_Info; /* ISO1443A Remote device info */ +} phNfc_uRemoteDevInfo_t; + +/* +* +* The RF Device Type List is used to identify the type of +* remote device that is discovered and connected. +* +*/ + +typedef enum phNfc_eRFDevType { + phNfc_eUnknown_DevType = 0x00U, + + phNfc_eISO14443_A_PCD, + phNfc_eISO14443_B_PCD, + phNfc_eISO14443_BPrime_PCD, + phNfc_eFelica_PCD, + phNfc_eJewel_PCD, + phNfc_eISO15693_PCD, + phNfc_eEpcGen2_PCD, + phNfc_ePCD_DevType, + + phNfc_ePICC_DevType, + phNfc_eISO14443_A_PICC, + phNfc_eISO14443_4A_PICC, + phNfc_eISO14443_3A_PICC, + phNfc_eMifare_PICC, + phNfc_eISO14443_B_PICC, + phNfc_eISO14443_4B_PICC, + phNfc_eISO14443_BPrime_PICC, + phNfc_eFelica_PICC, + phNfc_eJewel_PICC, + phNfc_eISO15693_PICC, + phNfc_eEpcGen2_PICC, + + phNfc_eNfcIP1_Target, + phNfc_eNfcIP1_Initiator, + + phNfc_eInvalid_DevType + +} phNfc_eRFDevType_t; + +/* + * The Remote Device Type List is used to identify the type of + * remote device that is discovered/connected + */ +typedef phNfc_eRFDevType_t phNfc_eRemDevType_t; +typedef phNfc_eRemDevType_t phHal_eRemDevType_t; + +/* + * Union for each available type of Commands. + */ + +typedef union phNfc_uCommand { + phNfc_eMifareCmdList_t MfCmd; /* Mifare command structure. */ +} phNfc_uCmdList_t; + +/* + * The Remote Device Information Structure holds information about one single + * Remote + * Device detected. + */ +typedef struct phNfc_sRemoteDevInformation { + uint8_t SessionOpened; /* Flag indicating the validity of + * the handle of the remote device. + * 1 = Device is not activer (Only discovered), 2 = + * Device is active and ready for use*/ + phNfc_eRemDevType_t RemDevType; /* Remote device type */ + phNfc_uRemoteDevInfo_t RemoteDevInfo; /* Union of available Remote Device */ +} phNfc_sRemoteDevInformation_t; + +/* + * Transceive Information Data Structure for sending commands/response to the + * remote device + */ + +typedef struct phNfc_sTransceiveInfo { + phNfc_uCmdList_t cmd; /* Command for transceive */ + uint8_t addr; /* Start Block Number */ + uint8_t NumBlock; /* Number of Blocks to perform operation */ + /* For Felica only*/ + uint16_t* ServiceCodeList; /* 2 Byte service Code List */ + uint16_t* Blocklist; /* 2 Byte Block list */ + phNfc_sData_t sSendData; /* Send data */ + phNfc_sData_t sRecvData; /* Recv data */ + /* For EPC-GEN */ + uint32_t dwWordPtr; /* Word address for the memory write */ + uint8_t bWordPtrLen; /* Specifies the length of word pointer + 00: 8 bits + 01: 16 bits + 10: 24 bits + 11: 32 bits + */ + uint8_t bWordCount; /* Number of words to be read or written */ +} phNfc_sTransceiveInfo_t; + +#define UNUSED(X) (void)X; + +#endif /* PHNFCTYPES_H */ diff --git a/pn54x/dnld/phDnldNfc.c b/pn54x/dnld/phDnldNfc.c new file mode 100644 index 0000000..d2258ef --- /dev/null +++ b/pn54x/dnld/phDnldNfc.c @@ -0,0 +1,1294 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Download Component + * Download Interface routines implementation + */ + +#include <dlfcn.h> +#include <phDnldNfc_Internal.h> +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include <phTmlNfc.h> + +static void* + pFwLibHandle; /* Global firmware lib handle used in this file only */ +uint16_t wMwVer = 0; /* Middleware version no */ +uint16_t wFwVer = 0; /* Firmware version no */ +#if (NFC_NXP_CHIP_TYPE != PN547C2) +uint8_t gRecFWDwnld; // flag set to true to indicate dummy FW download +#endif +static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */ +static pphDnldNfc_RspCb_t UserCb; /* Upper layer call back function */ +static void* UserCtxt; /* Pointer to upper layer context */ +#undef EEPROM_Read_Mem_IMP + +/* Function prototype declaration */ +static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status, + void* pInfo); + +/******************************************************************************* +** +** Function phDnldNfc_Reset +** +** Description Performs a soft reset of the download module +** +** Parameters pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - reset request to NFCC is successful +** NFCSTATUS_FAILED - reset request failed due to internal +** error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pNotify) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone; + (gpphDnldContext->tCmdId) = PH_DL_CMD_RESET; + (gpphDnldContext->tRspBuffInfo.pBuff) = NULL; + (gpphDnldContext->tRspBuffInfo.wLen) = 0; + (gpphDnldContext->tUserData.pBuff) = NULL; + (gpphDnldContext->tUserData.wLen) = 0; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventReset); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("Reset Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("Reset Request Failed!!"); + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_GetVersion +** +** Description Retrieves Hardware version, ROM Code version, Protected Data +** version, Trim data version, User data version, and Firmware +** version information +** +** Parameters pVersionInfo - response buffer which gets updated with +** complete version info from NFCC +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - GetVersion request to NFCC is successful +** NFCSTATUS_FAILED - GetVersion request failed due to internal +** error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo, + pphDnldNfc_RspCb_t pNotify, void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pVersionInfo) || (NULL == pNotify) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if ((NULL != pVersionInfo->pBuff) && (0 != pVersionInfo->wLen)) { + (gpphDnldContext->tRspBuffInfo.pBuff) = pVersionInfo->pBuff; + (gpphDnldContext->tRspBuffInfo.wLen) = pVersionInfo->wLen; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone; + (gpphDnldContext->tCmdId) = PH_DL_CMD_GETVERSION; + (gpphDnldContext->tUserData.pBuff) = NULL; + (gpphDnldContext->tUserData.wLen) = 0; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetVer); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("GetVersion Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("GetVersion Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Buff Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_GetSessionState +** +** Description Retrieves the current session state of NFCC +** +** Parameters pSession - response buffer which gets updated with complete +** version info from NFCC +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - GetSessionState request to NFCC is +** successful +** NFCSTATUS_FAILED - GetSessionState request failed due to +** internal error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession, + pphDnldNfc_RspCb_t pNotify, + void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pSession) || (NULL == pNotify) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if ((NULL != pSession->pBuff) && (0 != pSession->wLen)) { + (gpphDnldContext->tRspBuffInfo.pBuff) = pSession->pBuff; + (gpphDnldContext->tRspBuffInfo.wLen) = pSession->wLen; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone; + (gpphDnldContext->tCmdId) = PH_DL_CMD_GETSESSIONSTATE; + (gpphDnldContext->tUserData.pBuff) = NULL; + (gpphDnldContext->tUserData.wLen) = 0; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = + phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetSesnSt); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("GetSessionState Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("GetSessionState Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Buff Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_CheckIntegrity +** +** Description Inspects the integrity of EEPROM and FLASH contents of the +** NFCC, provides CRC for each section +** NOTE: The user data section CRC is valid only after fresh +** download +** +** Parameters bChipVer - current ChipVersion for including additional +** parameters in request payload +** pCRCData - response buffer which gets updated with +** respective section CRC status and CRC bytes from +** NFCC +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - CheckIntegrity request is successful +** NFCSTATUS_FAILED - CheckIntegrity request failed due to +** internal error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData, + pphDnldNfc_RspCb_t pNotify, void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pNotify) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if ((PHDNLDNFC_HWVER_MRA2_1 == bChipVer) || + (PHDNLDNFC_HWVER_MRA2_2 == bChipVer) +#if (NFC_NXP_CHIP_TYPE == PN551) + || (PHDNLDNFC_HWVER_PN551_MRA1_0 == bChipVer) +#elif (NFC_NXP_CHIP_TYPE == PN548C2) + || (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bChipVer) +#elif (NFC_NXP_CHIP_TYPE == PN553) + || (PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer) || + (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & bChipVer) +#endif + ) { + (gpphDnldContext->FrameInp.Type) = phDnldNfc_ChkIntg; + } else { + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone; + } + + if ((NULL != pCRCData->pBuff) && (0 != pCRCData->wLen)) { + (gpphDnldContext->tRspBuffInfo.pBuff) = pCRCData->pBuff; + (gpphDnldContext->tRspBuffInfo.wLen) = pCRCData->wLen; + (gpphDnldContext->tCmdId) = PH_DL_CMD_CHECKINTEGRITY; + (gpphDnldContext->tUserData.pBuff) = NULL; + (gpphDnldContext->tUserData.wLen) = 0; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = + phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventIntegChk); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("CheckIntegrity Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("CheckIntegrity Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Buff Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return wStatus; +} +/******************************************************************************* +** +** Function phDnldNfc_ReadLog +** +** Description Retrieves log data from EEPROM +** +** Parameters pData - response buffer which gets updated with data from +** EEPROM +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - Read request to NFCC is successful +** NFCSTATUS_FAILED - Read request failed due to internal error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, + void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if ((NULL != pData->pBuff) && (0 != pData->wLen)) { + (gpphDnldContext->tCmdId) = PH_DL_CMD_READ; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead; + (gpphDnldContext->FrameInp.dwAddr) = PHDNLDNFC_EEPROM_LOG_START_ADDR; + (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff; + (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen; + (gpphDnldContext->tUserData.pBuff) = NULL; + (gpphDnldContext->tUserData.wLen) = 0; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + memset(&(gpphDnldContext->tRWInfo), 0, + sizeof(gpphDnldContext->tRWInfo)); + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("Read Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("Read Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Buff Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_Write +** +** Description Writes requested data of length len to desired EEPROM/FLASH +** address +** +** Parameters bRecoverSeq - flag to indicate whether recover sequence data +** needs to be written or not +** pData - data buffer to write into EEPROM/FLASH by user +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - Write request to NFCC is successful +** NFCSTATUS_FAILED - Write request failed due to internal +** error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_Write(bool_t bRecoverSeq, pphDnldNfc_Buff_t pData, + pphDnldNfc_RspCb_t pNotify, void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t* pImgPtr = NULL; + uint16_t wLen = 0; + phDnldNfc_Buff_t tImgBuff; + + if ((NULL == pNotify) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if (NULL != pData) { + pImgPtr = pData->pBuff; + wLen = pData->wLen; + } else { + if (bRecoverSeq == false) { + pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fw; + wLen = gpphDnldContext->nxp_nfc_fw_len; + + } else { + if (PH_DL_STATUS_PLL_ERROR == (gpphDnldContext->tLastStatus)) { + wStatus = phDnldNfc_LoadRecInfo(); + } else if (PH_DL_STATUS_SIGNATURE_ERROR == + (gpphDnldContext->tLastStatus)) { + wStatus = phDnldNfc_LoadPKInfo(); + } else { + } + + if (NFCSTATUS_SUCCESS == wStatus) { + pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fwp; + wLen = gpphDnldContext->nxp_nfc_fwp_len; + } else { + NXPLOG_FWDNLD_E("Platform Recovery Image extraction Failed!!"); + pImgPtr = NULL; + wLen = 0; + } + } + } + + if ((NULL != pImgPtr) && (0 != wLen)) { + tImgBuff.pBuff = pImgPtr; + tImgBuff.wLen = wLen; + + (gpphDnldContext->tCmdId) = PH_DL_CMD_WRITE; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTWrite; + (gpphDnldContext->tRspBuffInfo.pBuff) = NULL; + (gpphDnldContext->tRspBuffInfo.wLen) = 0; + (gpphDnldContext->tUserData.pBuff) = pImgPtr; + (gpphDnldContext->tUserData.wLen) = wLen; + (gpphDnldContext->bResendLastFrame) = false; + + memset(&(gpphDnldContext->tRWInfo), 0, + sizeof(gpphDnldContext->tRWInfo)); + (gpphDnldContext->tRWInfo.bFirstWrReq) = true; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventWrite); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("Write Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("Write Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Download Image Primitives extraction failed!!"); + wStatus = NFCSTATUS_FAILED; + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_Log +** +** Description Provides a full page free write to EEPROM +** +** Parameters pData - data buffer to write into EEPROM/FLASH by user +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - Write request to NFCC is successful +** NFCSTATUS_FAILED - Write request failed due to internal +** error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific error +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, + void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if ((NULL != (pData->pBuff)) && + ((0 != (pData->wLen) && (PHDNLDNFC_MAX_LOG_SIZE >= (pData->wLen))))) { + (gpphDnldContext->tCmdId) = PH_DL_CMD_LOG; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTLog; + (gpphDnldContext->tRspBuffInfo.pBuff) = NULL; + (gpphDnldContext->tRspBuffInfo.wLen) = 0; + (gpphDnldContext->tUserData.pBuff) = (pData->pBuff); + (gpphDnldContext->tUserData.wLen) = (pData->wLen); + + memset(&(gpphDnldContext->tRWInfo), 0, + sizeof(gpphDnldContext->tRWInfo)); + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventLog); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("Log Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("Log Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Input Parameters for Log!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_Force +** +** Description Used as an emergency recovery procedure for NFCC due to +** corrupt settings of system platform specific parameters by +** the host +** +** Parameters pInputs - input buffer which contains clk src & clk freq +** settings for desired platform +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - Emergency Recovery request is successful +** NFCSTATUS_FAILED - Emergency Recovery failed due to internal +** error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify, + void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t bClkSrc = 0x00, bClkFreq = 0x00; + uint8_t bPldVal[3] = { + 0x11, 0x00, 0x00}; /* default values to be used if input not provided */ + + if ((NULL == pNotify) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + (gpphDnldContext->tCmdId) = PH_DL_CMD_FORCE; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTForce; + (gpphDnldContext->tRspBuffInfo.pBuff) = NULL; + (gpphDnldContext->tRspBuffInfo.wLen) = 0; + + if ((0 != (pInputs->wLen)) || (NULL != (pInputs->pBuff))) { + if (CLK_SRC_XTAL == (pInputs->pBuff[0])) { + bClkSrc = phDnldNfc_ClkSrcXtal; + } else if (CLK_SRC_PLL == (pInputs->pBuff[0])) { + bClkSrc = phDnldNfc_ClkSrcPLL; + if (CLK_FREQ_13MHZ == (pInputs->pBuff[1])) { + bClkFreq = phDnldNfc_ClkFreq_13Mhz; + } else if (CLK_FREQ_19_2MHZ == (pInputs->pBuff[1])) { + bClkFreq = phDnldNfc_ClkFreq_19_2Mhz; + } else if (CLK_FREQ_24MHZ == (pInputs->pBuff[1])) { + bClkFreq = phDnldNfc_ClkFreq_24Mhz; + } else if (CLK_FREQ_26MHZ == (pInputs->pBuff[1])) { + bClkFreq = phDnldNfc_ClkFreq_26Mhz; + } else if (CLK_FREQ_38_4MHZ == (pInputs->pBuff[1])) { + bClkFreq = phDnldNfc_ClkFreq_38_4Mhz; + } else if (CLK_FREQ_52MHZ == (pInputs->pBuff[1])) { + bClkFreq = phDnldNfc_ClkFreq_52Mhz; + } else { + NXPLOG_FWDNLD_E( + "Invalid Clk Frequency !! Using default value of 19.2Mhz.."); + bClkFreq = phDnldNfc_ClkFreq_19_2Mhz; + } + + } else if (CLK_SRC_PADDIRECT == (pInputs->pBuff[0])) { + bClkSrc = phDnldNfc_ClkSrcPad; + } else { + NXPLOG_FWDNLD_E("Invalid Clk src !! Using default value of PLL.."); + bClkSrc = phDnldNfc_ClkSrcPLL; + } + + bPldVal[0] = 0U; + bPldVal[0] = ((bClkSrc << 3U) | bClkFreq); + } else { + NXPLOG_FWDNLD_E("Clk src inputs not provided!! Using default values.."); + } + + (gpphDnldContext->tUserData.pBuff) = bPldVal; + (gpphDnldContext->tUserData.wLen) = sizeof(bPldVal); + + memset(&(gpphDnldContext->tRWInfo), 0, sizeof(gpphDnldContext->tRWInfo)); + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventForce); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("Force Command Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("Force Command Request Failed!!"); + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_SetHwDevHandle +** +** Description Stores the HwDev handle to download context. The handle is +** required for subsequent operations +** +** Parameters None +** +** Returns None - +** +*******************************************************************************/ +void phDnldNfc_SetHwDevHandle(void) { + pphDnldNfc_DlContext_t psDnldContext = NULL; + + if (NULL == gpphDnldContext) { + NXPLOG_FWDNLD_D("Allocating Mem for Dnld Context.."); + /* Create the memory for Download Mgmt Context */ + psDnldContext = + (pphDnldNfc_DlContext_t)malloc(sizeof(phDnldNfc_DlContext_t)); + + if (psDnldContext != NULL) { + (void)memset((void*)psDnldContext, 0, sizeof(phDnldNfc_DlContext_t)); + gpphDnldContext = psDnldContext; + } else { + NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context..") + } + } else { + (void)memset((void*)gpphDnldContext, 0, sizeof(phDnldNfc_DlContext_t)); + } + return; +} + +/******************************************************************************* +** +** Function phDnldNfc_ReSetHwDevHandle +** +** Description Frees the HwDev handle to download context. +** +** Parameters None +** +** Returns None - +** +*******************************************************************************/ +void phDnldNfc_ReSetHwDevHandle(void) { + if (gpphDnldContext != NULL) { + NXPLOG_FWDNLD_E("Freeing Mem for Dnld Context..") + free(gpphDnldContext); + gpphDnldContext = NULL; + } +} + +/******************************************************************************* +** +** Function phDnldNfc_RawReq +** +** Description Sends raw frame request to NFCC. +** It is currently used for sending an NCI RESET cmd after +** doing a production key update +** +** Parameters pFrameData - input buffer, contains raw frame packet to be +** sent to NFCC +** pRspData - response buffer received from NFCC +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - GetSessionState request to NFCC is +** successful +** NFCSTATUS_FAILED - GetSessionState request failed due to +** internal error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData, + pphDnldNfc_Buff_t pRspData, + pphDnldNfc_RspCb_t pNotify, void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pFrameData) || (NULL == pNotify) || (NULL == pRspData) || + (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Raw Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if (((NULL != pFrameData->pBuff) && (0 != pFrameData->wLen)) && + ((NULL != pRspData->pBuff) && (0 != pRspData->wLen))) { + (gpphDnldContext->tRspBuffInfo.pBuff) = pRspData->pBuff; + (gpphDnldContext->tRspBuffInfo.wLen) = pRspData->wLen; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRaw; + (gpphDnldContext->tCmdId) = PH_DL_CMD_NONE; + (gpphDnldContext->tUserData.pBuff) = pFrameData->pBuff; + (gpphDnldContext->tUserData.wLen) = pFrameData->wLen; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRaw); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("RawFrame Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("RawFrame Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Buff Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_InitImgInfo +** +** Description Extracts image information and stores it in respective +** variables, to be used internally for write operation +** +** Parameters None +** +** Returns NFC status +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_InitImgInfo(void) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t* pImageInfo = NULL; + uint16_t ImageInfoLen = 0; + char fwFileName[256]; + char fwpathName[256]; + char* pathName = NULL; + + /* if memory is not allocated then allocate memory for download context + * structure */ + phDnldNfc_SetHwDevHandle(); + + /*Read Firmware file name from config file*/ + if (GetNxpStrValue(NAME_NXP_FW_NAME, fwFileName, sizeof(fwFileName)) == + true) { + strcpy(fwpathName, FW_DLL_ROOT_DIR); + strncat(fwpathName, fwFileName, strlen(fwFileName)); + pathName = fwpathName; + } + +/* load the library and get the image info pointer */ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (gRecFWDwnld == true) + wStatus = phDnldNfc_LoadRecoveryFW(pathName, &pImageInfo, &ImageInfoLen); + else +#endif + wStatus = phDnldNfc_LoadFW(pathName, &pImageInfo, &ImageInfoLen); + + NXPLOG_FWDNLD_E("FW Image Length - ImageInfoLen %d", ImageInfoLen); + NXPLOG_FWDNLD_E("FW Image Info Pointer - pImageInfo %p", pImageInfo); + + if ((pImageInfo == NULL) || (ImageInfoLen == 0)) { + NXPLOG_FWDNLD_E( + "Image extraction Failed - invalid imginfo or imginfolen!!"); + wStatus = NFCSTATUS_FAILED; + } + + if (wStatus != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("Error loading libpn54x_fw !!\n"); + } + + /* get the MW version */ + if (NFCSTATUS_SUCCESS == wStatus) { + // NXPLOG_FWDNLD_D("MW Major Version Num - %x",NXP_MW_VERSION_MAJ); + // NXPLOG_FWDNLD_D("MW Minor Version Num - %x",NXP_MW_VERSION_MIN); + wMwVer = (((uint16_t)(NXP_MW_VERSION_MAJ) << 8U) | (NXP_MW_VERSION_MIN)); + } + + if (NFCSTATUS_SUCCESS == wStatus) { + gpphDnldContext->nxp_nfc_fw = (uint8_t*)pImageInfo; + gpphDnldContext->nxp_nfc_fw_len = ImageInfoLen; + if ((NULL != gpphDnldContext->nxp_nfc_fw) && + (0 != gpphDnldContext->nxp_nfc_fw_len)) { + NXPLOG_FWDNLD_E("FW Major Version Num - %x", + gpphDnldContext->nxp_nfc_fw[5]); + NXPLOG_FWDNLD_E("FW Minor Version Num - %x", + gpphDnldContext->nxp_nfc_fw[4]); + NXPLOG_FWDNLD_E("FW Image Length - %d", ImageInfoLen); + NXPLOG_FWDNLD_E("FW Image Info Pointer - %p", pImageInfo); + + /* get the FW version */ + wFwVer = (((uint16_t)(gpphDnldContext->nxp_nfc_fw[5]) << 8U) | + (gpphDnldContext->nxp_nfc_fw[4])); + wStatus = NFCSTATUS_SUCCESS; + } else { + NXPLOG_FWDNLD_E("Image details extraction Failed!!"); + wStatus = NFCSTATUS_FAILED; + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_LoadRecInfo +** +** Description Extracts recovery sequence image information and stores it +** in respective variables, to be used internally for write +** operation +** +** Parameters None +** +** Returns NFC status +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_LoadRecInfo(void) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t* pImageInfo = NULL; + uint16_t ImageInfoLen = 0; + + /* if memory is not allocated then allocate memory for donwload context + * structure */ + phDnldNfc_SetHwDevHandle(); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (gRecFWDwnld == true) + wStatus = + phDnldNfc_LoadRecoveryFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen); + else +#endif + wStatus = phDnldNfc_LoadFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen); + if ((pImageInfo == NULL) || (ImageInfoLen == 0)) { + NXPLOG_FWDNLD_E( + "Image extraction Failed - invalid imginfo or imginfolen!!"); + wStatus = NFCSTATUS_FAILED; + } + + /* load the PLL recovery image library */ + if (wStatus != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("Error loading libpn54x_fw_platform !!\n"); + } + + if (NFCSTATUS_SUCCESS == wStatus) { + /* fetch the PLL recovery image pointer and the image length */ + gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo; + gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen; + if ((NULL != gpphDnldContext->nxp_nfc_fwp) && + (0 != gpphDnldContext->nxp_nfc_fwp_len)) { + NXPLOG_FWDNLD_D("Recovery Image Length - %d", ImageInfoLen); + NXPLOG_FWDNLD_D("Recovery Image Info Pointer - %p", pImageInfo); + wStatus = NFCSTATUS_SUCCESS; + } else { + NXPLOG_FWDNLD_E("Recovery Image details extraction Failed!!"); + wStatus = NFCSTATUS_FAILED; + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_LoadPKInfo +** +** Description Extracts production sequence image information and stores it +** in respective variables, to be used internally for write +** operation +** +** Parameters None +** +** Returns NFC status +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_LoadPKInfo(void) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t* pImageInfo = NULL; + uint16_t ImageInfoLen = 0; + + /* if memory is not allocated then allocate memory for donwload context + * structure */ + phDnldNfc_SetHwDevHandle(); + +/* load the PKU image library */ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (gRecFWDwnld == true) + wStatus = + phDnldNfc_LoadRecoveryFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen); + else +#endif + wStatus = phDnldNfc_LoadFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen); + if ((pImageInfo == NULL) || (ImageInfoLen == 0)) { + NXPLOG_FWDNLD_E( + "Image extraction Failed - invalid imginfo or imginfolen!!"); + wStatus = NFCSTATUS_FAILED; + } + + if (wStatus != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("Error loading libpn54x_fw_pku !!\n"); + } + + if (NFCSTATUS_SUCCESS == wStatus) { + /* fetch the PKU image pointer and the image length */ + gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo; + gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen; + + if ((NULL != gpphDnldContext->nxp_nfc_fwp) && + (0 != gpphDnldContext->nxp_nfc_fwp_len)) { + NXPLOG_FWDNLD_D("PKU Image Length - %d", ImageInfoLen); + NXPLOG_FWDNLD_D("PKU Image Info Pointer - %p", pImageInfo); + wStatus = NFCSTATUS_SUCCESS; + } else { + NXPLOG_FWDNLD_E("PKU Image details extraction Failed!!"); + wStatus = NFCSTATUS_FAILED; + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_CloseFwLibHandle +** +** Description Closes previously opened fw library handle as part of +** dynamic loader processing +** +** Parameters None +** +** Returns None +** +*******************************************************************************/ +void phDnldNfc_CloseFwLibHandle(void) { + NFCSTATUS wStatus; + + wStatus = phDnldNfc_UnloadFW(); + if (wStatus != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("free library FAILED !!\n"); + } else { + NXPLOG_FWDNLD_E("free library SUCCESS !!\n"); + } + return; +} + +/******************************************************************************* +** +** Function phDnldNfc_LoadFW +** +** Description Load the firmware version form firmware lib +** +** Parameters pathName - Firmware image path +** pImgInfo - Firmware image handle +** pImgInfoLen - Firmware image length +** +** Returns NFC status +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t** pImgInfo, + uint16_t* pImgInfoLen) { + void* pImageInfo = NULL; + void* pImageInfoLen = NULL; + if (pathName == NULL) { +#if (NFC_NXP_CHIP_TYPE == PN548C2) + pathName = "/system/vendor/firmware/libpn548ad_fw.so"; +#elif (NFC_NXP_CHIP_TYPE == PN551) + pathName = "/system/vendor/firmware/libpn551_fw.so"; +#elif (NFC_NXP_CHIP_TYPE == PN553) + pathName = "/system/vendor/firmware/libpn553_fw.so"; +#else + pathName = "/system/vendor/firmware/libpn547_fw.so"; +#endif + } + + /* check if the handle is not NULL then free the library */ + if (pFwLibHandle != NULL) { + phDnldNfc_UnloadFW(); + pFwLibHandle = NULL; + } + + /* load the DLL file */ + pFwLibHandle = dlopen(pathName, RTLD_LAZY); + NXPLOG_FWDNLD_D("@@@%s", pathName); + + /* if library load failed then handle will be NULL */ + if (pFwLibHandle == NULL) { + NXPLOG_FWDNLD_E( + "NULL handler : unable to load the library file, specify correct path"); + return NFCSTATUS_FAILED; + } + + dlerror(); /* Clear any existing error */ + + /* load the address of download image pointer and image size */ + pImageInfo = (void*)dlsym(pFwLibHandle, "gphDnldNfc_DlSeq"); + + if (dlerror() || (NULL == pImageInfo)) { + NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeq"); + return NFCSTATUS_FAILED; + } + (*pImgInfo) = (*(uint8_t**)pImageInfo); + + pImageInfoLen = (void*)dlsym(pFwLibHandle, "gphDnldNfc_DlSeqSz"); + if (dlerror() || (NULL == pImageInfoLen)) { + NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqSz"); + return NFCSTATUS_FAILED; + } + + (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen)); + + return NFCSTATUS_SUCCESS; +} + +#if (NFC_NXP_CHIP_TYPE != PN547C2) +/******************************************************************************* +** +** Function phDnldNfc_LoadRecoveryFW +** +** Description Load the dummy firmware version form firmware lib for +** recovery. This will change the FW version of the NFCC +** firmware and enable flashing of firmware of same version. +** +** Parameters pathName - Firmware image path +** pImgInfo - Firmware image handle +** pImgInfoLen - Firmware image length +** +** Returns NFCSTATUS +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_LoadRecoveryFW(const char* pathName, uint8_t** pImgInfo, + uint16_t* pImgInfoLen) { + void* pImageInfo = NULL; + void* pImageInfoLen = NULL; + + /* check for path name */ + if (pathName == NULL) { +#if (NFC_NXP_CHIP_TYPE == PN548C2) + pathName = "/system/vendor/firmware/libpn548ad_fw.so"; +#elif (NFC_NXP_CHIP_TYPE == PN551) + pathName = "/system/vendor/firmware/libpn551_fw.so"; +#elif (NFC_NXP_CHIP_TYPE == PN553) + pathName = "/system/vendor/firmware/libpn553_fw.so"; +#else + pathName = "/system/vendor/firmware/libpn547_fw.so"; +#endif + } + + /* check if the handle is not NULL then free the library */ + if (pFwLibHandle != NULL) { + phDnldNfc_UnloadFW(); + pFwLibHandle = NULL; + } + /* load the DLL file */ + pFwLibHandle = dlopen(pathName, RTLD_LAZY); + NXPLOG_FWDNLD_D("phDnldNfc_LoadRecoveryFW %s ", pathName); + + /* if library load failed then handle will be NULL */ + if (pFwLibHandle == NULL) { + NXPLOG_FWDNLD_E( + "NULL handler : unable to load the library file, specify correct path"); + return NFCSTATUS_FAILED; + } + + dlerror(); /* Clear any existing error */ + + /* load the address of download image pointer and image size */ + pImageInfo = (void*)dlsym(pFwLibHandle, "gphDnldNfc_DummyDlSeq"); + + if (dlerror() || (NULL == pImageInfo)) { + NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DummyDlSeq"); + return NFCSTATUS_FAILED; + } + + (*pImgInfo) = (*(uint8_t**)pImageInfo); + pImageInfoLen = (void*)dlsym(pFwLibHandle, "gphDnldNfc_DlSeqDummyFwSz"); + if (dlerror() || (NULL == pImageInfoLen)) { + NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqDummyFwSz"); + return NFCSTATUS_FAILED; + } + + (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen)); + + return NFCSTATUS_SUCCESS; +} +#endif + +/******************************************************************************* +** +** Function phDnldNfc_UnloadFW +** +** Description Deinit the firmware handle +** +** Parameters None +** +** Returns NFC status +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_UnloadFW(void) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + int32_t status; + + /* check if the handle is not NULL then free the library */ + if (pFwLibHandle != NULL) { + status = dlclose(pFwLibHandle); + pFwLibHandle = NULL; + + dlerror(); /* Clear any existing error */ + if (status != 0) { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E("Free library file failed"); + } + } + + return wStatus; +} + +#ifdef EEPROM_Read_Mem_IMP +/******************************************************************************* +** +** Function phDnldNfc_ReadMem +** +** Description Dumps the contents of EEPROM. The handle is required for +** subsequent operations +** +** Parameters pHwRef - pointer to the hardware device +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - request to NFCC is successful +** NFCSTATUS_FAILED - request failed due to internal error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_ReadMem(void* pHwRef, pphDnldNfc_RspCb_t pNotify, + void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint32_t wAddr = 0x2011C0; /* eeprom platform specific area start address */ + uint32_t wRdAddr = 0; + uint8_t* pAddr; + static uint8_t bRdData[3519]; /* buffer to hold the read data */ + static phDnldNfc_Buff_t Data; + + if ((NULL == pNotify) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + /* Call Tml Ioctl to enable download mode */ + wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode); + + if (NFCSTATUS_SUCCESS == wStatus) { + /* Set the obtained device handle to download module */ + phDnldNfc_SetHwDevHandle(); + } else { + wStatus = NFCSTATUS_FAILED; + } + + if (NFCSTATUS_SUCCESS == wStatus) { + pAddr = (uint8_t*)&wAddr; + + wRdAddr = (pAddr[3]); + wRdAddr <<= 8; + wRdAddr |= (pAddr[2]); + wRdAddr <<= 8; + wRdAddr |= (pAddr[1]); + wRdAddr <<= 8; + wRdAddr |= (pAddr[0]); + + Data.pBuff = bRdData; + Data.wLen = sizeof(bRdData); + UserCb = pNotify; + UserCtxt = pContext; + + wStatus = phDnldNfc_Read(&Data, wRdAddr, + (pphDnldNfc_RspCb_t)phDnldNfc_ReadComplete, + gpphDnldContext); + } else { + Data.pBuff = NULL; + Data.wLen = 0; + wStatus = NFCSTATUS_FAILED; + } + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("Read Request submitted successfully.."); + } else { + NXPLOG_FWDNLD_E("Read Request submission failed!!"); + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_ReadComplete +** +** Description Read complete +** +** Parameters pContext - caller layer context +** status - status of the transaction +** pInfo - transaction info +** +** Returns None +** +*******************************************************************************/ +static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + UNUSED(pContext); + + /* Call Tml Ioctl to enable/restore normal mode */ + wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("Read Done!!"); + } + + UserCb(&UserCtxt, status, pInfo); + + return; +} + +/******************************************************************************* +** +** Function phDnldNfc_Read +** +** Description Retrieves requested data of specified length from desired +** EEPROM address +** +** Parameters pData - response buffer which gets updated with data from +** EEPROM +** dwRdAddr - EEPROM address for data read +** pNotify - notify caller after getting response +** pContext - caller context +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - Read request to NFCC is successful +** NFCSTATUS_FAILED - Read request failed due to internal error +** NFCSTATUS_NOT_ALLOWED - command not allowed +** Other command specific errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr, + pphDnldNfc_RspCb_t pNotify, void* pContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) { + NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY); + } else { + if ((NULL != pData->pBuff) && (0 != pData->wLen)) { + (gpphDnldContext->tCmdId) = PH_DL_CMD_READ; + (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead; + (gpphDnldContext->FrameInp.dwAddr) = dwRdAddr; + (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff; + (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen; + (gpphDnldContext->tUserData.pBuff) = NULL; + (gpphDnldContext->tUserData.wLen) = 0; + (gpphDnldContext->UserCb) = pNotify; + (gpphDnldContext->UserCtxt) = pContext; + + memset(&(gpphDnldContext->tRWInfo), 0, + sizeof(gpphDnldContext->tRWInfo)); + + wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead); + + if (NFCSTATUS_PENDING == wStatus) { + NXPLOG_FWDNLD_D("Read Request submitted successfully"); + } else { + NXPLOG_FWDNLD_E("Read Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Buff Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return wStatus; +} +#endif diff --git a/pn54x/dnld/phDnldNfc.h b/pn54x/dnld/phDnldNfc.h new file mode 100644 index 0000000..5b7e420 --- /dev/null +++ b/pn54x/dnld/phDnldNfc.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Firmware Download Interface File + */ +#ifndef PHDNLDNFC_H +#define PHDNLDNFC_H + +#include <phNfcStatus.h> + +/* + * + * Callback for handling the received data/response from PN54X. + * Parameters to be passed/registered to download context during respective + * download function call: + * pContext - Upper layer context + * wStatus - Status of the transaction + * pInfo - Contains the Transaction Info + */ +typedef void (*pphDnldNfc_RspCb_t)(void* pContext, NFCSTATUS wStatus, + void* pInfo); + +#define PHLIBNFC_FWDNLD_SESSNOPEN (0x01U) /* download session is Open */ +#define PHLIBNFC_FWDNLD_SESSNCLOSED (0x00U) /* download session is Closed */ + +#define PHDNLDNFC_HWVER_MRA1_0 (0x01U) /* ChipVersion MRA1.0 */ +#define PHDNLDNFC_HWVER_MRA1_1 (0x02U) /* ChipVersion MRA1.1 */ +#define PHDNLDNFC_HWVER_MRA2_0 (0x03U) /* ChipVersion MRA2.0 */ +#define PHDNLDNFC_HWVER_MRA2_1 (0x04U) /* ChipVersion MRA2.1 */ +#define PHDNLDNFC_HWVER_MRA2_2 (0x05U) /* ChipVersion MRA2.2 */ + +/* PN548AD ChipVersion MRA1.0 */ +#define PHDNLDNFC_HWVER_PN548AD_MRA1_0 (0x08U) + +/* PN551 ChipVersion MRA1.0 */ +#define PHDNLDNFC_HWVER_PN551_MRA1_0 (0x08U) +/* PN553-NCI1.0 ChipVersion MRA1.0 */ +#define PHDNLDNFC_HWVER_PN553_MRA1_0 (0x0BU) +/* PN553 A0 -> 0x40 hardware version + PN553 B0 -> 0x41 + PN80T A0 -> 0x50 + PN80T B0 -> 0x51 */ +#define PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED (0x40U) +/* + * Enum definition contains Download Life Cycle States + */ +typedef enum phDnldNfc_LC { + phDnldNfc_LCCreat = 11, /* Life Cycle Creation*/ + phDnldNfc_LCInit = 13, /* Life Cycle Initializing */ + phDnldNfc_LCOper = 17, /* Life Cycle Operational */ + phDnldNfc_LCTerm = 19 /* Life Cycle Termination */ +} phDnldNfc_LC_t; + +/* + * Enum definition contains Clk Source Options for Force command request + */ +typedef enum phDnldNfc_ClkSrc { + phDnldNfc_ClkSrcXtal = 1U, /* Crystal */ + phDnldNfc_ClkSrcPLL = 2U, /* PLL output */ + phDnldNfc_ClkSrcPad = 3U /* Directly use clk on CLK_IN Pad */ +} phDnldNfc_ClkSrc_t; + +/* + * Enum definition contains Clk Frequency value for Force command request + */ +typedef enum phDnldNfc_ClkFreq { + phDnldNfc_ClkFreq_13Mhz = 0U, /* 13Mhz Clk Frequency */ + phDnldNfc_ClkFreq_19_2Mhz = 1U, /* 19.2Mhz Clk Frequency */ + phDnldNfc_ClkFreq_24Mhz = 2U, /* 24Mhz Clk Frequency */ + phDnldNfc_ClkFreq_26Mhz = 3U, /* 26Mhz Clk Frequency */ + phDnldNfc_ClkFreq_38_4Mhz = 4U, /* 38.4Mhz Clk Frequency */ + phDnldNfc_ClkFreq_52Mhz = 5U /* 52Mhz Clk Frequency */ +} phDnldNfc_ClkFreq_t; + +/* + * Struct contains buffer where user payload shall be stored + */ +typedef struct phDnldNfc_Buff { + uint8_t* pBuff; /*pointer to the buffer where user payload shall be stored*/ + uint16_t wLen; /*Buffer length*/ +} phDnldNfc_Buff_t, *pphDnldNfc_Buff_t; /* pointer to #phDnldNfc_Buff_t */ + +/* +*********************** Function Prototype Declaration ************************* +*/ + +extern NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void* pContext); +extern NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo, + pphDnldNfc_RspCb_t pNotify, + void* pContext); +extern NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, + pphDnldNfc_Buff_t pCRCData, + pphDnldNfc_RspCb_t pNotify, + void* pContext); +extern NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession, + pphDnldNfc_RspCb_t pNotify, + void* pContext); +extern NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, + pphDnldNfc_RspCb_t pNotify, void* pContext); +extern NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr, + pphDnldNfc_RspCb_t pNotify, void* pContext); +extern NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, + pphDnldNfc_RspCb_t pNotify, void* pContext); +extern NFCSTATUS phDnldNfc_Write(bool_t bRecoverSeq, pphDnldNfc_Buff_t pData, + pphDnldNfc_RspCb_t pNotify, void* pContext); +extern NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, + pphDnldNfc_RspCb_t pNotify, void* pContext); +extern void phDnldNfc_SetHwDevHandle(void); +void phDnldNfc_ReSetHwDevHandle(void); +extern NFCSTATUS phDnldNfc_ReadMem(void* pHwRef, pphDnldNfc_RspCb_t pNotify, + void* pContext); +extern NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData, + pphDnldNfc_Buff_t pRspData, + pphDnldNfc_RspCb_t pNotify, void* pContext); +extern NFCSTATUS phDnldNfc_InitImgInfo(void); +extern NFCSTATUS phDnldNfc_LoadRecInfo(void); +extern NFCSTATUS phDnldNfc_LoadPKInfo(void); +extern void phDnldNfc_CloseFwLibHandle(void); +extern NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t** pImgInfo, + uint16_t* pImgInfoLen); +#if (NFC_NXP_CHIP_TYPE != PN547C2) +extern NFCSTATUS phDnldNfc_LoadRecoveryFW(const char* pathName, + uint8_t** pImgInfo, + uint16_t* pImgInfoLen); +#endif +extern NFCSTATUS phDnldNfc_UnloadFW(void); +#endif /* PHDNLDNFC_H */ diff --git a/pn54x/dnld/phDnldNfc_Cmd.h b/pn54x/dnld/phDnldNfc_Cmd.h new file mode 100644 index 0000000..31992f6 --- /dev/null +++ b/pn54x/dnld/phDnldNfc_Cmd.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Firmware Download command values + */ + +#ifndef PHDNLDNFC_CMD_H +#define PHDNLDNFC_CMD_H + +#include <phNfcStatus.h> + +/* + * Enum definition contains Firmware Download Command Ids + */ +typedef enum phDnldNfc_CmdId { + PH_DL_CMD_NONE = 0x00, /* Invalid Cmd */ + PH_DL_CMD_RESET = 0xF0, /* Reset */ + PH_DL_CMD_GETVERSION = 0xF1, /* Get Version */ + PH_DL_CMD_CHECKINTEGRITY = 0xE0, /* Check Integrity */ + PH_DL_CMD_WRITE = 0xC0, /* Write */ + PH_DL_CMD_READ = 0xA2, /* Read */ + PH_DL_CMD_LOG = 0xA7, /* Log */ + PH_DL_CMD_FORCE = 0xD0, /* Force */ + PH_DL_CMD_GETSESSIONSTATE = 0xF2 /* Get Session State */ +} phDnldNfc_CmdId_t; + +#endif /* PHDNLDNFC_CMD_H */ diff --git a/pn54x/dnld/phDnldNfc_Internal.c b/pn54x/dnld/phDnldNfc_Internal.c new file mode 100644 index 0000000..2a66af1 --- /dev/null +++ b/pn54x/dnld/phDnldNfc_Internal.c @@ -0,0 +1,1215 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Internal Download Management routines + * Download Component + */ + +#include <phDnldNfc_Internal.h> +#include <phDnldNfc_Utils.h> +#include <phNxpLog.h> +#include <phNxpNciHal_utils.h> +#include <phTmlNfc.h> + +/* Minimum length of payload including 1 byte CmdId */ +#define PHDNLDNFC_MIN_PLD_LEN (0x04U) + +/* Offset of Length byte within the frame */ +#define PHDNLDNFC_FRAME_HDR_OFFSET (0x00) +/* Offset of FrameId within the frame */ +#define PHDNLDNFC_FRAMEID_OFFSET (PHDNLDNFC_FRAME_HDR_LEN) +/* Offset of status byte within the frame */ +#define PHDNLDNFC_FRAMESTATUS_OFFSET PHDNLDNFC_FRAMEID_OFFSET +/* Offset within frame where payload starts*/ +#define PHDNLDNFC_PLD_OFFSET (PHDNLDNFC_MIN_PLD_LEN - 1) + +#define PHDNLDNFC_FRAME_RDDATA_OFFSET \ + ((PHDNLDNFC_FRAME_HDR_LEN) + \ + (PHDNLDNFC_MIN_PLD_LEN)) /* recvd frame offset where data starts */ + +/* Size of first secure write frame Signature */ +#define PHDNLDNFC_FRAME_SIGNATURE_SIZE (0xC0U) +/* Size of first secure write frame payload */ +#define PHDNLDNFC_FIRST_FRAME_PLD_SIZE (0xE4U) + +/* Status response for first fragmented write frame */ +#define PHDNLDNFC_FIRST_FRAGFRAME_RESP (0x2DU) +/* Status response for subsequent fragmented write frame */ +#define PHDNLDNFC_NEXT_FRAGFRAME_RESP (0x2EU) + +#define PHDNLDNFC_SET_HDR_FRAGBIT(n) \ + ((n) | (1 << 10)) /* Header chunk bit set macro */ +#define PHDNLDNFC_CLR_HDR_FRAGBIT(n) \ + ((n) & ~(1U << 10)) /* Header chunk bit clear macro */ +#define PHDNLDNFC_CHK_HDR_FRAGBIT(n) \ + ((n)&0x04) /* macro to check if frag bit is set in Hdr */ + +/* Timeout value to wait for response from NFCC */ +#define PHDNLDNFC_RSP_TIMEOUT (2500) +/* Timeout value to wait before resending the last frame */ +#define PHDNLDNFC_RETRY_FRAME_WRITE (50) + +/* size of EEPROM user data length */ +#define PHDNLDNFC_USERDATA_EEPROM_LENSIZE (0x02U) +/* size of EEPROM offset */ +#define PHDNLDNFC_USERDATA_EEPROM_OFFSIZE (0x02U) + +#ifdef NXP_PN547C1_DOWNLOAD +/* EEPROM offset and length value for PN547C1 */ +/* 16 bits offset indicating user data area start location */ +#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x003CU) +/* 16 bits length of user data area */ +#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0DC0U) +#else + +#if (NFC_NXP_CHIP_TYPE == PN548C2) +/* EEPROM offset and length value for PN548AD */ +/* 16 bits offset indicating user data area start location */ +#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x02BCU) +/* 16 bits length of user data area */ +#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0C00U) +#elif (NFC_NXP_CHIP_TYPE == PN551) +/* EEPROM offset and length value for PN551 */ +/* 16 bits offset indicating user data area start location */ +#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x02BCU) +/* 16 bits length of user data area */ +#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0C00U) +#else +/* EEPROM offset and length value for PN547C2 */ +/* 16 bits offset indicating user data area start location */ +#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x023CU) +/* 16 bits length of user data area */ +#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0C80U) +#endif + +#endif +#define PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT (1) + +/* Function prototype declarations */ +static void phDnldNfc_ProcessSeqState(void* pContext, + phTmlNfc_TransactInfo_t* pInfo); +static void phDnldNfc_ProcessRWSeqState(void* pContext, + phTmlNfc_TransactInfo_t* pInfo); +static NFCSTATUS phDnldNfc_ProcessFrame(void* pContext, + phTmlNfc_TransactInfo_t* pInfo); +static NFCSTATUS phDnldNfc_ProcessRecvInfo(void* pContext, + phTmlNfc_TransactInfo_t* pInfo); +static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext); +static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext); +static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext); +static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t pDlContext, + phTmlNfc_TransactInfo_t* pInfo, + uint16_t wPldLen); +static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void* pContext); +static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void* pContext); + +/* +*************************** Function Definitions *************************** +*/ + +/******************************************************************************* +** +** Function phDnldNfc_CmdHandler +** +** Description Download Command Handler Mechanism +** - holds the sub states for each command processing +** - coordinates with TML download thread to complete a +** download command request +** - calls the user callback on completion of a cmd +** +** Parameters pContext - pointer to the download context structure +** TrigEvent - event requested by user +** +** Returns NFC status: +** NFCSTATUS_PENDING - download request sent to NFCC +** successfully,response pending +** NFCSTATUS_BUSY - handler is busy processing a download +** request +** NFCSTATUS_INVALID_PARAMETER - one or more of the supplied +** parameters could not be +** interpreted properly +** Other errors +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_CmdHandler(void* pContext, phDnldNfc_Event_t TrigEvent) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext; + + if (NULL == pDlCtxt) { + NXPLOG_FWDNLD_E("Invalid Input Parameter!!"); + status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + switch (TrigEvent) { + case phDnldNfc_EventReset: + case phDnldNfc_EventGetVer: + case phDnldNfc_EventIntegChk: + case phDnldNfc_EventGetSesnSt: + case phDnldNfc_EventRaw: { + if (phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent)) { + NXPLOG_FWDNLD_D("Processing Normal Sequence.."); + pDlCtxt->tCurrEvent = TrigEvent; + pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy; + + phDnldNfc_ProcessSeqState(pDlCtxt, NULL); + + status = pDlCtxt->wCmdSendStatus; + } else { + NXPLOG_FWDNLD_E("Prev Norml Sequence not completed/restored!!"); + status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + break; + } + case phDnldNfc_EventWrite: + case phDnldNfc_EventRead: + case phDnldNfc_EventLog: + case phDnldNfc_EventForce: { + if (phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent)) { + NXPLOG_FWDNLD_D("Processing R/W Sequence.."); + pDlCtxt->tCurrEvent = TrigEvent; + pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy; + + phDnldNfc_ProcessRWSeqState(pDlCtxt, NULL); + + status = pDlCtxt->wCmdSendStatus; + } else { + NXPLOG_FWDNLD_E("Prev R/W Sequence not completed/restored!!"); + status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + break; + } + default: { + /* Unknown Event */ + NXPLOG_FWDNLD_E("Unknown Event Parameter!!"); + status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + break; + } + } + } + + return status; +} + +/******************************************************************************* +** +** Function phDnldNfc_ProcessSeqState +** +** Description Processes all cmd/resp sequences except read & write +** +** Parameters pContext - pointer to the download context structure +** pInfo - pointer to the Transaction buffer updated by TML +** Thread +** +** Returns None +** +*******************************************************************************/ +static void phDnldNfc_ProcessSeqState(void* pContext, + phTmlNfc_TransactInfo_t* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + NFCSTATUS wIntStatus; + uint32_t TimerId; + pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext; + + if (NULL == pDlCtxt) { + NXPLOG_FWDNLD_E("Invalid Input Parameter!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + switch (pDlCtxt->tCurrState) { + case phDnldNfc_StateInit: { + NXPLOG_FWDNLD_D("Initializing Sequence.."); + + if (0 == (pDlCtxt->TimerInfo.dwRspTimerId)) { + TimerId = phOsalNfc_Timer_Create(); + + if (0 == TimerId) { + NXPLOG_FWDNLD_W("Response Timer Create failed!!"); + wStatus = NFCSTATUS_INSUFFICIENT_RESOURCES; + pDlCtxt->wCmdSendStatus = wStatus; + break; + } else { + NXPLOG_FWDNLD_D("Response Timer Created Successfully"); + (pDlCtxt->TimerInfo.dwRspTimerId) = TimerId; + (pDlCtxt->TimerInfo.TimerStatus) = 0; + (pDlCtxt->TimerInfo.wTimerExpStatus) = 0; + } + } + pDlCtxt->tCurrState = phDnldNfc_StateSend; + } + case phDnldNfc_StateSend: { + wStatus = phDnldNfc_BuildFramePkt(pDlCtxt); + + if (NFCSTATUS_SUCCESS == wStatus) { + pDlCtxt->tCurrState = phDnldNfc_StateRecv; + + wStatus = phTmlNfc_Write( + (pDlCtxt->tCmdRspFrameInfo.aFrameBuff), + (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength), + (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState, + pDlCtxt); + } + pDlCtxt->wCmdSendStatus = wStatus; + break; + } + case phDnldNfc_StateRecv: { + wStatus = phDnldNfc_ProcessRecvInfo(pContext, pInfo); + + if (NFCSTATUS_SUCCESS == wStatus) { + wStatus = phOsalNfc_Timer_Start((pDlCtxt->TimerInfo.dwRspTimerId), + PHDNLDNFC_RSP_TIMEOUT, + &phDnldNfc_RspTimeOutCb, pDlCtxt); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("Response timer started"); + pDlCtxt->TimerInfo.TimerStatus = 1; + pDlCtxt->tCurrState = phDnldNfc_StateTimer; + } else { + NXPLOG_FWDNLD_W("Response timer not started"); + pDlCtxt->tCurrState = phDnldNfc_StateResponse; + } + /* Call TML_Read function and register the call back function */ + wStatus = phTmlNfc_Read( + pDlCtxt->tCmdRspFrameInfo.aFrameBuff, + (uint16_t)PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE, + (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState, + (void*)pDlCtxt); + + /* set read status to pDlCtxt->wCmdSendStatus to enable callback */ + pDlCtxt->wCmdSendStatus = wStatus; + break; + } else { + /* Setting TimerExpStatus below to avoid frame processing in response + * state */ + (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT; + pDlCtxt->tCurrState = phDnldNfc_StateResponse; + } + } + case phDnldNfc_StateTimer: { + if (1 == (pDlCtxt->TimerInfo.TimerStatus)) /*Is Timer Running*/ + { + /*Stop Timer*/ + (void)phOsalNfc_Timer_Stop(pDlCtxt->TimerInfo.dwRspTimerId); + (pDlCtxt->TimerInfo.TimerStatus) = 0; /*timer stopped*/ + } + pDlCtxt->tCurrState = phDnldNfc_StateResponse; + } + case phDnldNfc_StateResponse: { + if (NFCSTATUS_RF_TIMEOUT != (pDlCtxt->TimerInfo.wTimerExpStatus)) { + /* Process response */ + wStatus = phDnldNfc_ProcessFrame(pContext, pInfo); + } else { + if (phDnldNfc_EventReset != pDlCtxt->tCurrEvent) { + wStatus = (pDlCtxt->TimerInfo.wTimerExpStatus); + } else { + wStatus = NFCSTATUS_SUCCESS; + } + (pDlCtxt->TimerInfo.wTimerExpStatus) = 0; + } + + /* Abort TML read operation which is always kept open */ + wIntStatus = phTmlNfc_ReadAbort(); + + if (NFCSTATUS_SUCCESS != wIntStatus) { + /* TODO:-Action to take in this case:-Tml read abort failed!? */ + NXPLOG_FWDNLD_W("Tml Read Abort failed!!"); + } + + pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid; + pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle; + pDlCtxt->tCurrState = phDnldNfc_StateInit; + + /* Delete the timer & reset timer primitives in context */ + (void)phOsalNfc_Timer_Delete(pDlCtxt->TimerInfo.dwRspTimerId); + (pDlCtxt->TimerInfo.dwRspTimerId) = 0; + (pDlCtxt->TimerInfo.TimerStatus) = 0; + (pDlCtxt->TimerInfo.wTimerExpStatus) = 0; + + if ((NULL != (pDlCtxt->UserCb)) && (NULL != (pDlCtxt->UserCtxt))) { + pDlCtxt->UserCb((pDlCtxt->UserCtxt), wStatus, + &(pDlCtxt->tRspBuffInfo)); + } + break; + } + default: { + pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid; + pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle; + break; + } + } + } + + return; +} + +/******************************************************************************* +** +** Function phDnldNfc_ProcessRWSeqState +** +** Description Processes read/write cmd/rsp sequence +** +** Parameters pContext - pointer to the download context structure +** pInfo - pointer to the Transaction buffer updated by TML +** Thread +** +** Returns None +** +*******************************************************************************/ +static void phDnldNfc_ProcessRWSeqState(void* pContext, + phTmlNfc_TransactInfo_t* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + NFCSTATUS wIntStatus = wStatus; + uint32_t TimerId; + pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext; + + if (NULL == pDlCtxt) { + NXPLOG_FWDNLD_E("Invalid Input Parameter!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + switch (pDlCtxt->tCurrState) { + case phDnldNfc_StateInit: { + if (0 == (pDlCtxt->TimerInfo.dwRspTimerId)) { + TimerId = phOsalNfc_Timer_Create(); + + if (0 == TimerId) { + NXPLOG_FWDNLD_E("Response Timer Create failed!!"); + wStatus = NFCSTATUS_INSUFFICIENT_RESOURCES; + } else { + NXPLOG_FWDNLD_D("Response Timer Created Successfully"); + (pDlCtxt->TimerInfo.dwRspTimerId) = TimerId; + (pDlCtxt->TimerInfo.TimerStatus) = 0; + (pDlCtxt->TimerInfo.wTimerExpStatus) = 0; + } + } + pDlCtxt->tCurrState = phDnldNfc_StateSend; + } + case phDnldNfc_StateSend: { + if (pDlCtxt->bResendLastFrame == false) { + wStatus = phDnldNfc_BuildFramePkt(pDlCtxt); + } else { + pDlCtxt->bResendLastFrame = false; + } + + if (NFCSTATUS_SUCCESS == wStatus) { + pDlCtxt->tCurrState = phDnldNfc_StateRecv; + + wStatus = phTmlNfc_Write( + (pDlCtxt->tCmdRspFrameInfo.aFrameBuff), + (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength), + (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState, + pDlCtxt); + } + pDlCtxt->wCmdSendStatus = wStatus; + break; + } + case phDnldNfc_StateRecv: { + wStatus = phDnldNfc_ProcessRecvInfo(pContext, pInfo); + + if (NFCSTATUS_SUCCESS == wStatus) { + /* processing For Pipelined write before calling timer below */ + wStatus = phOsalNfc_Timer_Start((pDlCtxt->TimerInfo.dwRspTimerId), + PHDNLDNFC_RSP_TIMEOUT, + &phDnldNfc_RspTimeOutCb, pDlCtxt); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("Response timer started"); + pDlCtxt->TimerInfo.TimerStatus = 1; + pDlCtxt->tCurrState = phDnldNfc_StateTimer; + } else { + NXPLOG_FWDNLD_W("Response timer not started"); + pDlCtxt->tCurrState = phDnldNfc_StateResponse; + /* Todo:- diagnostic in this case */ + } + /* Call TML_Read function and register the call back function */ + wStatus = phTmlNfc_Read( + pDlCtxt->tCmdRspFrameInfo.aFrameBuff, + (uint16_t)PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE, + (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState, + (void*)pDlCtxt); + + /* set read status to pDlCtxt->wCmdSendStatus to enable callback */ + pDlCtxt->wCmdSendStatus = wStatus; + break; + } else { + /* Setting TimerExpStatus below to avoid frame processing in reponse + * state */ + (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT; + pDlCtxt->tCurrState = phDnldNfc_StateResponse; + } + } + case phDnldNfc_StateTimer: { + if (1 == (pDlCtxt->TimerInfo.TimerStatus)) /*Is Timer Running*/ + { + /* Stop Timer */ + (void)phOsalNfc_Timer_Stop(pDlCtxt->TimerInfo.dwRspTimerId); + (pDlCtxt->TimerInfo.TimerStatus) = 0; /*timer stopped*/ + } + pDlCtxt->tCurrState = phDnldNfc_StateResponse; + } + case phDnldNfc_StateResponse: { + if (NFCSTATUS_RF_TIMEOUT != (pDlCtxt->TimerInfo.wTimerExpStatus)) { + /* Process response */ + wStatus = phDnldNfc_ProcessFrame(pContext, pInfo); + + if (NFCSTATUS_BUSY == wStatus) { + /* store the status for use in subsequent processing */ + wIntStatus = wStatus; + + /* setup the resend wait timer */ + wStatus = phDnldNfc_SetupResendTimer(pDlCtxt); + + if (NFCSTATUS_SUCCESS == wStatus) { + /* restore the last mem_bsy status to avoid re-building frame + * below */ + wStatus = wIntStatus; + } + } + } else { + wStatus = (pDlCtxt->TimerInfo.wTimerExpStatus); + (pDlCtxt->TimerInfo.wTimerExpStatus) = 0; + } + + if ((0 != (pDlCtxt->tRWInfo.wRemBytes)) && + (NFCSTATUS_SUCCESS == wStatus)) { + /* Abort TML read operation which is always kept open */ + wIntStatus = phTmlNfc_ReadAbort(); + + if (NFCSTATUS_SUCCESS != wIntStatus) { + NXPLOG_FWDNLD_W("Tml read abort failed!"); + } + + wStatus = phDnldNfc_BuildFramePkt(pDlCtxt); + + if (NFCSTATUS_SUCCESS == wStatus) { + pDlCtxt->tCurrState = phDnldNfc_StateRecv; + wStatus = phTmlNfc_Write( + (pDlCtxt->tCmdRspFrameInfo.aFrameBuff), + (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength), + (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState, + pDlCtxt); + + /* TODO:- Verify here if TML_Write returned NFC_PENDING status & + take appropriate + action otherwise ?? */ + } + } else if (NFCSTATUS_BUSY == wStatus) { + /* No processing to be done,since resend wait timer should have + * already been started */ + } else { + (pDlCtxt->tRWInfo.bFramesSegmented) = false; + /* Abort TML read operation which is always kept open */ + wIntStatus = phTmlNfc_ReadAbort(); + + if (NFCSTATUS_SUCCESS != wIntStatus) { + NXPLOG_FWDNLD_W("Tml read abort failed!"); + } + + pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid; + pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle; + pDlCtxt->tCurrState = phDnldNfc_StateInit; + pDlCtxt->bResendLastFrame = false; + + /* Delete the timer & reset timer primitives in context */ + (void)phOsalNfc_Timer_Delete(pDlCtxt->TimerInfo.dwRspTimerId); + (pDlCtxt->TimerInfo.dwRspTimerId) = 0; + (pDlCtxt->TimerInfo.TimerStatus) = 0; + (pDlCtxt->TimerInfo.wTimerExpStatus) = 0; + + if ((NULL != (pDlCtxt->UserCb)) && (NULL != (pDlCtxt->UserCtxt))) { + pDlCtxt->UserCb((pDlCtxt->UserCtxt), wStatus, + &(pDlCtxt->tRspBuffInfo)); + } + } + break; + } + default: { + pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid; + pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle; + break; + } + } + } + + return; +} + +/******************************************************************************* +** +** Function phDnldNfc_BuildFramePkt +** +** Description Forms the frame packet +** +** Parameters pDlContext - pointer to the download context structure +** +** Returns NFC status +** +*******************************************************************************/ +static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint16_t wFrameLen = 0; + uint16_t wCrcVal; + uint8_t* pFrameByte; + + if (NULL == pDlContext) { + NXPLOG_FWDNLD_E("Invalid Input Parameter!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (phDnldNfc_FTWrite == (pDlContext->FrameInp.Type)) { + if ((0 == (pDlContext->tUserData.wLen)) || + (NULL == (pDlContext->tUserData.pBuff))) { + NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Write!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if ((pDlContext->tRWInfo.bFirstWrReq) == true) { + (pDlContext->tRWInfo.wRemBytes) = (pDlContext->tUserData.wLen); + (pDlContext->tRWInfo.wOffset) = 0; + } + } + } else if (phDnldNfc_FTRead == (pDlContext->FrameInp.Type)) { + if ((0 == (pDlContext->tRspBuffInfo.wLen)) || + (NULL == (pDlContext->tRspBuffInfo.pBuff))) { + NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Read!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if ((pDlContext->tRWInfo.bFramesSegmented) == false) { + NXPLOG_FWDNLD_D("Verifying RspBuffInfo for Read Request.."); + wFrameLen = (pDlContext->tRspBuffInfo.wLen) + PHDNLDNFC_MIN_PLD_LEN; + + (pDlContext->tRWInfo.wRWPldSize) = + (PHDNLDNFC_CMDRESP_MAX_PLD_SIZE - PHDNLDNFC_MIN_PLD_LEN); + (pDlContext->tRWInfo.wRemBytes) = (pDlContext->tRspBuffInfo.wLen); + (pDlContext->tRWInfo.dwAddr) = (pDlContext->FrameInp.dwAddr); + (pDlContext->tRWInfo.wOffset) = 0; + (pDlContext->tRWInfo.wBytesRead) = 0; + + if (PHDNLDNFC_CMDRESP_MAX_PLD_SIZE < wFrameLen) { + (pDlContext->tRWInfo.bFramesSegmented) = true; + } + } + } + } else if (phDnldNfc_FTLog == (pDlContext->FrameInp.Type)) { + if ((0 == (pDlContext->tUserData.wLen)) || + (NULL == (pDlContext->tUserData.pBuff))) { + NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Log!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } + } else { + } + + if (NFCSTATUS_SUCCESS == wStatus) { + wStatus = phDnldNfc_CreateFramePld(pDlContext); + } + + if (NFCSTATUS_SUCCESS == wStatus) { + wFrameLen = 0; + wFrameLen = (pDlContext->tCmdRspFrameInfo.dwSendlength); + + if (phDnldNfc_FTRaw != (pDlContext->FrameInp.Type)) { + if (phDnldNfc_FTWrite != (pDlContext->FrameInp.Type)) { + pFrameByte = (uint8_t*)&wFrameLen; + + pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = + pFrameByte[1]; + pDlContext->tCmdRspFrameInfo + .aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0]; + + NXPLOG_FWDNLD_D("Inserting FrameId .."); + pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET] = + (pDlContext->tCmdId); + + wFrameLen += PHDNLDNFC_FRAME_HDR_LEN; + } else { + if (0 != (pDlContext->tRWInfo.wRWPldSize)) { + if ((pDlContext->tRWInfo.bFramesSegmented) == true) { + /* Turning ON the Fragmentation bit in FrameLen */ + wFrameLen = PHDNLDNFC_SET_HDR_FRAGBIT(wFrameLen); + } + + pFrameByte = (uint8_t*)&wFrameLen; + + pDlContext->tCmdRspFrameInfo + .aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = pFrameByte[1]; + pDlContext->tCmdRspFrameInfo + .aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0]; + + /* To ensure we have no frag bit set for crc calculation */ + wFrameLen = PHDNLDNFC_CLR_HDR_FRAGBIT(wFrameLen); + + wFrameLen += PHDNLDNFC_FRAME_HDR_LEN; + } + } + if (wFrameLen > PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE) { + NXPLOG_FWDNLD_D("wFrameLen exceeds the limit"); + return NFCSTATUS_FAILED; + } + /* calculate CRC16 */ + wCrcVal = phDnldNfc_CalcCrc16((pDlContext->tCmdRspFrameInfo.aFrameBuff), + wFrameLen); + + pFrameByte = (uint8_t*)&wCrcVal; + + /* Insert the computed Crc value */ + pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen] = pFrameByte[1]; + pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen + 1] = pFrameByte[0]; + + wFrameLen += PHDNLDNFC_FRAME_CRC_LEN; + } + + (pDlContext->tCmdRspFrameInfo.dwSendlength) = wFrameLen; + NXPLOG_FWDNLD_D("Frame created successfully"); + } else { + NXPLOG_FWDNLD_E("Frame creation failed!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_CreateFramePld +** +** Description Forms the frame payload +** +** Parameters pDlContext - pointer to the download context structure +** +** Returns NFC status +** +*******************************************************************************/ +static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint16_t wBuffIdx = 0; + uint16_t wChkIntgVal = 0; + uint16_t wFrameLen = 0; + + if (NULL == pDlContext) { + NXPLOG_FWDNLD_E("Invalid Input Parameter!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + memset((pDlContext->tCmdRspFrameInfo.aFrameBuff), 0, + PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE); + (pDlContext->tCmdRspFrameInfo.dwSendlength) = 0; + + if (phDnldNfc_FTNone == (pDlContext->FrameInp.Type)) { + (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN; + } else if (phDnldNfc_ChkIntg == (pDlContext->FrameInp.Type)) { + (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN; + + wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_OFFSET; + memcpy(&(pDlContext->tCmdRspFrameInfo + .aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]), + &wChkIntgVal, sizeof(wChkIntgVal)); + + wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_LEN; + memcpy(&(pDlContext->tCmdRspFrameInfo + .aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET + + PHDNLDNFC_USERDATA_EEPROM_OFFSIZE]), + &wChkIntgVal, sizeof(wChkIntgVal)); + + (pDlContext->tCmdRspFrameInfo.dwSendlength) += + PHDNLDNFC_USERDATA_EEPROM_LENSIZE; + (pDlContext->tCmdRspFrameInfo.dwSendlength) += + PHDNLDNFC_USERDATA_EEPROM_OFFSIZE; + } else if (phDnldNfc_FTWrite == (pDlContext->FrameInp.Type)) { + wBuffIdx = (pDlContext->tRWInfo.wOffset); + + if ((pDlContext->tRWInfo.bFramesSegmented) == false) { + wFrameLen = (pDlContext->tUserData.pBuff[wBuffIdx]); + wFrameLen <<= 8; + wFrameLen |= (pDlContext->tUserData.pBuff[wBuffIdx + 1]); + + (pDlContext->tRWInfo.wRWPldSize) = wFrameLen; + } + + if ((pDlContext->tRWInfo.wRWPldSize) > PHDNLDNFC_CMDRESP_MAX_PLD_SIZE) { + if ((pDlContext->tRWInfo.bFirstChunkResp) == false) { + (pDlContext->tRWInfo.wRemChunkBytes) = wFrameLen; + (pDlContext->tRWInfo.wOffset) += PHDNLDNFC_FRAME_HDR_LEN; + wBuffIdx = (pDlContext->tRWInfo.wOffset); + } + + if (PHDNLDNFC_CMDRESP_MAX_PLD_SIZE < + (pDlContext->tRWInfo.wRemChunkBytes)) { + (pDlContext->tRWInfo.wBytesToSendRecv) = + PHDNLDNFC_CMDRESP_MAX_PLD_SIZE; + (pDlContext->tRWInfo.bFramesSegmented) = true; + } else { + (pDlContext->tRWInfo.wBytesToSendRecv) = + (pDlContext->tRWInfo.wRemChunkBytes); + (pDlContext->tRWInfo.bFramesSegmented) = false; + } + + memcpy(&(pDlContext->tCmdRspFrameInfo + .aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET]), + &(pDlContext->tUserData.pBuff[wBuffIdx]), + (pDlContext->tRWInfo.wBytesToSendRecv)); + } else { + (pDlContext->tRWInfo.wRWPldSize) = 0; + (pDlContext->tRWInfo.wBytesToSendRecv) = + (wFrameLen + PHDNLDNFC_FRAME_HDR_LEN); + + memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[0]), + &(pDlContext->tUserData.pBuff[wBuffIdx]), + (pDlContext->tRWInfo.wBytesToSendRecv)); + } + (pDlContext->tCmdRspFrameInfo.dwSendlength) += + (pDlContext->tRWInfo.wBytesToSendRecv); + } else if (phDnldNfc_FTRead == (pDlContext->FrameInp.Type)) { + (pDlContext->tRWInfo.wBytesToSendRecv) = + ((pDlContext->tRWInfo.wRemBytes) > (pDlContext->tRWInfo.wRWPldSize)) + ? (pDlContext->tRWInfo.wRWPldSize) + : (pDlContext->tRWInfo.wRemBytes); + + wBuffIdx = (PHDNLDNFC_PLD_OFFSET + + ((sizeof(pDlContext->tRWInfo.wBytesToSendRecv)) % + PHDNLDNFC_MIN_PLD_LEN) - + 1); + + memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]), + &(pDlContext->tRWInfo.wBytesToSendRecv), + (sizeof(pDlContext->tRWInfo.wBytesToSendRecv))); + + wBuffIdx += sizeof(pDlContext->tRWInfo.wBytesToSendRecv); + + memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]), + &(pDlContext->tRWInfo.dwAddr), sizeof(pDlContext->tRWInfo.dwAddr)); + + (pDlContext->tCmdRspFrameInfo.dwSendlength) += + (PHDNLDNFC_MIN_PLD_LEN + (sizeof(pDlContext->tRWInfo.dwAddr))); + } else if (phDnldNfc_FTLog == (pDlContext->FrameInp.Type)) { + (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN; + + wBuffIdx = (PHDNLDNFC_MIN_PLD_LEN + PHDNLDNFC_FRAME_HDR_LEN); + + memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]), + (pDlContext->tUserData.pBuff), (pDlContext->tUserData.wLen)); + + (pDlContext->tCmdRspFrameInfo.dwSendlength) += + (pDlContext->tUserData.wLen); + } else if (phDnldNfc_FTForce == (pDlContext->FrameInp.Type)) { + (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN; + + wBuffIdx = PHDNLDNFC_PLD_OFFSET; + + memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]), + (pDlContext->tUserData.pBuff), (pDlContext->tUserData.wLen)); + } else if (phDnldNfc_FTRaw == (pDlContext->FrameInp.Type)) { + if ((0 == (pDlContext->tUserData.wLen)) || + (NULL == (pDlContext->tUserData.pBuff))) { + NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Raw Request!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]), + (pDlContext->tUserData.pBuff), (pDlContext->tUserData.wLen)); + + (pDlContext->tCmdRspFrameInfo.dwSendlength) += + (pDlContext->tUserData.wLen); + } + } else { + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_ProcessFrame +** +** Description Processes response frame received +** +** Parameters pContext - pointer to the download context structure +** pInfo - pointer to the Transaction buffer updated by TML +** Thread +** +** Returns NFCSTATUS_SUCCESS - parameters successfully validated +** NFCSTATUS_INVALID_PARAMETER - invalid parameters +** +*******************************************************************************/ +static NFCSTATUS phDnldNfc_ProcessFrame(void* pContext, + phTmlNfc_TransactInfo_t* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint16_t wCrcVal, wRecvdCrc, wRecvdLen, wPldLen; + pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext; + + if ((NULL == pDlCtxt) || (NULL == pInfo)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if ((PH_DL_STATUS_OK != pInfo->wStatus) || (0 == pInfo->wLength) || + (NULL == pInfo->pBuff)) { + NXPLOG_FWDNLD_E("Dnld Cmd Request Failed!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } else { + if (phDnldNfc_FTRaw == (pDlCtxt->FrameInp.Type)) { + if ((0 != (pDlCtxt->tRspBuffInfo.wLen)) && + (NULL != (pDlCtxt->tRspBuffInfo.pBuff))) { + memcpy((pDlCtxt->tRspBuffInfo.pBuff), (pInfo->pBuff), + (pInfo->wLength)); + + (pDlCtxt->tRspBuffInfo.wLen) = (pInfo->wLength); + } else { + NXPLOG_FWDNLD_E("Cannot update Response buff with received data!!"); + } + } else { + /* calculate CRC16 */ + wCrcVal = phDnldNfc_CalcCrc16( + (pInfo->pBuff), ((pInfo->wLength) - PHDNLDNFC_FRAME_CRC_LEN)); + + wRecvdCrc = 0; + wRecvdCrc = (((uint16_t)(pInfo->pBuff[(pInfo->wLength) - 2]) << 8U) | + (pInfo->pBuff[(pInfo->wLength) - 1])); + + if (wRecvdCrc == wCrcVal) { + wRecvdLen = + (((uint16_t)(pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET]) << 8U) | + (pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1])); + + wPldLen = ((pInfo->wLength) - + (PHDNLDNFC_FRAME_HDR_LEN + PHDNLDNFC_FRAME_CRC_LEN)); + + if (wRecvdLen != wPldLen) { + NXPLOG_FWDNLD_E("Invalid frame payload length received"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } else { + wStatus = phDnldNfc_UpdateRsp(pDlCtxt, pInfo, (wPldLen - 1)); + } + } else { + NXPLOG_FWDNLD_E("Invalid frame received"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_ProcessRecvInfo +** +** Description Processes the response during the state phDnldNfc_StateRecv +** +** Parameters pContext - pointer to the download context structure +** pInfo - pointer to the Transaction buffer updated by TML +** Thread +** +** Returns NFCSTATUS_SUCCESS - parameters successfully validated +** NFCSTATUS_INVALID_PARAMETER - invalid parameters +** +*******************************************************************************/ +static NFCSTATUS phDnldNfc_ProcessRecvInfo(void* pContext, + phTmlNfc_TransactInfo_t* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if (NULL != pContext) { + if (NULL == pInfo) { + NXPLOG_FWDNLD_E("Invalid pInfo received from TML!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } else { + wStatus = PHNFCSTATUS(pInfo->wStatus); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("Send Success"); + } else { + NXPLOG_FWDNLD_E("Tml Write error!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + } + } else { + NXPLOG_FWDNLD_E("Invalid context received from TML!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phDnldNfc_SetupResendTimer +** +** Description Sets up the timer for resending the previous write frame +** +** Parameters pDlContext - pointer to the download context structure +** +** Returns NFC status +** +*******************************************************************************/ +static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + wStatus = phOsalNfc_Timer_Start((pDlContext->TimerInfo.dwRspTimerId), + PHDNLDNFC_RETRY_FRAME_WRITE, + &phDnldNfc_ResendTimeOutCb, pDlContext); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("Frame Resend wait timer started"); + (pDlContext->TimerInfo.TimerStatus) = 1; + pDlContext->tCurrState = phDnldNfc_StateTimer; + } else { + NXPLOG_FWDNLD_W("Frame Resend wait timer not started"); + (pDlContext->TimerInfo.TimerStatus) = 0; /*timer stopped*/ + pDlContext->tCurrState = phDnldNfc_StateResponse; + /* Todo:- diagnostic in this case */ + } + + return wStatus; +} + +#if !defined(PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT) +#error PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT has to be defined +#endif + +/******************************************************************************* +** +** Function phDnldNfc_RspTimeOutCb +** +** Description Callback function in case of timer expiration +** +** Parameters TimerId - expired timer id +** pContext - pointer to the download context structure +** +** Returns None +** +*******************************************************************************/ +static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void* pContext) { + pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext; + + if (NULL != pDlCtxt) { + UNUSED(TimerId); + + if (1 == pDlCtxt->TimerInfo.TimerStatus) { + /* No response received and the timer expired */ + pDlCtxt->TimerInfo.TimerStatus = 0; /* Reset timer status flag */ + + NXPLOG_FWDNLD_D("%x", pDlCtxt->tLastStatus); + +#if (PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT == TRUE) + if (PH_DL_STATUS_SIGNATURE_ERROR == pDlCtxt->tLastStatus) { + /* Do a VEN Reset of the chip. */ + NXPLOG_FWDNLD_E("Performing a VEN Reset"); + phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode); + phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode); + NXPLOG_FWDNLD_E("VEN Reset Done"); + } +#endif + + (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT; + + if ((phDnldNfc_EventRead == pDlCtxt->tCurrEvent) || + (phDnldNfc_EventWrite == pDlCtxt->tCurrEvent)) { + phDnldNfc_ProcessRWSeqState(pDlCtxt, NULL); + } else { + phDnldNfc_ProcessSeqState(pDlCtxt, NULL); + } + } + } + + return; +} + +/******************************************************************************* +** +** Function phDnldNfc_ResendTimeOutCb +** +** Description Callback function in case of Frame Resend Wait timer +** expiration +** +** Parameters TimerId - expired timer id +** pContext - pointer to the download context structure +** +** Returns None +** +*******************************************************************************/ +static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void* pContext) { + pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext; + + if (NULL != pDlCtxt) { + UNUSED(TimerId); + + if (1 == pDlCtxt->TimerInfo.TimerStatus) { + /* No response received and the timer expired */ + pDlCtxt->TimerInfo.TimerStatus = 0; /* Reset timer status flag */ + + (pDlCtxt->TimerInfo.wTimerExpStatus) = 0; + + pDlCtxt->tCurrState = phDnldNfc_StateSend; + + /* set the flag to trigger last frame re-transmission */ + pDlCtxt->bResendLastFrame = true; + + phDnldNfc_ProcessRWSeqState(pDlCtxt, NULL); + } + } + + return; +} + +/******************************************************************************* +** +** Function phDnldNfc_UpdateRsp +** +** Description verifies the payload status byte and copies data +** to response buffer if successful +** +** Parameters pDlContext - pointer to the download context structure +** pInfo - pointer to the Transaction buffer updated by TML +** Thread +** wPldLen - Length of the payload bytes to copy to response +** buffer +** +** Returns NFC status +** +*******************************************************************************/ +static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t pDlContext, + phTmlNfc_TransactInfo_t* pInfo, + uint16_t wPldLen) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint16_t wReadLen = 0; + + if ((NULL == pDlContext) || (NULL == pInfo)) { + NXPLOG_FWDNLD_E("Invalid Input Parameters!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); + } else { + if (PH_DL_CMD_WRITE == (pDlContext->tCmdId)) { + if (PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { + /* first write frame response received case */ + if ((pDlContext->tRWInfo.bFirstWrReq) == true) { + NXPLOG_FWDNLD_D("First Write Frame Success Status received!!"); + (pDlContext->tRWInfo.bFirstWrReq) = false; + } + + if ((pDlContext->tRWInfo.bFirstChunkResp) == true) { + if ((pDlContext->tRWInfo.bFramesSegmented) == false) { + NXPLOG_FWDNLD_D("Chunked Write Frame Success Status received!!"); + (pDlContext->tRWInfo.wRemChunkBytes) -= + (pDlContext->tRWInfo.wBytesToSendRecv); + (pDlContext->tRWInfo.bFirstChunkResp) = false; + } else { + NXPLOG_FWDNLD_E("UnExpected Status received!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + } + + if (NFCSTATUS_SUCCESS == wStatus) { + (pDlContext->tRWInfo.wRemBytes) -= + (pDlContext->tRWInfo.wBytesToSendRecv); + (pDlContext->tRWInfo.wOffset) += + (pDlContext->tRWInfo.wBytesToSendRecv); + } + } else if (((pDlContext->tRWInfo.bFirstChunkResp) == false) && + ((pDlContext->tRWInfo.bFramesSegmented) == true) && + (PHDNLDNFC_FIRST_FRAGFRAME_RESP == + (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))) { + (pDlContext->tRWInfo.bFirstChunkResp) = true; + (pDlContext->tRWInfo.wRemChunkBytes) -= + (pDlContext->tRWInfo.wBytesToSendRecv); + (pDlContext->tRWInfo.wRemBytes) -= + ((pDlContext->tRWInfo.wBytesToSendRecv) + PHDNLDNFC_FRAME_HDR_LEN); + (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv); + + /* first write frame response received case */ + if ((pDlContext->tRWInfo.bFirstWrReq) == true) { + NXPLOG_FWDNLD_D("First Write Frame Success Status received!!"); + (pDlContext->tRWInfo.bFirstWrReq) = false; + } + } else if (((pDlContext->tRWInfo.bFirstChunkResp) == true) && + ((pDlContext->tRWInfo.bFramesSegmented) == true) && + (PHDNLDNFC_NEXT_FRAGFRAME_RESP == + (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))) { + (pDlContext->tRWInfo.wRemChunkBytes) -= + (pDlContext->tRWInfo.wBytesToSendRecv); + (pDlContext->tRWInfo.wRemBytes) -= + (pDlContext->tRWInfo.wBytesToSendRecv); + (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv); + } else if (PH_DL_STATUS_FIRMWARE_VERSION_ERROR == + (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { + NXPLOG_FWDNLD_E( + "FW version Error !!!could be either due to FW major version " + "mismatch or Firmware Already Up To Date !!"); + (pDlContext->tRWInfo.bFirstWrReq) = false; + /* resetting wRemBytes to 0 to avoid any further write frames send */ + (pDlContext->tRWInfo.wRemBytes) = 0; + (pDlContext->tRWInfo.wOffset) = 0; + wStatus = NFCSTATUS_FW_VERSION_ERROR; + } else if (PH_DL_STATUS_PLL_ERROR == + (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { + NXPLOG_FWDNLD_E("PLL Error Status received!!"); + (pDlContext->tLastStatus) = PH_DL_STATUS_PLL_ERROR; + wStatus = NFCSTATUS_WRITE_FAILED; + } else if (PH_DL_STATUS_SIGNATURE_ERROR == + (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { + NXPLOG_FWDNLD_E("Signature Mismatch Error received!!"); + /* save the status for use in loading the relevant recovery image + * (either signature or platform) */ + (pDlContext->tLastStatus) = PH_DL_STATUS_SIGNATURE_ERROR; + wStatus = NFCSTATUS_REJECTED; + } else if (PH_DL_STATUS_MEM_BSY == + (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { + NXPLOG_FWDNLD_E("Mem Busy Status received!!"); + (pDlContext->tLastStatus) = PH_DL_STATUS_MEM_BSY; + wStatus = NFCSTATUS_BUSY; + } else { + NXPLOG_FWDNLD_E("Unsuccessful Status received!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + } else if (PH_DL_CMD_READ == (pDlContext->tCmdId)) { + if (PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { + wReadLen = (((uint16_t)(pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 3]) + << 8U) | + (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 2])); + + if (wReadLen != (pDlContext->tRWInfo.wBytesToSendRecv)) { + NXPLOG_FWDNLD_E("Desired Length bytes not received!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } else { + memcpy( + &(pDlContext->tRspBuffInfo.pBuff[(pDlContext->tRWInfo.wOffset)]), + &(pInfo->pBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]), wReadLen); + + (pDlContext->tRWInfo.wBytesRead) += wReadLen; + + (pDlContext->tRspBuffInfo.wLen) = (pDlContext->tRWInfo.wBytesRead); + + (pDlContext->tRWInfo.wRemBytes) -= + (pDlContext->tRWInfo.wBytesToSendRecv); + (pDlContext->tRWInfo.dwAddr) += + (pDlContext->tRWInfo.wBytesToSendRecv); + (pDlContext->tRWInfo.wOffset) += + (pDlContext->tRWInfo.wBytesToSendRecv); + } + } else { + NXPLOG_FWDNLD_E("Unsuccessful Status received!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + } else { + if (PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { + if ((0 != (pDlContext->tRspBuffInfo.wLen)) && + (NULL != (pDlContext->tRspBuffInfo.pBuff))) { + memcpy((pDlContext->tRspBuffInfo.pBuff), + &(pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 1]), wPldLen); + + (pDlContext->tRspBuffInfo.wLen) = wPldLen; + } + } else { + NXPLOG_FWDNLD_E("Unsuccessful Status received!!"); + wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); + } + } + } + + return wStatus; +} diff --git a/pn54x/dnld/phDnldNfc_Internal.h b/pn54x/dnld/phDnldNfc_Internal.h new file mode 100644 index 0000000..9a9d422 --- /dev/null +++ b/pn54x/dnld/phDnldNfc_Internal.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Internal Primitives (Functions + Variables) used for Firmware Download + */ +#ifndef PHDNLDNFC_INTERNAL_H +#define PHDNLDNFC_INTERNAL_H + +#include <phDnldNfc.h> +#include <phDnldNfc_Cmd.h> +#include <phDnldNfc_Status.h> + +#define PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE \ + (0x100U) /* DL Host Frame Buffer Size for all CMD/RSP \ + except pipelined WRITE */ +#if (PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE > PHNFC_I2C_FRAGMENT_SIZE) +#undef PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE +#define PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE (PHNFC_I2C_FRAGMENT_SIZE) +#endif + +/* DL Host Short Frame Buffer Size for pipelined WRITE RSP */ +#define PHDNLDNFC_WRITERSP_BUFF_SIZE (0x08U) + +/* DL Host Frame Buffer Header Length */ +#define PHDNLDNFC_FRAME_HDR_LEN (0x02U) +/* DL Host Frame Buffer CRC Length */ +#define PHDNLDNFC_FRAME_CRC_LEN (PHDNLDNFC_FRAME_HDR_LEN) +#define PHDNLDNFC_FRAME_ID_LEN (0x01U) /* Length of Cmd Id */ + +/* size of EEPROM/Flash address */ +#define PHDNLDNFC_EEFL_ADDR_SIZE (0x03U) +/* 2 Byte size of data */ +#define PHDNLDNFC_DATA_SIZE (PHDNLDNFC_FRAME_HDR_LEN) + +/* Start of EEPROM address for log */ +#define PHDNLDNFC_EEPROM_LOG_START_ADDR (0x201F80U) +/* End of EEPROM address for log */ +#define PHDNLDNFC_EEPROM_LOG_END_ADDR (0x201FBFU) + +#define PHDNLDNFC_MAX_LOG_SIZE \ + ((PHDNLDNFC_EEPROM_LOG_END_ADDR - PHDNLDNFC_EEPROM_LOG_START_ADDR) + 1) + +/* DL Max Payload Size */ +#define PHDNLDNFC_CMDRESP_MAX_PLD_SIZE \ + ((PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE) - \ + (PHDNLDNFC_FRAME_HDR_LEN + PHDNLDNFC_FRAME_CRC_LEN)) + +/* + * Enum definition contains Download Event Types + */ +typedef enum phDnldNfc_Event { + phDnldNfc_EventInvalid = 0x00, /*Invalid Event Value*/ + phDnldNfc_EventReset, /* Reset event */ + phDnldNfc_EventGetVer, /* Get Version event*/ + phDnldNfc_EventWrite, /* Write event*/ + phDnldNfc_EventRead, /* Read event*/ + phDnldNfc_EventIntegChk, /* Integrity Check event*/ + phDnldNfc_EventGetSesnSt, /* Get Session State event*/ + phDnldNfc_EventLog, /* Log event*/ + phDnldNfc_EventForce, /* Force event*/ + phDnldNfc_EventRaw, /* Raw Req/Rsp event,used currently for sending NCI RESET + cmd */ + phDnldNfc_EVENT_INT_MAX /* Max Event Count*/ +} phDnldNfc_Event_t; + +/* + * Enum definition contains Download Handler states for each event requested + */ +typedef enum phDnldNfc_State { + phDnldNfc_StateInit = 0x00, /* Handler init state */ + phDnldNfc_StateSend, /* Send frame to NFCC state */ + phDnldNfc_StateRecv, /* Recv Send complete State */ + phDnldNfc_StateTimer, /* State to stop prev set timer on Recv or handle timed + out scenario */ + phDnldNfc_StateResponse, /* Process response from NFCC state */ + phDnldNfc_StatePipelined, /* Write requests to be pipelined state */ + phDnldNfc_StateInvalid /* Invalid Handler state */ +} phDnldNfc_State_t; + +/* + * Enum definition contains Download Handler Transition + */ +typedef enum phDnldNfc_Transition { + phDnldNfc_TransitionIdle = + 0x00, /* Handler in Idle state - No Download in progress */ + phDnldNfc_TransitionBusy, /* Handler is busy processing download request */ + phDnldNfc_TransitionInvalid /* Invalid Handler Transition */ +} phDnldNfc_Transition_t; + +/* + * Enum definition contains the Frame input type for CmdId in process + */ +typedef enum { + phDnldNfc_FTNone = 0, /* input type None */ + phDnldNfc_ChkIntg, /* user eeprom offset & len to be added for Check Integrity + Request */ + phDnldNfc_FTWrite, /* Frame inputs for Write request */ + phDnldNfc_FTLog, /* Frame inputs for Log request */ + phDnldNfc_FTForce, /* Frame input for Force cmd request */ + phDnldNfc_FTRead, /* Addr input required for read request */ + phDnldNfc_FTRaw /* Raw Req/Rsp type */ +} phDnldNfc_FrameInputType_t; + +/* + * Contains Host Frame Buffer information. + */ +typedef struct phDnldNfc_FrameInfo { + uint16_t dwSendlength; /* length of the payload */ + uint8_t + aFrameBuff[PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE]; /* Buffer to store command + that needs to be sent*/ +} phDnldNfc_FrameInfo_t, + *pphDnldNfc_FrameInfo_t; /* pointer to #phDnldNfc_FrameInfo_t */ + +/* + * Frame Input Type & Value for CmdId in Process + */ +typedef struct phDnldNfc_FrameInput { + phDnldNfc_FrameInputType_t + Type; /* Type of frame input required for current cmd in process */ + uint32_t dwAddr; /* Address value required for Read/Write Cmd*/ +} phDnldNfc_FrameInput_t, + *pphDnldNfc_FrameInput_t; /* pointer to #phDnldNfc_FrameInput_t */ + +/* + * Context for the response timeout + */ +typedef struct phDnldNfc_RspTimerInfo { + uint32_t dwRspTimerId; /* Timer for Core to handle response */ + uint8_t TimerStatus; /* 0 = Timer not running 1 = timer running*/ + NFCSTATUS wTimerExpStatus; /* Holds the status code on timer expiry */ +} phDnldNfc_RspTimerInfo_t; + +/* + * Read/Write Processing Info + */ +typedef struct phDnldNfc_RWInfo { + uint32_t dwAddr; /* current Addr updated for read/write */ + uint16_t wOffset; /* current offset within the user buffer to read/write */ + uint16_t wRemBytes; /* Remaining bytes to read/write */ + uint16_t wRemChunkBytes; /* Remaining bytes within the chunked frame */ + uint16_t wRWPldSize; /* Size of the read/write payload per transaction */ + uint16_t wBytesToSendRecv; /* Num of Bytes being written/read currently */ + uint16_t wBytesRead; /* Bytes read from read cmd currently */ + bool_t bFramesSegmented; /* Flag to indicate if Read/Write frames are + segmented */ + bool_t bFirstWrReq; /* Flag to indicate if this is the first write frame being + sent */ + bool_t + bFirstChunkResp; /* Flag to indicate if we got the first chunk response */ +} phDnldNfc_RWInfo_t, *pphDnldNfc_RWInfo_t; /* pointer to #phDnldNfc_RWInfo_t */ + +/* + * Download context structure + */ +typedef struct phDnldNfc_DlContext { + const uint8_t* nxp_nfc_fw; /* Pointer to firmware version from image */ + const uint8_t* + nxp_nfc_fwp; /* Pointer to firmware version from get_version cmd */ + uint16_t nxp_nfc_fwp_len; /* Length of firmware image length */ + uint16_t nxp_nfc_fw_len; /* Firmware image length */ + bool_t bResendLastFrame; /* Flag to resend the last write frame after MEM_BSY + status */ + phDnldNfc_Transition_t + tDnldInProgress; /* Flag to indicate if download request is ongoing */ + phDnldNfc_Event_t tCurrEvent; /* Current event being processed */ + phDnldNfc_State_t tCurrState; /* Current state being processed */ + pphDnldNfc_RspCb_t UserCb; /* Upper layer call back function */ + void* UserCtxt; /* Pointer to upper layer context */ + phDnldNfc_Buff_t tUserData; /* Data buffer provided by caller */ + phDnldNfc_Buff_t + tRspBuffInfo; /* Buffer to store payload field of the received response*/ + phDnldNfc_FrameInfo_t tCmdRspFrameInfo; /* Buffer to hold the cmd/resp frame + except pipeline write */ + phDnldNfc_FrameInfo_t + tPipeLineWrFrameInfo; /* Buffer to hold the pipelined write frame */ + NFCSTATUS + wCmdSendStatus; /* Holds the status of cmd request made to cmd handler */ + phDnldNfc_CmdId_t tCmdId; /* Cmd Id of the currently processed cmd */ + phDnldNfc_FrameInput_t + FrameInp; /* input value required for current cmd in process */ + phDnldNfc_RspTimerInfo_t + TimerInfo; /* Timer context handled into download context*/ + phDnldNfc_Buff_t tTKey; /* Defualt Transport Key provided by caller */ + phDnldNfc_RWInfo_t tRWInfo; /* Read/Write segmented frame info */ + phDnldNfc_Status_t tLastStatus; /* saved status to distinguish signature or + pltform recovery */ +} phDnldNfc_DlContext_t, + *pphDnldNfc_DlContext_t; /* pointer to #phDnldNfc_DlContext_t structure */ + +/* The phDnldNfc_CmdHandler function declaration */ +extern NFCSTATUS phDnldNfc_CmdHandler(void* pContext, + phDnldNfc_Event_t TrigEvent); + +#endif /* PHDNLDNFC_INTERNAL_H */ diff --git a/pn54x/dnld/phDnldNfc_Status.h b/pn54x/dnld/phDnldNfc_Status.h new file mode 100644 index 0000000..a5b9125 --- /dev/null +++ b/pn54x/dnld/phDnldNfc_Status.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Firmware Download Status Values + */ +#ifndef PHDNLDNFC_STATUS_H +#define PHDNLDNFC_STATUS_H + +#include <phNfcStatus.h> + +/* reusing LibNfcStatus.h value below as a placeholder for now, need to find + the right value */ +#define NFCSTATUS_ABORTED (0x0096) /* Command aborted */ + +/* + * Enum definition contains Firmware Download Status codes + */ +typedef enum phDnldNfc_Status { + PH_DL_STATUS_PLL_ERROR = 0x0D, + PH_DL_STATUS_LC_WRONG = 0x13, + PH_DL_STATUS_LC_TERMINATION_NOT_SUPPORTED = 0x14, + PH_DL_STATUS_LC_CREATION_NOT_SUPPORTED = 0x15, + PH_DL_STATUS_LC_UNKNOWN = 0x16, + PH_DL_STATUS_AUTHENTICATION_ERROR = 0x19, + PH_DL_STATUS_NOT_AUTHENTICATED = 0x1A, + PH_DL_STATUS_AUTHENTICATION_LOST = 0x1B, + PH_DL_STATUS_WRITE_PROTECTED = 0x1C, + PH_DL_STATUS_READ_PROTECTED = 0x1D, + PH_DL_STATUS_ADDR_RANGE_OFL_ERROR = 0x1E, + PH_DL_STATUS_BUFFER_OFL_ERROR = 0x1F, + PH_DL_STATUS_MEM_BSY = 0x20, + PH_DL_STATUS_SIGNATURE_ERROR = 0x21, + PH_DL_STATUS_SESSION_WAS_OPEN = 0x22, + PH_DL_STATUS_SESSION_WAS_CLOSED = 0x23, + /* the Firmware version passed to CommitSession is not greater than + the EEPROM resident stored Firmware version number */ + PH_DL_STATUS_FIRMWARE_VERSION_ERROR = 0x24, + PH_DL_STATUS_LOOPBACK_DATA_MISSMATCH_ERROR = 0x25, + /*****************************/ + PH_DL_STATUS_HOST_PAYLOAD_UFL_ERROR = 0x26, + PH_DL_STATUS_HOST_PAYLOAD_OFL_ERROR = 0x27, + PH_DL_STATUS_PROTOCOL_ERROR = 0x28, + /* Download codes re-mapped to generic entries */ + PH_DL_STATUS_INVALID_ADDR = NFCSTATUS_INVALID_PARAMETER, + PH_DL_STATUS_GENERIC_ERROR = NFCSTATUS_FAILED, + PH_DL_STATUS_ABORTED_CMD = NFCSTATUS_ABORTED, + PH_DL_STATUS_FLASH_WRITE_PROTECTED = PH_DL_STATUS_WRITE_PROTECTED, + PH_DL_STATUS_FLASH_READ_PROTECTED = PH_DL_STATUS_READ_PROTECTED, + PH_DL_STATUS_USERDATA_WRITE_PROTECTED = PH_DL_STATUS_WRITE_PROTECTED, + PH_DL_STATUS_USERDATA_READ_PROTECTED = PH_DL_STATUS_READ_PROTECTED, + PH_DL_STATUS_OK = NFCSTATUS_SUCCESS +} phDnldNfc_Status_t; + +#endif /* PHDNLDNFC_STATUS_H */ diff --git a/pn54x/dnld/phDnldNfc_Utils.c b/pn54x/dnld/phDnldNfc_Utils.c new file mode 100644 index 0000000..014ca66 --- /dev/null +++ b/pn54x/dnld/phDnldNfc_Utils.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Download Component + * Download Utility routines implementation + */ + +#include <phDnldNfc_Utils.h> +#include <phNxpLog.h> + +static uint16_t const aCrcTab[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, + 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, + 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, + 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, + 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, + 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, + 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, + 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, + 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, + 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, + 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, + 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, + 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, + 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, + 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, + 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, + 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, + 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, + 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, + 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, + 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, + 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, + 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, + 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, + 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, + 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; + +/******************************************************************************* +** +** Function phDnldNfc_CalcCrc16 +** +** Description Calculates CRC16 for the frame buffer +** +** Parameters pBuff - CRC16 calculation input buffer +** wLen - input buffer length +** +** Returns wCrc - computed 2 byte CRC16 value +** +*******************************************************************************/ +uint16_t phDnldNfc_CalcCrc16(uint8_t* pBuff, uint16_t wLen) { + uint16_t wTmp; + uint16_t wValue; + uint16_t wCrc = 0xffff; + uint32_t i; + + if ((NULL == pBuff) || (0 == wLen)) { + NXPLOG_FWDNLD_W("Invalid Params supplied!!"); + } else { + /* Perform CRC calculation according to ccitt with a initial value of 0x1d0f + */ + for (i = 0; i < wLen; i++) { + wValue = 0x00ffU & (uint16_t)pBuff[i]; + wTmp = (wCrc >> 8U) ^ wValue; + wCrc = (wCrc << 8U) ^ aCrcTab[wTmp]; + } + } + + return wCrc; +} diff --git a/pn54x/dnld/phDnldNfc_Utils.h b/pn54x/dnld/phDnldNfc_Utils.h new file mode 100644 index 0000000..4b4e2af --- /dev/null +++ b/pn54x/dnld/phDnldNfc_Utils.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Firmware Download Utilities File + */ +#ifndef PHDNLDNFC_UTILS_H +#define PHDNLDNFC_UTILS_H + +#include <phDnldNfc.h> + +extern uint16_t phDnldNfc_CalcCrc16(uint8_t* pBuff, uint16_t wLen); + +#endif /* PHDNLDNFC_UTILS_H */ diff --git a/pn54x/dnld/phNxpNciHal_Dnld.c b/pn54x/dnld/phNxpNciHal_Dnld.c new file mode 100644 index 0000000..42cadba --- /dev/null +++ b/pn54x/dnld/phNxpNciHal_Dnld.c @@ -0,0 +1,1808 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <phDnldNfc.h> +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include <phNxpNciHal_Dnld.h> +#include <phNxpNciHal_utils.h> +#include <phTmlNfc.h> + +/* Macro */ +#define PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS 3 +#define PHLIBNFC_IOCTL_DNLD_GETVERLEN (0x0BU) +#define PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1 (0x09U) +#define PHLIBNFC_DNLD_MEM_READ (0xECU) +#define PHLIBNFC_DNLD_MEM_WRITE (0xEDU) +#define PHLIBNFC_DNLD_READ_LOG (0xEEU) +#define NFC_MEM_READ (0xD0U) +#define NFC_MEM_WRITE (0xD1U) +#define NFC_FW_DOWNLOAD (0x09F7U) + +/* External global variable to get FW version */ +extern uint16_t wFwVer; +extern uint16_t wMwVer; +#if (NFC_NXP_CHIP_TYPE != PN547C2) +extern uint8_t gRecFWDwnld; +#endif +/* RF Configuration structure */ +typedef struct phLibNfc_IoctlSetRfConfig { + uint8_t bNumOfParams; /* Number of Rf configurable parameters to be set */ + uint8_t* pInputBuffer; /* Buffer containing Rf configurable parameters */ + uint8_t bSetSysPmuFlag; /* Flag to decide wether to set SystemPmu or no from + the first byte */ +} phLibNfc_IoctlSetRfConfig; + +/* Structure to hold information from EEPROM */ +typedef struct phLibNfc_EELogParams { + uint16_t wCurrMwVer; /* Holds current MW version on the chip */ + uint16_t wCurrFwVer; /* Holds current FW version on the chip */ + uint16_t wNumDnldTrig; /* Total number of times dnld has been attempted */ + uint16_t wNumDnldSuccess; /* Total number of times dnld has been successful */ + uint16_t wNumDnldFail; /* Total number of times dnld has Failed */ + uint16_t wDnldFailCnt; /* holds the number of times dnld has failed,will be + reset on success */ + bool_t bConfig; /* Flag to be set in dnld mode after successful dnld,to be + reset in NCI Mode + after setting the NCI configuration */ +} phLibNfc_EELogParams_t; + +/* FW download module context structure */ +typedef struct { + bool_t bDnldEepromWrite; /* Flag to indicate eeprom write request*/ + bool_t + bSkipSeq; /* Flag to indicate FW download sequence to be skipped or not */ + bool_t bSkipReset; /* Flag to indicate Reset cmd to be skipped or not in FW + download sequence */ + bool_t bSkipForce; /* Flag to indicate Force cmd to be skipped or not in FW + recovery sequence */ + bool_t bPrevSessnOpen; /* Flag to indicate previous download session is open + or not */ + bool_t bLibNfcCtxtMem; /* flag to indicate if mem was allocated for + gpphLibNfc_Context */ + bool_t bDnldInitiated; /* Flag to indicate if fw upgrade was initiated */ + bool_t + bSendNciCmd; /* Flag to indicate if NCI cmd to be sent or not,after PKU */ + uint8_t bChipVer; /* holds the hw chip version */ + bool_t bDnldRecovery; /* Flag to indicate if dnld recovery sequence needs to + be triggered */ + bool_t bForceDnld; /* Flag to indicate if forced download option is enabled */ + bool_t bRetryDnld; /* Flag to indicate retry download after successful + recovery complete */ + uint8_t + bDnldAttempts; /* Holds the count of no. of dnld attempts made.max 3 */ + uint16_t IoctlCode; /* Ioctl code*/ + bool_t bDnldAttemptFailed; /* Flag to indicate last download attempt failed */ + NFCSTATUS bLastStatus; /* Holds the actual download write attempt status */ + phLibNfc_EELogParams_t + tLogParams; /* holds the params that could be logged to reserved EE + address */ + uint8_t bClkSrcVal; /* Holds the System clock source read from config file */ + uint8_t + bClkFreqVal; /* Holds the System clock frequency read from config file */ +} phNxpNciHal_fw_Ioctl_Cntx_t; + +/* Global variables used in this file only*/ +static phNxpNciHal_fw_Ioctl_Cntx_t gphNxpNciHal_fw_IoctlCtx; + +/* Local function prototype */ +static NFCSTATUS phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_get_version_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext, + NFCSTATUS status, void* pInfo); + +static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext, + NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext, + NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext, + NFCSTATUS status, void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext, + NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status, + void* pInfo); + +static void phNxpNciHal_fw_dnld_send_ncicmd_Cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, + NFCSTATUS status, void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status, + void* pInfo); + +/* Internal function to verify Crc Status byte received during CheckIntegrity */ +static NFCSTATUS phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus); + +static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status, + void* pInfo); + +static NFCSTATUS phNxpNciHal_fw_seq_handler( + NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo)); + +/* Array of pointers to start fw download seq */ +static NFCSTATUS (*phNxpNciHal_dwnld_seqhandler[])(void* pContext, + NFCSTATUS status, + void* pInfo) = { +#if (NFC_NXP_CHIP_TYPE == PN547C2) + phNxpNciHal_fw_dnld_normal, + phNxpNciHal_fw_dnld_normal, +#endif + phNxpNciHal_fw_dnld_get_sessn_state, + phNxpNciHal_fw_dnld_get_version, + phNxpNciHal_fw_dnld_log_read, + phNxpNciHal_fw_dnld_write, + phNxpNciHal_fw_dnld_get_sessn_state, + phNxpNciHal_fw_dnld_get_version, + phNxpNciHal_fw_dnld_log, + phNxpNciHal_fw_dnld_chk_integrity, + NULL}; + +#if (NFC_NXP_CHIP_TYPE != PN547C2) +/* Array of pointers to start dummy fw download seq */ +static NFCSTATUS (*phNxpNciHal_dummy_rec_dwnld_seqhandler[])(void* pContext, + NFCSTATUS status, + void* pInfo) = { + phNxpNciHal_fw_dnld_normal, + phNxpNciHal_fw_dnld_normal, + phNxpNciHal_fw_dnld_get_sessn_state, + phNxpNciHal_fw_dnld_get_version, + phNxpNciHal_fw_dnld_log_read, + phNxpNciHal_fw_dnld_write, + NULL}; +#endif + +/* Download Recovery Sequence */ +static NFCSTATUS (*phNxpNciHal_dwnld_rec_seqhandler[])(void* pContext, + NFCSTATUS status, + void* pInfo) = { + phNxpNciHal_fw_dnld_reset, phNxpNciHal_fw_dnld_force, + phNxpNciHal_fw_dnld_recover, phNxpNciHal_fw_dnld_send_ncicmd, NULL}; + +/* Download Log Sequence */ +static NFCSTATUS (*phNxpNciHal_dwnld_log_seqhandler[])(void* pContext, + NFCSTATUS status, + void* pInfo) = { + phNxpNciHal_fw_dnld_log, NULL}; + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_reset_cb +** +** Description Download Reset callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + UNUSED(pInfo); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_reset_cb - Request Successful"); + } else { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset_cb - Request Failed!!"); + } + p_cb_data->status = status; + + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_reset +** +** Description Download Reset +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + UNUSED(pContext); + UNUSED(status); + UNUSED(pInfo); + if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) || + ((gphNxpNciHal_fw_IoctlCtx.bSkipReset) == true)) { + if ((gphNxpNciHal_fw_IoctlCtx.bSkipReset) == true) { + (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false; + } + return NFCSTATUS_SUCCESS; + } + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed"); + return NFCSTATUS_FAILED; + } + wStatus = phDnldNfc_Reset((pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_reset_cb, + (void*)&cb_data); + + if (wStatus != NFCSTATUS_PENDING) { + NXPLOG_FWDNLD_E("phDnldNfc_Reset failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_normal_cb +** +** Description Download Normal callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + UNUSED(pInfo); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_normal_cb - Request Successful"); + } else { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal_cb - Request Failed!!"); + /* In this fail scenario trick the sequence handler to call next recover + * sequence */ + status = NFCSTATUS_SUCCESS; + } + p_cb_data->status = status; + + SEM_POST(p_cb_data); + usleep(1000 * 10); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_force_cb +** +** Description Download Force callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + UNUSED(pInfo); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_FWDNLD_D("phLibNfc_DnldForceCb - Request Successful"); + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true; + (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = true; + } else { + /* In this fail scenario trick the sequence handler to call next recover + * sequence */ + status = NFCSTATUS_SUCCESS; + NXPLOG_FWDNLD_E("phLibNfc_DnldForceCb - Request Failed!!"); + } + p_cb_data->status = status; + + SEM_POST(p_cb_data); + usleep(1000 * 10); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_normal +** +** Description Download Normal +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t bClkVal[2]; + phDnldNfc_Buff_t tData; + phNxpNciHal_Sem_t cb_data; + UNUSED(pContext); + UNUSED(status); + UNUSED(pInfo); + if ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == true) { + return NFCSTATUS_SUCCESS; + } else { + /* + bClkVal[0] = NXP_SYS_CLK_SRC_SEL; + bClkVal[1] = NXP_SYS_CLK_FREQ_SEL; + */ + bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal; + bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal; + + (tData.pBuff) = bClkVal; + (tData.wLen) = sizeof(bClkVal); + + if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) { + (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; + } + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed"); + return NFCSTATUS_FAILED; + } + wStatus = phDnldNfc_Force( + &tData, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_normal_cb, + (void*)&cb_data); + + if (NFCSTATUS_PENDING != wStatus) { + NXPLOG_FWDNLD_E("phDnldNfc_Normal failed"); + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + goto clean_and_return; + } + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_force +** +** Description Download Force +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t bClkVal[2]; + phDnldNfc_Buff_t tData; + phNxpNciHal_Sem_t cb_data; + UNUSED(pContext); + UNUSED(status); + UNUSED(pInfo); + if ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == true) { + return NFCSTATUS_SUCCESS; + } else { + /* + bClkVal[0] = NXP_SYS_CLK_SRC_SEL; + bClkVal[1] = NXP_SYS_CLK_FREQ_SEL; + */ + bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal; + bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal; + + (tData.pBuff) = bClkVal; + (tData.wLen) = sizeof(bClkVal); + + if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) { + (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; + } + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed"); + return NFCSTATUS_FAILED; + } + wStatus = phDnldNfc_Force(&tData, + (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_force_cb, + (void*)&cb_data); + + if (NFCSTATUS_PENDING != wStatus) { + NXPLOG_FWDNLD_E("phDnldNfc_Force failed"); + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + goto clean_and_return; + } + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_get_version_cb +** +** Description Download Get version callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_get_version_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + NFCSTATUS wStatus = status; + pphDnldNfc_Buff_t pRespBuff; + uint16_t wFwVern = 0; + uint16_t wMwVern = 0; + uint8_t bHwVer = 0; + uint8_t bExpectedLen = 0; + uint8_t bNewVer[2]; + uint8_t bCurrVer[2]; + + if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_version_cb - Request Successful"); + + pRespBuff = (pphDnldNfc_Buff_t)pInfo; + + if ((0 != pRespBuff->wLen) && (NULL != pRespBuff->pBuff)) { + bHwVer = (pRespBuff->pBuff[0]); + bHwVer &= 0x0F; /* 0x0F is the mask to extract chip version */ + + if ((PHDNLDNFC_HWVER_MRA2_1 == bHwVer) || + (PHDNLDNFC_HWVER_MRA2_2 == bHwVer) +#if (NFC_NXP_CHIP_TYPE == PN551) + || (PHDNLDNFC_HWVER_PN551_MRA1_0 == bHwVer) +#elif (NFC_NXP_CHIP_TYPE == PN548C2) + || (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bHwVer) +#elif (NFC_NXP_CHIP_TYPE == PN553) + || (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer || + PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]) +#endif + ) { + bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1; + (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer; +#if (NFC_NXP_CHIP_TYPE == PN553) + if (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]) { + (gphNxpNciHal_fw_IoctlCtx.bChipVer) = pRespBuff->pBuff[0]; + } +#endif + } else if ((bHwVer >= PHDNLDNFC_HWVER_MRA1_0) && + (bHwVer <= PHDNLDNFC_HWVER_MRA2_0)) { + bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN; + (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer; + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_get_version_cb - Invalid ChipVersion!!"); + } + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff " + "Invalid...\n"); + } + + if ((NFCSTATUS_SUCCESS == wStatus) && (bExpectedLen == pRespBuff->wLen) && + (NULL != pRespBuff->pBuff)) { + NXPLOG_FWDNLD_D( + "phNxpNciHal_fw_dnld_get_version_cb - Valid Version Resp " + "Buff!!...\n"); + + /* Validate version details to confirm if continue with the next sequence + * of Operations. */ + memcpy(bCurrVer, &(pRespBuff->pBuff[bExpectedLen - 2]), sizeof(bCurrVer)); + wFwVern = wFwVer; + wMwVern = wMwVer; + + memcpy(bNewVer, &wFwVern, sizeof(bNewVer)); + + /* check if the ROM code version and FW Major version is valid for the + * chip*/ + /* ES2.2 Rom Version - 0x7 and Valid FW Major Version - 0x1 */ + if ((pRespBuff->pBuff[1] == 0x07) && (bNewVer[1] != 0x01)) { + NXPLOG_FWDNLD_E( + "C1 FW on C2 chip is not allowed - FW Major Version!= 1 on ES2.2"); + wStatus = NFCSTATUS_NOT_ALLOWED; + } + /* Major Version number check */ + else if ((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && + (bNewVer[1] < bCurrVer[1])) { + NXPLOG_FWDNLD_E("Version Check Failed - MajorVerNum Mismatch\n"); + NXPLOG_FWDNLD_E("NewVer %d != CurrVer %d\n", bNewVer[1], bCurrVer[1]); + wStatus = NFCSTATUS_NOT_ALLOWED; + } + /* Minor Version number check - before download.*/ + else if ((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && + ((bNewVer[0] == bCurrVer[0]) && (bNewVer[1] == bCurrVer[1]))) { + wStatus = NFCSTATUS_SUCCESS; +#if (PH_LIBNFC_ENABLE_FORCE_DOWNLOAD == 0) + NXPLOG_FWDNLD_D("Version Already UpToDate!!\n"); + (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE; +#else + (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = TRUE; +#endif + + } + /* Minor Version number check - after download + * after download, we should get the same version information.*/ + else if ((TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && + ((bNewVer[0] != bCurrVer[0]) || (bNewVer[1] != bCurrVer[1]))) { + NXPLOG_FWDNLD_E("Version Not Updated After Download!!\n"); + wStatus = NFCSTATUS_FAILED; + } else { + NXPLOG_FWDNLD_D("Version Check Successful\n"); + /* Store the Mw & Fw Version for updating in EEPROM Log Area after + * successful download */ + if (TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) { + NXPLOG_FWDNLD_W("Updating Fw & Mw Versions.."); + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrMwVer) = wMwVern; + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrFwVer) = wFwVern; + } + } + } else { + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff " + "Invalid...\n"); + } + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Request Failed!!"); + } + + p_cb_data->status = wStatus; + SEM_POST(p_cb_data); + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_get_version +** +** Description Download Get version +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext, + NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + static uint8_t bGetVerRes[11]; + phDnldNfc_Buff_t tDnldBuff; + UNUSED(pContext); + UNUSED(status); + UNUSED(pInfo); + if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) || + ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) { + return NFCSTATUS_SUCCESS; + } + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed"); + return NFCSTATUS_FAILED; + } + + tDnldBuff.pBuff = bGetVerRes; + tDnldBuff.wLen = sizeof(bGetVerRes); + + wStatus = phDnldNfc_GetVersion( + &tDnldBuff, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_get_version_cb, + (void*)&cb_data); + if (wStatus != NFCSTATUS_PENDING) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_get_sessn_state_cb +** +** Description Download Get session state callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext, + NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + NFCSTATUS wStatus = status; + pphDnldNfc_Buff_t pRespBuff; + if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) { + NXPLOG_FWDNLD_D( + "phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Successful"); + + pRespBuff = (pphDnldNfc_Buff_t)pInfo; + + if ((3 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) { + NXPLOG_FWDNLD_D( + "phNxpNciHal_fw_dnld_get_sessn_state_cb - Valid Session State Resp " + "Buff!!..."); + + if (phDnldNfc_LCOper == pRespBuff->pBuff[2]) { + if (PHLIBNFC_FWDNLD_SESSNOPEN == pRespBuff->pBuff[0]) { + NXPLOG_FWDNLD_E("Prev Fw Upgrade Session still Open.."); + (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = true; + if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) { + NXPLOG_FWDNLD_D( + "Session still Open after Prev Fw Upgrade attempt!!"); + + if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < + PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) { + NXPLOG_FWDNLD_W("Setting Dnld Retry .."); + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true; + } else { + NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!"); + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + } + wStatus = NFCSTATUS_FAILED; + } + } else { + gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen = false; + } + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E( + "NFCC not in Operational State..Fw Upgrade not allowed!!"); + } + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_get_sessn_state_cb - Session State Resp Buff " + "Invalid..."); + } + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Failed!!"); + } + + p_cb_data->status = wStatus; + + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_get_sessn_state +** +** Description Download Get session state +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext, + NFCSTATUS status, + void* pInfo) { + phDnldNfc_Buff_t tDnldBuff; + static uint8_t bGSnStateRes[3]; + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + UNUSED(pContext); + UNUSED(status); + UNUSED(pInfo); + if (gphNxpNciHal_fw_IoctlCtx.bSkipSeq == true) { + return NFCSTATUS_SUCCESS; + } + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed"); + return NFCSTATUS_FAILED; + } + + tDnldBuff.pBuff = bGSnStateRes; + tDnldBuff.wLen = sizeof(bGSnStateRes); + + wStatus = phDnldNfc_GetSessionState( + &tDnldBuff, &phNxpNciHal_fw_dnld_get_sessn_state_cb, (void*)&cb_data); + if (wStatus != NFCSTATUS_PENDING) { + NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_log_read_cb +** +** Description Download Logread callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + + if ((NFCSTATUS_SUCCESS == status) && (NULL != pInfo)) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_log_read_cb - Request Successful"); + } else { + status = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read_cb - Request Failed!!"); + } + + p_cb_data->status = status; + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_log_read +** +** Description Download Log Read +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + phDnldNfc_Buff_t Data; + UNUSED(pContext); + UNUSED(status); + UNUSED(pInfo); + if (((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) || + ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) && + ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) || + ((((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) && + ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true))) + + { + return NFCSTATUS_SUCCESS; + } + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb_data creation failed"); + return NFCSTATUS_FAILED; + } + + (Data.pBuff) = (void*)&(gphNxpNciHal_fw_IoctlCtx.tLogParams); + (Data.wLen) = sizeof(phLibNfc_EELogParams_t); + + wStatus = phDnldNfc_ReadLog( + &Data, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_read_cb, + (void*)&cb_data); + if (wStatus != NFCSTATUS_PENDING) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_write_cb +** +** Description Download Write callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + UNUSED(pInfo); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Request Successful"); + (gphNxpNciHal_fw_IoctlCtx.bDnldEepromWrite) = false; + if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) { + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldSuccess) += 1; + + if ((gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) > 0) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Resetting DnldFailCnt"); + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) = 0; + } + + if ((gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) == false) { + NXPLOG_FWDNLD_D( + "phNxpNciHal_fw_dnld_write_cb - Setting bConfig for use by NCI " + "mode"); + (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = true; + } + } + + /* Reset the previously set DnldAttemptFailed flag */ + if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) == true) { + (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = false; + } + } else { + if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) { + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1; + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1; + (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = false; + } + if (NFCSTATUS_WRITE_FAILED == status) { + (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = true; + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true; + } + // status = NFCSTATUS_FAILED; + + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write_cb - Request Failed!!"); + } + + p_cb_data->status = status; + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_write +** +** Description Download Write +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + UNUSED(pContext); + UNUSED(status); + UNUSED(pInfo); + if ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) { + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + } + + if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) && + ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) { + return NFCSTATUS_SUCCESS; + } + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb_data creation failed"); + return NFCSTATUS_FAILED; + } + if ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write - Incrementing NumDnldTrig.."); + (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = true; + (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldTrig) += 1; + } + wStatus = phDnldNfc_Write(false, NULL, + (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_write_cb, + (void*)&cb_data); + if ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) { + if (wStatus != NFCSTATUS_PENDING) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write failed"); + wStatus = NFCSTATUS_FAILED; + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1; + (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1; + (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = false; + goto clean_and_return; + } + } + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb failed"); + wStatus = cb_data.status; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_chk_integrity_cb +** +** Description Download Check Integrity callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext, + NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + NFCSTATUS wStatus = status; + pphDnldNfc_Buff_t pRespBuff; + // uint8_t bUserDataCrc[4]; + + if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) { + NXPLOG_FWDNLD_D( + "phNxpNciHal_fw_dnld_chk_integrity_cb - Request Successful"); + pRespBuff = (pphDnldNfc_Buff_t)pInfo; + + if ((31 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) { + NXPLOG_FWDNLD_D( + "phNxpNciHal_fw_dnld_chk_integrity_cb - Valid Resp Buff!!...\n"); + wStatus = phLibNfc_VerifyCrcStatus(pRespBuff->pBuff[0]); + /* + memcpy(bUserDataCrc, &(pRespBuff->pBuff[27]), + sizeof(bUserDataCrc));*/ + } else { + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_chk_integrity_cb - Resp Buff Invalid...\n"); + } + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Failed!!"); + } + + p_cb_data->status = wStatus; + + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_chk_integrity +** +** Description Download Check Integrity +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext, + NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + phDnldNfc_Buff_t tDnldBuff; + static uint8_t bChkIntgRes[31]; + UNUSED(pInfo); + UNUSED(pContext); + UNUSED(status); + if (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) { + NXPLOG_FWDNLD_D( + "Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!"); + return NFCSTATUS_SUCCESS; + } + + if ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) { + return NFCSTATUS_SUCCESS; + } else if (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) { + NXPLOG_FWDNLD_E( + "Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!"); + return NFCSTATUS_SUCCESS; + } + + tDnldBuff.pBuff = bChkIntgRes; + tDnldBuff.wLen = sizeof(bChkIntgRes); + + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_chk_integrity cb_data creation failed"); + return NFCSTATUS_FAILED; + } + + wStatus = phDnldNfc_CheckIntegrity( + (gphNxpNciHal_fw_IoctlCtx.bChipVer), &tDnldBuff, + &phNxpNciHal_fw_dnld_chk_integrity_cb, (void*)&cb_data); + if (wStatus != NFCSTATUS_PENDING) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_recover +** +** Description Download Recover +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + + UNUSED(pInfo); + UNUSED(status); + UNUSED(pContext); + if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) { + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb_data creation failed"); + return NFCSTATUS_FAILED; + } + (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; + + /* resetting this flag to avoid cyclic issuance of recovery sequence in case + * of failure */ + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + + wStatus = phDnldNfc_Write( + true, NULL, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_recover_cb, + (void*)&cb_data); + + if (NFCSTATUS_PENDING != wStatus) { + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + goto clean_and_return; + } + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + wStatus = NFCSTATUS_SUCCESS; + + clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_recover_cb +** +** Description Download Recover callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + NFCSTATUS wStatus = status; + UNUSED(pContext); + UNUSED(pInfo); + + if (NFCSTATUS_SUCCESS == wStatus) { + if ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == false) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Successful"); + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true; + } else { + NXPLOG_FWDNLD_D( + "phNxpNciHal_fw_dnld_recoverCb - Production key update Request " + "Successful"); + (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = true; + } + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Failed!!"); + } + + /* resetting this flag to avoid cyclic issuance of recovery sequence in case + * of failure */ + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + + /* reset previously set SkipForce */ + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false; + p_cb_data->status = wStatus; + + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_send_ncicmd_cb +** +** Description Download Send NCI Command callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_send_ncicmd_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + NFCSTATUS wStatus = status; + pphDnldNfc_Buff_t pRespBuff; + UNUSED(pContext); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Successful"); + pRespBuff = (pphDnldNfc_Buff_t)pInfo; + + if ((0 != (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) { + if (0 == (pRespBuff->pBuff[3])) { + NXPLOG_FWDNLD_D("Successful Response received for Nci Reset Cmd"); + } else { + NXPLOG_FWDNLD_E("Nci Reset Request Failed!!"); + } + } else { + NXPLOG_FWDNLD_E("Invalid Response received for Nci Reset Request!!"); + } + /* Call Tml Ioctl to enable download mode */ + wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("Switched Successfully to dnld mode.."); + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true; + } else { + NXPLOG_FWDNLD_E("Switching back to dnld mode Failed!!"); + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + wStatus = NFCSTATUS_FAILED; + } + } else { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Failed!!"); + } + + (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false; + p_cb_data->status = wStatus; + + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_send_ncicmd +** +** Description Download Send NCI Command +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, + NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + static uint8_t bNciCmd[4] = {0x20, 0x00, 0x01, + 0x00}; /* Nci Reset Cmd with KeepConfig option */ + static uint8_t bNciResp[6]; + phDnldNfc_Buff_t tsData; + phDnldNfc_Buff_t trData; + phNxpNciHal_Sem_t cb_data; + + UNUSED(pInfo); + UNUSED(status); + UNUSED(pContext); + if ((gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) == false) { + return NFCSTATUS_SUCCESS; + } else { + /* Call Tml Ioctl to enable/restore normal mode */ + wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode); + + if (NFCSTATUS_SUCCESS != wStatus) { + NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!"); + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false; + } else { + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_send_ncicmd cb_data creation failed"); + return NFCSTATUS_FAILED; + } + (tsData.pBuff) = bNciCmd; + (tsData.wLen) = sizeof(bNciCmd); + (trData.pBuff) = bNciResp; + (trData.wLen) = sizeof(bNciResp); + + wStatus = phDnldNfc_RawReq( + &tsData, &trData, + (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_send_ncicmd_cb, + (void*)&cb_data); + if (NFCSTATUS_PENDING != wStatus) { + goto clean_and_return; + } + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + wStatus = NFCSTATUS_SUCCESS; + + clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_log_cb +** +** Description Download Log callback +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status, + void* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + NFCSTATUS wStatus = status; + UNUSED(pContext); + UNUSED(pInfo); + + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_FWDNLD_D("phLibNfc_DnldLogCb - Request Successful"); + (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false; + } else { + wStatus = NFCSTATUS_FAILED; + NXPLOG_FWDNLD_E("phLibNfc_DnldLogCb - Request Failed!!"); + } + p_cb_data->status = wStatus; + + SEM_POST(p_cb_data); + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_log +** +** Description Download Log +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + phDnldNfc_Buff_t tData; + + UNUSED(pInfo); + UNUSED(status); + UNUSED(pContext); + if ((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) || + ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) && + ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == false)) { + return NFCSTATUS_SUCCESS; + } else { + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log cb_data creation failed"); + return NFCSTATUS_FAILED; + } + (tData.pBuff) = (void*)&(gphNxpNciHal_fw_IoctlCtx.tLogParams); + (tData.wLen) = sizeof(gphNxpNciHal_fw_IoctlCtx.tLogParams); + + wStatus = + phDnldNfc_Log(&tData, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_cb, + (void*)&cb_data); + + if (wStatus != NFCSTATUS_PENDING) { + NXPLOG_FWDNLD_E("phDnldNfc_Log failed"); + (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false; + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log semaphore error"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_cb failed"); + wStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + wStatus = NFCSTATUS_SUCCESS; + + clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return wStatus; + } +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_seq_handler +** +** Description Sequence Handler +** +** Returns NFCSTATUS_SUCCESS if sequence completed uninterrupted +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_seq_handler( + NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo)) { + char* pContext = "FW-Download"; + int16_t seq_counter = 0; + phDnldNfc_Buff_t pInfo; + NFCSTATUS status = NFCSTATUS_FAILED; + + status = phTmlNfc_ReadAbort(); + if (NFCSTATUS_SUCCESS != status) { + NXPLOG_FWDNLD_E("Tml Read Abort failed!!"); + return status; + } + + while (seq_handler[seq_counter] != NULL) { + status = NFCSTATUS_FAILED; + status = (seq_handler[seq_counter])(pContext, status, &pInfo); + if (NFCSTATUS_SUCCESS != status) { + NXPLOG_FWDNLD_E(" phNxpNciHal_fw_seq_handler : FAILED"); + break; + } + seq_counter++; + } + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_dnld_complete +** +** Description Download Sequence Complete +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status, + void* pInfo) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + NFCSTATUS fStatus = status; + UNUSED(pInfo); + UNUSED(pContext); + + if (NFCSTATUS_WRITE_FAILED == status) { + if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < + PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) { + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true; + } else { + NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!"); + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + } + } else if (NFCSTATUS_REJECTED == status) { + if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < + PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) { + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true; + + /* in case of signature error we need to try recover sequence directly + * bypassing the force cmd */ + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = true; + } else { + NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!"); + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + } + } + + if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) { + (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = status; + (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = true; + + NXPLOG_FWDNLD_E("Invoking Pending Download Log Sequence.."); + (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false; + /* Perform the Logging sequence */ + wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_log_seqhandler); + if (NFCSTATUS_SUCCESS != gphNxpNciHal_fw_IoctlCtx.bLastStatus) { + /* update the previous Download Write status to upper layer and not the + * status of Log command */ + wStatus = gphNxpNciHal_fw_IoctlCtx.bLastStatus; + NXPLOG_FWDNLD_E( + "phNxpNciHal_fw_dnld_complete: Last Download Write Status before Log " + "command bLastStatus = 0x%x", + gphNxpNciHal_fw_IoctlCtx.bLastStatus); + } + status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); + } else { + NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); + } + } else if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) { + NXPLOG_FWDNLD_E("Invoking Download Recovery Sequence.."); + + if (NFCSTATUS_SUCCESS == wStatus) { + /* Perform the download Recovery sequence */ + wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_rec_seqhandler); + + status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); + } else { + NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); + } + } + } else if ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) { + (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false; + (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false; + (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false; + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false; + + /* Perform the download sequence ... after successful recover attempt */ + wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler); + + status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); + } else { + NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); + } + } else { + NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_complete: Download Status = 0x%x", + status); + if ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == false) { + if (NFCSTATUS_SUCCESS == status) { + if (NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("Fw Download success.. "); + } else if (PHLIBNFC_DNLD_MEM_READ == + gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("Read Request success.. "); + } else if (PHLIBNFC_DNLD_MEM_WRITE == + gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("Write Request success.. "); + } else if (PHLIBNFC_DNLD_READ_LOG == + gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("ReadLog Request success.. "); + } else { + NXPLOG_FWDNLD_E("Invalid Request!!"); + } + } else { + if (NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("Fw Download Failed!!"); + } else if (NFC_MEM_READ == gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("Read Request Failed!!"); + } else if (NFC_MEM_WRITE == gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("Write Request Failed!!"); + } else if (PHLIBNFC_DNLD_READ_LOG == + gphNxpNciHal_fw_IoctlCtx.IoctlCode) { + NXPLOG_FWDNLD_E("ReadLog Request Failed!!"); + } else { + NXPLOG_FWDNLD_E("Invalid Request!!"); + } + } + } + + if (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd == false) { + /* Call Tml Ioctl to enable/restore normal mode */ + wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode); + + if (NFCSTATUS_SUCCESS != wStatus) { + NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!"); + } else { + wStatus = fStatus; + } + } + + (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false; + (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0; + (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false; + (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false; + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false; + (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0; + + if (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed == false) { + } else { + NXPLOG_FWDNLD_E("Returning Download Failed Status to Caller!!"); + + (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = NFCSTATUS_SUCCESS; + (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = false; + } + phDnldNfc_CloseFwLibHandle(); + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phNxpNciHal_fw_download_seq +** +** Description Download Sequence +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal) { + NFCSTATUS status = NFCSTATUS_FAILED; + phDnldNfc_Buff_t pInfo; + char* pContext = "FW-Download"; + + /* reset the global flags */ + gphNxpNciHal_fw_IoctlCtx.IoctlCode = NFC_FW_DOWNLOAD; + (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false; + (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0; + (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false; + (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false; + (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false; + (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false; + (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false; + (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false; + (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0; + (gphNxpNciHal_fw_IoctlCtx.bClkSrcVal) = bClkSrcVal; + (gphNxpNciHal_fw_IoctlCtx.bClkFreqVal) = bClkFreqVal; + /* Get firmware version */ + if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo()) { + NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS"); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (gRecFWDwnld == true) { + status = + phNxpNciHal_fw_seq_handler(phNxpNciHal_dummy_rec_dwnld_seqhandler); + } else +#endif + { + status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler); + } + } else { + NXPLOG_FWDNLD_E("phDnldNfc_InitImgInfo: FAILED"); + } + + /* Chage to normal mode */ + status = phNxpNciHal_fw_dnld_complete(pContext, status, &pInfo); + /*if (NFCSTATUS_SUCCESS == status) + { + NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); + } + else + { + NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); + }*/ + + return status; +} + +static NFCSTATUS phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus) { +#if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553)) + uint8_t bBitPos = 1; + uint8_t bShiftVal = 2; +#else + uint8_t bBitPos = 0; + uint8_t bShiftVal = 1; +#endif + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + while (bBitPos < 7) { + if (!(bCrcStatus & bShiftVal)) { + switch (bBitPos) { + case 0: { + NXPLOG_FWDNLD_E("User Data Crc is NOT OK!!"); + wStatus = NFCSTATUS_FAILED; + break; + } + case 1: { + NXPLOG_FWDNLD_E("Trim Data Crc is NOT OK!!"); + wStatus = NFCSTATUS_FAILED; + break; + } + case 2: { + NXPLOG_FWDNLD_E("Protected Data Crc is NOT OK!!"); + wStatus = NFCSTATUS_FAILED; + break; + } + case 3: { + NXPLOG_FWDNLD_E("Patch Code Crc is NOT OK!!"); + wStatus = NFCSTATUS_FAILED; + break; + } + case 4: { + NXPLOG_FWDNLD_E("Function Code Crc is NOT OK!!"); + wStatus = NFCSTATUS_FAILED; + break; + } + case 5: { + NXPLOG_FWDNLD_E("Patch Table Crc is NOT OK!!"); + wStatus = NFCSTATUS_FAILED; + break; + } + case 6: { + NXPLOG_FWDNLD_E("Function Table Crc is NOT OK!!"); + wStatus = NFCSTATUS_FAILED; + break; + } + default: { break; } + } + } + + bShiftVal <<= 1; + ++bBitPos; + } + + return wStatus; +} diff --git a/pn54x/dnld/phNxpNciHal_Dnld.h b/pn54x/dnld/phNxpNciHal_Dnld.h new file mode 100644 index 0000000..d32fead --- /dev/null +++ b/pn54x/dnld/phNxpNciHal_Dnld.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _PHNXPNCIHAL_DNLD_H_ +#define _PHNXPNCIHAL_DNLD_H_ + +#include <phNfcStatus.h> +#include <phNfcTypes.h> + +NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal); + +#endif /* _PHNXPNCIHAL_DNLD_H_ */ diff --git a/pn54x/hal/phNxpNciHal.c b/pn54x/hal/phNxpNciHal.c new file mode 100644 index 0000000..5a799d5 --- /dev/null +++ b/pn54x/hal/phNxpNciHal.c @@ -0,0 +1,2653 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <phDal4Nfc_messageQueueLib.h> +#include <phDnldNfc.h> +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include <phNxpNciHal.h> +#include <phNxpNciHal_Adaptation.h> +#include <phNxpNciHal_Dnld.h> +#include <phNxpNciHal_NfcDepSWPrio.h> +#include <phNxpNciHal_ext.h> +#include <phTmlNfc.h> +#include <sys/stat.h> +/*********************** Global Variables *************************************/ +#define PN547C2_CLOCK_SETTING +#undef PN547C2_FACTORY_RESET_DEBUG +#define CORE_RES_STATUS_BYTE 3 +/* FW Mobile major number */ +#define FW_MOBILE_MAJOR_NUMBER_PN553 0x01 +#define FW_MOBILE_MAJOR_NUMBER_PN81A 0x02 +#define FW_MOBILE_MAJOR_NUMBER_PN551 0x05 +#define FW_MOBILE_MAJOR_NUMBER_PN48AD 0x01 + +#if (NFC_NXP_CHIP_TYPE == PN551) +#define FW_MOBILE_MAJOR_NUMBER FW_MOBILE_MAJOR_NUMBER_PN551 +#elif (NFC_NXP_CHIP_TYPE == PN553) +#define FW_MOBILE_MAJOR_NUMBER FW_MOBILE_MAJOR_NUMBER_PN553 +#else +#define FW_MOBILE_MAJOR_NUMBER FW_MOBILE_MAJOR_NUMBER_PN48AD +#endif +/* Processing of ISO 15693 EOF */ +extern uint8_t icode_send_eof; +extern uint8_t icode_detected; +static uint8_t cmd_icode_eof[] = {0x00, 0x00, 0x00}; + +/* FW download success flag */ +static uint8_t fw_download_success = 0; + +static uint8_t config_access = false; +static uint8_t config_success = true; +/* NCI HAL Control structure */ +phNxpNciHal_Control_t nxpncihal_ctrl; + +/* NXP Poll Profile structure */ +phNxpNciProfile_Control_t nxpprofile_ctrl; + +/* TML Context */ +extern phTmlNfc_Context_t* gpphTmlNfc_Context; +extern void phTmlNfc_set_fragmentation_enabled( + phTmlNfc_i2cfragmentation_t result); +/* global variable to get FW version from NCI response*/ +uint32_t wFwVerRsp; +/* External global variable to get FW version */ +extern uint16_t wFwVer; + +extern uint16_t fw_maj_ver; +extern uint16_t rom_version; +#if (NFC_NXP_CHIP_TYPE != PN547C2) +extern uint8_t gRecFWDwnld; +static uint8_t gRecFwRetryCount; // variable to hold dummy FW recovery count +#endif +static uint8_t Rx_data[NCI_MAX_DATA_LEN]; + +#if (NFC_NXP_CHIP_TYPE == PN548C2) +uint8_t discovery_cmd[50] = {0}; +uint8_t discovery_cmd_len = 0; +#endif +uint32_t timeoutTimerId = 0; +phNxpNciHal_Sem_t config_data; + +phNxpNciClock_t phNxpNciClock = {0, {0}, false}; + +phNxpNciRfSetting_t phNxpNciRfSet = {false, {0}}; + +phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {false, {0}}; + +/**************** local methods used in this file only ************************/ +static NFCSTATUS phNxpNciHal_fw_download(void); +static void phNxpNciHal_open_complete(NFCSTATUS status); +static void phNxpNciHal_write_complete(void* pContext, + phTmlNfc_TransactInfo_t* pInfo); +static void phNxpNciHal_read_complete(void* pContext, + phTmlNfc_TransactInfo_t* pInfo); +static void phNxpNciHal_close_complete(NFCSTATUS status); +static void phNxpNciHal_core_initialized_complete(NFCSTATUS status); +static void phNxpNciHal_pre_discover_complete(NFCSTATUS status); +static void phNxpNciHal_power_cycle_complete(NFCSTATUS status); +static void phNxpNciHal_kill_client_thread( + phNxpNciHal_Control_t* p_nxpncihal_ctrl); +static void* phNxpNciHal_client_thread(void* arg); +static void phNxpNciHal_get_clk_freq(void); +static void phNxpNciHal_set_clock(void); +static void phNxpNciHal_check_factory_reset(void); +static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len); +static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void); +static void phNxpNciHal_enable_i2c_fragmentation(); +static NFCSTATUS phNxpNciHal_get_mw_eeprom(void); +static NFCSTATUS phNxpNciHal_set_mw_eeprom(void); +static int phNxpNciHal_fw_mw_ver_check(); +NFCSTATUS phNxpNciHal_check_clock_config(void); +NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void); +#if (NFC_NXP_CHIP_TYPE != PN547C2) +static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence(); +static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus(); +#endif +int check_config_parameter(); + +/****************************************************************************** + * Function phNxpNciHal_client_thread + * + * Description This function is a thread handler which handles all TML and + * NCI messages. + * + * Returns void + * + ******************************************************************************/ +static void* phNxpNciHal_client_thread(void* arg) { + phNxpNciHal_Control_t* p_nxpncihal_ctrl = (phNxpNciHal_Control_t*)arg; + phLibNfc_Message_t msg; + + NXPLOG_NCIHAL_D("thread started"); + + p_nxpncihal_ctrl->thread_running = 1; + + while (p_nxpncihal_ctrl->thread_running == 1) { + /* Fetch next message from the NFC stack message queue */ + if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId, &msg, 0, 0) == + -1) { + NXPLOG_NCIHAL_E("NFC client received bad message"); + continue; + } + + if (p_nxpncihal_ctrl->thread_running == 0) { + break; + } + + switch (msg.eMsgType) { + case PH_LIBNFC_DEFERREDCALL_MSG: { + phLibNfc_DeferredCall_t* deferCall = + (phLibNfc_DeferredCall_t*)(msg.pMsgData); + + REENTRANCE_LOCK(); + deferCall->pCallback(deferCall->pParameter); + REENTRANCE_UNLOCK(); + + break; + } + + case NCI_HAL_OPEN_CPLT_MSG: { + REENTRANCE_LOCK(); + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /* Send the event */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT, + HAL_NFC_STATUS_OK); + } + REENTRANCE_UNLOCK(); + break; + } + + case NCI_HAL_CLOSE_CPLT_MSG: { + REENTRANCE_LOCK(); + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /* Send the event */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT, + HAL_NFC_STATUS_OK); + phNxpNciHal_kill_client_thread(&nxpncihal_ctrl); + } + REENTRANCE_UNLOCK(); + break; + } + + case NCI_HAL_POST_INIT_CPLT_MSG: { + REENTRANCE_LOCK(); + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /* Send the event */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT, + HAL_NFC_STATUS_OK); + } + REENTRANCE_UNLOCK(); + break; + } + + case NCI_HAL_PRE_DISCOVER_CPLT_MSG: { + REENTRANCE_LOCK(); + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /* Send the event */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_PRE_DISCOVER_CPLT_EVT, + HAL_NFC_STATUS_OK); + } + REENTRANCE_UNLOCK(); + break; + } + + case NCI_HAL_ERROR_MSG: { + REENTRANCE_LOCK(); + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /* Send the event */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT, + HAL_NFC_STATUS_FAILED); + } + REENTRANCE_UNLOCK(); + break; + } + + case NCI_HAL_RX_MSG: { + REENTRANCE_LOCK(); + if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) { + (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rsp_len, + nxpncihal_ctrl.p_rsp_data); + } + REENTRANCE_UNLOCK(); + break; + } + } + } + + NXPLOG_NCIHAL_D("NxpNciHal thread stopped"); + + return NULL; +} + +/****************************************************************************** + * Function phNxpNciHal_kill_client_thread + * + * Description This function safely kill the client thread and clean all + * resources. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_kill_client_thread( + phNxpNciHal_Control_t* p_nxpncihal_ctrl) { + NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread..."); + + p_nxpncihal_ctrl->p_nfc_stack_cback = NULL; + p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL; + p_nxpncihal_ctrl->thread_running = 0; + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_fw_download + * + * Description This function download the PN54X secure firmware to IC. If + * firmware version in Android filesystem and firmware in the + * IC is same then firmware download will return with success + * without downloading the firmware. + * + * Returns NFCSTATUS_SUCCESS if firmware download successful + * NFCSTATUS_FAILED in case of failure + * + ******************************************************************************/ +static NFCSTATUS phNxpNciHal_fw_download(void) { + NFCSTATUS status = NFCSTATUS_FAILED; + /*NCI_RESET_CMD*/ + static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00}; + + phNxpNciHal_get_clk_freq(); + status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode); + if (NFCSTATUS_SUCCESS == status) { + /* Set the obtained device handle to download module */ + phDnldNfc_SetHwDevHandle(); + NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n"); + status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal, + nxpprofile_ctrl.bClkFreqVal); + if (status != NFCSTATUS_SUCCESS) { + /* Abort any pending read and write */ + phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + phTmlNfc_ReadAbort(); + phTmlNfc_WriteAbort(); + } + phDnldNfc_ReSetHwDevHandle(); + } else { + status = NFCSTATUS_FAILED; + } + + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_CheckValidFwVersion + * + * Description This function checks the valid FW for Mobile device. + * If the FW doesn't belong the Mobile device it further + * checks nxp config file to override. + * + * Returns NFCSTATUS_SUCCESS if valid fw version found + * NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile + * device + * + ******************************************************************************/ +static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void) { + NFCSTATUS status = NFCSTATUS_NOT_ALLOWED; + const unsigned char sfw_infra_major_no = 0x02; + unsigned char ufw_current_major_no = 0x00; + unsigned long num = 0; + int isfound = 0; + + /* extract the firmware's major no */ + ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U)); + + NXPLOG_NCIHAL_D("%s current_major_no = 0x%x", __FUNCTION__, + ufw_current_major_no); + if ((ufw_current_major_no == FW_MOBILE_MAJOR_NUMBER) || + ((ufw_current_major_no == FW_MOBILE_MAJOR_NUMBER_PN81A && + (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0))) +#if (NFC_NXP_CHIP_TYPE == PN553) + || ((rom_version == 0x00) && + (ufw_current_major_no == FW_MOBILE_MAJOR_NUMBER_PN81A)) +#endif + ) + + { + status = NFCSTATUS_SUCCESS; + } else if (ufw_current_major_no == sfw_infra_major_no) { + if (rom_version == FW_MOBILE_ROM_VERSION_PN553 && + nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + NXPLOG_NCIHAL_D(" PN81A allow Fw download with major number = 0x%x", + ufw_current_major_no); + status = NFCSTATUS_SUCCESS; + } else { + /* Check the nxp config file if still want to go for download */ + /* By default NAME_NXP_FW_PROTECION_OVERRIDE will not be defined in config + file. + If user really want to override the Infra firmware over mobile + firmware, please + put "NXP_FW_PROTECION_OVERRIDE=0x01" in libnfc-nxp.conf file. + Please note once Infra firmware downloaded to Mobile device, The device + can never be updated to Mobile firmware*/ + isfound = + GetNxpNumValue(NAME_NXP_FW_PROTECION_OVERRIDE, &num, sizeof(num)); + if (isfound > 0) { + if (num == 0x01) { + NXPLOG_NCIHAL_D("Override Infra FW over Mobile"); + status = NFCSTATUS_SUCCESS; + } else { + NXPLOG_NCIHAL_D( + "Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE " + "invalid value)"); + } + } else { + NXPLOG_NCIHAL_D( + "Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not " + "defined)"); + } + } + } +#if (NFC_NXP_CHIP_TYPE != PN547C2) + else if (gRecFWDwnld == TRUE) { + status = NFCSTATUS_SUCCESS; + } +#endif + else if (wFwVerRsp == 0) { + NXPLOG_NCIHAL_E( + "FW Version not received by NCI command >>> Force Firmware download"); + status = NFCSTATUS_SUCCESS; + } else { + NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed"); + } + + return status; +} + +static void phNxpNciHal_get_clk_freq(void) { + unsigned long num = 0; + int isfound = 0; + + nxpprofile_ctrl.bClkSrcVal = 0; + nxpprofile_ctrl.bClkFreqVal = 0; + nxpprofile_ctrl.bTimeout = 0; + + isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num)); + if (isfound > 0) { + nxpprofile_ctrl.bClkSrcVal = num; + } + + num = 0; + isfound = 0; + isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num)); + if (isfound > 0) { + nxpprofile_ctrl.bClkFreqVal = num; + } + + num = 0; + isfound = 0; + isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num)); + if (isfound > 0) { + nxpprofile_ctrl.bTimeout = num; + } + + NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x", + nxpprofile_ctrl.bClkSrcVal); + NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", + nxpprofile_ctrl.bClkFreqVal); + NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", + nxpprofile_ctrl.bTimeout); + + if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) || + (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL)) { + NXPLOG_FWDNLD_E( + "Clock source value is wrong in config file, setting it as default"); + nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL; + } + if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) || + (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ)) { + NXPLOG_FWDNLD_E( + "Clock frequency value is wrong in config file, setting it as default"); + nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL; + } + if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) || + (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX)) { + NXPLOG_FWDNLD_E( + "Clock timeout value is wrong in config file, setting it as default"); + nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF; + } +} + +/****************************************************************************** + * Function phNxpNciHal_open + * + * Description This function is called by libnfc-nci during the + * initialization of the NFCC. It opens the physical connection + * with NFCC (PN54X) and creates required client thread for + * operation. + * After open is complete, status is informed to libnfc-nci + * through callback function. + * + * Returns This function return NFCSTATUS_SUCCES (0) in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +int phNxpNciHal_open(nfc_stack_callback_t* p_cback, + nfc_stack_data_callback_t* p_data_cback) { + phOsalNfc_Config_t tOsalConfig; + phTmlNfc_Config_t tTmlConfig; + char* nfc_dev_node = NULL; + const uint16_t max_len = 260; + NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS; + NFCSTATUS status = NFCSTATUS_SUCCESS; + /*NCI_INIT_CMD*/ + static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00}; + /*NCI_RESET_CMD*/ + static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00}; + /*NCI2_0_INIT_CMD*/ + static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00}; + if (nxpncihal_ctrl.halStatus == HAL_STATUS_OPEN) { + NXPLOG_NCIHAL_E("phNxpNciHal_open already open"); + return NFCSTATUS_SUCCESS; + } + /* reset config cache */ + resetNxpConfig(); + + int init_retry_cnt = 0; + int8_t ret_val = 0x00; + + /* initialize trace level */ + phNxpLog_InitializeLogLevel(); + + /*Create the timer for extns write response*/ + timeoutTimerId = phOsalNfc_Timer_Create(); + + if (phNxpNciHal_init_monitor() == NULL) { + NXPLOG_NCIHAL_E("Init monitor failed"); + return NFCSTATUS_FAILED; + } + + CONCURRENCY_LOCK(); + memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl)); + memset(&tOsalConfig, 0x00, sizeof(tOsalConfig)); + memset(&tTmlConfig, 0x00, sizeof(tTmlConfig)); + memset(&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t)); + + /* By default HAL status is HAL_STATUS_OPEN */ + nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN; + + nxpncihal_ctrl.p_nfc_stack_cback = p_cback; + nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback; + /*nci version NCI_VERSION_UNKNOWN version by default*/ + nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_UNKNOWN; + /* Read the nfc device node name */ + nfc_dev_node = (char*)malloc(max_len * sizeof(char)); + if (nfc_dev_node == NULL) { + NXPLOG_NCIHAL_E("malloc of nfc_dev_node failed "); + goto clean_and_return; + } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node, + sizeof(nfc_dev_node))) { + NXPLOG_NCIHAL_E( + "Invalid nfc device node name keeping the default device node " + "/dev/pn54x"); + strcpy(nfc_dev_node, "/dev/pn54x"); + } + + /* Configure hardware link */ + nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600); + nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */ + tTmlConfig.pDevName = (int8_t*)nfc_dev_node; + tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId; + tOsalConfig.pLogFile = NULL; + tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId; + +#if (NFC_NXP_CHIP_TYPE == PN548C2) + memset(discovery_cmd, 0, sizeof(discovery_cmd)); + discovery_cmd_len = 0; +#endif + + /* Initialize TML layer */ + wConfigStatus = phTmlNfc_Init(&tTmlConfig); + if (wConfigStatus != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("phTmlNfc_Init Failed"); + goto clean_and_return; + } else { + if (nfc_dev_node != NULL) { + free(nfc_dev_node); + nfc_dev_node = NULL; + } + } + + /* Create the client thread */ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ret_val = pthread_create(&nxpncihal_ctrl.client_thread, &attr, + phNxpNciHal_client_thread, &nxpncihal_ctrl); + pthread_attr_destroy(&attr); + if (ret_val != 0) { + NXPLOG_NCIHAL_E("pthread_create failed"); + wConfigStatus = phTmlNfc_Shutdown(); + goto clean_and_return; + } + + CONCURRENCY_UNLOCK(); + + /* call read pending */ + status = phTmlNfc_Read( + nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN, + (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL); + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("TML Read status error status = %x", status); + wConfigStatus = phTmlNfc_Shutdown(); + wConfigStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + +init_retry: + + phNxpNciHal_ext_init(); + + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + if ((status != NFCSTATUS_SUCCESS) && + (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) { + NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby"); + wConfigStatus = NFCSTATUS_FAILED; + goto force_download; + } else if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed"); + if (init_retry_cnt < 3) { + init_retry_cnt++; + (void)phNxpNciHal_power_cycle(); + goto init_retry; + } else + init_retry_cnt = 0; + wConfigStatus = phTmlNfc_Shutdown(); + wConfigStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0); + if (status == NFCSTATUS_SUCCESS) { + if (nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0) { + NXPLOG_NCIHAL_E("Chip is in NCI1.0 mode reset the chip again"); + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + if (status == NFCSTATUS_SUCCESS) { + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), + cmd_init_nci2_0); + } else { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci); + } + } + } + } + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed"); + if (init_retry_cnt < 3) { + init_retry_cnt++; + (void)phNxpNciHal_power_cycle(); + goto init_retry; + } else + init_retry_cnt = 0; + wConfigStatus = phTmlNfc_Shutdown(); + wConfigStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + phNxpNciHal_enable_i2c_fragmentation(); + /*Get FW version from device*/ + status = phDnldNfc_InitImgInfo(); + NXPLOG_NCIHAL_E("FW version for FW file = 0x%x", wFwVer); + NXPLOG_NCIHAL_E("FW version from device = 0x%x", wFwVerRsp); + if ((wFwVerRsp & 0x0000FFFF) == wFwVer) { + NXPLOG_NCIHAL_D("FW uptodate not required"); + phDnldNfc_ReSetHwDevHandle(); + } else { + force_download: + if (wFwVerRsp == 0) { + phDnldNfc_InitImgInfo(); + } + if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) { + NXPLOG_NCIHAL_D("FW update required"); + fw_download_success = 0; + status = phNxpNciHal_fw_download(); + if (status != NFCSTATUS_SUCCESS) { + if (NFCSTATUS_SUCCESS != phNxpNciHal_fw_mw_ver_check()) { + NXPLOG_NCIHAL_D("Chip Version Middleware Version mismatch!!!!"); + phOsalNfc_Timer_Cleanup(); + phTmlNfc_Shutdown(); + wConfigStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + NXPLOG_NCIHAL_E("FW Download failed - NFCC init will continue"); + } else { + wConfigStatus = NFCSTATUS_SUCCESS; + fw_download_success = 1; + /* call read pending */ + status = phTmlNfc_Read( + nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN, + (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL); + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("TML Read status error status = %x", status); + wConfigStatus = phTmlNfc_Shutdown(); + wConfigStatus = NFCSTATUS_FAILED; + goto clean_and_return; + } + } + } else { + if (wFwVerRsp == 0) phDnldNfc_ReSetHwDevHandle(); + } + } + /* Call open complete */ + phNxpNciHal_open_complete(wConfigStatus); + + return wConfigStatus; + +clean_and_return: + CONCURRENCY_UNLOCK(); + if (nfc_dev_node != NULL) { + free(nfc_dev_node); + nfc_dev_node = NULL; + } + /* Report error status */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT, + HAL_NFC_STATUS_FAILED); + + nxpncihal_ctrl.p_nfc_stack_cback = NULL; + nxpncihal_ctrl.p_nfc_stack_data_cback = NULL; + phNxpNciHal_cleanup_monitor(); + nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE; + return NFCSTATUS_FAILED; +} + +/****************************************************************************** + * Function phNxpNciHal_fw_mw_check + * + * Description This function inform the status of phNxpNciHal_fw_mw_check + * function to libnfc-nci. + * + * Returns int. + * + ******************************************************************************/ +int phNxpNciHal_fw_mw_ver_check() { + NFCSTATUS status = NFCSTATUS_FAILED; + if (!(strcmp(COMPILATION_MW, "PN553")) && + (rom_version == FW_MOBILE_ROM_VERSION_PN553) && + (fw_maj_ver == 0x01 || fw_maj_ver == 0x02)) { + status = NFCSTATUS_SUCCESS; + } else if (!strcmp(COMPILATION_MW, "PN551") && + (rom_version == FW_MOBILE_ROM_VERSION_PN551) && + (fw_maj_ver == 0x05)) { + status = NFCSTATUS_SUCCESS; + } else if (!strcmp(COMPILATION_MW, "PN548C2") && + (rom_version == FW_MOBILE_ROM_VERSION_PN548AD) && + (fw_maj_ver == 0x01)) { + status = NFCSTATUS_SUCCESS; + } else if (!strcmp(COMPILATION_MW, "PN547C2") && + (rom_version == FW_MOBILE_ROM_VERSION_PN547C2) && + (fw_maj_ver == 0x01)) { + status = NFCSTATUS_SUCCESS; + } + return status; +} +/****************************************************************************** + * Function phNxpNciHal_open_complete + * + * Description This function inform the status of phNxpNciHal_open + * function to libnfc-nci. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_open_complete(NFCSTATUS status) { + static phLibNfc_Message_t msg; + + if (status == NFCSTATUS_SUCCESS) { + msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG; + nxpncihal_ctrl.hal_open_status = true; + } else { + msg.eMsgType = NCI_HAL_ERROR_MSG; + } + + msg.pMsgData = NULL; + msg.Size = 0; + + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, + (phLibNfc_Message_t*)&msg); + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_write + * + * Description This function write the data to NFCC through physical + * interface (e.g. I2C) using the PN54X driver interface. + * Before sending the data to NFCC, phNxpNciHal_write_ext + * is called to check if there is any extension processing + * is required for the NCI packet being sent out. + * + * Returns It returns number of bytes successfully written to NFCC. + * + ******************************************************************************/ +int phNxpNciHal_write(uint16_t data_len, const uint8_t* p_data) { + NFCSTATUS status = NFCSTATUS_FAILED; + static phLibNfc_Message_t msg; + if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) { + return NFCSTATUS_FAILED; + } + /* Create local copy of cmd_data */ + memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len); + nxpncihal_ctrl.cmd_len = data_len; + if (nxpncihal_ctrl.cmd_len > NCI_MAX_DATA_LEN) { + NXPLOG_NCIHAL_D("cmd_len exceeds limit NCI_MAX_DATA_LEN"); + goto clean_and_return; + } +#ifdef P2P_PRIO_LOGIC_HAL_IMP + /* Specific logic to block RF disable when P2P priority logic is busy */ + if (p_data[0] == 0x21 && p_data[1] == 0x06 && p_data[2] == 0x01 && + EnableP2P_PrioLogic == true) { + NXPLOG_NCIHAL_D("P2P priority logic busy: Disable it."); + phNxpNciHal_clean_P2P_Prio(); + } +#endif + + /* Check for NXP ext before sending write */ + status = + phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data, + &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data); + if (status != NFCSTATUS_SUCCESS) { + /* Do not send packet to PN54X, send response directly */ + msg.eMsgType = NCI_HAL_RX_MSG; + msg.pMsgData = NULL; + msg.Size = 0; + + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, + (phLibNfc_Message_t*)&msg); + goto clean_and_return; + } + + CONCURRENCY_LOCK(); + data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len, + nxpncihal_ctrl.p_cmd_data); + CONCURRENCY_UNLOCK(); + + if (icode_send_eof == 1) { + usleep(10000); + icode_send_eof = 2; + phNxpNciHal_send_ext_cmd(3, cmd_icode_eof); + } + +clean_and_return: + /* No data written */ + return data_len; +} + +/****************************************************************************** + * Function phNxpNciHal_write_unlocked + * + * Description This is the actual function which is being called by + * phNxpNciHal_write. This function writes the data to NFCC. + * It waits till write callback provide the result of write + * process. + * + * Returns It returns number of bytes successfully written to NFCC. + * + ******************************************************************************/ +int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data) { + NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER; + phNxpNciHal_Sem_t cb_data; + nxpncihal_ctrl.retry_cnt = 0; + static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, + 0xC7, 0xD4, 0x00, 0x00}; + + /* Create the local semaphore */ + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed"); + data_len = 0; + goto clean_and_return; + } + + /* Create local copy of cmd_data */ + memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len); + nxpncihal_ctrl.cmd_len = data_len; + +retry: + + data_len = nxpncihal_ctrl.cmd_len; + + status = phTmlNfc_Write( + (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len, + (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_complete, + (void*)&cb_data); + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("write_unlocked status error"); + data_len = 0; + goto clean_and_return; + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_NCIHAL_E("write_unlocked semaphore error"); + data_len = 0; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + data_len = 0; + if (nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT) { + NXPLOG_NCIHAL_E( + "write_unlocked failed - PN54X Maybe in Standby Mode - Retry"); + /* 10ms delay to give NFCC wake up delay */ + usleep(1000 * 10); + goto retry; + } else { + NXPLOG_NCIHAL_E( + "write_unlocked failed - PN54X Maybe in Standby Mode (max count = " + "0x%x)", + nxpncihal_ctrl.retry_cnt); + + status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice); + + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n"); + } else { + NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); + } + if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL && + nxpncihal_ctrl.p_rx_data != NULL && + nxpncihal_ctrl.hal_open_status == true) { + NXPLOG_NCIHAL_D( + "Send the Core Reset NTF to upper layer, which will trigger the " + "recovery\n"); + // Send the Core Reset NTF to upper layer, which will trigger the + // recovery. + nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf); + memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf)); + (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, + nxpncihal_ctrl.p_rx_data); + } + } + } + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + return data_len; +} + +/****************************************************************************** + * Function phNxpNciHal_write_complete + * + * Description This function handles write callback. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_write_complete(void* pContext, + phTmlNfc_TransactInfo_t* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + + if (pInfo->wStatus == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus); + } else { + NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus); + } + + p_cb_data->status = pInfo->wStatus; + + SEM_POST(p_cb_data); + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_read_complete + * + * Description This function is called whenever there is an NCI packet + * received from NFCC. It could be RSP or NTF packet. This + * function provide the received NCI packet to libnfc-nci + * using data callback of libnfc-nci. + * There is a pending read called from each + * phNxpNciHal_read_complete so each a packet received from + * NFCC can be provide to libnfc-nci. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_read_complete(void* pContext, + phTmlNfc_TransactInfo_t* pInfo) { + NFCSTATUS status = NFCSTATUS_FAILED; + UNUSED(pContext); + if (nxpncihal_ctrl.read_retry_cnt == 1) { + nxpncihal_ctrl.read_retry_cnt = 0; + } + + if (pInfo->wStatus == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus); + + nxpncihal_ctrl.p_rx_data = pInfo->pBuff; + nxpncihal_ctrl.rx_data_len = pInfo->wLength; + + status = phNxpNciHal_process_ext_rsp(nxpncihal_ctrl.p_rx_data, + &nxpncihal_ctrl.rx_data_len); + + phNxpNciHal_print_res_status(nxpncihal_ctrl.p_rx_data, + &nxpncihal_ctrl.rx_data_len); + /* Check if response should go to hal module only */ + if (nxpncihal_ctrl.hal_ext_enabled == TRUE && + (nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP) { + if (status == NFCSTATUS_FAILED) { + NXPLOG_NCIHAL_D("enter into NFCC init recovery"); + nxpncihal_ctrl.ext_cb_data.status = status; + } + /* Unlock semaphore only for responses*/ + if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP || + ((icode_detected == true) && (icode_send_eof == 3))) { + /* Unlock semaphore */ + SEM_POST(&(nxpncihal_ctrl.ext_cb_data)); + } + } // Notification Checking + else if ((nxpncihal_ctrl.hal_ext_enabled == TRUE) && + ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) && + (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE)) { + /* Unlock semaphore waiting for only ntf*/ + SEM_POST(&(nxpncihal_ctrl.ext_cb_data)); + nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE; + } + /* Read successful send the event to higher layer */ + else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) && + (status == NFCSTATUS_SUCCESS)) { + (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, + nxpncihal_ctrl.p_rx_data); + } + } else { + NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus); + } + + if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE && + nxpncihal_ctrl.nci_info.wait_for_ntf == FALSE) { + NXPLOG_NCIHAL_E(" Ignoring read , HAL close triggered"); + return; + } + /* Read again because read must be pending always.*/ + status = phTmlNfc_Read( + Rx_data, NCI_MAX_DATA_LEN, + (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL); + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("read status error status = %x", status); + /* TODO: Not sure how to handle this ? */ + } + + return; +} + +void read_retry() { + /* Read again because read must be pending always.*/ + NFCSTATUS status = phTmlNfc_Read( + Rx_data, NCI_MAX_DATA_LEN, + (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL); + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("read status error status = %x", status); + /* TODO: Not sure how to handle this ? */ + } +} +/****************************************************************************** + * Function phNxpNciHal_core_initialized + * + * Description This function is called by libnfc-nci after successful open + * of NFCC. All proprietary setting for PN54X are done here. + * After completion of proprietary settings notification is + * provided to libnfc-nci through callback function. + * + * Returns Always returns NFCSTATUS_SUCCESS (0). + * + ******************************************************************************/ +int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + static uint8_t p2p_listen_mode_routing_cmd[] = {0x21, 0x01, 0x07, 0x00, 0x01, + 0x01, 0x03, 0x00, 0x01, 0x05}; + + uint8_t swp_full_pwr_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01, + 0xA0, 0xF1, 0x01, 0x01}; + + static uint8_t android_l_aid_matching_mode_on_cmd[] = { + 0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01}; + static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0, + 0xF3, 0x02, 0x00, 0x00}; + config_success = true; + uint8_t* buffer = NULL; + long bufflen = 260; + long retlen = 0; + int isfound; + /* Temp fix to re-apply the proper clock setting */ + int temp_fix = 1; + unsigned long num = 0; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + // initialize dummy FW recovery variables + gRecFwRetryCount = 0; + gRecFWDwnld = 0; +#endif + // recovery --start + /*NCI_INIT_CMD*/ + static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00}; + /*NCI_RESET_CMD*/ + static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, + 0x00}; // keep configuration + static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00}; + /* reset config cache */ + static uint8_t retry_core_init_cnt; + if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) { + return NFCSTATUS_FAILED; + } + if ((*p_core_init_rsp_params > 0) && + (*p_core_init_rsp_params < 4)) // initializing for recovery. + { + retry_core_init: + config_access = false; + if (buffer != NULL) { + free(buffer); + buffer = NULL; + } + if (retry_core_init_cnt > 3) { + return NFCSTATUS_FAILED; + } + + status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n"); + } else { + NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); + } + + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + if ((status != NFCSTATUS_SUCCESS) && + (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) { + NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby"); + retry_core_init_cnt++; + goto retry_core_init; + } else if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + if (*p_core_init_rsp_params == 2) { + NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!"); + goto invoke_callback; + } + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = + phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0); + } else { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci); + } + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + if (*p_core_init_rsp_params == 3) { + NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!"); + goto invoke_callback; + } + } + // recovery --end + + buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t)); + if (NULL == buffer) { + return NFCSTATUS_FAILED; + } + config_access = true; + retlen = 0; + isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char*)buffer, bufflen, + &retlen); + if (retlen > 0) { + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + + // Check if firmware download success + status = phNxpNciHal_get_mw_eeprom(); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP GET MW EEPROM AREA Proprietary Ext failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + // + status = phNxpNciHal_check_clock_config(); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + +#ifdef PN547C2_CLOCK_SETTING + if (isNxpConfigModified() || (fw_download_success == 1) || + (phNxpNciClock.issetConfig) +#if (NFC_NXP_HFO_SETTINGS == TRUE) + || temp_fix == 1 +#endif + ) { + // phNxpNciHal_get_clk_freq(); + phNxpNciHal_set_clock(); + phNxpNciClock.issetConfig = false; +#if (NFC_NXP_HFO_SETTINGS == TRUE) + if (temp_fix == 1) { + NXPLOG_NCIHAL_D( + "Applying Default Clock setting and DPLL register at power on"); + /* + # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG + # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG + # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET + CLIF_DPLL_INIT_FREQ_REG + # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET + CLIF_DPLL_CONTROL_REG + */ + static uint8_t cmd_dpll_set_reg_nci[] = { + 0x20, 0x02, 0x25, 0x04, 0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55, + 0x2A, 0x04, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14, + 0x17, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00, + 0x80, 0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00}; + + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci), + cmd_dpll_set_reg_nci); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + /* reset the NFCC after applying the clock setting and DPLL setting */ + // phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice); + temp_fix = 0; + goto retry_core_init; + } +#endif + } +#endif + + phNxpNciHal_check_factory_reset(); + retlen = 0; + config_access = true; + isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + + if (isNxpConfigModified() || (fw_download_success == 1)) { + retlen = 0; + fw_download_success = 0; + +#if (NFC_NXP_CHIP_TYPE != PN547C2) + NXPLOG_NCIHAL_D("Performing TVDD Settings"); + isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num)); + if (isfound > 0) { + if (num == 1) { + isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + } else if (num == 2) { + isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + } else if (num == 3) { + isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + } else { + NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num); + } + } +#endif + retlen = 0; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + config_access = false; +#endif + NXPLOG_NCIHAL_D("Performing RF Settings BLK 1"); + isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (status == NFCSTATUS_SUCCESS) { + status = phNxpNciHal_CheckRFCmdRespStatus(); + /*STATUS INVALID PARAM 0x09*/ + if (status == 0x09) { + phNxpNciHalRFConfigCmdRecSequence(); + retry_core_init_cnt++; + goto retry_core_init; + } + } else +#endif + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("RF Settings BLK 1 failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + retlen = 0; + + NXPLOG_NCIHAL_D("Performing RF Settings BLK 2"); + isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (status == NFCSTATUS_SUCCESS) { + status = phNxpNciHal_CheckRFCmdRespStatus(); + /*STATUS INVALID PARAM 0x09*/ + if (status == 0x09) { + phNxpNciHalRFConfigCmdRecSequence(); + retry_core_init_cnt++; + goto retry_core_init; + } + } else +#endif + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("RF Settings BLK 2 failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + retlen = 0; + + NXPLOG_NCIHAL_D("Performing RF Settings BLK 3"); + isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (status == NFCSTATUS_SUCCESS) { + status = phNxpNciHal_CheckRFCmdRespStatus(); + /*STATUS INVALID PARAM 0x09*/ + if (status == 0x09) { + phNxpNciHalRFConfigCmdRecSequence(); + retry_core_init_cnt++; + goto retry_core_init; + } + } else +#endif + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("RF Settings BLK 3 failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + retlen = 0; + + NXPLOG_NCIHAL_D("Performing RF Settings BLK 4"); + isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (status == NFCSTATUS_SUCCESS) { + status = phNxpNciHal_CheckRFCmdRespStatus(); + /*STATUS INVALID PARAM 0x09*/ + if (status == 0x09) { + phNxpNciHalRFConfigCmdRecSequence(); + retry_core_init_cnt++; + goto retry_core_init; + } + } else +#endif + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("RF Settings BLK 4 failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + retlen = 0; + + NXPLOG_NCIHAL_D("Performing RF Settings BLK 5"); + isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (status == NFCSTATUS_SUCCESS) { + status = phNxpNciHal_CheckRFCmdRespStatus(); + /*STATUS INVALID PARAM 0x09*/ + if (status == 0x09) { + phNxpNciHalRFConfigCmdRecSequence(); + retry_core_init_cnt++; + goto retry_core_init; + } + } else +#endif + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("RF Settings BLK 5 failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + retlen = 0; + + NXPLOG_NCIHAL_D("Performing RF Settings BLK 6"); + isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (status == NFCSTATUS_SUCCESS) { + status = phNxpNciHal_CheckRFCmdRespStatus(); + /*STATUS INVALID PARAM 0x09*/ + if (status == 0x09) { + phNxpNciHalRFConfigCmdRecSequence(); + retry_core_init_cnt++; + goto retry_core_init; + } + } else +#endif + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("RF Settings BLK 6 failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + retlen = 0; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + config_access = true; +#endif + NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF_EXTN Settings"); + isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP Core configuration failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + + retlen = 0; + + isfound = GetNxpByteArrayValue(NAME_NXP_CORE_MFCKEY_SETTING, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Setting mifare keys failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + + retlen = 0; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + config_access = false; +#endif + isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD, (char*)buffer, + bufflen, &retlen); + if (retlen > 0) { + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if (NFC_NXP_CHIP_TYPE != PN547C2) + if (status == NFCSTATUS_SUCCESS) { + status = phNxpNciHal_CheckRFCmdRespStatus(); + /*STATUS INVALID PARAM 0x09*/ + if (status == 0x09) { + phNxpNciHalRFConfigCmdRecSequence(); + retry_core_init_cnt++; + goto retry_core_init; + } + } else +#endif + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } +#if (NFC_NXP_CHIP_TYPE != PN547C2) + config_access = true; +#endif + + retlen = 0; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + /* NXP SWP switch timeout Setting*/ + if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&retlen, + sizeof(retlen))) { + // Check the permissible range [0 - 60] + if (0 <= retlen && retlen <= 60) { + if (0 < retlen) { + unsigned int timeout = retlen * 1000; + unsigned int timeoutHx = 0x0000; + + char tmpbuffer[10] = {0}; + snprintf((char*)tmpbuffer, 10, "%04x", timeout); + sscanf((char*)tmpbuffer, "%x", &timeoutHx); + + swp_switch_timeout_cmd[7] = (timeoutHx & 0xFF); + swp_switch_timeout_cmd[8] = ((timeoutHx & 0xFF00) >> 8); + } + + status = phNxpNciHal_send_ext_cmd(sizeof(swp_switch_timeout_cmd), + swp_switch_timeout_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } else { + NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!"); + } + } + + status = phNxpNciHal_china_tianjin_rf_setting(); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed"); + return NFCSTATUS_FAILED; + } +#endif + // Update eeprom value + status = phNxpNciHal_set_mw_eeprom(); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP Update MW EEPROM Proprietary Ext failed"); + } + } + + retlen = 0; + + isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char*)buffer, bufflen, + &retlen); + if (retlen > 0) { + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Stand by mode enable failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + retlen = 0; + + isfound = + GetNxpByteArrayValue(NAME_NXP_CORE_CONF, (char*)buffer, bufflen, &retlen); + if (retlen > 0) { + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(retlen, buffer); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Core Set Config failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + + config_access = false; + // if recovery mode and length of last command is 0 then only reset the P2P + // listen mode routing. + if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4) && + p_core_init_rsp_params[35] == 0) { + /* P2P listen mode routing */ + status = phNxpNciHal_send_ext_cmd(sizeof(p2p_listen_mode_routing_cmd), + p2p_listen_mode_routing_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("P2P listen mode routing failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + + retlen = 0; + + /* SWP FULL PWR MODE SETTING ON */ + if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&retlen, + sizeof(retlen))) { + if (1 == retlen) { + status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd), + swp_full_pwr_mode_on_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED"); + retry_core_init_cnt++; + goto retry_core_init; + } + } else { + swp_full_pwr_mode_on_cmd[7] = 0x00; + status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd), + swp_full_pwr_mode_on_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + } + + /* Android L AID Matching Platform Setting*/ + if (GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void*)&retlen, + sizeof(retlen))) { + if (1 == retlen) { + status = + phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd), + android_l_aid_matching_mode_on_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } else if (2 == retlen) { + android_l_aid_matching_mode_on_cmd[7] = 0x00; + status = + phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd), + android_l_aid_matching_mode_on_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + } + + if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) { + static phLibNfc_Message_t msg; + uint16_t tmp_len = 0; + uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01}; + uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00}; // SCREEN ON + uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01, + 0x01, 0x02, 0x01, 0x01}; + uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01}; + + NXPLOG_NCIHAL_E( + "Sending DH and NFCC core connection command as raw packet!!"); + status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_core_conn_create), + nfcc_core_conn_create); + + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E( + "Sending DH and NFCC core connection command as raw packet!! Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!!"); + status = + phNxpNciHal_send_ext_cmd(sizeof(nfcc_mode_set_on), nfcc_mode_set_on); + + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!!"); + status = phNxpNciHal_send_ext_cmd(sizeof(uicc_set_mode), uicc_set_mode); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + if (*(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!! + { + NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!"); + status = + phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E( + "Sending Set Screen ON State Command as raw packet!! Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + NXPLOG_NCIHAL_E("Sending discovery as raw packet!!"); + status = phNxpNciHal_send_ext_cmd(p_core_init_rsp_params[2], + (uint8_t*)&p_core_init_rsp_params[3]); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + } else { + NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!"); + set_screen_state[3] = 0x01; // Screen OFF + status = + phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E( + "Sending Set Screen OFF State Command as raw packet!! Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + NXPLOG_NCIHAL_E("Sending last command for Recovery "); + + if (p_core_init_rsp_params[35] > 0) { // if length of last command is 0 + // then it doesn't need to send last + // command. + if (!(((p_core_init_rsp_params[36] == 0x21) && + (p_core_init_rsp_params[37] == 0x03)) && + (*(p_core_init_rsp_params + 1) == 1)) && + !((p_core_init_rsp_params[36] == 0x21) && + (p_core_init_rsp_params[37] == 0x06) && + (p_core_init_rsp_params[39] == 0x00) && + (*(p_core_init_rsp_params + 1) == 0x00))) + // if last command is discovery and RF status is also discovery state, + // then it doesn't need to execute or similarly + // if the last command is deactivate to idle and RF status is also idle , + // no need to execute the command . + { + tmp_len = p_core_init_rsp_params[35]; + + /* Check for NXP ext before sending write */ + status = phNxpNciHal_write_ext( + &tmp_len, (uint8_t*)&p_core_init_rsp_params[36], + &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data); + if (status != NFCSTATUS_SUCCESS) { + if (buffer) { + free(buffer); + buffer = NULL; + } + /* Do not send packet to PN54X, send response directly */ + msg.eMsgType = NCI_HAL_RX_MSG; + msg.pMsgData = NULL; + msg.Size = 0; + + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, + (phLibNfc_Message_t*)&msg); + return NFCSTATUS_SUCCESS; + } + + p_core_init_rsp_params[35] = (uint8_t)tmp_len; + + status = phNxpNciHal_send_ext_cmd( + p_core_init_rsp_params[35], (uint8_t*)&p_core_init_rsp_params[36]); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("Sending last command for Recovery Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + } + } + } + + retry_core_init_cnt = 0; + + if (buffer) { + free(buffer); + buffer = NULL; + } +#if (NFC_NXP_CHIP_TYPE != PN547C2) + // initialize dummy FW recovery variables + gRecFWDwnld = 0; + gRecFwRetryCount = 0; +#endif + if (!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))) + phNxpNciHal_core_initialized_complete(status); + else { + invoke_callback: + config_access = false; + if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) { + *p_core_init_rsp_params = 0; + NXPLOG_NCIHAL_E("Invoking data callback!!"); + (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, + nxpncihal_ctrl.p_rx_data); + } + } + + if (config_success == false) return NFCSTATUS_FAILED; +#ifdef PN547C2_CLOCK_SETTING + if (isNxpConfigModified()) { + updateNxpConfigTimestamp(); + } +#endif + return NFCSTATUS_SUCCESS; +} +#if (NFC_NXP_CHIP_TYPE != PN547C2) +/****************************************************************************** + * Function phNxpNciHal_CheckRFCmdRespStatus + * + * Description This function is called to check the resp status of + * RF update commands. + * + * Returns NFCSTATUS_SUCCESS if successful, + * NFCSTATUS_INVALID_PARAMETER if parameter is inavlid + * NFCSTATUS_FAILED if failed response + * + ******************************************************************************/ +NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() { + NFCSTATUS status = NFCSTATUS_SUCCESS; + static uint16_t INVALID_PARAM = 0x09; + if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) { + if (nxpncihal_ctrl.p_rx_data[3] == 0x09) { + status = INVALID_PARAM; + } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) { + status = NFCSTATUS_FAILED; + } + } + return status; +} +/****************************************************************************** + * Function phNxpNciHalRFConfigCmdRecSequence + * + * Description This function is called to handle dummy FW recovery sequence + * Whenever RF settings are failed to apply with invalid param + * response, recovery mechanism includes dummy firmware + *download + * followed by firmware download and then config settings. The + *dummy + * firmware changes the major number of the firmware inside + *NFCC. + * Then actual firmware dowenload will be successful. This can + *be + * retried maximum three times. + * + * Returns Always returns NFCSTATUS_SUCCESS + * + ******************************************************************************/ +NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() { + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint16_t recFWState = 1; + gRecFWDwnld = true; + gRecFwRetryCount++; + if (gRecFwRetryCount > 0x03) { + NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded "); + gRecFWDwnld = false; + return NFCSTATUS_FAILED; + } + do { + status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice); + phDnldNfc_InitImgInfo(); + if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) { + fw_download_success = 0; + status = phNxpNciHal_fw_download(); + if (status == NFCSTATUS_SUCCESS) { + fw_download_success = 1; + } + status = phTmlNfc_Read( + nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN, + (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL); + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("TML Read status error status = %x", status); + phOsalNfc_Timer_Cleanup(); + phTmlNfc_Shutdown(); + status = NFCSTATUS_FAILED; + } + break; + } + gRecFWDwnld = false; + } while (recFWState--); + gRecFWDwnld = false; + return status; +} +#endif +/****************************************************************************** + * Function phNxpNciHal_core_initialized_complete + * + * Description This function is called when phNxpNciHal_core_initialized + * complete all proprietary command exchanges. This function + * informs libnfc-nci about completion of core initialize + * and result of that through callback. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_core_initialized_complete(NFCSTATUS status) { + static phLibNfc_Message_t msg; + + if (status == NFCSTATUS_SUCCESS) { + msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG; + } else { + msg.eMsgType = NCI_HAL_ERROR_MSG; + } + msg.pMsgData = NULL; + msg.Size = 0; + + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, + (phLibNfc_Message_t*)&msg); + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_pre_discover + * + * Description This function is called by libnfc-nci to perform any + * proprietary exchange before RF discovery. When proprietary + * exchange is over completion is informed to libnfc-nci + * through phNxpNciHal_pre_discover_complete function. + * + * Returns It always returns NFCSTATUS_SUCCESS (0). + * + ******************************************************************************/ +int phNxpNciHal_pre_discover(void) { + /* Nothing to do here for initial version */ + return NFCSTATUS_SUCCESS; +} + +/****************************************************************************** + * Function phNxpNciHal_pre_discover_complete + * + * Description This function informs libnfc-nci about completion and + * status of phNxpNciHal_pre_discover through callback. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_pre_discover_complete(NFCSTATUS status) { + static phLibNfc_Message_t msg; + + if (status == NFCSTATUS_SUCCESS) { + msg.eMsgType = NCI_HAL_PRE_DISCOVER_CPLT_MSG; + } else { + msg.eMsgType = NCI_HAL_ERROR_MSG; + } + msg.pMsgData = NULL; + msg.Size = 0; + + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg); + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_close + * + * Description This function close the NFCC interface and free all + * resources.This is called by libnfc-nci on NFC service stop. + * + * Returns Always return NFCSTATUS_SUCCESS (0). + * + ******************************************************************************/ +int phNxpNciHal_close(void) { + NFCSTATUS status; + /*NCI_RESET_CMD*/ + static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00}; + + static uint8_t cmd_ce_disc_nci[] = {0x21, 0x03, 0x07, 0x03, 0x80, + 0x01, 0x81, 0x01, 0x82, 0x01}; + + if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) { + NXPLOG_NCIHAL_E("phNxpNciHal_close is already closed, ignoring close"); + return NFCSTATUS_FAILED; + } + CONCURRENCY_LOCK(); + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci), cmd_ce_disc_nci); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed"); + } + + nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE; + + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed"); + } + + if (NULL != gpphTmlNfc_Context->pDevHandle) { + phNxpNciHal_close_complete(NFCSTATUS_SUCCESS); + /* Abort any pending read and write */ + status = phTmlNfc_ReadAbort(); + status = phTmlNfc_WriteAbort(); + + phOsalNfc_Timer_Cleanup(); + + status = phTmlNfc_Shutdown(); + + phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId); + + memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl)); + + NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed"); + } + + CONCURRENCY_UNLOCK(); + + phNxpNciHal_cleanup_monitor(); + + /* Return success always */ + return NFCSTATUS_SUCCESS; +} + +/****************************************************************************** + * Function phNxpNciHal_close_complete + * + * Description This function inform libnfc-nci about result of + * phNxpNciHal_close. + * + * Returns void. + * + ******************************************************************************/ +void phNxpNciHal_close_complete(NFCSTATUS status) { + static phLibNfc_Message_t msg; + + if (status == NFCSTATUS_SUCCESS) { + msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG; + } else { + msg.eMsgType = NCI_HAL_ERROR_MSG; + } + msg.pMsgData = NULL; + msg.Size = 0; + + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg); + + return; +} +/****************************************************************************** + * Function phNxpNciHal_notify_i2c_fragmentation + * + * Description This function can be used by HAL to inform + * libnfc-nci that i2c fragmentation is enabled/disabled + * + * Returns void. + * + ******************************************************************************/ +void phNxpNciHal_notify_i2c_fragmentation(void) { + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /*inform libnfc-nci that i2c fragmentation is enabled/disabled */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT, + HAL_NFC_STATUS_OK); + } +} +/****************************************************************************** + * Function phNxpNciHal_control_granted + * + * Description Called by libnfc-nci when NFCC control is granted to HAL. + * + * Returns Always returns NFCSTATUS_SUCCESS (0). + * + ******************************************************************************/ +int phNxpNciHal_control_granted(void) { + /* Take the concurrency lock so no other calls from upper layer + * will be allowed + */ + CONCURRENCY_LOCK(); + + if (NULL != nxpncihal_ctrl.p_control_granted_cback) { + (*nxpncihal_ctrl.p_control_granted_cback)(); + } + /* At the end concurrency unlock so calls from upper layer will + * be allowed + */ + CONCURRENCY_UNLOCK(); + return NFCSTATUS_SUCCESS; +} + +/****************************************************************************** + * Function phNxpNciHal_request_control + * + * Description This function can be used by HAL to request control of + * NFCC to libnfc-nci. When control is provided to HAL it is + * notified through phNxpNciHal_control_granted. + * + * Returns void. + * + ******************************************************************************/ +void phNxpNciHal_request_control(void) { + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /* Request Control of NCI Controller from NCI NFC Stack */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT, + HAL_NFC_STATUS_OK); + } + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_release_control + * + * Description This function can be used by HAL to release the control of + * NFCC back to libnfc-nci. + * + * Returns void. + * + ******************************************************************************/ +void phNxpNciHal_release_control(void) { + if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) { + /* Release Control of NCI Controller to NCI NFC Stack */ + (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT, + HAL_NFC_STATUS_OK); + } + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_power_cycle + * + * Description This function is called by libnfc-nci when power cycling is + * performed. When processing is complete it is notified to + * libnfc-nci through phNxpNciHal_power_cycle_complete. + * + * Returns Always return NFCSTATUS_SUCCESS (0). + * + ******************************************************************************/ +int phNxpNciHal_power_cycle(void) { + NXPLOG_NCIHAL_D("Power Cycle"); + NFCSTATUS status = NFCSTATUS_FAILED; + if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) { + NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open"); + return NFCSTATUS_FAILED; + } + status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice); + + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n"); + } else { + NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); + } + + phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS); + return NFCSTATUS_SUCCESS; +} + +/****************************************************************************** + * Function phNxpNciHal_power_cycle_complete + * + * Description This function is called to provide the status of + * phNxpNciHal_power_cycle to libnfc-nci through callback. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_power_cycle_complete(NFCSTATUS status) { + static phLibNfc_Message_t msg; + + if (status == NFCSTATUS_SUCCESS) { + msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG; + } else { + msg.eMsgType = NCI_HAL_ERROR_MSG; + } + msg.pMsgData = NULL; + msg.Size = 0; + + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg); + + return; +} + +/****************************************************************************** + * Function phNxpNciHal_get_mw_eeprom + * + * Description This function is called to retreive data in mw eeprom area + * + * Returns NFCSTATUS. + * + ******************************************************************************/ +static NFCSTATUS phNxpNciHal_get_mw_eeprom(void) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint8_t retry_cnt = 0; + static uint8_t get_mw_eeprom_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x0F}; + uint8_t bConfig; + +retry_send_ext: + if (retry_cnt > 3) { + return NFCSTATUS_FAILED; + } + + phNxpNciMwEepromArea.isGetEepromArea = true; + status = + phNxpNciHal_send_ext_cmd(sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("unable to get the mw eeprom data"); + phNxpNciMwEepromArea.isGetEepromArea = false; + retry_cnt++; + goto retry_send_ext; + } + phNxpNciMwEepromArea.isGetEepromArea = false; + + if (phNxpNciMwEepromArea.p_rx_data[12]) { + fw_download_success = 1; + } + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_set_mw_eeprom + * + * Description This function is called to update data in mw eeprom area + * + * Returns void. + * + ******************************************************************************/ +static NFCSTATUS phNxpNciHal_set_mw_eeprom(void) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint8_t retry_cnt = 0; + uint8_t set_mw_eeprom_cmd[39] = {0}; + uint8_t cmd_header[] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x0F, 0x20}; + + memcpy(set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header)); + phNxpNciMwEepromArea.p_rx_data[12] = 0; + memcpy(set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data, + sizeof(phNxpNciMwEepromArea.p_rx_data)); + +retry_send_ext: + if (retry_cnt > 3) { + return NFCSTATUS_FAILED; + } + + status = + phNxpNciHal_send_ext_cmd(sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("unable to update the mw eeprom data"); + retry_cnt++; + goto retry_send_ext; + } + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_set_clock + * + * Description This function is called after successfull download + * to apply the clock setting provided in config file + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_set_clock(void) { + NFCSTATUS status = NFCSTATUS_FAILED; + int retryCount = 0; + +retrySetclock: + phNxpNciClock.isClockSet = true; + if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) { + static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x09, 0x02, 0xA0, 0x03, + 0x01, 0x11, 0xA0, 0x04, 0x01, 0x01}; +#if (NFC_NXP_CHIP_TYPE == PN553) + uint8_t param_clock_src = 0x00; +#else + uint8_t param_clock_src = CLK_SRC_PLL; + param_clock_src = param_clock_src << 3; +#endif + + if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) { + param_clock_src |= 0x00; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) { + param_clock_src |= 0x01; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) { + param_clock_src |= 0x02; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) { + param_clock_src |= 0x03; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) { + param_clock_src |= 0x04; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) { + param_clock_src |= 0x05; + } else { + NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz"); +#if (NFC_NXP_CHIP_TYPE == PN553) + param_clock_src = 0x01; +#else + param_clock_src = 0x11; +#endif + } + + set_clock_cmd[7] = param_clock_src; + set_clock_cmd[11] = nxpprofile_ctrl.bTimeout; + status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("PLL colck setting failed !!"); + } + } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) { + static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, + 0xA0, 0x03, 0x01, 0x08}; + status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("XTAL colck setting failed !!"); + } + } else { + NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification") + } + + // Checking for SET CONFG SUCCESS, re-send the command if not. + phNxpNciClock.isClockSet = false; + if (phNxpNciClock.p_rx_data[3] != NFCSTATUS_SUCCESS) { + if (retryCount++ < 3) { + NXPLOG_NCIHAL_E("Set-clk failed retry again "); + goto retrySetclock; + } else { + NXPLOG_NCIHAL_D("Set clk failed - max count = 0x%x exceeded ", + retryCount); + // NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to + // elctrical disturbances, aborting the NFC process"); + // abort (); + } + } +} + +/****************************************************************************** + * Function phNxpNciHal_check_clock_config + * + * Description This function is called after successfull download + * to check if clock settings in config file and chip + * is same + * + * Returns void. + * + ******************************************************************************/ +NFCSTATUS phNxpNciHal_check_clock_config(void) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint8_t param_clock_src; + static uint8_t get_clock_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0, + 0x02, 0xA0, 0x03, 0xA0, 0x04}; + phNxpNciClock.isClockSet = true; + phNxpNciHal_get_clk_freq(); + status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd), get_clock_cmd); + + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel"); + return status; + } + param_clock_src = check_config_parameter(); + if (phNxpNciClock.p_rx_data[12] == param_clock_src && + phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout) { + phNxpNciClock.issetConfig = false; + } else { + phNxpNciClock.issetConfig = true; + } + phNxpNciClock.isClockSet = false; + + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_china_tianjin_rf_setting + * + * Description This function is called to check RF Setting + * + * Returns Status. + * + ******************************************************************************/ +NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + int isfound = 0; + int rf_enable = false; + int rf_val = 0; + int send_flag; + uint8_t retry_cnt = 0; + int enable_bit = 0; + static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85}; + +retry_send_ext: + if (retry_cnt > 3) { + return NFCSTATUS_FAILED; + } + send_flag = true; + phNxpNciRfSet.isGetRfSetting = true; + status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd), get_rf_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("unable to get the RF setting"); + phNxpNciRfSet.isGetRfSetting = false; + retry_cnt++; + goto retry_send_ext; + } + phNxpNciRfSet.isGetRfSetting = false; + if (phNxpNciRfSet.p_rx_data[3] != 0x00) { + NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN"); + return status; + } + rf_val = phNxpNciRfSet.p_rx_data[10]; + isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED, + (void*)&rf_enable, sizeof(rf_enable))); + if (isfound > 0) { + enable_bit = rf_val & 0x40; + if ((enable_bit != 0x40) && (rf_enable == 1)) { + phNxpNciRfSet.p_rx_data[10] |= 0x40; // Enable if it is disabled + } else if ((enable_bit == 0x40) && (rf_enable == 0)) { + phNxpNciRfSet.p_rx_data[10] &= 0xBF; // Disable if it is Enabled + } else { + send_flag = false; // No need to change in RF setting + } + + if (send_flag == true) { + static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85, + 0x04, 0x50, 0x08, 0x68, 0x00}; + memcpy(&set_rf_cmd[4], &phNxpNciRfSet.p_rx_data[5], 7); + status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd), set_rf_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("unable to set the RF setting"); + retry_cnt++; + goto retry_send_ext; + } + } + } + + return status; +} + +int check_config_parameter() { + NFCSTATUS status = NFCSTATUS_FAILED; + uint8_t param_clock_src = CLK_SRC_PLL; + if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) { +#if (NFC_NXP_CHIP_TYPE != PN553) + param_clock_src = param_clock_src << 3; +#endif + if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) { + param_clock_src |= 0x00; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) { + param_clock_src |= 0x01; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) { + param_clock_src |= 0x02; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) { + param_clock_src |= 0x03; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) { + param_clock_src |= 0x04; + } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) { + param_clock_src |= 0x05; + } else { + NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz"); + param_clock_src = 0x11; + } + } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) { + param_clock_src = 0x08; + + } else { + NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification") + } + return param_clock_src; +} +/****************************************************************************** + * Function phNxpNciHal_enable_i2c_fragmentation + * + * Description This function is called to process the response status + * and print the status byte. + * + * Returns void. + * + ******************************************************************************/ +void phNxpNciHal_enable_i2c_fragmentation() { + NFCSTATUS status = NFCSTATUS_FAILED; + static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01, + 0xA0, 0x05, 0x01, 0x10}; + int isfound = 0; + long i2c_status = 0x00; + long config_i2c_vlaue = 0xff; + /*NCI_RESET_CMD*/ + static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00}; + /*NCI_INIT_CMD*/ + static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00}; + static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00}; + static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03, + 0x01, 0xA0, 0x05}; + isfound = (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, + (void*)&i2c_status, sizeof(i2c_status))); + status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd), + get_i2c_fragmentation_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("unable to retrieve get_i2c_fragmentation_cmd"); + } else { + if (nxpncihal_ctrl.p_rx_data[8] == 0x10) { + config_i2c_vlaue = 0x01; + phNxpNciHal_notify_i2c_fragmentation(); + phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED); + } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) { + config_i2c_vlaue = 0x00; + } + if (config_i2c_vlaue == i2c_status) { + NXPLOG_NCIHAL_E("i2c_fragmentation_status existing"); + } else { + if (i2c_status == 0x01) { + /* NXP I2C fragmenation enabled*/ + status = + phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), + fragmentation_enable_config_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP fragmentation enable failed"); + } + } else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff) { + fragmentation_enable_config_cmd[7] = 0x00; + /* NXP I2C fragmentation disabled*/ + status = + phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), + fragmentation_enable_config_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP fragmentation disable failed"); + } + } + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed"); + } + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = + phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0); + } else { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci); + } + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed"); + } else if (i2c_status == 0x01) { + phNxpNciHal_notify_i2c_fragmentation(); + phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED); + } + } + } +} +/****************************************************************************** + * Function phNxpNciHal_check_factory_reset + * + * Description This function is called at init time to check + * the presence of ese related info. If file are not + * present set the SWP_INT_SESSION_ID_CFG to FF to + * force the NFCEE to re-run its initialization sequence. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_check_factory_reset(void) { + struct stat st; + int ret = 0; + NFCSTATUS status = NFCSTATUS_FAILED; + const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1"; + static uint8_t reset_ese_session_identity_set[] = { + 0x20, 0x02, 0x17, 0x02, 0xA0, 0xEA, 0x08, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xEB, 0x08, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +#ifdef PN547C2_FACTORY_RESET_DEBUG + static uint8_t reset_ese_session_identity[] = {0x20, 0x03, 0x05, 0x02, + 0xA0, 0xEA, 0xA0, 0xEB}; +#endif + if (stat(config_eseinfo_path, &st) == -1) { + NXPLOG_NCIHAL_D("%s file not present = %s", __func__, config_eseinfo_path); + ret = -1; + } else { + ret = 0; + } + + if (ret == -1) { +#ifdef PN547C2_FACTORY_RESET_DEBUG + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity), + reset_ese_session_identity); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed"); + } +#endif + status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity_set), + reset_ese_session_identity_set); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed"); + } +#ifdef PN547C2_FACTORY_RESET_DEBUG + /* NXP ACT Proprietary Ext */ + status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity), + reset_ese_session_identity); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed"); + } +#endif + } +} + +/****************************************************************************** + * Function phNxpNciHal_print_res_status + * + * Description This function is called to process the response status + * and print the status byte. + * + * Returns void. + * + ******************************************************************************/ +static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len) { + static uint8_t response_buf[][30] = {"STATUS_OK", + "STATUS_REJECTED", + "STATUS_RF_FRAME_CORRUPTED", + "STATUS_FAILED", + "STATUS_NOT_INITIALIZED", + "STATUS_SYNTAX_ERROR", + "STATUS_SEMANTIC_ERROR", + "RFU", + "RFU", + "STATUS_INVALID_PARAM", + "STATUS_MESSAGE_SIZE_EXCEEDED", + "STATUS_UNDEFINED"}; + int status_byte; + if (p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03)) { + if (p_rx_data[2] && p_rx_data[3] <= 10) { + status_byte = p_rx_data[CORE_RES_STATUS_BYTE]; + NXPLOG_NCIHAL_D("%s: response status =%s", __func__, + response_buf[status_byte]); + } else { + NXPLOG_NCIHAL_D("%s: response status =%s", __func__, response_buf[11]); + } + if (phNxpNciClock.isClockSet) { + int i; + for (i = 0; i < *p_len; i++) { + phNxpNciClock.p_rx_data[i] = p_rx_data[i]; + } + } + + else if (phNxpNciRfSet.isGetRfSetting) { + int i; + for (i = 0; i < *p_len; i++) { + phNxpNciRfSet.p_rx_data[i] = p_rx_data[i]; + // NXPLOG_NCIHAL_D("%s: response status =0x%x",__func__,p_rx_data[i]); + } + } else if (phNxpNciMwEepromArea.isGetEepromArea) { + int i; + for (i = 8; i < *p_len; i++) { + phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i]; + } + } + } + + if (p_rx_data[2] && (config_access == true)) { + if (p_rx_data[3] != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_W("Invalid Data from config file."); + config_success = false; + } + } +} + +#if (NFC_NXP_CHIP_TYPE == PN548C2) +NFCSTATUS phNxpNciHal_core_reset_recovery() { + NFCSTATUS status = NFCSTATUS_FAILED; + + uint8_t buffer[260]; + long bufflen = 260; + + /*NCI_INIT_CMD*/ + static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00}; + /*NCI_RESET_CMD*/ + static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, + 0x00}; // keep configuration + static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00}; + /* reset config cache */ + uint8_t retry_core_init_cnt = 0; + + if (discovery_cmd_len == 0) { + goto FAILURE; + } + NXPLOG_NCIHAL_D("%s: recovery", __func__); + +retry_core_init: + if (retry_core_init_cnt > 3) { + goto FAILURE; + } + + status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); + goto FAILURE; + } + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + if ((status != NFCSTATUS_SUCCESS) && + (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) { + retry_core_init_cnt++; + goto retry_core_init; + } else if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("NCI_CORE_RESET: Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0); + } else { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci); + } + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("NCI_CORE_INIT : Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + status = phNxpNciHal_send_ext_cmd(discovery_cmd_len, discovery_cmd); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("RF_DISCOVERY : Failed"); + retry_core_init_cnt++; + goto retry_core_init; + } + + return NFCSTATUS_SUCCESS; +FAILURE: + abort(); +} + +void phNxpNciHal_discovery_cmd_ext(uint8_t* p_cmd_data, uint16_t cmd_len) { + NXPLOG_NCIHAL_D("phNxpNciHal_discovery_cmd_ext"); + if (cmd_len > 0 && cmd_len <= sizeof(discovery_cmd)) { + memcpy(discovery_cmd, p_cmd_data, cmd_len); + discovery_cmd_len = cmd_len; + } +} +#endif diff --git a/pn54x/hal/phNxpNciHal.h b/pn54x/hal/phNxpNciHal.h new file mode 100644 index 0000000..00ec236 --- /dev/null +++ b/pn54x/hal/phNxpNciHal.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _PHNXPNCIHAL_H_ +#define _PHNXPNCIHAL_H_ + +#include <hardware/nfc.h> +#include <phNxpNciHal_utils.h> + +/********************* Definitions and structures *****************************/ +#define MAX_RETRY_COUNT 5 +#define NCI_MAX_DATA_LEN 300 +#define NCI_POLL_DURATION 500 +#define HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT 0x07 +#undef P2P_PRIO_LOGIC_HAL_IMP +#define NCI_VERSION_2_0 0x20 +#define NCI_VERSION_1_1 0x11 +#define NCI_VERSION_1_0 0x10 +#define NCI_VERSION_UNKNOWN 0x00 +typedef void(phNxpNciHal_control_granted_callback_t)(); + +/*ROM CODE VERSION FW*/ +#define FW_MOBILE_ROM_VERSION_PN551 0x10 +#define FW_MOBILE_ROM_VERSION_PN553 0x11 +#define FW_MOBILE_ROM_VERSION_PN548AD 0x10 +#define FW_MOBILE_ROM_VERSION_PN547C2 0x08 +/* NCI Data */ + +#define NCI_MT_CMD 0x20 +#define NCI_MT_RSP 0x40 +#define NCI_MT_NTF 0x60 + +#define CORE_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED 0x02 +#define CORE_RESET_TRIGGER_TYPE_POWERED_ON 0x01 +#define NCI_MSG_CORE_RESET 0x00 +#define NCI_MSG_CORE_INIT 0x01 +#define NCI_MT_MASK 0xE0 +#define NCI_OID_MASK 0x3F +typedef struct nci_data { + uint16_t len; + uint8_t p_data[NCI_MAX_DATA_LEN]; +} nci_data_t; + +typedef enum { HAL_STATUS_CLOSE = 0, HAL_STATUS_OPEN } phNxpNci_HalStatus; + +/* Macros to enable and disable extensions */ +#define HAL_ENABLE_EXT() (nxpncihal_ctrl.hal_ext_enabled = 1) +#define HAL_DISABLE_EXT() (nxpncihal_ctrl.hal_ext_enabled = 0) +typedef struct phNxpNciInfo { + uint8_t nci_version; + bool_t wait_for_ntf; +} phNxpNciInfo_t; +/* NCI Control structure */ +typedef struct phNxpNciHal_Control { + phNxpNci_HalStatus halStatus; /* Indicate if hal is open or closed */ + pthread_t client_thread; /* Integration thread handle */ + uint8_t thread_running; /* Thread running if set to 1, else set to 0 */ + phLibNfc_sConfig_t gDrvCfg; /* Driver config data */ + + /* Rx data */ + uint8_t* p_rx_data; + uint16_t rx_data_len; + + /* libnfc-nci callbacks */ + nfc_stack_callback_t* p_nfc_stack_cback; + nfc_stack_data_callback_t* p_nfc_stack_data_cback; + + /* control granted callback */ + phNxpNciHal_control_granted_callback_t* p_control_granted_cback; + + /* HAL open status */ + bool_t hal_open_status; + + /* HAL extensions */ + uint8_t hal_ext_enabled; + + /* Waiting semaphore */ + phNxpNciHal_Sem_t ext_cb_data; + + uint16_t cmd_len; + uint8_t p_cmd_data[NCI_MAX_DATA_LEN]; + uint16_t rsp_len; + uint8_t p_rsp_data[NCI_MAX_DATA_LEN]; + + /* retry count used to force download */ + uint16_t retry_cnt; + uint8_t read_retry_cnt; + phNxpNciInfo_t nci_info; +} phNxpNciHal_Control_t; + +typedef struct phNxpNciClock { + bool_t isClockSet; + uint8_t p_rx_data[20]; + bool_t issetConfig; +} phNxpNciClock_t; + +typedef struct phNxpNciRfSetting { + bool_t isGetRfSetting; + uint8_t p_rx_data[20]; +} phNxpNciRfSetting_t; + +typedef struct phNxpNciMwEepromArea { + bool_t isGetEepromArea; + uint8_t p_rx_data[32]; +} phNxpNciMwEepromArea_t; + +typedef enum { + NFC_FORUM_PROFILE, + EMV_CO_PROFILE, + INVALID_PROFILe +} phNxpNciProfile_t; +/* NXP Poll Profile control structure */ +typedef struct phNxpNciProfile_Control { + phNxpNciProfile_t profile_type; + uint8_t bClkSrcVal; /* Holds the System clock source read from config file */ + uint8_t + bClkFreqVal; /* Holds the System clock frequency read from config file */ + uint8_t bTimeout; /* Holds the Timeout Value */ +} phNxpNciProfile_Control_t; + +/* Internal messages to handle callbacks */ +#define NCI_HAL_OPEN_CPLT_MSG 0x411 +#define NCI_HAL_CLOSE_CPLT_MSG 0x412 +#define NCI_HAL_POST_INIT_CPLT_MSG 0x413 +#define NCI_HAL_PRE_DISCOVER_CPLT_MSG 0x414 +#define NCI_HAL_ERROR_MSG 0x415 +#define NCI_HAL_RX_MSG 0xF01 + +#define NCIHAL_CMD_CODE_LEN_BYTE_OFFSET (2U) +#define NCIHAL_CMD_CODE_BYTE_LEN (3U) + +/******************** NCI HAL exposed functions *******************************/ + +void phNxpNciHal_request_control(void); +void phNxpNciHal_release_control(void); +int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data); +#if (NFC_NXP_CHIP_TYPE == PN548C2) +NFCSTATUS phNxpNciHal_core_reset_recovery(); +void phNxpNciHal_discovery_cmd_ext(uint8_t* p_cmd_data, uint16_t cmd_len); +#endif +#endif /* _PHNXPNCIHAL_H_ */ diff --git a/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c b/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c new file mode 100644 index 0000000..4243904 --- /dev/null +++ b/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <phNxpLog.h> +#include <phNxpNciHal.h> +#include <phNxpNciHal_NfcDepSWPrio.h> + +/* Timeout value to wait for NFC-DEP detection.*/ +#define CUSTOM_POLL_TIMEOUT 160 +#define CLEAN_UP_TIMEOUT 250 +#define MAX_WRITE_RETRY 5 + +/******************* Global variables *****************************************/ +extern phNxpNciHal_Control_t nxpncihal_ctrl; +extern NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t* p_cmd); +static uint8_t cmd_stop_rf_discovery[] = {0x21, 0x06, 0x01, 0x00}; /* IDLE */ +static uint8_t cmd_resume_rf_discovery[] = {0x21, 0x06, 0x01, + 0x03}; /* RF_DISCOVER */ + +/*RF_DISCOVER_SELECT_CMD*/ +static uint8_t cmd_select_rf_discovery[] = {0x21, 0x04, 0x03, 0x01, 0x04, 0x02}; + +static uint8_t cmd_poll[64]; +static uint8_t cmd_poll_len = 0; +int discover_type = 0xFF; +uint32_t cleanup_timer; + +/*PRIO LOGIC related dead functions undefined*/ +#ifdef P2P_PRIO_LOGIC_HAL_IMP + +static int iso_dep_detected = 0x00; +static int poll_timer_fired = 0x00; +static uint8_t bIgnorep2plogic = 0; +static uint8_t* p_iso_ntf_buff = NULL; /* buffer to store second notification */ +static uint8_t bIgnoreIsoDep = 0; +static uint32_t custom_poll_timer; + +/************** NFC-DEP SW PRIO functions *************************************/ + +static NFCSTATUS phNxpNciHal_start_polling_loop(void); +static NFCSTATUS phNxpNciHal_stop_polling_loop(void); +static NFCSTATUS phNxpNciHal_resume_polling_loop(void); +static void phNxpNciHal_NfcDep_store_ntf(uint8_t* p_cmd_data, uint16_t cmd_len); + +/******************************************************************************* +** +** Function cleanup_timer_handler +** +** Description Callback function for cleanup timer. +** +** Returns None +** +*******************************************************************************/ +static void cleanup_timer_handler(uint32_t timerId, void* pContext) { + NXPLOG_NCIHAL_D(">> cleanup_timer_handler."); + + NXPLOG_NCIHAL_D( + ">> cleanup_timer_handler. ISO_DEP not detected second time."); + + phOsalNfc_Timer_Delete(cleanup_timer); + cleanup_timer = 0; + iso_dep_detected = 0x00; + EnableP2P_PrioLogic = false; + return; +} + +/******************************************************************************* +** +** Function custom_poll_timer_handler +** +** Description Callback function for custom poll timer. +** +** Returns None +** +*******************************************************************************/ +static void custom_poll_timer_handler(uint32_t timerId, void* pContext) { + NXPLOG_NCIHAL_D(">> custom_poll_timer_handler."); + + NXPLOG_NCIHAL_D( + ">> custom_poll_timer_handler. NFC_DEP not detected. so giving early " + "chance to ISO_DEP."); + + phOsalNfc_Timer_Delete(custom_poll_timer); + + if (iso_dep_detected == 0x01) { + poll_timer_fired = 0x01; + + /* + * Restart polling loop. + * When the polling loop is stopped, polling will be restarted. + */ + NXPLOG_NCIHAL_D(">> custom_poll_timer_handler - restart polling loop."); + + phNxpNciHal_stop_polling_loop(); + } else { + NXPLOG_NCIHAL_E( + ">> custom_poll_timer_handler - invalid flag state (iso_dep_detected)"); + } + + return; +} +/******************************************************************************* +** +** Function phNxpNciHal_stop_polling_loop +** +** Description Sends stop polling cmd to NFCC +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_stop_polling_loop() { + NFCSTATUS status = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + pthread_t pthread; + discover_type = STOP_POLLING; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&pthread, &attr, tmp_thread, (void*)&discover_type) != 0) { + NXPLOG_NCIHAL_E("fail to create pthread"); + } + pthread_attr_destroy(&attr); + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_resume_polling_loop +** +** Description Sends resume polling cmd to NFCC +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_resume_polling_loop() { + NFCSTATUS status = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + pthread_t pthread; + discover_type = RESUME_POLLING; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&pthread, &attr, tmp_thread, (void*)&discover_type) != 0) { + NXPLOG_NCIHAL_E("fail to create pthread"); + } + pthread_attr_destroy(&attr); + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_start_polling_loop +** +** Description Sends start polling cmd to NFCC +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_start_polling_loop() { + NFCSTATUS status = NFCSTATUS_FAILED; + phNxpNciHal_Sem_t cb_data; + pthread_t pthread; + discover_type = START_POLLING; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&pthread, &attr, tmp_thread, (void*)&discover_type) != 0) { + NXPLOG_NCIHAL_E("fail to create pthread"); + } + pthread_attr_destroy(&attr); + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_NfcDep_rsp_ext +** +** Description Implements algorithm for NFC-DEP protocol priority over +** ISO-DEP protocol. +** Following the algorithm: +** IF ISO-DEP detected first time,set the ISO-DEP detected flag +** and resume polling loop with 60ms timeout value. +** a) if than NFC-DEP detected than send the response to +** libnfc-nci stack and stop the timer. +** b) if NFC-DEP not detected with in 60ms, than restart +** the polling loop to give early chance to ISO-DEP with +** a cleanup timer. +** c) if ISO-DEP detected second time send the response to +** libnfc-nci stack and stop the cleanup timer. +** d) if ISO-DEP not detected with in cleanup timeout, than +** clear the ISO-DEP detection flag. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_NfcDep_rsp_ext(uint8_t* p_ntf, uint16_t* p_len) { + NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER; + + NXPLOG_NCIHAL_D(">> p_ntf[0]=%02x , p_ntf[1]=%02x", p_ntf[0], p_ntf[1]); + + if (p_ntf[0] == 0x41 && p_ntf[1] == 0x04) { + // Tag selected, Disable P2P Prio logic. + bIgnoreIsoDep = 1; + NXPLOG_NCIHAL_D(">> Tag selected, Disable P2P Prio logic."); + + } else if (((p_ntf[0] == 0x61 && p_ntf[1] == 0x06) || + (p_ntf[0] == 0x41 && p_ntf[1] == 0x06)) && + bIgnoreIsoDep == 1) { + // Tag deselected, enable P2P Prio logic. + bIgnoreIsoDep = 0x00; + NXPLOG_NCIHAL_D(">> Tag deselected, enable P2P Prio logic."); + } + if (bIgnoreIsoDep == 0x00 && p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && + *p_len > 5) { + if (p_ntf[5] == 0x04 && p_ntf[6] < 0x80) { + NXPLOG_NCIHAL_D(">> ISO DEP detected."); + + if (iso_dep_detected == 0x00) { + NXPLOG_NCIHAL_D(">> ISO DEP detected first time. Resume polling loop"); + + iso_dep_detected = 0x01; + status = phNxpNciHal_resume_polling_loop(); + + custom_poll_timer = phOsalNfc_Timer_Create(); + NXPLOG_NCIHAL_D("custom poll timer started - %d", custom_poll_timer); + + status = phOsalNfc_Timer_Start(custom_poll_timer, CUSTOM_POLL_TIMEOUT, + &custom_poll_timer_handler, NULL); + + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("custom poll timer started"); + } else { + NXPLOG_NCIHAL_E("custom poll timer not started!!!"); + status = NFCSTATUS_FAILED; + } + + status = NFCSTATUS_FAILED; + } else { + NXPLOG_NCIHAL_D(">> ISO DEP detected second time."); + /* Store notification */ + phNxpNciHal_NfcDep_store_ntf(p_ntf, *p_len); + + /* Stop Cleanup_timer */ + phOsalNfc_Timer_Stop(cleanup_timer); + phOsalNfc_Timer_Delete(cleanup_timer); + cleanup_timer = 0; + EnableP2P_PrioLogic = false; + iso_dep_detected = 0; + status = NFCSTATUS_SUCCESS; + } + } else if (p_ntf[5] == 0x05) { + NXPLOG_NCIHAL_D(">> NFC-DEP Detected - stopping the custom poll timer"); + + phOsalNfc_Timer_Stop(custom_poll_timer); + phOsalNfc_Timer_Delete(custom_poll_timer); + EnableP2P_PrioLogic = false; + iso_dep_detected = 0; + status = NFCSTATUS_SUCCESS; + } else { + NXPLOG_NCIHAL_D( + ">> detected other technology- stopping the custom poll timer"); + phOsalNfc_Timer_Stop(custom_poll_timer); + phOsalNfc_Timer_Delete(custom_poll_timer); + EnableP2P_PrioLogic = false; + iso_dep_detected = 0; + status = NFCSTATUS_INVALID_PARAMETER; + } + } else if (bIgnoreIsoDep == 0x00 && + ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || + (p_ntf[0] == 0x61 && p_ntf[1] == 0x06))) { + NXPLOG_NCIHAL_D(">> RF disabled"); + if (poll_timer_fired == 0x01) { + poll_timer_fired = 0x00; + + NXPLOG_NCIHAL_D(">>restarting polling loop."); + + /* start polling loop */ + phNxpNciHal_start_polling_loop(); + EnableP2P_PrioLogic = false; + NXPLOG_NCIHAL_D( + ">> NFC DEP NOT detected - custom poll timer expired - RF disabled"); + + cleanup_timer = phOsalNfc_Timer_Create(); + + /* Start cleanup_timer */ + NFCSTATUS status = phOsalNfc_Timer_Start(cleanup_timer, CLEAN_UP_TIMEOUT, + &cleanup_timer_handler, NULL); + + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("cleanup timer started"); + } else { + NXPLOG_NCIHAL_E("cleanup timer not started!!!"); + status = NFCSTATUS_FAILED; + } + + status = NFCSTATUS_FAILED; + } else { + status = NFCSTATUS_SUCCESS; + } + } + if (bIgnoreIsoDep == 0x00 && iso_dep_detected == 1) { + if ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || + (p_ntf[0] == 0x61 && p_ntf[1] == 0x06)) { + NXPLOG_NCIHAL_D(">>iso_dep_detected Disconnect related notification"); + status = NFCSTATUS_FAILED; + } else { + NXPLOG_NCIHAL_W("Never come here"); + } + } + + return status; +} +/******************************************************************************* +** +** Function phNxpNciHal_NfcDep_store_ntf +** +** Description Stores the iso dep notification locally. +** +** Returns None +** +*******************************************************************************/ +static void phNxpNciHal_NfcDep_store_ntf(uint8_t* p_cmd_data, + uint16_t cmd_len) { + p_iso_ntf_buff = NULL; + + p_iso_ntf_buff = malloc(sizeof(uint8_t) * cmd_len); + if (p_iso_ntf_buff == NULL) { + NXPLOG_NCIHAL_E("Error allocating memory (p_iso_ntf_buff)"); + return; + } + memcpy(p_iso_ntf_buff, p_cmd_data, cmd_len); + bIgnorep2plogic = 1; +} + +/******************************************************************************* +** +** Function phNxpNciHal_NfcDep_comapre_ntf +** +** Description Compare the notification with previous iso dep notification. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_NfcDep_comapre_ntf(uint8_t* p_cmd_data, + uint16_t cmd_len) { + NFCSTATUS status = NFCSTATUS_FAILED; + int32_t ret_val = -1; + + if (bIgnorep2plogic == 1) { + ret_val = memcmp(p_cmd_data, p_iso_ntf_buff, cmd_len); + if (ret_val != 0) { + NXPLOG_NCIHAL_E("Third notification is not equal to last"); + } else { + NXPLOG_NCIHAL_E( + "Third notification is equal to last (disable p2p logic)"); + status = NFCSTATUS_SUCCESS; + } + bIgnorep2plogic = 0; + } + if (p_iso_ntf_buff != NULL) { + free(p_iso_ntf_buff); + p_iso_ntf_buff = NULL; + } + + return status; +} + +extern NFCSTATUS phNxpNciHal_clean_P2P_Prio() { + NFCSTATUS status = NFCSTATUS_SUCCESS; + + iso_dep_detected = 0x00; + EnableP2P_PrioLogic = false; + poll_timer_fired = 0x00; + bIgnorep2plogic = 0x00; + bIgnoreIsoDep = 0x00; + + status = phOsalNfc_Timer_Stop(cleanup_timer); + status |= phOsalNfc_Timer_Delete(cleanup_timer); + + status |= phOsalNfc_Timer_Stop(custom_poll_timer); + status |= phOsalNfc_Timer_Delete(custom_poll_timer); + cleanup_timer = 0; + return status; +} + +#endif +/******************************************************************************* +** +** Function hal_write_cb +** +** Description Callback function for hal write. +** +** Returns None +** +*******************************************************************************/ +static void hal_write_cb(void* pContext, phTmlNfc_TransactInfo_t* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + + if (pInfo->wStatus == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("hal_write_cb: write successful status = 0x%x", + pInfo->wStatus); + } else { + NXPLOG_NCIHAL_E("hal_write_cb: write error status = 0x%x", pInfo->wStatus); + } + + p_cb_data->status = pInfo->wStatus; + + SEM_POST(p_cb_data); + return; +} + +/******************************************************************************* + ** + ** Function tmp_thread + ** + ** Description Thread to execute custom poll commands . + ** + ** Returns None + ** + *******************************************************************************/ +void* tmp_thread(void* tmp) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint16_t data_len; + NXPLOG_NCIHAL_E("tmp_thread: enter type=0x0%x", *((int*)tmp)); + usleep(10 * 1000); + + switch (*((int*)tmp)) { + case START_POLLING: { + CONCURRENCY_LOCK(); + data_len = phNxpNciHal_write_unlocked(cmd_poll_len, cmd_poll); + CONCURRENCY_UNLOCK(); + + if (data_len != cmd_poll_len) { + NXPLOG_NCIHAL_E("phNxpNciHal_start_polling_loop: data len mismatch"); + status = NFCSTATUS_FAILED; + } + } break; + + case RESUME_POLLING: { + CONCURRENCY_LOCK(); + data_len = phNxpNciHal_write_unlocked(sizeof(cmd_resume_rf_discovery), + cmd_resume_rf_discovery); + CONCURRENCY_UNLOCK(); + + if (data_len != sizeof(cmd_resume_rf_discovery)) { + NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch"); + status = NFCSTATUS_FAILED; + } + } break; + + case STOP_POLLING: { + CONCURRENCY_LOCK(); + data_len = phNxpNciHal_write_unlocked(sizeof(cmd_stop_rf_discovery), + cmd_stop_rf_discovery); + CONCURRENCY_UNLOCK(); + + if (data_len != sizeof(cmd_stop_rf_discovery)) { + NXPLOG_NCIHAL_E("phNxpNciHal_stop_polling_loop: data len mismatch"); + status = NFCSTATUS_FAILED; + } + } break; + + case DISCOVER_SELECT: { + CONCURRENCY_LOCK(); + data_len = phNxpNciHal_write_unlocked(sizeof(cmd_select_rf_discovery), + cmd_select_rf_discovery); + CONCURRENCY_UNLOCK(); + + if (data_len != sizeof(cmd_resume_rf_discovery)) { + NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch"); + status = NFCSTATUS_FAILED; + } + } break; + + default: + NXPLOG_NCIHAL_E("No Matching case"); + status = NFCSTATUS_FAILED; + break; + } + + NXPLOG_NCIHAL_E("tmp_thread: exit"); + return NULL; +} +/******************************************************************************* + ** + ** Function phNxpNciHal_select_RF_Discovery + ** + ** Description Sends RF_DISCOVER_SELECT_CMD + ** Parameters RfID , RfProtocolType + ** Returns NFCSTATUS_PENDING if success + ** + *******************************************************************************/ +NFCSTATUS phNxpNciHal_select_RF_Discovery(unsigned int RfID, + unsigned int RfProtocolType) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + pthread_t pthread; + discover_type = DISCOVER_SELECT; + cmd_select_rf_discovery[3] = RfID; + cmd_select_rf_discovery[4] = RfProtocolType; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&pthread, &attr, tmp_thread, (void*)&discover_type) != 0) { + NXPLOG_NCIHAL_E("fail to create pthread"); + } + pthread_attr_destroy(&attr); + return status; +} +/******************************************************************************* +** +** Function phNxpNciHal_NfcDep_cmd_ext +** +** Description Stores the polling loop configuration locally. +** +** Returns None +** +*******************************************************************************/ +void phNxpNciHal_NfcDep_cmd_ext(uint8_t* p_cmd_data, uint16_t* cmd_len) { + if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) { + if (*cmd_len == 6 && p_cmd_data[3] == 0x01 && p_cmd_data[4] == 0x02 && + p_cmd_data[5] == 0x01) { + /* DO NOTHING */ + } else { + /* Store the polling loop configuration */ + cmd_poll_len = *cmd_len; + memset(&cmd_poll, 0, cmd_poll_len); + memcpy(&cmd_poll, p_cmd_data, cmd_poll_len); + } + } + + return; +} diff --git a/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h b/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h new file mode 100644 index 0000000..12bf9d4 --- /dev/null +++ b/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _PHNXPNCIHAL_NFCDEPSWPRIO_H_ +#define _PHNXPNCIHAL_NFCDEPSWPRIO_H_ + +#include <phNxpNciHal.h> +#include <phTmlNfc.h> +#include <string.h> + +#define START_POLLING 0x00 +#define RESUME_POLLING 0x01 +#define STOP_POLLING 0x02 +#define DISCOVER_SELECT 0x03 +#define CLEAR_PIPE_RSP 0x04 + +extern uint8_t EnableP2P_PrioLogic; + +extern NFCSTATUS phNxpNciHal_NfcDep_rsp_ext(uint8_t* p_ntf, uint16_t* p_len); +extern void phNxpNciHal_NfcDep_cmd_ext(uint8_t* p_cmd_data, uint16_t* cmd_len); +extern NFCSTATUS phNxpNciHal_NfcDep_comapre_ntf(uint8_t* p_cmd_data, + uint16_t cmd_len); +extern NFCSTATUS phNxpNciHal_select_RF_Discovery(unsigned int RfID, + unsigned int RfProtocolType); +extern NFCSTATUS phNxpNciHal_clean_P2P_Prio(); +extern NFCSTATUS phNxpNciHal_send_clear_pipe_rsp(void); + +#endif /* _PHNXPNCIHAL_NFCDEPSWPRIO_H_ */ diff --git a/pn54x/hal/phNxpNciHal_dta.c b/pn54x/hal/phNxpNciHal_dta.c new file mode 100644 index 0000000..a6611ea --- /dev/null +++ b/pn54x/hal/phNxpNciHal_dta.c @@ -0,0 +1,232 @@ +/* +* Copyright (C) 2012-2014 NXP Semiconductors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include <phNxpNciHal_dta.h> + +/*********************** Global Variables *************************************/ +static phNxpDta_Control_t nxpdta_ctrl = {0, 0, 0}; + +/******************************************************************************* +** +** Function phNxpEnable_DtaMode +** +** Description This function configures +** HAL in DTA mode +** +*******************************************************************************/ +void phNxpEnable_DtaMode(uint16_t pattern_no) { + nxpdta_ctrl.dta_ctrl_flag = false; + nxpdta_ctrl.dta_t1t_flag = false; + nxpdta_ctrl.dta_pattern_no = pattern_no; + ALOGD(">>>>DTA - Mode is enabled"); + nxpdta_ctrl.dta_ctrl_flag = true; +} + +/******************************************************************************* +** +** Function phNxpDisable_DtaMode +** +** Description This function disable DTA mode +** +*******************************************************************************/ +void phNxpDisable_DtaMode(void) { + nxpdta_ctrl.dta_ctrl_flag = false; + nxpdta_ctrl.dta_t1t_flag = false; + NXPLOG_NCIHAL_D(">>>>DTA - Mode is Disabled"); +} + +/****************************************************************************** + * Function phNxpDta_IsEnable + * + * Description This function checks the DTA mode is enable or not. + * + * Returns It returns TRUE if DTA enabled otherwise FALSE + * + ******************************************************************************/ +NFCSTATUS phNxpDta_IsEnable(void) { return nxpdta_ctrl.dta_ctrl_flag; } + +/****************************************************************************** + * Function phNxpDta_T1TEnable + * + * Description This function enables DTA mode for T1T tag. + * + * + ******************************************************************************/ +void phNxpDta_T1TEnable(void) { nxpdta_ctrl.dta_t1t_flag = true; } +/****************************************************************************** + * Function phNxpNHal_DtaUpdate + * + * Description This function changes the command and responses specific + * to make DTA application success + * + * Returns It return NFCSTATUS_SUCCESS then continue with send else + * sends NFCSTATUS_FAILED direct response is prepared and + * do not send anything to NFCC. + * + ******************************************************************************/ + +NFCSTATUS phNxpNHal_DtaUpdate(uint16_t* cmd_len, uint8_t* p_cmd_data, + uint16_t* rsp_len, uint8_t* p_rsp_data) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + + if (nxpdta_ctrl.dta_ctrl_flag == true) { + // Workaround for DTA, block the set config command with general bytes */ + if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x17 && p_cmd_data[3] == 0x01 && + p_cmd_data[4] == 0x29 && p_cmd_data[5] == 0x14) { + *rsp_len = 5; + NXPLOG_NCIHAL_D(">>>>DTA - Block set config command"); + phNxpNciHal_print_packet("DTASEND", p_cmd_data, *cmd_len); + + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + + phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5); + + status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_D( + "Going through DTA workaround - Block set config command END"); + + } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x08 && + p_cmd_data[2] == 0x04 && p_cmd_data[3] == 0xFF && + p_cmd_data[4] == 0xFF) { + NXPLOG_NCIHAL_D(">>>>DTA Change Felica system code"); + *rsp_len = 4; + p_rsp_data[0] = 0x41; + p_rsp_data[1] = 0x08; + p_rsp_data[2] = 0x01; + p_rsp_data[3] = 0x00; + status = NFCSTATUS_FAILED; + + phNxpNciHal_print_packet("DTARECV", p_rsp_data, 4); + } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x10 && p_cmd_data[3] == 0x05 && + p_cmd_data[10] == 0x32 && p_cmd_data[12] == 0x00) { + NXPLOG_NCIHAL_D(">>>>DTA Update LA_SEL_INFO param"); + + p_cmd_data[12] = 0x40; + p_cmd_data[18] = 0x02; + status = NFCSTATUS_SUCCESS; + } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04 && + p_cmd_data[10] == 0x32 && p_cmd_data[12] == 0x00) { + NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config"); + *rsp_len = 5; + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + status = NFCSTATUS_FAILED; + phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5); + } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) { + NXPLOG_NCIHAL_D(">>>>DTA Add NFC-F listen tech params"); + p_cmd_data[2] += 6; + p_cmd_data[3] += 3; + p_cmd_data[*cmd_len] = 0x80; + p_cmd_data[*cmd_len + 1] = 0x01; + p_cmd_data[*cmd_len + 2] = 0x82; + p_cmd_data[*cmd_len + 3] = 0x01; + p_cmd_data[*cmd_len + 4] = 0x85; + p_cmd_data[*cmd_len + 5] = 0x01; + + *cmd_len += 6; + status = NFCSTATUS_SUCCESS; + } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04 && + p_cmd_data[10] == 0x32 && p_cmd_data[12] == 0x20 && + nxpdta_ctrl.dta_pattern_no == 0x1000) { + NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config for analog testing"); + *rsp_len = 5; + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + status = NFCSTATUS_FAILED; + phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5); + } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04 && + p_cmd_data[4] == 0x32 && p_cmd_data[5] == 0x01 && + p_cmd_data[6] == 0x00) { + NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config"); + *rsp_len = 5; + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + status = NFCSTATUS_FAILED; + phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5); + } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x04 && p_cmd_data[3] == 0x01 && + p_cmd_data[4] == 0x50 && p_cmd_data[5] == 0x01 && + p_cmd_data[6] == 0x00 && nxpdta_ctrl.dta_pattern_no == 0x1000) { + NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config for analog testing"); + *rsp_len = 5; + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + status = NFCSTATUS_FAILED; + phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5); + } else { + } + if (nxpdta_ctrl.dta_t1t_flag == true) { + if (p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x78 && + p_cmd_data[4] == 0x00 && p_cmd_data[5] == 0x00) { + /*if (nxpdta_ctrl.dta_pattern_no == 0) + { + NXPLOG_NCIHAL_D(">>>>DTA - T1T modification block RID command Custom + Response (pattern 0)"); + phNxpNciHal_print_packet("DTASEND", p_cmd_data, *cmd_len); + *rsp_len = 10; + p_rsp_data[0] = 0x00; + p_rsp_data[1] = 0x00; + p_rsp_data[2] = 0x07; + p_rsp_data[3] = 0x12; + p_rsp_data[4] = 0x49; + p_rsp_data[5] = 0x00; + p_rsp_data[6] = 0x00; + p_rsp_data[7] = 0x00; + p_rsp_data[8] = 0x00; + p_rsp_data[9] = 0x00; + + status = NFCSTATUS_FAILED; + + phNxpNciHal_print_packet("DTARECV", p_rsp_data, *rsp_len); + } + else + {*/ + NXPLOG_NCIHAL_D("Change RID command's UID echo bytes to 0"); + + nxpdta_ctrl.dta_t1t_flag = false; + p_cmd_data[6] = 0x00; + p_cmd_data[7] = 0x00; + p_cmd_data[8] = 0x00; + p_cmd_data[9] = 0x00; + status = NFCSTATUS_SUCCESS; + /*}*/ + } + } + } + return status; +} diff --git a/pn54x/hal/phNxpNciHal_dta.h b/pn54x/hal/phNxpNciHal_dta.h new file mode 100644 index 0000000..ebcae1a --- /dev/null +++ b/pn54x/hal/phNxpNciHal_dta.h @@ -0,0 +1,35 @@ +/* +* Copyright (C) 2012-2014 NXP Semiconductors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _PHNXPNCIHAL_DTA_H_ +#define _PHNXPNCIHAL_DTA_H_ + +#include <phNxpNciHal_utils.h> +/* DTA Control structure */ +typedef struct phNxpDta_Control { + uint8_t dta_ctrl_flag; + uint16_t dta_pattern_no; + uint8_t dta_t1t_flag; +} phNxpDta_Control_t; + +void phNxpEnable_DtaMode(uint16_t pattern_no); +void phNxpDisable_DtaMode(void); +NFCSTATUS phNxpDta_IsEnable(void); +void phNxpDta_T1TEnable(void); +NFCSTATUS phNxpNHal_DtaUpdate(uint16_t* cmd_len, uint8_t* p_cmd_data, + uint16_t* rsp_len, uint8_t* p_rsp_data); + +#endif /* _PHNXPNICHAL_DTA_H_ */ diff --git a/pn54x/hal/phNxpNciHal_ext.c b/pn54x/hal/phNxpNciHal_ext.c new file mode 100644 index 0000000..864f9ae --- /dev/null +++ b/pn54x/hal/phNxpNciHal_ext.c @@ -0,0 +1,945 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <log/log.h> +#include <phDal4Nfc_messageQueueLib.h> +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include <phNxpNciHal.h> +#include <phNxpNciHal_NfcDepSWPrio.h> +#include <phNxpNciHal_ext.h> +#include <phTmlNfc.h> + +/* Timeout value to wait for response from PN548AD */ +#define HAL_EXTNS_WRITE_RSP_TIMEOUT (1000) + +#undef P2P_PRIO_LOGIC_HAL_IMP + +/******************* Global variables *****************************************/ +extern phNxpNciHal_Control_t nxpncihal_ctrl; +extern phNxpNciProfile_Control_t nxpprofile_ctrl; + +extern uint32_t cleanup_timer; +uint8_t icode_detected = 0x00; +uint8_t icode_send_eof = 0x00; +#if (NFC_NXP_CHIP_TYPE == PN548C2) +uint8_t nfcdep_detected = 0x00; +#endif +static uint8_t ee_disc_done = 0x00; +uint8_t EnableP2P_PrioLogic = false; +static uint32_t RfDiscID = 1; +static uint32_t RfProtocolType = 4; +/* NFCEE Set mode */ +static uint8_t setEEModeDone = 0x00; +static uint8_t cmd_nfcee_setmode_enable[] = {0x22, 0x01, 0x02, 0x01, 0x01}; + +/* External global variable to get FW version from NCI response*/ +extern uint32_t wFwVerRsp; +/* External global variable to get FW version from FW file*/ +extern uint16_t wFwVer; + +uint16_t fw_maj_ver; +uint16_t rom_version; +/* local buffer to store CORE_INIT response */ +static uint32_t bCoreInitRsp[40]; +static uint32_t iCoreInitRspLen; + +extern uint32_t timeoutTimerId; + +extern NFCSTATUS read_retry(); + +/************** HAL extension functions ***************************************/ +static void hal_extns_write_rsp_timeout_cb(uint32_t TimerId, void* pContext); + +/*Proprietary cmd sent to HAL to send reader mode flag + * Last byte of 4 byte proprietary cmd data contains ReaderMode flag + * If this flag is enabled, NFC-DEP protocol is modified to T3T protocol + * if FrameRF interface is selected. This needs to be done as the FW + * always sends Ntf for FrameRF with NFC-DEP even though FrameRF with T3T is + * previously selected with DISCOVER_SELECT_CMD + */ +#define PROPRIETARY_CMD_FELICA_READER_MODE 0xFE +static uint8_t gFelicaReaderMode; + +static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf, + uint16_t* p_len); +/******************************************************************************* +** +** Function phNxpNciHal_ext_init +** +** Description initialize extension function +** +*******************************************************************************/ +void phNxpNciHal_ext_init(void) { + icode_detected = 0x00; + icode_send_eof = 0x00; + setEEModeDone = 0x00; + EnableP2P_PrioLogic = false; +} + +/******************************************************************************* +** +** Function phNxpNciHal_process_ext_rsp +** +** Description Process extension function response +** +** Returns NFCSTATUS_SUCCESS if success +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_process_ext_rsp(uint8_t* p_ntf, uint16_t* p_len) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint16_t rf_technology_length_param = 0; + + if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && *p_len < 14) { + if (*p_len <= 6) { + android_errorWriteLog(0x534e4554, "118152591"); + } + NXPLOG_NCIHAL_E("RF_INTF_ACTIVATED_NTF length error!"); + status = NFCSTATUS_FAILED; + return status; + } + + if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x03 && + p_ntf[5] == 0x05 && nxpprofile_ctrl.profile_type == EMV_CO_PROFILE) { + p_ntf[4] = 0xFF; + p_ntf[5] = 0xFF; + p_ntf[6] = 0xFF; + NXPLOG_NCIHAL_D("Nfc-Dep Detect in EmvCo profile - Restart polling"); + } + + if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 && + p_ntf[5] == 0x05 && p_ntf[6] == 0x02 && gFelicaReaderMode) { + /*If FelicaReaderMode is enabled,Change Protocol to T3T from NFC-DEP + * when FrameRF interface is selected*/ + p_ntf[5] = 0x03; + NXPLOG_NCIHAL_D("FelicaReaderMode:Activity 1.1"); + } + +#ifdef P2P_PRIO_LOGIC_HAL_IMP + if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x02 && + p_ntf[5] == 0x04 && nxpprofile_ctrl.profile_type == NFC_FORUM_PROFILE) { + EnableP2P_PrioLogic = true; + } + + NXPLOG_NCIHAL_D("Is EnableP2P_PrioLogic: 0x0%X", EnableP2P_PrioLogic); + if (phNxpDta_IsEnable() == false) { + if ((icode_detected != 1) && (EnableP2P_PrioLogic == true)) { + if (phNxpNciHal_NfcDep_comapre_ntf(p_ntf, *p_len) == NFCSTATUS_FAILED) { + status = phNxpNciHal_NfcDep_rsp_ext(p_ntf, p_len); + if (status != NFCSTATUS_INVALID_PARAMETER) { + return status; + } + } + } + } +#endif + + status = NFCSTATUS_SUCCESS; + + if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05) { +#if (NFC_NXP_CHIP_TYPE == PN548C2) + if (nfcdep_detected) { + nfcdep_detected = 0x00; + } +#endif + + switch (p_ntf[4]) { + case 0x00: + NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFCEE Direct RF"); + break; + case 0x01: + NXPLOG_NCIHAL_D("NxpNci: RF Interface = Frame RF"); + break; + case 0x02: + NXPLOG_NCIHAL_D("NxpNci: RF Interface = ISO-DEP"); + break; + case 0x03: + NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFC-DEP"); +#if (NFC_NXP_CHIP_TYPE == PN548C2) + nfcdep_detected = 0x01; +#endif + break; + case 0x80: + NXPLOG_NCIHAL_D("NxpNci: RF Interface = MIFARE"); + break; + default: + NXPLOG_NCIHAL_D("NxpNci: RF Interface = Unknown"); + break; + } + + switch (p_ntf[5]) { + case 0x01: + NXPLOG_NCIHAL_D("NxpNci: Protocol = T1T"); + phNxpDta_T1TEnable(); + break; + case 0x02: + NXPLOG_NCIHAL_D("NxpNci: Protocol = T2T"); + break; + case 0x03: + NXPLOG_NCIHAL_D("NxpNci: Protocol = T3T"); + break; + case 0x04: + NXPLOG_NCIHAL_D("NxpNci: Protocol = ISO-DEP"); + break; + case 0x05: + NXPLOG_NCIHAL_D("NxpNci: Protocol = NFC-DEP"); + break; + case 0x06: + NXPLOG_NCIHAL_D("NxpNci: Protocol = 15693"); + break; + case 0x80: + NXPLOG_NCIHAL_D("NxpNci: Protocol = MIFARE"); + break; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + case 0x81: +#else + case 0x8A: +#endif + NXPLOG_NCIHAL_D("NxpNci: Protocol = Kovio"); + break; + default: + NXPLOG_NCIHAL_D("NxpNci: Protocol = Unknown"); + break; + } + + switch (p_ntf[6]) { + case 0x00: + NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Poll"); + break; + case 0x01: + NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Poll"); + break; + case 0x02: + NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Poll"); + break; + case 0x03: + NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Poll"); + break; + case 0x05: + NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Poll"); + break; + case 0x06: + NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Poll"); + break; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + case 0x70: +#else + case 0x77: +#endif + NXPLOG_NCIHAL_D("NxpNci: Mode = Kovio"); + break; + case 0x80: + NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Listen"); + break; + case 0x81: + NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Listen"); + break; + case 0x82: + NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Listen"); + break; + case 0x83: + NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Listen"); + break; + case 0x85: + NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Listen"); + break; + case 0x86: + NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Listen"); + break; + default: + NXPLOG_NCIHAL_D("NxpNci: Mode = Unknown"); + break; + } + } + phNxpNciHal_ext_process_nfc_init_rsp(p_ntf, p_len); + + if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[2] == 0x15 && + p_ntf[4] == 0x01 && p_ntf[5] == 0x06 && p_ntf[6] == 0x06) { + NXPLOG_NCIHAL_D("> Going through workaround - notification of ISO 15693"); + icode_detected = 0x01; + p_ntf[21] = 0x01; + p_ntf[22] = 0x01; + } else if (icode_detected == 1 && icode_send_eof == 2) { + icode_send_eof = 3; + } else if (p_ntf[0] == 0x00 && p_ntf[1] == 0x00 && icode_detected == 1) { + if (icode_send_eof == 3) { + icode_send_eof = 0; + } + if (nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0) { + if (p_ntf[p_ntf[2] + 2] == 0x00) { + NXPLOG_NCIHAL_D("> Going through workaround - data of ISO 15693"); + p_ntf[2]--; + (*p_len)--; + } else { + p_ntf[p_ntf[2] + 2] |= 0x01; + } + } + } else if (p_ntf[2] == 0x02 && p_ntf[1] == 0x00 && icode_detected == 1) { + NXPLOG_NCIHAL_D("> ICODE EOF response do not send to upper layer"); + } else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x06 && icode_detected == 1) { + NXPLOG_NCIHAL_D("> Polling Loop Re-Started"); + icode_detected = 0; + icode_send_eof = 0; + } else if (*p_len == 4 && p_ntf[0] == 0x40 && p_ntf[1] == 0x02 && + p_ntf[2] == 0x01 && p_ntf[3] == 0x06) { + NXPLOG_NCIHAL_D("> Deinit workaround for LLCP set_config 0x%x 0x%x 0x%x", + p_ntf[21], p_ntf[22], p_ntf[23]); + p_ntf[0] = 0x40; + p_ntf[1] = 0x02; + p_ntf[2] = 0x02; + p_ntf[3] = 0x00; + p_ntf[4] = 0x00; + *p_len = 5; + } + // 4200 02 00 01 + else if (p_ntf[0] == 0x42 && p_ntf[1] == 0x00 && ee_disc_done == 0x01) { + NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP"); + if (p_ntf[4] == 0x01) { + p_ntf[4] = 0x00; + + ee_disc_done = 0x00; + } + NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP - END"); + + } else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x03 /*&& cleanup_timer!=0*/) { + if (cleanup_timer != 0) { + /* if RF Notification Type of RF_DISCOVER_NTF is Last Notification */ + if (0 == (*(p_ntf + 2 + (*(p_ntf + 2))))) { + phNxpNciHal_select_RF_Discovery(RfDiscID, RfProtocolType); + status = NFCSTATUS_FAILED; + return status; + } else { + RfDiscID = p_ntf[3]; + RfProtocolType = p_ntf[4]; + } + status = NFCSTATUS_FAILED; + return status; + } + } else if (p_ntf[0] == 0x41 && p_ntf[1] == 0x04 && cleanup_timer != 0) { + status = NFCSTATUS_FAILED; + return status; + } +#if (NFC_NXP_CHIP_TYPE == PN547C2) + else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x02 && + p_ntf[5] == 0x80 && p_ntf[6] == 0x00) { + NXPLOG_NCIHAL_D( + "Going through workaround - iso-dep interface mifare protocol with " + "sak value not equal to 0x20"); + rf_technology_length_param = p_ntf[9]; + if ((p_ntf[9 + rf_technology_length_param] & 0x20) != 0x20) { + p_ntf[4] = 0x80; + } + } +#endif + else if (*p_len == 4 && p_ntf[0] == 0x4F && p_ntf[1] == 0x11 && + p_ntf[2] == 0x01) { + if (p_ntf[3] == 0x00) { + NXPLOG_NCIHAL_D( + "> Workaround for ISO-DEP Presence Check, ignore response and wait " + "for notification"); + p_ntf[0] = 0x60; + p_ntf[1] = 0x06; + p_ntf[2] = 0x03; + p_ntf[3] = 0x01; + p_ntf[4] = 0x00; + p_ntf[5] = 0x01; + *p_len = 6; + } else { + NXPLOG_NCIHAL_D( + "> Workaround for ISO-DEP Presence Check, presence check return " + "failed"); + p_ntf[0] = 0x60; + p_ntf[1] = 0x08; + p_ntf[2] = 0x02; + p_ntf[3] = 0xB2; + p_ntf[4] = 0x00; + *p_len = 5; + } + } else if (*p_len == 4 && p_ntf[0] == 0x6F && p_ntf[1] == 0x11 && + p_ntf[2] == 0x01) { + if (p_ntf[3] == 0x01) { + NXPLOG_NCIHAL_D( + "> Workaround for ISO-DEP Presence Check - Card still in field"); + p_ntf[0] = 0x00; + p_ntf[1] = 0x00; + p_ntf[2] = 0x01; + p_ntf[3] = 0x7E; + } else { + NXPLOG_NCIHAL_D( + "> Workaround for ISO-DEP Presence Check - Card not in field"); + p_ntf[0] = 0x60; + p_ntf[1] = 0x08; + p_ntf[2] = 0x02; + p_ntf[3] = 0xB2; + p_ntf[4] = 0x00; + *p_len = 5; + } + } + /* + else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 && p_ntf[5] + == 0x00 && p_ntf[6] == 0x01) + { + NXPLOG_NCIHAL_D("Picopass type 3-B with undefined protocol is not + supported, disabling"); + p_ntf[4] = 0xFF; + p_ntf[5] = 0xFF; + p_ntf[6] = 0xFF; + }*/ + + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_ext_process_nfc_init_rsp + * + * Description This function is used to process the HAL NFC core reset rsp + * and ntf and core init rsp of NCI 1.0 or NCI2.0 and update + * NCI version. + * It also handles error response such as core_reset_ntf with + * error status in both NCI2.0 and NCI1.0. + * + * Returns Returns NFCSTATUS_SUCCESS if parsing response is successful + * or returns failure. + * + *******************************************************************************/ +static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf, + uint16_t* p_len) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + /* Parsing CORE_RESET_RSP and CORE_RESET_NTF to update NCI version.*/ + if (p_ntf == NULL || *p_len == 0x00) { + return NFCSTATUS_FAILED; + } + if (p_ntf[0] == NCI_MT_RSP && + ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) { + if (p_ntf[2] == 0x01 && p_ntf[3] == 0x00) { + NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI2.0"); + if (nxpncihal_ctrl.hal_ext_enabled == TRUE) { + nxpncihal_ctrl.nci_info.wait_for_ntf = TRUE; + } + } else if (p_ntf[2] == 0x03 && p_ntf[3] == 0x00) { + NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI1.0"); + nxpncihal_ctrl.nci_info.nci_version = p_ntf[4]; + } + } else if (p_ntf[0] == NCI_MT_NTF && + ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) { + if (p_ntf[3] == CORE_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED || + p_ntf[3] == CORE_RESET_TRIGGER_TYPE_POWERED_ON) { + NXPLOG_NCIHAL_D("CORE_RESET_NTF NCI2.0 reason CORE_RESET_CMD received !"); + nxpncihal_ctrl.nci_info.nci_version = p_ntf[5]; + int len = p_ntf[2] + 2; /*include 2 byte header*/ + wFwVerRsp = (((uint32_t)p_ntf[len - 2]) << 16U) | + (((uint32_t)p_ntf[len - 1]) << 8U) | p_ntf[len]; + NXPLOG_NCIHAL_D("NxpNci> FW Version: %x.%x.%x", p_ntf[len - 2], + p_ntf[len - 1], p_ntf[len]); + } else { +#if (NFC_NXP_CHIP_TYPE == PN548C2) + if (nfcdep_detected && + !(p_ntf[2] == 0x06 && p_ntf[3] == 0xA0 && p_ntf[4] == 0x00 && + ((p_ntf[5] == 0xC9 && p_ntf[6] == 0x95 && p_ntf[7] == 0x00 && + p_ntf[8] == 0x00) || + (p_ntf[5] == 0x07 && p_ntf[6] == 0x39 && p_ntf[7] == 0xF2 && + p_ntf[8] == 0x00)))) { + nfcdep_detected = 0x00; + } +#endif + phNxpNciHal_emergency_recovery(); + status = NFCSTATUS_FAILED; + } /* Parsing CORE_INIT_RSP*/ + } else if (p_ntf[0] == NCI_MT_RSP && + ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_INIT)) { + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI2.0 received !"); + } else { + NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI1.0 received !"); + int len = p_ntf[2] + 2; /*include 2 byte header*/ + wFwVerRsp = (((uint32_t)p_ntf[len - 2]) << 16U) | + (((uint32_t)p_ntf[len - 1]) << 8U) | p_ntf[len]; + if (wFwVerRsp == 0) status = NFCSTATUS_FAILED; + iCoreInitRspLen = *p_len; + memcpy(bCoreInitRsp, p_ntf, *p_len); + NXPLOG_NCIHAL_D("NxpNci> FW Version: %x.%x.%x", p_ntf[len - 2], + p_ntf[len - 1], p_ntf[len]); + fw_maj_ver = p_ntf[len - 1]; + rom_version = p_ntf[len - 2]; + } + } + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_process_ext_cmd_rsp + * + * Description This function process the extension command response. It + * also checks the received response to expected response. + * + * Returns returns NFCSTATUS_SUCCESS if response is as expected else + * returns failure. + * + ******************************************************************************/ +static NFCSTATUS phNxpNciHal_process_ext_cmd_rsp(uint16_t cmd_len, + uint8_t* p_cmd) { + NFCSTATUS status = NFCSTATUS_FAILED; + uint16_t data_written = 0; + + /* Create the local semaphore */ + if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL) != + NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("Create ext_cb_data failed"); + return NFCSTATUS_FAILED; + } + + nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_SUCCESS; + + /* Send ext command */ + data_written = phNxpNciHal_write_unlocked(cmd_len, p_cmd); + if (data_written != cmd_len) { + NXPLOG_NCIHAL_D("phNxpNciHal_write failed for hal ext"); + goto clean_and_return; + } + + /* Start timer */ + status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_EXTNS_WRITE_RSP_TIMEOUT, + &hal_extns_write_rsp_timeout_cb, NULL); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("Response timer started"); + } else { + NXPLOG_NCIHAL_E("Response timer not started!!!"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + + /* Wait for rsp */ + NXPLOG_NCIHAL_D("Waiting after ext cmd sent"); + if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data)) { + NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error"); + goto clean_and_return; + } + + /* Stop Timer */ + status = phOsalNfc_Timer_Stop(timeoutTimerId); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("Response timer stopped"); + } else { + NXPLOG_NCIHAL_E("Response timer stop ERROR!!!"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + /* Start timer to wait for NTF*/ + if (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE) { + status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_EXTNS_WRITE_RSP_TIMEOUT, + &hal_extns_write_rsp_timeout_cb, NULL); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("Response timer started"); + } else { + NXPLOG_NCIHAL_E("Response timer not started!!!"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data)) { + NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error"); + /* Stop Timer */ + status = phOsalNfc_Timer_Stop(timeoutTimerId); + goto clean_and_return; + } + status = phOsalNfc_Timer_Stop(timeoutTimerId); + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("Response timer stopped"); + } else { + NXPLOG_NCIHAL_E("Response timer stop ERROR!!!"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + } + + if (nxpncihal_ctrl.ext_cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E( + "Callback Status is failed!! Timer Expired!! Couldn't read it! 0x%x", + nxpncihal_ctrl.ext_cb_data.status); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + + NXPLOG_NCIHAL_D("Checking response"); + status = NFCSTATUS_SUCCESS; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data); + nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE; + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_write_ext + * + * Description This function inform the status of phNxpNciHal_open + * function to libnfc-nci. + * + * Returns It return NFCSTATUS_SUCCESS then continue with send else + * sends NFCSTATUS_FAILED direct response is prepared and + * do not send anything to NFCC. + * + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_write_ext(uint16_t* cmd_len, uint8_t* p_cmd_data, + uint16_t* rsp_len, uint8_t* p_rsp_data) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + + unsigned long retval = 0; + int isfound = + GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &retval, sizeof(unsigned long)); + + phNxpNciHal_NfcDep_cmd_ext(p_cmd_data, cmd_len); + + if (phNxpDta_IsEnable() == true) { + status = phNxpNHal_DtaUpdate(cmd_len, p_cmd_data, rsp_len, p_rsp_data); + } + + if (p_cmd_data[0] == PROPRIETARY_CMD_FELICA_READER_MODE && + p_cmd_data[1] == PROPRIETARY_CMD_FELICA_READER_MODE && + p_cmd_data[2] == PROPRIETARY_CMD_FELICA_READER_MODE) { + NXPLOG_NCIHAL_D("Received proprietary command to set Felica Reader mode:%d", + p_cmd_data[3]); + gFelicaReaderMode = p_cmd_data[3]; + /* frame the dummy response */ + *rsp_len = 4; + p_rsp_data[0] = 0x00; + p_rsp_data[1] = 0x00; + p_rsp_data[2] = 0x00; + p_rsp_data[3] = 0x00; + status = NFCSTATUS_FAILED; + } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x01 && + p_cmd_data[4] == 0xA0 && p_cmd_data[5] == 0x44 && + p_cmd_data[6] == 0x01 && p_cmd_data[7] == 0x01) { + nxpprofile_ctrl.profile_type = EMV_CO_PROFILE; + NXPLOG_NCIHAL_D("EMV_CO_PROFILE mode - Enabled"); + status = NFCSTATUS_SUCCESS; + } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 && + p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x01 && + p_cmd_data[4] == 0xA0 && p_cmd_data[5] == 0x44 && + p_cmd_data[6] == 0x01 && p_cmd_data[7] == 0x00) { + NXPLOG_NCIHAL_D("NFC_FORUM_PROFILE mode - Enabled"); + nxpprofile_ctrl.profile_type = NFC_FORUM_PROFILE; + status = NFCSTATUS_SUCCESS; + } + + if (nxpprofile_ctrl.profile_type == EMV_CO_PROFILE) { + if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x06 && + p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x03) { +#if 0 + //Needs clarification whether to keep it or not + NXPLOG_NCIHAL_D ("EmvCo Poll mode - RF Deactivate discard"); + phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len); + *rsp_len = 4; + p_rsp_data[0] = 0x41; + p_rsp_data[1] = 0x06; + p_rsp_data[2] = 0x01; + p_rsp_data[3] = 0x00; + phNxpNciHal_print_packet("RECV", p_rsp_data, 4); + status = NFCSTATUS_FAILED; +#endif + } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) { + NXPLOG_NCIHAL_D("EmvCo Poll mode - Discover map only for A and B"); + p_cmd_data[2] = 0x05; + p_cmd_data[3] = 0x02; + p_cmd_data[4] = 0x00; + p_cmd_data[5] = 0x01; + p_cmd_data[6] = 0x01; + p_cmd_data[7] = 0x01; + *cmd_len = 8; + } + } + + if (retval == 0x01 && p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x00) { + NXPLOG_NCIHAL_D("Going through extns - Adding Mifare in RF Discovery"); + p_cmd_data[2] += 3; + p_cmd_data[3] += 1; + p_cmd_data[*cmd_len] = 0x80; + p_cmd_data[*cmd_len + 1] = 0x01; + p_cmd_data[*cmd_len + 2] = 0x80; + *cmd_len += 3; + status = NFCSTATUS_SUCCESS; + NXPLOG_NCIHAL_D( + "Going through extns - Adding Mifare in RF Discovery - END"); + } else if (p_cmd_data[3] == 0x81 && p_cmd_data[4] == 0x01 && + p_cmd_data[5] == 0x03) { + NXPLOG_NCIHAL_D("> Going through workaround - set host list"); + +#if (NFC_NXP_CHIP_TYPE != PN547C2) + *cmd_len = 8; + + p_cmd_data[2] = 0x05; + p_cmd_data[6] = 0x02; + p_cmd_data[7] = 0xC0; +#else + *cmd_len = 7; + + p_cmd_data[2] = 0x04; + p_cmd_data[6] = 0xC0; +#endif + + NXPLOG_NCIHAL_D("> Going through workaround - set host list - END"); + status = NFCSTATUS_SUCCESS; + } else if (icode_detected) { + if ((p_cmd_data[3] & 0x40) == 0x40 && + (p_cmd_data[4] == 0x21 || p_cmd_data[4] == 0x22 || + p_cmd_data[4] == 0x24 || p_cmd_data[4] == 0x27 || + p_cmd_data[4] == 0x28 || p_cmd_data[4] == 0x29 || + p_cmd_data[4] == 0x2a)) { + NXPLOG_NCIHAL_D("> Send EOF set"); + icode_send_eof = 1; + } + + if (p_cmd_data[3] == 0x20 || p_cmd_data[3] == 0x24 || + p_cmd_data[3] == 0x60) { + NXPLOG_NCIHAL_D("> NFC ISO_15693 Proprietary CMD "); + p_cmd_data[3] += 0x02; + } + } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) { + NXPLOG_NCIHAL_D("> Polling Loop Started"); + icode_detected = 0; + icode_send_eof = 0; +#if (NFC_NXP_CHIP_TYPE == PN548C2) + // Cache discovery cmd for recovery + phNxpNciHal_discovery_cmd_ext(p_cmd_data, *cmd_len); +#endif + } + // 22000100 + else if (p_cmd_data[0] == 0x22 && p_cmd_data[1] == 0x00 && + p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x00) { + // ee_disc_done = 0x01;//Reader Over SWP event getting + *rsp_len = 0x05; + p_rsp_data[0] = 0x42; + p_rsp_data[1] = 0x00; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + phNxpNciHal_print_packet("RECV", p_rsp_data, 5); + status = NFCSTATUS_FAILED; + } + // 2002 0904 3000 3100 3200 5000 + else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) && + ((p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) /*|| + (p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/ + )) { + *cmd_len += 0x01; + p_cmd_data[2] += 0x01; + p_cmd_data[9] = 0x01; + p_cmd_data[10] = 0x40; + p_cmd_data[11] = 0x50; + p_cmd_data[12] = 0x00; + + NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config "); + // phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len); + NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End "); + } + // 20020703300031003200 + // 2002 0301 3200 + else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) && + ((p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x03) || + (p_cmd_data[2] == 0x03 && p_cmd_data[3] == 0x01 && + p_cmd_data[4] == 0x32))) { + NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config "); + phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len); + *rsp_len = 5; + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + + phNxpNciHal_print_packet("RECV", p_rsp_data, 5); + status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End "); + } + + // 2002 0D04 300104 310100 320100 500100 + // 2002 0401 320100 + else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) && + ( + /*(p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/ + (p_cmd_data[2] == 0x04 && p_cmd_data[3] == 0x01 && + p_cmd_data[4] == 0x32 && p_cmd_data[5] == 0x00))) { + // p_cmd_data[12] = 0x40; + + NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config "); + phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len); + p_cmd_data[6] = 0x60; + + phNxpNciHal_print_packet("RECV", p_rsp_data, 5); + // status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End "); + } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x00) { + NXPLOG_NCIHAL_D( + "> Going through workaround - Add Mifare Classic in Discovery Map"); + p_cmd_data[*cmd_len] = 0x80; + p_cmd_data[*cmd_len + 1] = 0x01; + p_cmd_data[*cmd_len + 2] = 0x80; + p_cmd_data[5] = 0x01; + p_cmd_data[6] = 0x01; + p_cmd_data[2] += 3; + p_cmd_data[3] += 1; + *cmd_len += 3; + } else if (*cmd_len == 3 && p_cmd_data[0] == 0x00 && p_cmd_data[1] == 0x00 && + p_cmd_data[2] == 0x00) { + NXPLOG_NCIHAL_D("> Going through workaround - ISO-DEP Presence Check "); + p_cmd_data[0] = 0x2F; + p_cmd_data[1] = 0x11; + p_cmd_data[2] = 0x00; + status = NFCSTATUS_SUCCESS; + NXPLOG_NCIHAL_D( + "> Going through workaround - ISO-DEP Presence Check - End"); + } +#if 0 + else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) && + ((p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) || + (p_cmd_data[2] == 0x0B && p_cmd_data[3] == 0x05) || + (p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x02) || + (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x03) || + (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x04) || + (p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x02)) + ) + { + NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config "); + phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len); + *rsp_len = 5; + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + + phNxpNciHal_print_packet("RECV", p_rsp_data, 5); + status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End "); + } + + else if((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) && + ((p_cmd_data[3] == 0x00) || + ((*cmd_len >= 0x06) && (p_cmd_data[5] == 0x00)))) /*If the length of the first param id is zero don't allow*/ + { + NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config "); + phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len); + *rsp_len = 5; + p_rsp_data[0] = 0x40; + p_rsp_data[1] = 0x02; + p_rsp_data[2] = 0x02; + p_rsp_data[3] = 0x00; + p_rsp_data[4] = 0x00; + + phNxpNciHal_print_packet("RECV", p_rsp_data, 5); + status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End "); + } +#endif + else if ((wFwVerRsp & 0x0000FFFF) == wFwVer) { + /* skip CORE_RESET and CORE_INIT from Brcm */ + if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x00 && + p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x01) { + // *rsp_len = 6; + // + // NXPLOG_NCIHAL_D("> Going - core reset optimization"); + // + // p_rsp_data[0] = 0x40; + // p_rsp_data[1] = 0x00; + // p_rsp_data[2] = 0x03; + // p_rsp_data[3] = 0x00; + // p_rsp_data[4] = 0x10; + // p_rsp_data[5] = 0x01; + // + // status = NFCSTATUS_FAILED; + // NXPLOG_NCIHAL_D("> Going - core reset optimization - END"); + } + /* CORE_INIT */ + else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x01 && + p_cmd_data[2] == 0x00) { + // NXPLOG_NCIHAL_D("> Going - core init optimization"); + // *rsp_len = iCoreInitRspLen; + // memcpy(p_rsp_data, bCoreInitRsp, iCoreInitRspLen); + // status = NFCSTATUS_FAILED; + // NXPLOG_NCIHAL_D("> Going - core init optimization - END"); + } + } + +#if (NFC_NXP_CHIP_TYPE == PN548C2) + if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) { + uint8_t temp; + uint8_t* p = p_cmd_data + 4; + uint8_t* end = p_cmd_data + *cmd_len; + while (p < end) { + if (*p == 0x53) // LF_T3T_FLAGS + { + NXPLOG_NCIHAL_D("> Going through workaround - LF_T3T_FLAGS swap"); + temp = *(p + 3); + *(p + 3) = *(p + 2); + *(p + 2) = temp; + NXPLOG_NCIHAL_D("> Going through workaround - LF_T3T_FLAGS - End"); + status = NFCSTATUS_SUCCESS; + break; + } + if (*p == 0xA0) { + p += *(p + 2) + 3; + } else { + p += *(p + 1) + 2; + } + } + } +#endif + + return status; +} + +/****************************************************************************** + * Function phNxpNciHal_send_ext_cmd + * + * Description This function send the extension command to NFCC. No + * response is checked by this function but it waits for + * the response to come. + * + * Returns Returns NFCSTATUS_SUCCESS if sending cmd is successful and + * response is received. + * + ******************************************************************************/ +NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t* p_cmd) { + NFCSTATUS status = NFCSTATUS_FAILED; + + HAL_ENABLE_EXT(); + nxpncihal_ctrl.cmd_len = cmd_len; + memcpy(nxpncihal_ctrl.p_cmd_data, p_cmd, cmd_len); + status = phNxpNciHal_process_ext_cmd_rsp(nxpncihal_ctrl.cmd_len, + nxpncihal_ctrl.p_cmd_data); + HAL_DISABLE_EXT(); + + return status; +} + +/****************************************************************************** + * Function hal_extns_write_rsp_timeout_cb + * + * Description Timer call back function + * + * Returns None + * + ******************************************************************************/ +static void hal_extns_write_rsp_timeout_cb(uint32_t timerId, void* pContext) { + UNUSED(timerId); + UNUSED(pContext); + NXPLOG_NCIHAL_E("hal_extns_write_rsp_timeout_cb - write timeout!!!"); + nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED; + usleep(1); + SEM_POST(&(nxpncihal_ctrl.ext_cb_data)); + + return; +} diff --git a/pn54x/hal/phNxpNciHal_ext.h b/pn54x/hal/phNxpNciHal_ext.h new file mode 100644 index 0000000..72387e9 --- /dev/null +++ b/pn54x/hal/phNxpNciHal_ext.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _PHNXPNCIHAL_EXT_H_ +#define _PHNXPNCIHAL_EXT_H_ + +#include <phNxpNciHal.h> +#include <phNxpNciHal_dta.h> +#include <string.h> + +void phNxpNciHal_ext_init(void); +NFCSTATUS phNxpNciHal_process_ext_rsp(uint8_t* p_ntf, uint16_t* p_len); +NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t* p_cmd); +NFCSTATUS phNxpNciHal_write_ext(uint16_t* cmd_len, uint8_t* p_cmd_data, + uint16_t* rsp_len, uint8_t* p_rsp_data); + +#endif /* _PHNXPNICHAL_EXT_H_ */ diff --git a/pn54x/inc/phNxpNciHal_Adaptation.h b/pn54x/inc/phNxpNciHal_Adaptation.h new file mode 100644 index 0000000..b4d5566 --- /dev/null +++ b/pn54x/inc/phNxpNciHal_Adaptation.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PHNXPNCIHAL_ADAPTATION_H_ +#define _PHNXPNCIHAL_ADAPTATION_H_ + +#include <hardware/hardware.h> +#include <hardware/nfc.h> + +typedef struct { + struct nfc_nci_device nci_device; + + /* Local definitions */ +} pn547_dev_t; + +/* NXP HAL functions */ + +int phNxpNciHal_open(nfc_stack_callback_t* p_cback, + nfc_stack_data_callback_t* p_data_cback); +int phNxpNciHal_write(uint16_t data_len, const uint8_t* p_data); +int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params); +int phNxpNciHal_pre_discover(void); +int phNxpNciHal_close(void); +int phNxpNciHal_control_granted(void); +int phNxpNciHal_power_cycle(void); + +#endif /* _PHNXPNCIHAL_ADAPTATION_H_ */ diff --git a/pn54x/inc/phNxpNciHal_Api.h b/pn54x/inc/phNxpNciHal_Api.h new file mode 100644 index 0000000..e1e0649 --- /dev/null +++ b/pn54x/inc/phNxpNciHal_Api.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _PHNXPNCIHAL_API_H_ +#define _PHNXPNCIHAL_API_H_ + +#include <phNfcStatus.h> +#include <phNxpNciHal.h> +#include <phTmlNfc.h> + +/******************************************************************************* + ** + ** Function phNxpNciHal_get_version + ** + ** Description Function to get the HW, FW and SW versions. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_get_version(uint32_t* hw_ver, uint32_t* fw_ver, + uint32_t* sw_ver); + +#endif /* _PHNXPNCIHAL_API_H_ */ diff --git a/pn54x/inc/phNxpNciHal_SelfTest.h b/pn54x/inc/phNxpNciHal_SelfTest.h new file mode 100644 index 0000000..ee7c8d6 --- /dev/null +++ b/pn54x/inc/phNxpNciHal_SelfTest.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _PHNXPNCIHAL_SELFTEST_H_ +#define _PHNXPNCIHAL_SELFTEST_H_ + +#ifdef NXP_HW_SELF_TEST + +#include <phNfcStatus.h> +#include <phNxpNciHal.h> +#include <phTmlNfc.h> + +/* PRBS Generation type */ +typedef enum { + NFC_FW_PRBS, /* FW software would generate the PRBS */ + NFC_HW_PRBS /* Hardware would generate the PRBS */ +} phNxpNfc_PrbsType_t; + +/* Different HW PRBS types */ +typedef enum { NFC_HW_PRBS9, NFC_HW_PRBS15 } phNxpNfc_PrbsHwType_t; +/* RF Technology */ +typedef enum { + NFC_RF_TECHNOLOGY_A, + NFC_RF_TECHNOLOGY_B, + NFC_RF_TECHNOLOGY_F, +} phNxpNfc_Tech_t; + +/* Bit rates */ +typedef enum { + NFC_BIT_RATE_106, + NFC_BIT_RATE_212, + NFC_BIT_RATE_424, + NFC_BIT_RATE_848, +} phNxpNfc_Bitrate_t; + +typedef struct phAntenna_St_Resp { + /* Txdo Raw Value*/ + uint16_t wTxdoRawValue; + uint16_t wTxdoMeasuredRangeMin; /*Txdo Measured Range Max */ + uint16_t wTxdoMeasuredRangeMax; /*Txdo Measured Range Min */ + uint16_t wTxdoMeasuredTolerance; /*Txdo Measured Range Tolerance */ + /* Agc Values */ + uint16_t wAgcValue; /*Agc Min Value*/ + uint16_t wAgcValueTolerance; /*Txdo Measured Range*/ + /* Agc value with NFCLD */ + uint16_t wAgcValuewithfixedNFCLD; /*Agc Value with Fixed NFCLD Max */ + uint16_t wAgcValuewithfixedNFCLDTolerance; /*Agc Value with Fixed NFCLD + Tolerance */ + /* Agc Differential Values With Open/Short RM */ + uint16_t wAgcDifferentialWithOpen1; /*Agc Differential With Open 1*/ + uint16_t wAgcDifferentialWithOpenTolerance1; /*Agc Differential With Open + Tolerance 1*/ + uint16_t wAgcDifferentialWithOpen2; /*Agc Differential With Open 2*/ + uint16_t wAgcDifferentialWithOpenTolerance2; /*Agc Differential With Open + Tolerance 2*/ +} phAntenna_St_Resp_t; /* Instance of Transaction structure */ + +/******************************************************************************* + ** + ** Function phNxpNciHal_TestMode_open + ** + ** Description It opens the physical connection with NFCC (pn547) and + ** creates required client thread for operation. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_TestMode_open(void); + +/******************************************************************************* + ** + ** Function phNxpNciHal_TestMode_close + ** + ** Description This function close the NFCC interface and free all + ** resources. + ** + ** Returns None. + ** + ******************************************************************************/ + +void phNxpNciHal_TestMode_close(void); + +/******************************************************************************* + ** + ** Function phNxpNciHal_SwpTest + ** + ** Description Test function to validate the SWP line. SWP line number is + ** is sent as parameter to the API. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_SwpTest(uint8_t swp_line); + +/******************************************************************************* + ** + ** Function phNxpNciHal_PrbsTestStart + ** + ** Description Test function start RF generation for RF technology and bit + ** rate. RF technology and bit rate are sent as parameter to + ** the API. + ** + ** Returns NFCSTATUS_SUCCESS if RF generation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ +#if (NFC_NXP_CHIP_TYPE != PN547C2) +NFCSTATUS phNxpNciHal_PrbsTestStart(phNxpNfc_PrbsType_t prbs_type, + phNxpNfc_PrbsHwType_t hw_prbs_type, + phNxpNfc_Tech_t tech, + phNxpNfc_Bitrate_t bitrate); +#else +NFCSTATUS phNxpNciHal_PrbsTestStart(phNxpNfc_Tech_t tech, + phNxpNfc_Bitrate_t bitrate); +#endif +/******************************************************************************* + ** + ** Function phNxpNciHal_PrbsTestStop + ** + ** Description Test function stop RF generation for RF technology started + ** by phNxpNciHal_PrbsTestStart. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_PrbsTestStop(); + +/******************************************************************************* +** +** Function phNxpNciHal_AntennaSelfTest +** +** Description Test function to validate the Antenna's discrete +** components connection. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. +** +*******************************************************************************/ + +NFCSTATUS phNxpNciHal_AntennaSelfTest(phAntenna_St_Resp_t* phAntenna_St_Resp); + +/******************************************************************************* +** +** Function phNxpNciHal_RfFieldTest +** +** Description Test function performs RF filed test. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. +** +*******************************************************************************/ + +NFCSTATUS phNxpNciHal_RfFieldTest(uint8_t on); + +/******************************************************************************* + ** + ** Function phNxpNciHal_DownloadPinTest + ** + ** Description Test function to validate the FW download pin connection. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_DownloadPinTest(void); + +#endif /* _NXP_HW_SELF_TEST_H_ */ +#endif /* _PHNXPNCIHAL_SELFTEST_H_ */ diff --git a/pn54x/libnfc-brcm.conf b/pn54x/libnfc-brcm.conf new file mode 100644 index 0000000..14c6912 --- /dev/null +++ b/pn54x/libnfc-brcm.conf @@ -0,0 +1,400 @@ +###################### Start of libnfc-brcm.conf ####################### + +############################################################################### +# Application options +APPL_TRACE_LEVEL=0xFF +PROTOCOL_TRACE_LEVEL=0xFFFFFFFF + +############################################################################### +# performance measurement +# Change this setting to control how often USERIAL log the performance (throughput) +# data on read/write/poll +# defailt is to log performance dara for every 100 read or write +#REPORT_PERFORMANCE_MEASURE=100 + +############################################################################### +# File used for NFA storage +NFA_STORAGE="/data/nfc" + +############################################################################### +# Snooze Mode Settings +# +# By default snooze mode is enabled. Set SNOOZE_MODE_CFG byte[0] to 0 +# to disable. +# +# If SNOOZE_MODE_CFG is not provided, the default settings are used: +# They are as follows: +# 8 Sleep Mode (0=Disabled 1=UART 8=SPI/I2C) +# 0 Idle Threshold Host +# 0 Idle Threshold HC +# 0 NFC Wake active mode (0=ActiveLow 1=ActiveHigh) +# 1 Host Wake active mode (0=ActiveLow 1=ActiveHigh) +# +#SNOOZE_MODE_CFG={08:00:00:00:01} + +############################################################################### +# Insert a delay in milliseconds after NFC_WAKE and before write to NFCC +#NFC_WAKE_DELAY=20 + +############################################################################### +# Various Delay settings (in ms) used in USERIAL +# POWER_ON_DELAY +# Delay after turning on chip, before writing to transport (default 300) +# PRE_POWER_OFF_DELAY +# Delay after deasserting NFC-Wake before turn off chip (default 0) +# POST_POWER_OFF_DELAY +# Delay after turning off chip, before USERIAL_close returns (default 0) +# +#POWER_ON_DELAY=300 +#PRE_POWER_OFF_DELAY=0 +#POST_POWER_OFF_DELAY=0 + +############################################################################### +# Maximum time (ms) to wait for RESET NTF after setting REG_PU to high +# The default is 1000. +#NFCC_ENABLE_TIMEOUT=0 + +############################################################################### +# LPTD mode configuration +# byte[0] is the length of the remaining bytes in this value +# if set to 0, LPTD params will NOT be sent to NFCC (i.e. disabled). +# byte[1] is the param id it should be set to B9. +# byte[2] is the length of the LPTD parameters +# byte[3] indicates if LPTD is enabled +# if set to 0, LPTD will be disabled (parameters will still be sent). +# byte[4-n] are the LPTD parameters. +# By default, LPTD is enabled and default settings are used. +# See nfc_hal_dm_cfg.c for defaults +#LPTD_CFG={23:B9:21:01:02:FF:FF:04:A0:0F:40:00:80:02:02:10:00:00:00:31:0C:30:00:00:00:00:00:00:00:00:00:00:00:00:00:00} + +############################################################################### +# Startup Configuration (100 bytes maximum) +# +# For the 0xCA parameter, byte[9] (marked by 'AA') is for UICC0, and byte[10] (marked by BB) is +# for UICC1. The values are defined as: +# 0 : UICCx only supports ISO_DEP in low power mode. +# 2 : UICCx only supports Mifare in low power mode. +# 3 : UICCx supports both ISO_DEP and Mifare in low power mode. +# +# AA BB +#NFA_DM_START_UP_CFG={1F:CB:01:01:A5:01:01:CA:14:00:00:00:00:06:E8:03:00:00:00:00:00:00:00:00:00:00:00:00:00:80:01:01} + +############################################################################### +# Startup Vendor Specific Configuration (100 bytes maximum); +# byte[0] TLV total len = 0x5 +# byte[1] NCI_MTS_CMD|NCI_GID_PROP = 0x2f +# byte[2] NCI_MSG_FRAME_LOG = 0x9 +# byte[3] 2 +# byte[4] 0=turn off RF frame logging; 1=turn on +# byte[5] 0=turn off SWP frame logging; 1=turn on +# NFA_DM_START_UP_VSC_CFG={05:2F:09:02:01:01} + +############################################################################### +# Antenna Configuration - This data is used when setting 0xC8 config item +# at startup (before discovery is started). If not used, no value is sent. +# +# The settings for this value are documented here: +# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/ +# Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx +# This document is maintained by Paul Forshaw. +# +# The values marked as ?? should be tweaked per antenna or customer/app: +# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04} +# array[0] = 0x20 is length of the payload from array[1] to the end +# array[1] = 0xC8 is PREINIT_DSP_CFG +#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04} + +############################################################################### +# Configure crystal frequency when internal LPO can't detect the frequency. +#XTAL_FREQUENCY=0 +############################################################################### +# Configure the default Destination Gate used by HCI (the default is 4, which +# is the ETSI loopback gate. +NFA_HCI_DEFAULT_DEST_GATE=0xF0 + +############################################################################### +# Configure the single default SE to use. The default is to use the first +# SE that is detected by the stack. This value might be used when the phone +# supports multiple SE (e.g. 0xF3 and 0xF4) but you want to force it to use +# one of them (e.g. 0xF4). +#ACTIVE_SE=0xF3 + +############################################################################### +# Configure the default NfcA/IsoDep techology and protocol route. Can be +# either a secure element (e.g. 0xF4) or the host (0x00) +#DEFAULT_ISODEP_ROUTE=0x00 + +############################################################################### +# Configure the NFC Extras to open and use a static pipe. If the value is +# not set or set to 0, then the default is use a dynamic pipe based on a +# destination gate (see NFA_HCI_DEFAULT_DEST_GATE). Note there is a value +# for each UICC (where F3="UICC0" and F4="UICC1") +#NFA_HCI_STATIC_PIPE_ID_F3=0x70 +#NFA_HCI_STATIC_PIPE_ID_01=0x19 +NFA_HCI_STATIC_PIPE_ID_C0=0x19 +############################################################################### +# When disconnecting from Oberthur secure element, perform a warm-reset of +# the secure element to deselect the applet. +# The default hex value of the command is 0x3. If this variable is undefined, +# then this feature is not used. +#OBERTHUR_WARM_RESET_COMMAND=0x03 + +############################################################################### +# Force UICC to only listen to the following technology(s). +# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h. +# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F +UICC_LISTEN_TECH_MASK=0x07 + +############################################################################### +# Force HOST listen feature enable or disable. +# 0: Disable +# 1: Enable +HOST_LISTEN_ENABLE=0x01 + +############################################################################### +# Enabling/Disabling Forward functionality +# Disable 0x00 +# Enable 0x01 +NXP_FWD_FUNCTIONALITY_ENABLE=0x01 + +############################################################################### +# Allow UICC to be powered off if there is no traffic. +# Timeout is in ms. If set to 0, then UICC will not be powered off. +#UICC_IDLE_TIMEOUT=30000 +UICC_IDLE_TIMEOUT=0 + +############################################################################### +# AID for Empty Select command +# If specified, this AID will be substituted when an Empty SELECT command is +# detected. The first byte is the length of the AID. Maximum length is 16. +AID_FOR_EMPTY_SELECT={08:A0:00:00:01:51:00:00:00} +############################################################################### +# Maximum Number of Credits to be allowed by the NFCC +# This value overrides what the NFCC specifices allowing the host to have +# the control to work-around transport limitations. If this value does +# not exist or is set to 0, the NFCC will provide the number of credits. +MAX_RF_DATA_CREDITS=1 + +############################################################################### +# This setting allows you to disable registering the T4t Virtual SE that causes +# the NFCC to send PPSE requests to the DH. +# The default setting is enabled (i.e. T4t Virtual SE is registered). +#REGISTER_VIRTUAL_SE=1 + +############################################################################### +# When screen is turned off, specify the desired power state of the controller. +# 0: power-off-sleep state; DEFAULT +# 1: full-power state +# 2: screen-off card-emulation (CE4/CE3/CE1 modes are used) +SCREEN_OFF_POWER_STATE=1 + +############################################################################### +# Firmware patch file +# If the value is not set then patch download is disabled. +#FW_PATCH="/vendor/firmware/bcm2079x_firmware.ncd" + +############################################################################### +# Firmware pre-patch file (sent before the above patch file) +# If the value is not set then pre-patch is not used. +#FW_PRE_PATCH="/vendor/firmware/bcm2079x_pre_firmware.ncd" + +############################################################################### +# Firmware patch format +# 1 = HCD +# 2 = NCD (default) +#NFA_CONFIG_FORMAT=2 + +############################################################################### +# SPD Debug mode +# If set to 1, any failure of downloading a patch will trigger a hard-stop +#SPD_DEBUG=0 + +############################################################################### +# SPD Max Retry Count +# The number of attempts to download a patch before giving up (defualt is 3). +# Note, this resets after a power-cycle. +#SPD_MAX_RETRY_COUNT=3 + +############################################################################### +# transport driver +# +# TRANSPORT_DRIVER=<driver> +# +# where <driver> can be, for example: +# "/dev/ttyS" (UART) +# "/dev/bcmi2cnfc" (I2C) +# "hwtun" (HW Tunnel) +# "/dev/bcmspinfc" (SPI) +# "/dev/btusb0" (BT USB) +#TRANSPORT_DRIVER="/dev/bcm2079x-i2c" + +############################################################################### +# power control driver +# Specify a kernel driver that support ioctl commands to control NFC_EN and +# NFC_WAKE gpio signals. +# +# POWER_CONTRL_DRIVER=<driver> +# where <driver> can be, for example: +# "/dev/nfcpower" +# "/dev/bcmi2cnfc" (I2C) +# "/dev/bcmspinfc" (SPI) +# i2c and spi driver may be used to control NFC_EN and NFC_WAKE signal +#POWER_CONTROL_DRIVER="/dev/bcm2079x-i2c" + +############################################################################### +# I2C transport driver options +# Mako does not support 10-bit I2C addresses +# Revert to 7-bit address +#BCMI2CNFC_ADDRESS=0x77 + +############################################################################### +# I2C transport driver try to read multiple packets in read() if data is available +# remove the comment below to enable this feature +#READ_MULTIPLE_PACKETS=1 + +############################################################################### +# SPI transport driver options +#SPI_NEGOTIATION={0A:F0:00:01:00:00:00:FF:FF:00:00} + +############################################################################### +# UART transport driver options +# +# PORT=1,2,3,... +# BAUD=115200, 19200, 9600, 4800, +# DATABITS=8, 7, 6, 5 +# PARITY="even" | "odd" | "none" +# STOPBITS="0" | "1" | "1.5" | "2" + +#UART_PORT=2 +#UART_BAUD=115200 +#UART_DATABITS=8 +#UART_PARITY="none" +#UART_STOPBITS="1" + +############################################################################### +# Insert a delay in microseconds per byte after a write to NFCC. +# after writing a block of data to the NFCC, delay this an amopunt of time before +# writing next block of data. the delay is calculated as below +# NFC_WRITE_DELAY * (number of byte written) / 1000 milliseconds +# e.g. after 259 bytes is written, delay (259 * 20 / 1000) 5 ms before next write +#NFC_WRITE_DELAY=20 + +############################################################################### +# Maximum Number of Credits to be allowed by the NFCC +# This value overrides what the NFCC specifices allowing the host to have +# the control to work-around transport limitations. If this value does +# not exist or is set to 0, the NFCC will provide the number of credits. +MAX_RF_DATA_CREDITS=1 + +############################################################################### +# Default poll duration (in ms) +# The defualt is 500ms if not set (see nfc_target.h) +#NFA_DM_DISC_DURATION_POLL=333 +############################################################################### +# Antenna Configuration - This data is used when setting 0xC8 config item +# at startup (before discovery is started). If not used, no value is sent. +# +# The settings for this value are documented here: +# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/ +# Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx +# This document is maintained by Paul Forshaw. +# +# The values marked as ?? should be tweaked per antenna or customer/app: +# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04} +# array[0] = 0x20 is length of the payload from array[1] to the end +# array[1] = 0xC8 is PREINIT_DSP_CFG +#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04} + +############################################################################### +# Choose the presence-check algorithm for type-4 tag. If not defined, the default value is 1. +# 0 NFA_RW_PRES_CHK_DEFAULT; Let stack selects an algorithm +# 1 NFA_RW_PRES_CHK_I_BLOCK; ISO-DEP protocol's empty I-block +# 2 NFA_RW_PRES_CHK_RESET; Deactivate to Sleep, then re-activate +# 3 NFA_RW_PRES_CHK_RB_CH0; Type-4 tag protocol's ReadBinary command on channel 0 +# 4 NFA_RW_PRES_CHK_RB_CH3; Type-4 tag protocol's ReadBinary command on channel 3 +PRESENCE_CHECK_ALGORITHM=1 + +############################################################################### +# Force tag polling for the following technology(s). +# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h. +# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | +# NFA_TECHNOLOGY_MASK_F | NFA_TECHNOLOGY_MASK_ISO15693 | +# NFA_TECHNOLOGY_MASK_B_PRIME | NFA_TECHNOLOGY_MASK_KOVIO | +# NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE. +# +# Notable bits: +# NFA_TECHNOLOGY_MASK_A 0x01 /* NFC Technology A */ +# NFA_TECHNOLOGY_MASK_B 0x02 /* NFC Technology B */ +# NFA_TECHNOLOGY_MASK_F 0x04 /* NFC Technology F */ +# NFA_TECHNOLOGY_MASK_ISO15693 0x08 /* Proprietary Technology */ +# NFA_TECHNOLOGY_MASK_KOVIO 0x20 /* Proprietary Technology */ +# NFA_TECHNOLOGY_MASK_A_ACTIVE 0x40 /* NFC Technology A active mode */ +# NFA_TECHNOLOGY_MASK_F_ACTIVE 0x80 /* NFC Technology F active mode */ +POLLING_TECH_MASK=0xEF + +############################################################################### +# Force P2P to only listen for the following technology(s). +# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h. +# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F | +# NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE +# +# Notable bits: +# NFA_TECHNOLOGY_MASK_A 0x01 /* NFC Technology A */ +# NFA_TECHNOLOGY_MASK_F 0x04 /* NFC Technology F */ +# NFA_TECHNOLOGY_MASK_A_ACTIVE 0x40 /* NFC Technology A active mode */ +# NFA_TECHNOLOGY_MASK_F_ACTIVE 0x80 /* NFC Technology F active mode */ +P2P_LISTEN_TECH_MASK=0xC5 + +PRESERVE_STORAGE=0x01 + +############################################################################### +# Override the stack default for NFA_EE_MAX_EE_SUPPORTED set in nfc_target.h. +# The value is set to 3 by default as it assumes we will discover 0xF2, +# 0xF3, and 0xF4. If a platform will exclude and SE, this value can be reduced +# so that the stack will not wait any longer than necessary. + +# Maximum EE supported number +# NXP PN547C2 0x02 +# NXP PN65T 0x03 +# NXP PN548C2 0x02 +# NXP PN66T 0x03 +NFA_MAX_EE_SUPPORTED=0x02 + +############################################################################### +# NCI Hal Module name +NCI_HAL_MODULE="nfc_nci" + +############################################################################## +# Deactivate notification wait time out in seconds used in ETSI Reader mode +# 0 - Infinite wait +#NFA_DM_DISC_NTF_TIMEOUT=0 + +############################################################################### +# AID_MATCHING constants +# AID_MATCHING_EXACT_ONLY 0x00 +# AID_MATCHING_EXACT_OR_PREFIX 0x01 +# AID_MATCHING_PREFIX_ONLY 0x02 +AID_MATCHING_MODE=0x01 + +############################################################################### +# Default Secure Element route id +DEFAULT_OFFHOST_ROUTE=0x02 + +############################################################################### +# Vendor Specific Proprietary Protocol & Discovery Configuration +# Set to 0xFF if unsupported +# byte[0] NCI_PROTOCOL_18092_ACTIVE +# byte[1] NCI_PROTOCOL_B_PRIME +# byte[2] NCI_PROTOCOL_DUAL +# byte[3] NCI_PROTOCOL_15693 +# byte[4] NCI_PROTOCOL_KOVIO +# byte[5] NCI_PROTOCOL_MIFARE +# byte[6] NCI_DISCOVERY_TYPE_POLL_KOVIO +# byte[7] NCI_DISCOVERY_TYPE_POLL_B_PRIME +# byte[8] NCI_DISCOVERY_TYPE_LISTEN_B_PRIME +NFA_PROPRIETARY_CFG={05:FF:FF:06:81:80:70:FF:FF} + +############################################################################### +# Bail out mode +# If set to 1, NFCC is using bail out mode for either Type A or Type B poll. +NFA_POLL_BAIL_OUT_MODE=0x01 diff --git a/pn54x/libnfc-brcm_NCI2_0.conf b/pn54x/libnfc-brcm_NCI2_0.conf new file mode 100644 index 0000000..a4d3290 --- /dev/null +++ b/pn54x/libnfc-brcm_NCI2_0.conf @@ -0,0 +1,407 @@ +###################### Start of libnfc-brcm.conf ####################### + +############################################################################### +# Application options +APPL_TRACE_LEVEL=0xFF +PROTOCOL_TRACE_LEVEL=0xFFFFFFFF + +############################################################################### +# performance measurement +# Change this setting to control how often USERIAL log the performance (throughput) +# data on read/write/poll +# defailt is to log performance dara for every 100 read or write +#REPORT_PERFORMANCE_MEASURE=100 + +############################################################################### +# File used for NFA storage +NFA_STORAGE="/data/nfc" + +############################################################################### +# Snooze Mode Settings +# +# By default snooze mode is enabled. Set SNOOZE_MODE_CFG byte[0] to 0 +# to disable. +# +# If SNOOZE_MODE_CFG is not provided, the default settings are used: +# They are as follows: +# 8 Sleep Mode (0=Disabled 1=UART 8=SPI/I2C) +# 0 Idle Threshold Host +# 0 Idle Threshold HC +# 0 NFC Wake active mode (0=ActiveLow 1=ActiveHigh) +# 1 Host Wake active mode (0=ActiveLow 1=ActiveHigh) +# +#SNOOZE_MODE_CFG={08:00:00:00:01} + +############################################################################### +# Insert a delay in milliseconds after NFC_WAKE and before write to NFCC +#NFC_WAKE_DELAY=20 + +############################################################################### +# Various Delay settings (in ms) used in USERIAL +# POWER_ON_DELAY +# Delay after turning on chip, before writing to transport (default 300) +# PRE_POWER_OFF_DELAY +# Delay after deasserting NFC-Wake before turn off chip (default 0) +# POST_POWER_OFF_DELAY +# Delay after turning off chip, before USERIAL_close returns (default 0) +# +#POWER_ON_DELAY=300 +#PRE_POWER_OFF_DELAY=0 +#POST_POWER_OFF_DELAY=0 + +############################################################################### +# Maximum time (ms) to wait for RESET NTF after setting REG_PU to high +# The default is 1000. +#NFCC_ENABLE_TIMEOUT=0 + +############################################################################### +# LPTD mode configuration +# byte[0] is the length of the remaining bytes in this value +# if set to 0, LPTD params will NOT be sent to NFCC (i.e. disabled). +# byte[1] is the param id it should be set to B9. +# byte[2] is the length of the LPTD parameters +# byte[3] indicates if LPTD is enabled +# if set to 0, LPTD will be disabled (parameters will still be sent). +# byte[4-n] are the LPTD parameters. +# By default, LPTD is enabled and default settings are used. +# See nfc_hal_dm_cfg.c for defaults +#LPTD_CFG={23:B9:21:01:02:FF:FF:04:A0:0F:40:00:80:02:02:10:00:00:00:31:0C:30:00:00:00:00:00:00:00:00:00:00:00:00:00:00} + +############################################################################### +# Startup Configuration (100 bytes maximum) +# +# For the 0xCA parameter, byte[9] (marked by 'AA') is for UICC0, and byte[10] (marked by BB) is +# for UICC1. The values are defined as: +# 0 : UICCx only supports ISO_DEP in low power mode. +# 2 : UICCx only supports Mifare in low power mode. +# 3 : UICCx supports both ISO_DEP and Mifare in low power mode. +# +# AA BB +#NFA_DM_START_UP_CFG={1F:CB:01:01:A5:01:01:CA:14:00:00:00:00:06:E8:03:00:00:00:00:00:00:00:00:00:00:00:00:00:80:01:01} + +############################################################################### +# Startup Vendor Specific Configuration (100 bytes maximum); +# byte[0] TLV total len = 0x5 +# byte[1] NCI_MTS_CMD|NCI_GID_PROP = 0x2f +# byte[2] NCI_MSG_FRAME_LOG = 0x9 +# byte[3] 2 +# byte[4] 0=turn off RF frame logging; 1=turn on +# byte[5] 0=turn off SWP frame logging; 1=turn on +# NFA_DM_START_UP_VSC_CFG={05:2F:09:02:01:01} + +############################################################################### +# Antenna Configuration - This data is used when setting 0xC8 config item +# at startup (before discovery is started). If not used, no value is sent. +# +# The settings for this value are documented here: +# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/ +# Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx +# This document is maintained by Paul Forshaw. +# +# The values marked as ?? should be tweaked per antenna or customer/app: +# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04} +# array[0] = 0x20 is length of the payload from array[1] to the end +# array[1] = 0xC8 is PREINIT_DSP_CFG +#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04} + +############################################################################### +# Configure crystal frequency when internal LPO can't detect the frequency. +#XTAL_FREQUENCY=0 +############################################################################### +# Configure the default Destination Gate used by HCI (the default is 4, which +# is the ETSI loopback gate. +NFA_HCI_DEFAULT_DEST_GATE=0xF0 + +############################################################################### +# Configure the single default SE to use. The default is to use the first +# SE that is detected by the stack. This value might be used when the phone +# supports multiple SE (e.g. 0xF3 and 0xF4) but you want to force it to use +# one of them (e.g. 0xF4). +#ACTIVE_SE=0xF3 + +############################################################################### +# Configure the default NfcA/IsoDep techology and protocol route. Can be +# either a secure element (e.g. 0xF4) or the host (0x00) +#DEFAULT_ISODEP_ROUTE=0x00 + +############################################################################### +# Configure the NFC Extras to open and use a static pipe. If the value is +# not set or set to 0, then the default is use a dynamic pipe based on a +# destination gate (see NFA_HCI_DEFAULT_DEST_GATE). Note there is a value +# for each UICC (where F3="UICC0" and F4="UICC1") +#NFA_HCI_STATIC_PIPE_ID_F3=0x70 +#NFA_HCI_STATIC_PIPE_ID_01=0x19 +NFA_HCI_STATIC_PIPE_ID_C0=0x19 +############################################################################### +# When disconnecting from Oberthur secure element, perform a warm-reset of +# the secure element to deselect the applet. +# The default hex value of the command is 0x3. If this variable is undefined, +# then this feature is not used. +#OBERTHUR_WARM_RESET_COMMAND=0x03 + +############################################################################### +# Force UICC to only listen to the following technology(s). +# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h. +# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F +UICC_LISTEN_TECH_MASK=0x07 + +############################################################################### +# Force HOST listen feature enable or disable. +# 0: Disable +# 1: Enable +HOST_LISTEN_ENABLE=0x01 + +############################################################################### +# Enabling/Disabling Forward functionality +# Disable 0x00 +# Enable 0x01 +NXP_FWD_FUNCTIONALITY_ENABLE=0x01 + +############################################################################### +# Allow UICC to be powered off if there is no traffic. +# Timeout is in ms. If set to 0, then UICC will not be powered off. +#UICC_IDLE_TIMEOUT=30000 +UICC_IDLE_TIMEOUT=0 + +############################################################################### +# AID for Empty Select command +# If specified, this AID will be substituted when an Empty SELECT command is +# detected. The first byte is the length of the AID. Maximum length is 16. +AID_FOR_EMPTY_SELECT={08:A0:00:00:01:51:00:00:00} +############################################################################### +# Maximum Number of Credits to be allowed by the NFCC +# This value overrides what the NFCC specifices allowing the host to have +# the control to work-around transport limitations. If this value does +# not exist or is set to 0, the NFCC will provide the number of credits. +MAX_RF_DATA_CREDITS=1 + +############################################################################### +# This setting allows you to disable registering the T4t Virtual SE that causes +# the NFCC to send PPSE requests to the DH. +# The default setting is enabled (i.e. T4t Virtual SE is registered). +#REGISTER_VIRTUAL_SE=1 + +############################################################################### +# When screen is turned off, specify the desired power state of the controller. +# 0: power-off-sleep state; DEFAULT +# 1: full-power state +# 2: screen-off card-emulation (CE4/CE3/CE1 modes are used) +SCREEN_OFF_POWER_STATE=1 + +############################################################################### +# Firmware patch file +# If the value is not set then patch download is disabled. +#FW_PATCH="/vendor/firmware/bcm2079x_firmware.ncd" + +############################################################################### +# Firmware pre-patch file (sent before the above patch file) +# If the value is not set then pre-patch is not used. +#FW_PRE_PATCH="/vendor/firmware/bcm2079x_pre_firmware.ncd" + +############################################################################### +# Firmware patch format +# 1 = HCD +# 2 = NCD (default) +#NFA_CONFIG_FORMAT=2 + +############################################################################### +# SPD Debug mode +# If set to 1, any failure of downloading a patch will trigger a hard-stop +#SPD_DEBUG=0 + +############################################################################### +# SPD Max Retry Count +# The number of attempts to download a patch before giving up (defualt is 3). +# Note, this resets after a power-cycle. +#SPD_MAX_RETRY_COUNT=3 + +############################################################################### +# transport driver +# +# TRANSPORT_DRIVER=<driver> +# +# where <driver> can be, for example: +# "/dev/ttyS" (UART) +# "/dev/bcmi2cnfc" (I2C) +# "hwtun" (HW Tunnel) +# "/dev/bcmspinfc" (SPI) +# "/dev/btusb0" (BT USB) +#TRANSPORT_DRIVER="/dev/bcm2079x-i2c" + +############################################################################### +# power control driver +# Specify a kernel driver that support ioctl commands to control NFC_EN and +# NFC_WAKE gpio signals. +# +# POWER_CONTRL_DRIVER=<driver> +# where <driver> can be, for example: +# "/dev/nfcpower" +# "/dev/bcmi2cnfc" (I2C) +# "/dev/bcmspinfc" (SPI) +# i2c and spi driver may be used to control NFC_EN and NFC_WAKE signal +#POWER_CONTROL_DRIVER="/dev/bcm2079x-i2c" + +############################################################################### +# I2C transport driver options +# Mako does not support 10-bit I2C addresses +# Revert to 7-bit address +#BCMI2CNFC_ADDRESS=0x77 + +############################################################################### +# I2C transport driver try to read multiple packets in read() if data is available +# remove the comment below to enable this feature +#READ_MULTIPLE_PACKETS=1 + +############################################################################### +# SPI transport driver options +#SPI_NEGOTIATION={0A:F0:00:01:00:00:00:FF:FF:00:00} + +############################################################################### +# UART transport driver options +# +# PORT=1,2,3,... +# BAUD=115200, 19200, 9600, 4800, +# DATABITS=8, 7, 6, 5 +# PARITY="even" | "odd" | "none" +# STOPBITS="0" | "1" | "1.5" | "2" + +#UART_PORT=2 +#UART_BAUD=115200 +#UART_DATABITS=8 +#UART_PARITY="none" +#UART_STOPBITS="1" + +############################################################################### +# Insert a delay in microseconds per byte after a write to NFCC. +# after writing a block of data to the NFCC, delay this an amopunt of time before +# writing next block of data. the delay is calculated as below +# NFC_WRITE_DELAY * (number of byte written) / 1000 milliseconds +# e.g. after 259 bytes is written, delay (259 * 20 / 1000) 5 ms before next write +#NFC_WRITE_DELAY=20 + +############################################################################### +# Maximum Number of Credits to be allowed by the NFCC +# This value overrides what the NFCC specifices allowing the host to have +# the control to work-around transport limitations. If this value does +# not exist or is set to 0, the NFCC will provide the number of credits. +MAX_RF_DATA_CREDITS=1 + +############################################################################### +# Default poll duration (in ms) +# The defualt is 500ms if not set (see nfc_target.h) +#NFA_DM_DISC_DURATION_POLL=333 +############################################################################### +# Antenna Configuration - This data is used when setting 0xC8 config item +# at startup (before discovery is started). If not used, no value is sent. +# +# The settings for this value are documented here: +# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/ +# Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx +# This document is maintained by Paul Forshaw. +# +# The values marked as ?? should be tweaked per antenna or customer/app: +# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04} +# array[0] = 0x20 is length of the payload from array[1] to the end +# array[1] = 0xC8 is PREINIT_DSP_CFG +#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04} + +############################################################################### +# Choose the presence-check algorithm for type-4 tag. If not defined, the default value is 1. +# 0 NFA_RW_PRES_CHK_DEFAULT; Let stack selects an algorithm +# 1 NFA_RW_PRES_CHK_I_BLOCK; ISO-DEP protocol's empty I-block +# 2 NFA_RW_PRES_CHK_RESET; Deactivate to Sleep, then re-activate +# 3 NFA_RW_PRES_CHK_RB_CH0; Type-4 tag protocol's ReadBinary command on channel 0 +# 4 NFA_RW_PRES_CHK_RB_CH3; Type-4 tag protocol's ReadBinary command on channel 3 +# 5 NFA_RW_PRES_CHK_ISO_DEP_NAK; Type - 4 tag protocol iso-dep nak presence check +# command is sent waiting for rsp and ntf. +PRESENCE_CHECK_ALGORITHM=5 + +############################################################################### +# Force tag polling for the following technology(s). +# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h. +# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | +# NFA_TECHNOLOGY_MASK_F | NFA_TECHNOLOGY_MASK_ISO15693 | +# NFA_TECHNOLOGY_MASK_B_PRIME | NFA_TECHNOLOGY_MASK_KOVIO | +#NFA_TECHNOLOGY_MASK_ACTIVE +# +# Notable bits: +# NFA_TECHNOLOGY_MASK_A 0x01 /* NFC Technology A */ +# NFA_TECHNOLOGY_MASK_B 0x02 /* NFC Technology B */ +# NFA_TECHNOLOGY_MASK_F 0x04 /* NFC Technology F */ +# NFA_TECHNOLOGY_MASK_ISO15693 0x08 /* Proprietary Technology */ +# NFA_TECHNOLOGY_MASK_KOVIO 0x20 /* Proprietary Technology */ +# NFA_TECHNOLOGY_MASK_ACTIVE 0x40 /* NFC Technology Active */ +POLLING_TECH_MASK=0x6F + +############################################################################### +# Force P2P to only listen for the following technology(s). +# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h. +# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F | +#NFA_TECHNOLOGY_MASK_ACTIVE +# +# Notable bits: +# NFA_TECHNOLOGY_MASK_A 0x01 /* NFC Technology A */ +# NFA_TECHNOLOGY_MASK_F 0x04 /* NFC Technology F */ +#NFA_TECHNOLOGY_MASK_ACTIVE 0x40 /* NFC Technology Active */ +P2P_LISTEN_TECH_MASK=0x45 + +PRESERVE_STORAGE=0x01 + +############################################################################### +# Override the stack default for NFA_EE_MAX_EE_SUPPORTED set in nfc_target.h. +# The value is set to 3 by default as it assumes we will discover 0xF2, +# 0xF3, and 0xF4. If a platform will exclude and SE, this value can be reduced +# so that the stack will not wait any longer than necessary. + +# Maximum EE supported number +# NXP PN547C2 0x02 +# NXP PN65T 0x03 +# NXP PN548C2 0x02 +# NXP PN66T 0x03 +NFA_MAX_EE_SUPPORTED=0x02 + +############################################################################### +# NCI Hal Module name +NCI_HAL_MODULE="nfc_nci" + +############################################################################## +# Deactivate notification wait time out in seconds used in ETSI Reader mode +# 0 - Infinite wait +#NFA_DM_DISC_NTF_TIMEOUT=0 + +############################################################################### +# AID_MATCHING constants +# AID_MATCHING_EXACT_ONLY 0x00 +# AID_MATCHING_EXACT_OR_PREFIX 0x01 +# AID_MATCHING_PREFIX_ONLY 0x02 +# AID_MATCHING_EXACT_OR_SUBSET_OR_PREFIX 0x03 +AID_MATCHING_MODE=0x03 + +############################################################################### +# Default Secure Element route id +DEFAULT_OFFHOST_ROUTE=0x02 + +############################################################################### +# Vendor Specific Proprietary Protocol & Discovery Configuration +# Set to 0xFF if unsupported +# byte[0] NCI_PROTOCOL_18092_ACTIVE +# byte[1] NCI_PROTOCOL_B_PRIME +# byte[2] NCI_PROTOCOL_DUAL +# byte[3] NCI_PROTOCOL_15693 +# byte[4] NCI_PROTOCOL_KOVIO +# byte[5] NCI_PROTOCOL_MIFARE +# byte[6] NCI_DISCOVERY_TYPE_POLL_KOVIO +# byte[7] NCI_DISCOVERY_TYPE_POLL_B_PRIME +# byte[8] NCI_DISCOVERY_TYPE_LISTEN_B_PRIME +NFA_PROPRIETARY_CFG={05:FF:FF:06:81:80:70:FF:FF} + +############################################################################### +# Bail out mode +# If set to 1, NFCC is using bail out mode for either Type A or Type B poll. +NFA_POLL_BAIL_OUT_MODE=0x01 +############################################################################### +# Enable/Disable Block Route feature. +# Block Route will restrict routing to first matched rule +# Block Route enable 0x01 +# Block Route disable 0x00 +NFA_BLOCK_ROUTE=0x00 diff --git a/pn54x/libnfc-nxp-PN547C2_example.conf b/pn54x/libnfc-nxp-PN547C2_example.conf new file mode 100644 index 0000000..913030f --- /dev/null +++ b/pn54x/libnfc-nxp-PN547C2_example.conf @@ -0,0 +1,224 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x) + +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +# +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn54x" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn547_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 + +NXP_SYS_CLK_SRC_SEL=0x01 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 + +NXP_SYS_CLK_FREQ_SEL=0x00 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 + +NXP_SYS_CLOCK_TO_CFG=0x01 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# Standby enable settings +#NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +#Atonomous Mode +#Enable 0x01 +#Disable 0x00 +NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00 + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +# NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +NXP_CORE_CONF_EXTN={20, 02, 16, 04, + A0, EC, 01, 01, + A0, ED, 01, 01, + A0, 5E, 01, 01, + A0, 0D, 06, 3E, 2D, 15, 88, 15, 00 + } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 + } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 2B, 0D, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 60, 01, 0E, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 + +NXP_DEFAULT_SE=0x02 + +NXP_DEFAULT_NFCEE_TIMEOUT=0x06 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################## +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 + +NXP_NFC_CHIP=0x01 + +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +# CE when Screen state is locked +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 diff --git a/pn54x/libnfc-nxp-PN548AD_example.conf b/pn54x/libnfc-nxp-PN548AD_example.conf new file mode 100644 index 0000000..53121b2 --- /dev/null +++ b/pn54x/libnfc-nxp-PN548AD_example.conf @@ -0,0 +1,271 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x) + +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +# +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn54x" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn548ad_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 + +NXP_SYS_CLK_SRC_SEL=0x02 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 + +NXP_SYS_CLK_FREQ_SEL=0x02 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 + +NXP_SYS_CLOCK_TO_CFG=0x01 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# NFCC Configuration Control +# Allow NFCC to manage RF Config 0x01 +# Don't allow NFCC to manage RF Config 0x00 +NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01} + +############################################################################### +# Standby enable settings +#NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +# NXP TVDD configurations settings +# Allow NFCC to configure External TVDD, There are currently three +#configurations (1, 2 and 3) are supported, out of them only one can be +#supported. + +NXP_EXT_TVDD_CFG=0x01 + +############################################################################### +#config1:SLALM, 3.3V for both RM and CM +NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00} + +############################################################################### +#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM, +#monitoring 5V from DCDC, 4.7V for both RM and CM, DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 64, 0A} + +############################################################################### +#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC, +#DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +NXP_CORE_CONF_EXTN={20, 02, 19, 06, + A0, EC, 01, 01, + A0, ED, 01, 00, + A0, 5E, 01, 01, + A0, 40, 01, 01, + A0, DD, 01, 2D, + A0, 96, 01, 01 + } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 + } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 2E, 0E, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 32, 01, 60, + 38, 01, 01, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 + +NXP_DEFAULT_SE=0x03 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x00 + +############################################################################### +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 + +NXP_NFC_CHIP=0x03 + +############################################################################### +# CE when Screen state is locked +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +#Timeout in secs to get NFCEE Discover notification +NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20 + +NXP_DEFAULT_NFCEE_TIMEOUT=0x06 + +############################################################################### +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A + +############################################################################### +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A diff --git a/pn54x/libnfc-nxp-PN551_example.conf b/pn54x/libnfc-nxp-PN551_example.conf new file mode 100644 index 0000000..ba42b20 --- /dev/null +++ b/pn54x/libnfc-nxp-PN551_example.conf @@ -0,0 +1,273 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x) + +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +# +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn544" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn551_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 + +NXP_SYS_CLK_SRC_SEL=0x02 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 + +NXP_SYS_CLK_FREQ_SEL=0x02 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 + +NXP_SYS_CLOCK_TO_CFG=0x06 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# NFCC Configuration Control +# Allow NFCC to manage RF Config 0x01 +# Don't allow NFCC to manage RF Config 0x00 +NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01} + +############################################################################### +# Standby enable settings +#NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +# NXP TVDD configurations settings +# Allow NFCC to configure External TVDD, There are currently three +#configurations (1, 2 and 3) are supported, out of them only one can be +#supported. + +NXP_EXT_TVDD_CFG=0x01 + +############################################################################### +#config1:SLALM, 3.3V for both RM and CM +NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00} + +############################################################################### +#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM, +#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 24, 08 } + +############################################################################### +#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC, +#DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 40, 0A} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +NXP_CORE_CONF_EXTN={20, 02, 19, 06, + A0, EC, 01, 01, + A0, ED, 01, 00, + A0, 5E, 01, 01, + A0, 40, 01, 01, + A0, DD, 01, 2D, + A0, 96, 01, 01 + } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 + } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 2E, 0E, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 32, 01, 60, + 38, 01, 01, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 + +NXP_DEFAULT_SE=0x03 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x00 + +############################################################################### +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 +#PN551 0x05 +#PN67T 0x06 + +NXP_NFC_CHIP=0x05 + +############################################################################### +# CE when Screen state is locked +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +#Timeout in secs to get NFCEE Discover notification +NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20 + +NXP_DEFAULT_NFCEE_TIMEOUT=0x06 + +############################################################################### +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A + +############################################################################### +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A diff --git a/pn54x/libnfc-nxp-PN553_example.conf b/pn54x/libnfc-nxp-PN553_example.conf new file mode 100644 index 0000000..818e473 --- /dev/null +++ b/pn54x/libnfc-nxp-PN553_example.conf @@ -0,0 +1,447 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547) +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn553" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn553_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 +NXP_SYS_CLK_SRC_SEL=0x02 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 +NXP_SYS_CLK_FREQ_SEL=0x02 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 +NXP_SYS_CLOCK_TO_CFG=0x01 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# NFCC Configuration Control +# Allow NFCC to manage RF Config 0x01 +# Don't allow NFCC to manage RF Config 0x00 +NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01} + +############################################################################### +# Standby enable settings +#NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +# NXP TVDD configurations settings +# Allow NFCC to configure External TVDD, two configurations (1 and 2) supported, +# out of them only one can be configured at a time. +NXP_EXT_TVDD_CFG=0x02 + +############################################################################### +#config1:SLALM, 3.3V for both RM and CM +NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C} + +############################################################################### +#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM, +#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Set configuration optimization decision setting +# Enable = 0x01 +# Disable = 0x00 +NXP_SET_CONFIG_ALWAYS=0x00 + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +# Clock timeout settings A004 +# eSE (SVDD) PWR REQ settings A0F2 +# How eSE connected to PN553 A012 +# UICC2 bit rate A0D1 +# SWP1A interface A0D4 +# DWP intf behavior config, SVDD Load activated by default if set to 0x31 - A037 +NXP_CORE_CONF_EXTN={20, 02, 25, 09, + A0, EC, 01, 01, + A0, ED, 01, 00, + A0, 5E, 01, 01, + A0, 12, 01, 02, + A0, 40, 01, 01, + A0, DD, 01, 2D, + A0, D1, 01, 02, + A0, D4, 01, 01, + A0, 37, 01, 35 + } +# A0, F2, 01, 01, +# A0, 40, 01, 01, +# A0, 41, 01, 02, +# A0, 43, 01, 04, +# A0, 02, 01, 01, +# A0, 03, 01, 11, +# A0, 07, 01, 03, +# A0, 08, 01, 01 +# } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set +# to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set +# to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 2E, 0E, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 32, 01, 60, + 38, 01, 01, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x04 + +NXP_DEFAULT_SE=0x07 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x00 + +############################################################################### +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 +#PN551 0x05 +#PN67T 0x06 +#PN553 0x07 +#PN80T 0x08 +NXP_NFC_CHIP=0x07 + +############################################################################### +# CE when Screen state is locked +# This setting is for DEFAULT_AID_ROUTE, +# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +#Timeout in secs to get NFCEE Discover notification +NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20 + +############################################################################### +NXP_DEFAULT_NFCEE_TIMEOUT=20 + +############################################################################### +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A + +############################################################################### +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################### +#Set the default AID Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_AID_PWR_STATE=0x19 + +############################################################################### +#Set the Mifare Desfire Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_DESFIRE_PWR_STATE=0x1B + +############################################################################### +#Set the Mifare CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_MIFARE_CLT_PWR_STATE=0x1B + +############################################################################### +#Set the Felica CLT route Location : +#This settings will be used when application does not set this parameter +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_FELICA_CLT_ROUTE=0x01 + +############################################################################### +#Set the Felica CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_FELICA_CLT_PWR_STATE=0x1B + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +# P61 interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LS_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 LTSM interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LTSM_DEFAULT_INTERFACE=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A + +############################################################################### +# P61 interface options for JCOP Download +# NFC 0x01 +# SPI 0x02 +NXP_P61_JCOP_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 JCOP OS download options +# FRAMEWORK API BY APPLICATION 0x00 +# AT BOOT_TIME 0x01 +NXP_JCOPDL_AT_BOOT_ENABLE=0x00 + +############################################################################### +# Loader service version +# NFC service checks for LS version 2.0 or 2.1 +# LS2.0 0x20 +# LS2.1 0x21 +# LS2.2 0x22 +# AT NFC service intialization +NXP_LOADER_SERVICE_VERSION=0x22 + +############################################################################### +#Timeout value in milliseconds for NFCC standby mode.The range is between 5000 +#msec to 20000 msec and zero is to disable. +NXP_NFCC_STANDBY_TIMEOUT=20000 + +############################################################################### +#Dynamic RSSI feature enable +# Disable 0x00 +# Enable 0x01 +NXP_AGC_DEBUG_ENABLE=0x00 + +############################################################################### +#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode +# For Technology routing to ESE Technology Mask = 4 +# For ISO-DEP Protocol routing to ESE Mask = 2 +# It can also take TECH|PROTO = 6 +# To ignore the delay set mask to = 0 +NXP_ESE_WIRED_PRT_MASK=0x00 + +############################################################################### +#Virtual Mode UICC and Wired Mode ongoing delay Wired Mode +#For Technology routing to UICC Technology Mask = 4 +#For ISO-DEP Protocol routing to UICC set Mask = 2 +#For Select AID Routing to UICC set Mask = 1 +#It can also take values TECH|PROTO|SELECT_AID = 7 , 6 , 5 ,3 .To ignore delay +#set mask = 0 +NXP_UICC_WIRED_PRT_MASK=0x00 + +############################################################################### +#RF field true delay Wired Mode +# delay wired mode = 1 +# allow wired mode = 0 +NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00 + +############################################################################### +#Config to allow adding aids +#NFC on/off is required after this config +#1 = enabling adding aid to NFCC routing table. +#0 = disabling adding aid to NFCC routing table. +NXP_ENABLE_ADD_AID=0x01 + +############################################################################### +# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal +# JCOP CP TIMEOUT +NXP_CP_TIMEOUT={00, 77} + +############################################################################### +# Enable/Disable checking default proto SE Id +# Disable 0x00 +# Enable 0x01 +NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01 + +############################################################################### +#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE +#Enable/Disable block number checks for china transit use case +#Enable 0x01 +#Disable 0x00 +NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01 + +############################################################################### +# Restrict routing to first matched rule only. +# Blacklist enable 0x01 +# Blacklist disable 0x00 +NXP_PROP_BLACKLIST_ROUTING=0x00 + +############################################################################### +# Timeout value in milliseconds to send response for Felica command received +NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000 + +###############################################################################
\ No newline at end of file diff --git a/pn54x/libnfc-nxp-PN553_example_NCI2_0.conf b/pn54x/libnfc-nxp-PN553_example_NCI2_0.conf new file mode 100644 index 0000000..3dca16e --- /dev/null +++ b/pn54x/libnfc-nxp-PN553_example_NCI2_0.conf @@ -0,0 +1,449 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547) +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn553" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn553_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 +NXP_SYS_CLK_SRC_SEL=0x02 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 +NXP_SYS_CLK_FREQ_SEL=0x02 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 +NXP_SYS_CLOCK_TO_CFG=0x01 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# NFCC Configuration Control +# Allow NFCC to manage RF Config 0x01 +# Don't allow NFCC to manage RF Config 0x00 +NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01} + +############################################################################### +# Standby enable settings +#NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +# NXP TVDD configurations settings +# Allow NFCC to configure External TVDD, two configurations (1 and 2) supported, +# out of them only one can be configured at a time. +NXP_EXT_TVDD_CFG=0x02 + +############################################################################### +#config1:SLALM, 3.3V for both RM and CM +NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C} + +############################################################################### +#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM, +#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Set configuration optimization decision setting +# Enable = 0x01 +# Disable = 0x00 +NXP_SET_CONFIG_ALWAYS=0x00 + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +# Clock timeout settings A004 +# eSE (SVDD) PWR REQ settings A0F2 +# How eSE connected to PN553 A012 +# UICC2 bit rate A0D1 +# SWP1A interface A0D4 +# DWP intf behavior config, SVDD Load activated by default if set to 0x31 - A037 +NXP_CORE_CONF_EXTN={20, 02, 25, 09, + A0, EC, 01, 01, + A0, ED, 01, 00, + A0, 5E, 01, 01, + A0, 12, 01, 02, + A0, 40, 01, 01, + A0, DD, 01, 2D, + A0, D1, 01, 02, + A0, D4, 01, 01, + A0, 37, 01, 35 + } +# A0, F2, 01, 01, +# A0, 40, 01, 01, +# A0, 41, 01, 02, +# A0, 43, 01, 04, +# A0, 02, 01, 01, +# A0, 03, 01, 11, +# A0, 07, 01, 03, +# A0, 08, 01, 01 +# } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set +# to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set +# to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 34, 10, + 85, 01, 01, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 32, 01, 60, + 38, 01, 01, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01, + 68, 01, 00 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x04 + +NXP_DEFAULT_SE=0x07 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x00 + +############################################################################### +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 +#PN551 0x05 +#PN67T 0x06 +#PN553 0x07 +#PN80T 0x08 +NXP_NFC_CHIP=0x07 + +############################################################################### +# CE when Screen state is locked +# This setting is for DEFAULT_AID_ROUTE, +# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +#Timeout in secs to get NFCEE Discover notification +NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20 + +############################################################################### +NXP_DEFAULT_NFCEE_TIMEOUT=20 + +############################################################################### +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A + +############################################################################### +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################### +#Set the default AID Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_AID_PWR_STATE=0x19 + +############################################################################### +#Set the Mifare Desfire Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_DESFIRE_PWR_STATE=0x1B + +############################################################################### +#Set the Mifare CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_MIFARE_CLT_PWR_STATE=0x1B + +############################################################################### +#Set the Felica CLT route Location : +#This settings will be used when application does not set this parameter +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_FELICA_CLT_ROUTE=0x01 + +############################################################################### +#Set the Felica CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_FELICA_CLT_PWR_STATE=0x1B + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +# P61 interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LS_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 LTSM interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LTSM_DEFAULT_INTERFACE=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A + +############################################################################### +# P61 interface options for JCOP Download +# NFC 0x01 +# SPI 0x02 +NXP_P61_JCOP_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 JCOP OS download options +# FRAMEWORK API BY APPLICATION 0x00 +# AT BOOT_TIME 0x01 +NXP_JCOPDL_AT_BOOT_ENABLE=0x00 + +############################################################################### +# Loader service version +# NFC service checks for LS version 2.0 or 2.1 +# LS2.0 0x20 +# LS2.1 0x21 +# LS2.2 0x22 +# AT NFC service intialization +NXP_LOADER_SERVICE_VERSION=0x22 + +############################################################################### +#Timeout value in milliseconds for NFCC standby mode.The range is between 5000 +#msec to 20000 msec and zero is to disable. +NXP_NFCC_STANDBY_TIMEOUT=20000 + +############################################################################### +#Dynamic RSSI feature enable +# Disable 0x00 +# Enable 0x01 +NXP_AGC_DEBUG_ENABLE=0x00 + +############################################################################### +#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode +# For Technology routing to ESE Technology Mask = 4 +# For ISO-DEP Protocol routing to ESE Mask = 2 +# It can also take TECH|PROTO = 6 +# To ignore the delay set mask to = 0 +NXP_ESE_WIRED_PRT_MASK=0x00 + +############################################################################### +#Virtual Mode UICC and Wired Mode ongoing delay Wired Mode +#For Technology routing to UICC Technology Mask = 4 +#For ISO-DEP Protocol routing to UICC set Mask = 2 +#For Select AID Routing to UICC set Mask = 1 +#It can also take values TECH|PROTO|SELECT_AID = 7 , 6 , 5 ,3 .To ignore delay +#set mask = 0 +NXP_UICC_WIRED_PRT_MASK=0x00 + +############################################################################### +#RF field true delay Wired Mode +# delay wired mode = 1 +# allow wired mode = 0 +NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00 + +############################################################################### +#Config to allow adding aids +#NFC on/off is required after this config +#1 = enabling adding aid to NFCC routing table. +#0 = disabling adding aid to NFCC routing table. +NXP_ENABLE_ADD_AID=0x01 + +############################################################################### +# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal +# JCOP CP TIMEOUT +NXP_CP_TIMEOUT={00, 77} + +############################################################################### +# Enable/Disable checking default proto SE Id +# Disable 0x00 +# Enable 0x01 +NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01 + +############################################################################### +#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE +#Enable/Disable block number checks for china transit use case +#Enable 0x01 +#Disable 0x00 +NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01 + +############################################################################### +# Restrict routing to first matched rule only. +# Blacklist enable 0x01 +# Blacklist disable 0x00 +NXP_PROP_BLACKLIST_ROUTING=0x00 + +############################################################################### +# Timeout value in milliseconds to send response for Felica command received +NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000 + +###############################################################################
\ No newline at end of file diff --git a/pn54x/libnfc-nxp-PN65T_example.conf b/pn54x/libnfc-nxp-PN65T_example.conf new file mode 100644 index 0000000..317776c --- /dev/null +++ b/pn54x/libnfc-nxp-PN65T_example.conf @@ -0,0 +1,273 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x) + +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +# +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn54x" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn547_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 + +NXP_SYS_CLK_SRC_SEL=0x01 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 + +NXP_SYS_CLK_FREQ_SEL=0x00 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 + +NXP_SYS_CLOCK_TO_CFG=0x01 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# Standby enable settings +NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +#Atonomous Mode +#Enable 0x01 +#Disable 0x00 +NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00 + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +# NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +NXP_CORE_CONF_EXTN={20, 02, 1A, 05, + A0, EC, 01, 01, + A0, ED, 01, 01, + A0, 5E, 01, 01, + A0, 12, 01, 02, + A0, 0D, 06, 3E, 2D, 15, 88, 15, 00 + } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 + } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 2B, 0D, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 60, 01, 0E, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 + +NXP_DEFAULT_SE=0x02 + +NXP_DEFAULT_NFCEE_TIMEOUT=0x06 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################## +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 + +NXP_NFC_CHIP=0x02 + +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0xFF +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0xFF + +############################################################################### +# CE when Screen state is locked +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +# P61 interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LS_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 LTSM interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LTSM_DEFAULT_INTERFACE=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A + +############################################################################### +# P61 interface options for JCOP Download +# NFC 0x01 +# SPI 0x02 +NXP_P61_JCOP_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 JCOP OS download options +# FRAMEWORK API BY APPLICATION 0x00 +# AT BOOT_TIME 0x01 +NXP_JCOPDL_AT_BOOT_ENABLE=0x00 + +############################################################################### +# Loader service version +# NFC service checks for LS version 2.0 or 2.1 +# LS2.0 0x20 +# LS2.1 0x21 +# LS2.2 0x22 +# AT NFC service intialization +NXP_LOADER_SERVICE_VERSION=0x21 diff --git a/pn54x/libnfc-nxp-PN66T_example.conf b/pn54x/libnfc-nxp-PN66T_example.conf new file mode 100644 index 0000000..d63881f --- /dev/null +++ b/pn54x/libnfc-nxp-PN66T_example.conf @@ -0,0 +1,305 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x) + +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +# +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn54x" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn548ad_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 + +NXP_SYS_CLK_SRC_SEL=0x02 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 + +NXP_SYS_CLK_FREQ_SEL=0x02 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 + +NXP_SYS_CLOCK_TO_CFG=0x01 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# NFCC Configuration Control +# Allow NFCC to manage RF Config 0x01 +# Don't allow NFCC to manage RF Config 0x00 +NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01} + +############################################################################### +# Standby enable settings +NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +# NXP TVDD configurations settings +# Allow NFCC to configure External TVDD, There are currently three +#configurations (1, 2 and 3) are supported, out of them only one can be +#supported. + +NXP_EXT_TVDD_CFG=0x01 + +############################################################################### +#config1:SLALM, 3.3V for both RM and CM +NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00} + +############################################################################### +#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM, +#monitoring 5V from DCDC, 4.7V for both RM and CM, DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 64, 0A} + +############################################################################### +#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC, +#DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +# Clock timeout settings A004 +NXP_CORE_CONF_EXTN={20, 02, 1D, 07, + A0, EC, 01, 01, + A0, ED, 01, 03, + A0, 5E, 01, 01, + A0, 12, 01, 02, + A0, 40, 01, 01, + A0, DD, 01, 2D, + A0, F2, 01, 01 + } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 + } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 2E, 0E, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 32, 01, 60, + 38, 01, 01, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 + +NXP_DEFAULT_SE=0x03 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x00 + +############################################################################### +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 + +NXP_NFC_CHIP=0x04 + +############################################################################### +# CE when Screen state is locked +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +#Timeout in secs to get NFCEE Discover notification +NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20 + +NXP_DEFAULT_NFCEE_TIMEOUT=0x06 + +############################################################################### +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A + +############################################################################### +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +# P61 interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LS_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 LTSM interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LTSM_DEFAULT_INTERFACE=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A + +############################################################################### +# P61 interface options for JCOP Download +# NFC 0x01 +# SPI 0x02 +NXP_P61_JCOP_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 JCOP OS download options +# FRAMEWORK API BY APPLICATION 0x00 +# AT BOOT_TIME 0x01 +NXP_JCOPDL_AT_BOOT_ENABLE=0x00 + +############################################################################### +# Loader service version +# NFC service checks for LS version 2.0 or 2.1 +# LS2.0 0x20 +# LS2.1 0x21 +# LS2.2 0x22 +# AT NFC service intialization +NXP_LOADER_SERVICE_VERSION=0x21 diff --git a/pn54x/libnfc-nxp-PN80T_example.conf b/pn54x/libnfc-nxp-PN80T_example.conf new file mode 100644 index 0000000..45d276c --- /dev/null +++ b/pn54x/libnfc-nxp-PN80T_example.conf @@ -0,0 +1,487 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547) +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn553" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn553_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 +NXP_SYS_CLK_SRC_SEL=0x02 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 +NXP_SYS_CLK_FREQ_SEL=0x02 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 +NXP_SYS_CLOCK_TO_CFG=0x06 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# NFCC Configuration Control +# Allow NFCC to manage RF Config 0x01 +# Don't allow NFCC to manage RF Config 0x00 +NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01} + +############################################################################### +# Standby enable settings +#NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +# NXP TVDD configurations settings +# Allow NFCC to configure External TVDD, two configurations (1 and 2) supported, +# out of them only one can be configured at a time. +NXP_EXT_TVDD_CFG=0x02 + +############################################################################### +#config1:SLALM, 3.3V for both RM and CM +NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C} + +############################################################################### +#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM, +#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Set configuration optimization decision setting +# Enable = 0x01 +# Disable = 0x00 +NXP_SET_CONFIG_ALWAYS=0x00 + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +# Clock timeout settings A004 +# eSE (SVDD) PWR REQ settings A0F2 +# Window size A0D8 +# DWP Speed A0D5 +# How eSE connected to PN553 A012 +# UICC2 bit rate A0D1 +# SWP1A interface A0D4 +# DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037 +NXP_CORE_CONF_EXTN={20, 02, 29, 0A, + A0, EC, 01, 01, + A0, ED, 01, 01, + A0, 5E, 01, 01, + A0, 12, 01, 02, + A0, 40, 01, 01, + A0, D1, 01, 02, + A0, D4, 01, 01, + A0, 37, 01, 35, + A0, D8, 01, 02, + A0, D5, 01, 0A + } +# A0, F2, 01, 01, +# A0, 40, 01, 01, +# A0, 41, 01, 02, +# A0, 43, 01, 04, +# A0, 02, 01, 01, +# A0, 03, 01, 11, +# A0, 07, 01, 03, +# A0, 08, 01, 01 +# } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set +# to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set +# to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 2E, 0E, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 32, 01, 60, + 38, 01, 01, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x04 +NXP_DEFAULT_SE=0x07 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x00 + +############################################################################### +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 +#PN551 0x05 +#PN67T 0x06 +#PN553 0x07 +#PN80T 0x08 +NXP_NFC_CHIP=0x08 + +############################################################################### +# CE when Screen state is locked +# This setting is for DEFAULT_AID_ROUTE, +# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +#Timeout in secs to get NFCEE Discover notification +NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20 + +############################################################################### +NXP_DEFAULT_NFCEE_TIMEOUT=20 + +############################################################################### +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A + +############################################################################### +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################### +#Set the Felica CLT route Location : +#This settings will be used when application does not set this parameter +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_FELICA_CLT_ROUTE=0x01 + +############################################################################### +#Set the default AID Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_AID_PWR_STATE=0x19 + +############################################################################### +#Set the Mifare Desfire Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_DESFIRE_PWR_STATE=0x1B + +############################################################################### +#Set the Mifare CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_MIFARE_CLT_PWR_STATE=0x1B + +############################################################################### +#Set the Felica CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_FELICA_CLT_PWR_STATE=0x1B + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +# P61 interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LS_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 LTSM interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LTSM_DEFAULT_INTERFACE=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A + +############################################################################### +# P61 interface options for JCOP Download +# NFC 0x01 +# SPI 0x02 +NXP_P61_JCOP_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 JCOP OS download options +# FRAMEWORK API BY APPLICATION 0x00 +# AT BOOT_TIME 0x01 +NXP_JCOPDL_AT_BOOT_ENABLE=0x00 + +############################################################################### +# Loader service version +# NFC service checks for LS version 2.0 or 2.1 +# LS2.0 0x20 +# LS2.1 0x21 +# LS2.2 0x22 +# AT NFC service intialization +NXP_LOADER_SERVICE_VERSION=0x22 + +############################################################################### +#Timeout value in milliseconds for NFCC standby mode.The range is between 5000 +#msec to 20000 msec and zero is to disable. +NXP_NFCC_STANDBY_TIMEOUT=20000 + +############################################################################### +#Dynamic RSSI feature enable +# Disable 0x00 +# Enable 0x01 +NXP_AGC_DEBUG_ENABLE=0x00 + +############################################################################### +#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode +# For Technology routing to ESE Technology Mask = 4 +# For ISO-DEP Protocol routing to ESE Mask = 2 +# It can also take TECH|PROTO = 6 +# To ignore the delay set mask to = 0 +NXP_ESE_WIRED_PRT_MASK=0x00 + +############################################################################### +#Virtual Mode UICC and Wired Mode ongoing delay Wired Mode +#For Technology routing to UICC Technology Mask = 4 +#For ISO-DEP Protocol routing to UICC set Mask = 2 +#For Select AID Routing to UICC set Mask = 1 +#It can also take values TECH|PROTO|SELECT_AID = 7 , 6 , 5 ,3 .To ignore delay +#set mask = 0 +NXP_UICC_WIRED_PRT_MASK=0x00 + +################################################################################ +#RF field true delay Wired Mode +# delay wired mode = 1 +# allow wired mode = 0 +NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00 + +############################################################################### +#Config to allow adding aids +#NFC on/off is required after this config +#1 = enabling adding aid to NFCC routing table. +#0 = disabling adding aid to NFCC routing table. +NXP_ENABLE_ADD_AID=0x01 + +############################################################################### +# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal +# JCOP CP TIMEOUT +NXP_CP_TIMEOUT={00, 77} + +############################################################################### +# Enable/Disable checking default proto SE Id +# Disable 0x00 +# Enable 0x01 +NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01 + +############################################################################### +#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE +#Enable/Disable block number checks for china transit use case +#Enable 0x01 +#Disable 0x00 +NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01 + +############################################################################### +# Wired mode resume timeout vaule in wired mode resume feature enable +# DWP resume time out in ms( 4 bytes hex value and LSB first) +#example 1000 = 0x03E8 +#exmaple 2000 = 0x07D0 +#example 500 = 0x01F4 +NXP_WIREDMODE_RESUME_TIMEOUT={E8,03,00,00} +############################################################################### +# Power to eSE is controlled by DH or PMU depending on following configurations +#define DH_PWR_CONTROL 1 +#define PMU_PWR_CONTROL 2 +NXP_ESE_POWER_DH_CONTROL=1 + +############################################################################### +# Timeout value in milliseconds for wired mode resume after RF field event timeout +NXP_NFCC_RF_FIELD_EVENT_TIMEOUT=3000 + +############################################################################### +# NXP PMU Support configuration is sent if PMU_PWR_CONTROL is configured +# External PMU available in phone ON and phone OFF case if NXP_ESE_POWER_EXT_PMU=1 +# External PMU available only in phone ON case if NXP_ESE_POWER_EXT_PMU=2 +NXP_ESE_POWER_EXT_PMU=2 + +############################################################################### +# Whether to allow wired mode in desfire and mifare CLT +# Disable 0x00 +# Enable 0x01 +NXP_ALLOW_WIRED_IN_MIFARE_DESFIRE_CLT=0x00 + +############################################################################### +# Restrict routing to first matched rule only. +# Blacklist enable 0x01 +# Blacklist disable 0x00 +NXP_PROP_BLACKLIST_ROUTING=0x00 + +############################################################################### +# Send DWP interface reset command as part of SE open +# Disable 0x00 +# Enable 0x01 +NXP_DWP_INTF_RESET_ENABLE=0x01 + +############################################################################### +# Timeout value in milliseconds for JCOP OS download to complete +OS_DOWNLOAD_TIMEOUT_VALUE=60000 + +############################################################################### +# Timeout value in milliseconds to send response for Felica command received +NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000 + +###############################################################################
\ No newline at end of file diff --git a/pn54x/libnfc-nxp-PN80T_example_NCI2_0.conf b/pn54x/libnfc-nxp-PN80T_example_NCI2_0.conf new file mode 100644 index 0000000..1f64ec7 --- /dev/null +++ b/pn54x/libnfc-nxp-PN80T_example_NCI2_0.conf @@ -0,0 +1,488 @@ +## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547) +## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547) +############################################################################### +# Application options +# Logging Levels +# NXPLOG_DEFAULT_LOGLEVEL 0x01 +# ANDROID_LOG_DEBUG 0x03 +# ANDROID_LOG_WARN 0x02 +# ANDROID_LOG_ERROR 0x01 +# ANDROID_LOG_SILENT 0x00 +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 + +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/pn553" + +############################################################################### +# Extension for Mifare reader enable +MIFARE_READER_ENABLE=0x01 + +############################################################################### +# Vzw Feature enable +VZW_FEATURE_ENABLE=0x01 + +############################################################################### +# File name for Firmware +NXP_FW_NAME="libpn553_fw.so" + +############################################################################### +# System clock source selection configuration +#define CLK_SRC_XTAL 1 +#define CLK_SRC_PLL 2 +NXP_SYS_CLK_SRC_SEL=0x02 + +############################################################################### +# System clock frequency selection configuration +#define CLK_FREQ_13MHZ 1 +#define CLK_FREQ_19_2MHZ 2 +#define CLK_FREQ_24MHZ 3 +#define CLK_FREQ_26MHZ 4 +#define CLK_FREQ_38_4MHZ 5 +#define CLK_FREQ_52MHZ 6 +NXP_SYS_CLK_FREQ_SEL=0x02 + +############################################################################### +# The timeout value to be used for clock request acknowledgment +# min value = 0x01 to max = 0x06 +NXP_SYS_CLOCK_TO_CFG=0x06 + +############################################################################### +# NXP proprietary settings +NXP_ACT_PROP_EXTN={2F, 02, 00} + +############################################################################### +# NFC forum profile settings +NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00} + +############################################################################### +# NFCC Configuration Control +# Allow NFCC to manage RF Config 0x01 +# Don't allow NFCC to manage RF Config 0x00 +NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01} + +############################################################################### +# Standby enable settings +#NXP_CORE_STANDBY={2F, 00, 01, 01} + +############################################################################### +# NXP TVDD configurations settings +# Allow NFCC to configure External TVDD, two configurations (1 and 2) supported, +# out of them only one can be configured at a time. +NXP_EXT_TVDD_CFG=0x02 + +############################################################################### +#config1:SLALM, 3.3V for both RM and CM +NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C} + +############################################################################### +#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM, +#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms +NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_1={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_2={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_3={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_4={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_5={ +#} + +############################################################################### +# NXP RF configuration ALM/PLM settings +# This section needs to be updated with the correct values based on the platform +#NXP_RF_CONF_BLK_6={ +#} + +############################################################################### +# Set configuration optimization decision setting +# Enable = 0x01 +# Disable = 0x00 +NXP_SET_CONFIG_ALWAYS=0x00 + +############################################################################### +# Core configuration extensions +# It includes +# Wired mode settings A0ED, A0EE +# Tag Detector A040, A041, A043 +# Low Power mode A007 +# Clock settings A002, A003 +# PbF settings A008 +# Clock timeout settings A004 +# eSE (SVDD) PWR REQ settings A0F2 +# Window size A0D8 +# DWP Speed A0D5 +# How eSE connected to PN553 A012 +# UICC2 bit rate A0D1 +# SWP1A interface A0D4 +# DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037 +NXP_CORE_CONF_EXTN={20, 02, 29, 0A, + A0, EC, 01, 01, + A0, ED, 01, 01, + A0, 5E, 01, 01, + A0, 12, 01, 02, + A0, 40, 01, 01, + A0, D1, 01, 02, + A0, D4, 01, 01, + A0, 37, 01, 35, + A0, D8, 01, 02, + A0, D5, 01, 0A + } +# A0, F2, 01, 01, +# A0, 40, 01, 01, +# A0, 41, 01, 02, +# A0, 43, 01, 04, +# A0, 02, 01, 01, +# A0, 03, 01, 11, +# A0, 07, 01, 03, +# A0, 08, 01, 01 +# } + +############################################################################### +# Core configuration rf field filter settings to enable set to 01 to disable set +# to 00 last bit +NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 } + +############################################################################### +# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set +# to 0x00 +NXP_I2C_FRAGMENTATION_ENABLED=0x00 + +############################################################################### +# Core configuration settings +NXP_CORE_CONF={ 20, 02, 31, 0F, + 85, 01, 01, + 28, 01, 00, + 21, 01, 00, + 30, 01, 08, + 31, 01, 03, + 32, 01, 60, + 38, 01, 01, + 33, 04, 01, 02, 03, 04, + 54, 01, 06, + 50, 01, 02, + 5B, 01, 00, + 80, 01, 01, + 81, 01, 01, + 82, 01, 0E, + 18, 01, 01 + } + +############################################################################### +# Mifare Classic Key settings +#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5, +# A0, 52, 06, D3, F7, D3, F7, D3, F7, +# A0, 53, 06, FF, FF, FF, FF, FF, FF, +# A0, 54, 06, 00, 00, 00, 00, 00, 00} + +############################################################################### +# Default SE Options +# No secure element 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x04 +NXP_DEFAULT_SE=0x07 + +############################################################################### +#Enable SWP full power mode when phone is power off +NXP_SWP_FULL_PWR_ON=0x00 + +############################################################################### +#### Select the CHIP #### +#PN547C2 0x01 +#PN65T 0x02 +#PN548AD 0x03 +#PN66T 0x04 +#PN551 0x05 +#PN67T 0x06 +#PN553 0x07 +#PN80T 0x08 +NXP_NFC_CHIP=0x08 + +############################################################################### +# CE when Screen state is locked +# This setting is for DEFAULT_AID_ROUTE, +# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE +# Disable 0x00 +# Enable 0x01 +NXP_CE_ROUTE_STRICT_DISABLE=0x01 + +############################################################################### +#Timeout in secs to get NFCEE Discover notification +NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20 + +############################################################################### +NXP_DEFAULT_NFCEE_TIMEOUT=20 + +############################################################################### +#Timeout in secs +NXP_SWP_RD_START_TIMEOUT=0x0A + +############################################################################### +#Timeout in secs +NXP_SWP_RD_TAG_OP_TIMEOUT=0x01 + +############################################################################### +#Set the default AID route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_AID_ROUTE=0x00 + +############################################################################### +#Set the Mifare Desfire route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_DESFIRE_ROUTE=0x02 + +############################################################################### +#Set the Mifare CLT route Location : +#This settings will be used when application does not set this parameter +# host 0x00 +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_MIFARE_CLT_ROUTE=0x02 + +############################################################################### +#Set the Felica CLT route Location : +#This settings will be used when application does not set this parameter +# eSE 0x01 +# UICC 0x02 +# UICC2 0x03 +DEFAULT_FELICA_CLT_ROUTE=0x01 + +############################################################################### +#Set the default AID Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_AID_PWR_STATE=0x19 + +############################################################################### +#Set the Mifare Desfire Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_DESFIRE_PWR_STATE=0x1B + +############################################################################### +#Set the Mifare CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_MIFARE_CLT_PWR_STATE=0x1B + +############################################################################### +#Set the Felica CLT Power state : +#This settings will be used when application does not set this parameter +# bit pos 0 = Switch On +# bit pos 1 = Switch Off +# bit pos 2 = Battery Off +# bit pos 3 = Screen Lock +# bit pos 4 = Screen Off +DEFAULT_FELICA_CLT_PWR_STATE=0x1B + +############################################################################### +# AID Matching platform options +# AID_MATCHING_L 0x01 +# AID_MATCHING_K 0x02 +AID_MATCHING_PLATFORM=0x01 + +############################################################################### +# P61 interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LS_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 LTSM interface options +# NFC 0x01 +# SPI 0x02 +NXP_P61_LTSM_DEFAULT_INTERFACE=0x01 + +############################################################################### +#CHINA_TIANJIN_RF_SETTING +#Enable 0x01 +#Disable 0x00 +NXP_CHINA_TIANJIN_RF_ENABLED=0x01 + +############################################################################### +#SWP_SWITCH_TIMEOUT_SETTING +# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60]. +# Timeout in milliseconds, for example +# No Timeout 0x00 +# 10 millisecond timeout 0x0A +NXP_SWP_SWITCH_TIMEOUT=0x0A + +############################################################################### +# P61 interface options for JCOP Download +# NFC 0x01 +# SPI 0x02 +NXP_P61_JCOP_DEFAULT_INTERFACE=0x01 + +############################################################################### +# P61 JCOP OS download options +# FRAMEWORK API BY APPLICATION 0x00 +# AT BOOT_TIME 0x01 +NXP_JCOPDL_AT_BOOT_ENABLE=0x00 + +############################################################################### +# Loader service version +# NFC service checks for LS version 2.0 or 2.1 +# LS2.0 0x20 +# LS2.1 0x21 +# LS2.2 0x22 +# AT NFC service intialization +NXP_LOADER_SERVICE_VERSION=0x22 + +############################################################################### +#Timeout value in milliseconds for NFCC standby mode.The range is between 5000 +#msec to 20000 msec and zero is to disable. +NXP_NFCC_STANDBY_TIMEOUT=20000 + +############################################################################### +#Dynamic RSSI feature enable +# Disable 0x00 +# Enable 0x01 +NXP_AGC_DEBUG_ENABLE=0x00 + +############################################################################### +#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode +# For Technology routing to ESE Technology Mask = 4 +# For ISO-DEP Protocol routing to ESE Mask = 2 +# It can also take TECH|PROTO = 6 +# To ignore the delay set mask to = 0 +NXP_ESE_WIRED_PRT_MASK=0x00 + +############################################################################### +#Virtual Mode UICC and Wired Mode ongoing delay Wired Mode +#For Technology routing to UICC Technology Mask = 4 +#For ISO-DEP Protocol routing to UICC set Mask = 2 +#For Select AID Routing to UICC set Mask = 1 +#It can also take values TECH|PROTO|SELECT_AID = 7 , 6 , 5 ,3 .To ignore delay +#set mask = 0 +NXP_UICC_WIRED_PRT_MASK=0x00 + +################################################################################ +#RF field true delay Wired Mode +# delay wired mode = 1 +# allow wired mode = 0 +NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00 + +############################################################################### +#Config to allow adding aids +#NFC on/off is required after this config +#1 = enabling adding aid to NFCC routing table. +#0 = disabling adding aid to NFCC routing table. +NXP_ENABLE_ADD_AID=0x01 + +############################################################################### +# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal +# JCOP CP TIMEOUT +NXP_CP_TIMEOUT={00, 77} + +############################################################################### +# Enable/Disable checking default proto SE Id +# Disable 0x00 +# Enable 0x01 +NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01 + +############################################################################### +#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE +#Enable/Disable block number checks for china transit use case +#Enable 0x01 +#Disable 0x00 +NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01 + +############################################################################### +# Wired mode resume timeout vaule in wired mode resume feature enable +# DWP resume time out in ms( 4 bytes hex value and LSB first) +#example 1000 = 0x03E8 +#exmaple 2000 = 0x07D0 +#example 500 = 0x01F4 +NXP_WIREDMODE_RESUME_TIMEOUT={E8,03,00,00} +############################################################################### +# Power to eSE is controlled by DH or PMU depending on following configurations +#define DH_PWR_CONTROL 1 +#define PMU_PWR_CONTROL 2 +NXP_ESE_POWER_DH_CONTROL=1 + +############################################################################### +# Timeout value in milliseconds for wired mode resume after RF field event timeout +NXP_NFCC_RF_FIELD_EVENT_TIMEOUT=3000 + +############################################################################### +# NXP PMU Support configuration is sent if PMU_PWR_CONTROL is configured +# External PMU available in phone ON and phone OFF case if NXP_ESE_POWER_EXT_PMU=1 +# External PMU available only in phone ON case if NXP_ESE_POWER_EXT_PMU=2 +NXP_ESE_POWER_EXT_PMU=2 + +############################################################################### +# Whether to allow wired mode in desfire and mifare CLT +# Disable 0x00 +# Enable 0x01 +NXP_ALLOW_WIRED_IN_MIFARE_DESFIRE_CLT=0x00 + +############################################################################### +# Restrict routing to first matched rule only. +# Blacklist enable 0x01 +# Blacklist disable 0x00 +NXP_PROP_BLACKLIST_ROUTING=0x00 + +############################################################################### +# Send DWP interface reset command as part of SE open +# Disable 0x00 +# Enable 0x01 +NXP_DWP_INTF_RESET_ENABLE=0x01 + +############################################################################### +# Timeout value in milliseconds for JCOP OS download to complete +OS_DOWNLOAD_TIMEOUT_VALUE=60000 + +############################################################################### +# Timeout value in milliseconds to send response for Felica command received +NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000 + +###############################################################################
\ No newline at end of file diff --git a/pn54x/log/phNxpLog.c b/pn54x/log/phNxpLog.c new file mode 100644 index 0000000..49d6911 --- /dev/null +++ b/pn54x/log/phNxpLog.c @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <string.h> +#if !defined(NXPLOG__H_INCLUDED) +#include "phNxpConfig.h" +#include "phNxpLog.h" +#endif +#include <cutils/properties.h> + +const char* NXPLOG_ITEM_EXTNS = "NxpExtns"; +const char* NXPLOG_ITEM_NCIHAL = "NxpHal"; +const char* NXPLOG_ITEM_NCIX = "NxpNciX"; +const char* NXPLOG_ITEM_NCIR = "NxpNciR"; +const char* NXPLOG_ITEM_FWDNLD = "NxpFwDnld"; +const char* NXPLOG_ITEM_TML = "NxpTml"; + +#ifdef NXP_HCI_REQ +const char* NXPLOG_ITEM_HCPX = "NxpHcpX"; +const char* NXPLOG_ITEM_HCPR = "NxpHcpR"; +#endif /*NXP_HCI_REQ*/ + +/* global log level structure */ +nci_log_level_t gLog_level; + +/******************************************************************************* + * + * Function phNxpLog_SetGlobalLogLevel + * + * Description Sets the global log level for all modules. + * This value is set by Android property + *nfc.nxp_log_level_global. + * If value can be overridden by module log level. + * + * Returns The value of global log level + * + ******************************************************************************/ +static uint8_t phNxpLog_SetGlobalLogLevel(void) { + uint8_t level = NXPLOG_DEFAULT_LOGLEVEL; + unsigned long num = 0; + char valueStr[PROPERTY_VALUE_MAX] = {0}; + + int len = property_get(PROP_NAME_NXPLOG_GLOBAL_LOGLEVEL, valueStr, ""); + if (len > 0) { + /* let Android property override .conf variable */ + sscanf(valueStr, "%lu", &num); + level = (unsigned char)num; + } + memset(&gLog_level, level, sizeof(nci_log_level_t)); + return level; +} + +/******************************************************************************* + * + * Function phNxpLog_SetHALLogLevel + * + * Description Sets the HAL layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetHALLogLevel(uint8_t level) { + unsigned long num = 0; + int len; + char valueStr[PROPERTY_VALUE_MAX] = {0}; + + if (GetNxpNumValue(NAME_NXPLOG_HAL_LOGLEVEL, &num, sizeof(num))) { + gLog_level.hal_log_level = + (level > (unsigned char)num) ? level : (unsigned char)num; + ; + } + + len = property_get(PROP_NAME_NXPLOG_HAL_LOGLEVEL, valueStr, ""); + if (len > 0) { + /* let Android property override .conf variable */ + sscanf(valueStr, "%lu", &num); + gLog_level.hal_log_level = (unsigned char)num; + } +} + +/******************************************************************************* + * + * Function phNxpLog_SetExtnsLogLevel + * + * Description Sets the Extensions layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetExtnsLogLevel(uint8_t level) { + unsigned long num = 0; + int len; + char valueStr[PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue(NAME_NXPLOG_EXTNS_LOGLEVEL, &num, sizeof(num))) { + gLog_level.extns_log_level = + (level > (unsigned char)num) ? level : (unsigned char)num; + ; + } + + len = property_get(PROP_NAME_NXPLOG_EXTNS_LOGLEVEL, valueStr, ""); + if (len > 0) { + /* let Android property override .conf variable */ + sscanf(valueStr, "%lu", &num); + gLog_level.extns_log_level = (unsigned char)num; + } +} + +/******************************************************************************* + * + * Function phNxpLog_SetTmlLogLevel + * + * Description Sets the Tml layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetTmlLogLevel(uint8_t level) { + unsigned long num = 0; + int len; + char valueStr[PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue(NAME_NXPLOG_TML_LOGLEVEL, &num, sizeof(num))) { + gLog_level.tml_log_level = + (level > (unsigned char)num) ? level : (unsigned char)num; + ; + } + + len = property_get(PROP_NAME_NXPLOG_TML_LOGLEVEL, valueStr, ""); + if (len > 0) { + /* let Android property override .conf variable */ + sscanf(valueStr, "%lu", &num); + gLog_level.tml_log_level = (unsigned char)num; + } +} + +/******************************************************************************* + * + * Function phNxpLog_SetDnldLogLevel + * + * Description Sets the FW download layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetDnldLogLevel(uint8_t level) { + unsigned long num = 0; + int len; + char valueStr[PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue(NAME_NXPLOG_FWDNLD_LOGLEVEL, &num, sizeof(num))) { + gLog_level.dnld_log_level = + (level > (unsigned char)num) ? level : (unsigned char)num; + ; + } + + len = property_get(PROP_NAME_NXPLOG_FWDNLD_LOGLEVEL, valueStr, ""); + if (len > 0) { + /* let Android property override .conf variable */ + sscanf(valueStr, "%lu", &num); + gLog_level.dnld_log_level = (unsigned char)num; + } +} + +/******************************************************************************* + * + * Function phNxpLog_SetNciTxLogLevel + * + * Description Sets the NCI transaction layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetNciTxLogLevel(uint8_t level) { + unsigned long num = 0; + int len; + char valueStr[PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue(NAME_NXPLOG_NCIX_LOGLEVEL, &num, sizeof(num))) { + gLog_level.ncix_log_level = + (level > (unsigned char)num) ? level : (unsigned char)num; + } + if (GetNxpNumValue(NAME_NXPLOG_NCIR_LOGLEVEL, &num, sizeof(num))) { + gLog_level.ncir_log_level = + (level > (unsigned char)num) ? level : (unsigned char)num; + ; + } + + len = property_get(PROP_NAME_NXPLOG_NCI_LOGLEVEL, valueStr, ""); + if (len > 0) { + /* let Android property override .conf variable */ + sscanf(valueStr, "%lu", &num); + gLog_level.ncix_log_level = (unsigned char)num; + gLog_level.ncir_log_level = (unsigned char)num; + } +} + +/****************************************************************************** + * Function phNxpLog_InitializeLogLevel + * + * Description Initialize and get log level of module from libnfc-nxp.conf + *or + * Android runtime properties. + * The Android property nfc.nxp_global_log_level is to + * define log level for all modules. Modules log level will + *overwide global level. + * The Android property will overwide the level + * in libnfc-nxp.conf + * + * Android property names: + * nfc.nxp_log_level_global * defines log level for all + *modules + * nfc.nxp_log_level_extns * extensions module log + * nfc.nxp_log_level_hal * Hal module log + * nfc.nxp_log_level_dnld * firmware download module + *log + * nfc.nxp_log_level_tml * TML module log + * nfc.nxp_log_level_nci * NCI transaction log + * + * Log Level values: + * NXPLOG_LOG_SILENT_LOGLEVEL 0 * No trace to show + * NXPLOG_LOG_ERROR_LOGLEVEL 1 * Show Error trace + *only + * NXPLOG_LOG_WARN_LOGLEVEL 2 * Show Warning + *trace and Error trace + * NXPLOG_LOG_DEBUG_LOGLEVEL 3 * Show all traces + * + * Returns void + * + ******************************************************************************/ +void phNxpLog_InitializeLogLevel(void) { + uint8_t level = phNxpLog_SetGlobalLogLevel(); + phNxpLog_SetHALLogLevel(level); + phNxpLog_SetExtnsLogLevel(level); + phNxpLog_SetTmlLogLevel(level); + phNxpLog_SetDnldLogLevel(level); + phNxpLog_SetNciTxLogLevel(level); + + ALOGD( + "%s: global =%u, Fwdnld =%u, extns =%u, \ + hal =%u, tml =%u, ncir =%u, \ + ncix =%u", + __func__, gLog_level.global_log_level, gLog_level.dnld_log_level, + gLog_level.extns_log_level, gLog_level.hal_log_level, + gLog_level.tml_log_level, gLog_level.ncir_log_level, + gLog_level.ncix_log_level); +} diff --git a/pn54x/log/phNxpLog.h b/pn54x/log/phNxpLog.h new file mode 100644 index 0000000..5037a4c --- /dev/null +++ b/pn54x/log/phNxpLog.h @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(NXPLOG__H_INCLUDED) +#define NXPLOG__H_INCLUDED + +#include <log/log.h> + +typedef struct nci_log_level { + uint8_t global_log_level; + uint8_t extns_log_level; + uint8_t hal_log_level; + uint8_t dnld_log_level; + uint8_t tml_log_level; + uint8_t ncix_log_level; + uint8_t ncir_log_level; +} nci_log_level_t; + +/* global log level Ref */ +extern nci_log_level_t gLog_level; + +/* define log module included when compile */ +#define ENABLE_EXTNS_TRACES TRUE +#define ENABLE_HAL_TRACES TRUE +#define ENABLE_TML_TRACES TRUE +#define ENABLE_FWDNLD_TRACES TRUE +#define ENABLE_NCIX_TRACES TRUE +#define ENABLE_NCIR_TRACES TRUE + +#define ENABLE_HCPX_TRACES FALSE +#define ENABLE_HCPR_TRACES FALSE + +/* ####################### Set the log module name in .conf file + * ########################## */ +#define NAME_NXPLOG_EXTNS_LOGLEVEL "NXPLOG_EXTNS_LOGLEVEL" +#define NAME_NXPLOG_HAL_LOGLEVEL "NXPLOG_NCIHAL_LOGLEVEL" +#define NAME_NXPLOG_NCIX_LOGLEVEL "NXPLOG_NCIX_LOGLEVEL" +#define NAME_NXPLOG_NCIR_LOGLEVEL "NXPLOG_NCIR_LOGLEVEL" +#define NAME_NXPLOG_FWDNLD_LOGLEVEL "NXPLOG_FWDNLD_LOGLEVEL" +#define NAME_NXPLOG_TML_LOGLEVEL "NXPLOG_TML_LOGLEVEL" + +/* ####################### Set the log module name by Android property + * ########################## */ +#define PROP_NAME_NXPLOG_GLOBAL_LOGLEVEL "nfc.nxp_log_level_global" +#define PROP_NAME_NXPLOG_EXTNS_LOGLEVEL "nfc.nxp_log_level_extns" +#define PROP_NAME_NXPLOG_HAL_LOGLEVEL "nfc.nxp_log_level_hal" +#define PROP_NAME_NXPLOG_NCI_LOGLEVEL "nfc.nxp_log_level_nci" +#define PROP_NAME_NXPLOG_FWDNLD_LOGLEVEL "nfc.nxp_log_level_dnld" +#define PROP_NAME_NXPLOG_TML_LOGLEVEL "nfc.nxp_log_level_tml" + +/* ####################### Set the logging level for EVERY COMPONENT here + * ######################## :START: */ +#define NXPLOG_LOG_SILENT_LOGLEVEL 0x00 +#define NXPLOG_LOG_ERROR_LOGLEVEL 0x01 +#define NXPLOG_LOG_WARN_LOGLEVEL 0x02 +#define NXPLOG_LOG_DEBUG_LOGLEVEL 0x03 +/* ####################### Set the default logging level for EVERY COMPONENT + * here ########################## :END: */ + +/* The Default log level for all the modules. */ +#define NXPLOG_DEFAULT_LOGLEVEL NXPLOG_LOG_ERROR_LOGLEVEL + +/* ################################################################################################################ + */ +/* ############################################### Component Names + * ################################################ */ +/* ################################################################################################################ + */ + +extern const char* NXPLOG_ITEM_EXTNS; /* Android logging tag for NxpExtns */ +extern const char* NXPLOG_ITEM_NCIHAL; /* Android logging tag for NxpNciHal */ +extern const char* NXPLOG_ITEM_NCIX; /* Android logging tag for NxpNciX */ +extern const char* NXPLOG_ITEM_NCIR; /* Android logging tag for NxpNciR */ +extern const char* NXPLOG_ITEM_FWDNLD; /* Android logging tag for NxpFwDnld */ +extern const char* NXPLOG_ITEM_TML; /* Android logging tag for NxpTml */ + +#ifdef NXP_HCI_REQ +extern const char* NXPLOG_ITEM_HCPX; /* Android logging tag for NxpHcpX */ +extern const char* NXPLOG_ITEM_HCPR; /* Android logging tag for NxpHcpR */ +#endif /*NXP_HCI_REQ*/ + +/* ######################################## Defines used for Logging data + * ######################################### */ +#ifdef NXP_VRBS_REQ +#define NXPLOG_FUNC_ENTRY(COMP) \ + LOG_PRI(ANDROID_LOG_VERBOSE, (COMP), "+:%s", (__func__)) +#define NXPLOG_FUNC_EXIT(COMP) \ + LOG_PRI(ANDROID_LOG_VERBOSE, (COMP), "-:%s", (__func__)) +#endif /*NXP_VRBS_REQ*/ + +/* ################################################################################################################ + */ +/* ######################################## Logging APIs of actual modules + * ######################################## */ +/* ################################################################################################################ + */ +/* Logging APIs used by NxpExtns module */ +#if (ENABLE_EXTNS_TRACES == TRUE) +#define NXPLOG_EXTNS_D(...) \ + { \ + if (gLog_level.extns_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_EXTNS, __VA_ARGS__); \ + } +#define NXPLOG_EXTNS_W(...) \ + { \ + if (gLog_level.extns_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_EXTNS, __VA_ARGS__); \ + } +#define NXPLOG_EXTNS_E(...) \ + { \ + if (gLog_level.extns_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_EXTNS, __VA_ARGS__); \ + } +#else +#define NXPLOG_EXTNS_D(...) +#define NXPLOG_EXTNS_W(...) +#define NXPLOG_EXTNS_E(...) +#endif /* Logging APIs used by NxpExtns module */ + +/* Logging APIs used by NxpNciHal module */ +#if (ENABLE_HAL_TRACES == TRUE) +#define NXPLOG_NCIHAL_D(...) \ + { \ + if (gLog_level.hal_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_NCIHAL, __VA_ARGS__); \ + } +#define NXPLOG_NCIHAL_W(...) \ + { \ + if (gLog_level.hal_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_NCIHAL, __VA_ARGS__); \ + } +#define NXPLOG_NCIHAL_E(...) \ + { \ + if (gLog_level.hal_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_NCIHAL, __VA_ARGS__); \ + } +#else +#define NXPLOG_NCIHAL_D(...) +#define NXPLOG_NCIHAL_W(...) +#define NXPLOG_NCIHAL_E(...) +#endif /* Logging APIs used by HAL module */ + +/* Logging APIs used by NxpNciX module */ +#if (ENABLE_NCIX_TRACES == TRUE) +#define NXPLOG_NCIX_D(...) \ + { \ + if (gLog_level.ncix_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_NCIX, __VA_ARGS__); \ + } +#define NXPLOG_NCIX_W(...) \ + { \ + if (gLog_level.ncix_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_NCIX, __VA_ARGS__); \ + } +#define NXPLOG_NCIX_E(...) \ + { \ + if (gLog_level.ncix_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_NCIX, __VA_ARGS__); \ + } +#else +#define NXPLOG_NCIX_D(...) +#define NXPLOG_NCIX_W(...) +#define NXPLOG_NCIX_E(...) +#endif /* Logging APIs used by NCIx module */ + +/* Logging APIs used by NxpNciR module */ +#if (ENABLE_NCIR_TRACES == TRUE) +#define NXPLOG_NCIR_D(...) \ + { \ + if (gLog_level.ncir_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_NCIR, __VA_ARGS__); \ + } +#define NXPLOG_NCIR_W(...) \ + { \ + if (gLog_level.ncir_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_NCIR, __VA_ARGS__); \ + } +#define NXPLOG_NCIR_E(...) \ + { \ + if (gLog_level.ncir_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_NCIR, __VA_ARGS__); \ + } +#else +#define NXPLOG_NCIR_D(...) +#define NXPLOG_NCIR_W(...) +#define NXPLOG_NCIR_E(...) +#endif /* Logging APIs used by NCIR module */ + +/* Logging APIs used by NxpFwDnld module */ +#if (ENABLE_FWDNLD_TRACES == TRUE) +#define NXPLOG_FWDNLD_D(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#define NXPLOG_FWDNLD_W(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#define NXPLOG_FWDNLD_E(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#else +#define NXPLOG_FWDNLD_D(...) +#define NXPLOG_FWDNLD_W(...) +#define NXPLOG_FWDNLD_E(...) +#endif /* Logging APIs used by NxpFwDnld module */ + +/* Logging APIs used by NxpTml module */ +#if (ENABLE_TML_TRACES == TRUE) +#define NXPLOG_TML_D(...) \ + { \ + if (gLog_level.tml_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_TML, __VA_ARGS__); \ + } +#define NXPLOG_TML_W(...) \ + { \ + if (gLog_level.tml_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_TML, __VA_ARGS__); \ + } +#define NXPLOG_TML_E(...) \ + { \ + if (gLog_level.tml_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_TML, __VA_ARGS__); \ + } +#else +#define NXPLOG_TML_D(...) +#define NXPLOG_TML_W(...) +#define NXPLOG_TML_E(...) +#endif /* Logging APIs used by NxpTml module */ + +#ifdef NXP_HCI_REQ +/* Logging APIs used by NxpHcpX module */ +#if (ENABLE_HCPX_TRACES == TRUE) +#define NXPLOG_HCPX_D(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#define NXPLOG_HCPX_W(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#define NXPLOG_HCPX_E(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#else +#define NXPLOG_HCPX_D(...) +#define NXPLOG_HCPX_W(...) +#define NXPLOG_HCPX_E(...) +#endif /* Logging APIs used by NxpHcpX module */ + +/* Logging APIs used by NxpHcpR module */ +#if (ENABLE_HCPR_TRACES == TRUE) +#define NXPLOG_HCPR_D(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_DEBUG, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#define NXPLOG_HCPR_W(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_WARN, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#define NXPLOG_HCPR_E(...) \ + { \ + if (gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) \ + LOG_PRI(ANDROID_LOG_ERROR, NXPLOG_ITEM_FWDNLD, __VA_ARGS__); \ + } +#else +#define NXPLOG_HCPR_D(...) +#define NXPLOG_HCPR_W(...) +#define NXPLOG_HCPR_E(...) +#endif /* Logging APIs used by NxpHcpR module */ +#endif /* NXP_HCI_REQ */ + +#ifdef NXP_VRBS_REQ +#if (ENABLE_EXTNS_TRACES == TRUE) +#define NXPLOG_EXTNS_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_EXTNS) +#define NXPLOG_EXTNS_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_EXTNS) +#else +#define NXPLOG_EXTNS_ENTRY() +#define NXPLOG_EXTNS_EXIT() +#endif + +#if (ENABLE_HAL_TRACES == TRUE) +#define NXPLOG_NCIHAL_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIHAL) +#define NXPLOG_NCIHAL_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIHAL) +#else +#define NXPLOG_NCIHAL_ENTRY() +#define NXPLOG_NCIHAL_EXIT() +#endif + +#if (ENABLE_NCIX_TRACES == TRUE) +#define NXPLOG_NCIX_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIX) +#define NXPLOG_NCIX_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIX) +#else +#define NXPLOG_NCIX_ENTRY() +#define NXPLOG_NCIX_EXIT() +#endif + +#if (ENABLE_NCIR_TRACES == TRUE) +#define NXPLOG_NCIR_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIR) +#define NXPLOG_NCIR_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIR) +#else +#define NXPLOG_NCIR_ENTRY() +#define NXPLOG_NCIR_EXIT() +#endif + +#ifdef NXP_HCI_REQ + +#if (ENABLE_HCPX_TRACES == TRUE) +#define NXPLOG_HCPX_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_HCPX) +#define NXPLOG_HCPX_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_HCPX) +#else +#define NXPLOG_HCPX_ENTRY() +#define NXPLOG_HCPX_EXIT() +#endif + +#if (ENABLE_HCPR_TRACES == TRUE) +#define NXPLOG_HCPR_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_HCPR) +#define NXPLOG_HCPR_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_HCPR) +#else +#define NXPLOG_HCPR_ENTRY() +#define NXPLOG_HCPR_EXIT() +#endif +#endif /* NXP_HCI_REQ */ + +#endif /* NXP_VRBS_REQ */ + +void phNxpLog_InitializeLogLevel(void); + +#endif /* NXPLOG__H_INCLUDED */ diff --git a/pn54x/nfc_nci.c b/pn54x/nfc_nci.c new file mode 100644 index 0000000..611c83c --- /dev/null +++ b/pn54x/nfc_nci.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "NxpNfcNciHal" + +#include <errno.h> +#include <hardware/hardware.h> +#include <hardware/nfc.h> +#include <log/log.h> +#include <phNxpNciHal_Adaptation.h> +#include <stdlib.h> +#include <string.h> + +/***************************************************************************** + * NXP NCI HAL Function implementations. + *****************************************************************************/ + +/******************************************************************************* +** +** Function hal_open +** +** Description It opens and initialzes the physical connection with NFCC. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int hal_open(const struct nfc_nci_device* p_dev, + nfc_stack_callback_t p_hal_cback, + nfc_stack_data_callback_t* p_hal_data_callback) { + int retval = 0; + + pn547_dev_t* dev = (pn547_dev_t*)p_dev; + retval = phNxpNciHal_open(p_hal_cback, p_hal_data_callback); + + return retval; +} + +/******************************************************************************* +** +** Function hal_write +** +** Description Write the data to NFCC. +** +** Returns Number of bytes successfully written to NFCC. +** +*******************************************************************************/ +static int hal_write(const struct nfc_nci_device* p_dev, uint16_t data_len, + const uint8_t* p_data) { + int retval = 0; + pn547_dev_t* dev = (pn547_dev_t*)p_dev; + + retval = phNxpNciHal_write(data_len, p_data); + return retval; +} + +/******************************************************************************* +** +** Function hal_core_initialized +** +** Description Notify NFCC after successful initialization of NFCC. +** All proprietary settings can be done here. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int hal_core_initialized(const struct nfc_nci_device* p_dev, + uint8_t* p_core_init_rsp_params) { + int retval = 0; + pn547_dev_t* dev = (pn547_dev_t*)p_dev; + + retval = phNxpNciHal_core_initialized(p_core_init_rsp_params); + return retval; +} + +/******************************************************************************* +** +** Function hal_pre_discover +** +** Description Notify NFCC before start discovery. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int hal_pre_discover(const struct nfc_nci_device* p_dev) { + int retval = 0; + pn547_dev_t* dev = (pn547_dev_t*)p_dev; + + retval = phNxpNciHal_pre_discover(); + return retval; +} + +/******************************************************************************* +** +** Function hal_close +** +** Description Close the NFCC interface and free all resources. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int hal_close(const struct nfc_nci_device* p_dev) { + int retval = 0; + pn547_dev_t* dev = (pn547_dev_t*)p_dev; + + retval = phNxpNciHal_close(); + return retval; +} + +/******************************************************************************* +** +** Function hal_control_granted +** +** Description Notify NFCC that control is granted to HAL. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int hal_control_granted(const struct nfc_nci_device* p_dev) { + int retval = 0; + pn547_dev_t* dev = (pn547_dev_t*)p_dev; + + retval = phNxpNciHal_control_granted(); + return retval; +} + +/******************************************************************************* +** +** Function hal_power_cycle +** +** Description Notify power cycling has performed. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int hal_power_cycle(const struct nfc_nci_device* p_dev) { + int retval = 0; + pn547_dev_t* dev = (pn547_dev_t*)p_dev; + + retval = phNxpNciHal_power_cycle(); + return retval; +} + +/************************************* + * Generic device handling. + *************************************/ + +/******************************************************************************* +** +** Function nfc_close +** +** Description Close the nfc device instance. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int nfc_close(hw_device_t* dev) { + int retval = 0; + free(dev); + return retval; +} + +/******************************************************************************* +** +** Function nfc_open +** +** Description Open the nfc device instance. +** +** Returns 0 if successful +** +*******************************************************************************/ +static int nfc_open(const hw_module_t* module, const char* name, + hw_device_t** device) { + ALOGD("%s: enter; name=%s", __func__, name); + int retval = 0; /* 0 is ok; -1 is error */ + + if (strcmp(name, NFC_NCI_CONTROLLER) == 0) { + pn547_dev_t* dev = calloc(1, sizeof(pn547_dev_t)); + + /* Common hw_device_t fields */ + dev->nci_device.common.tag = HARDWARE_DEVICE_TAG; + dev->nci_device.common.version = + 0x00010000; /* [31:16] major, [15:0] minor */ + dev->nci_device.common.module = (struct hw_module_t*)module; + dev->nci_device.common.close = nfc_close; + + /* NCI HAL method pointers */ + dev->nci_device.open = hal_open; + dev->nci_device.write = hal_write; + dev->nci_device.core_initialized = hal_core_initialized; + dev->nci_device.pre_discover = hal_pre_discover; + dev->nci_device.close = hal_close; + dev->nci_device.control_granted = hal_control_granted; + dev->nci_device.power_cycle = hal_power_cycle; + + *device = (hw_device_t*)dev; + } else { + retval = -EINVAL; + } + + ALOGD("%s: exit %d", __func__, retval); + return retval; +} + +/* Android hardware module definition */ +static struct hw_module_methods_t nfc_module_methods = { + .open = nfc_open, +}; + +/* NFC module definition */ +struct nfc_nci_module_t HAL_MODULE_INFO_SYM = { + .common = + { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = 0x0100, /* [15:8] major, [7:0] minor (1.0) */ + .hal_api_version = 0x00, /* 0 is only valid value */ + .id = NFC_NCI_HARDWARE_MODULE_ID, + .name = "NXP PN54X NFC NCI HW HAL", + .author = "NXP Semiconductors", + .methods = &nfc_module_methods, + }, +}; diff --git a/pn54x/self-test/phNxpNciHal_SelfTest.c b/pn54x/self-test/phNxpNciHal_SelfTest.c new file mode 100644 index 0000000..37d6a3e --- /dev/null +++ b/pn54x/self-test/phNxpNciHal_SelfTest.c @@ -0,0 +1,1847 @@ +/* + * Copyright (C) 2012-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef NXP_HW_SELF_TEST + +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include <phNxpNciHal_SelfTest.h> +#include <phOsalNfc_Timer.h> +#include <pthread.h> + +/* Timeout value to wait for response from PN54X */ +#define HAL_WRITE_RSP_TIMEOUT (2000) +#define HAL_WRITE_MAX_RETRY (10) + +/******************* Structures and definitions *******************************/ + +typedef uint8_t (*st_validator_t)(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act); + +phAntenna_St_Resp_t phAntenna_resp; + +typedef struct nci_test_data { + nci_data_t cmd; + nci_data_t exp_rsp; + nci_data_t exp_ntf; + st_validator_t rsp_validator; + st_validator_t ntf_validator; + +} nci_test_data_t; + +/******************* Global variables *****************************************/ + +static int thread_running = 0; +static uint32_t timeoutTimerId = 0; +static int hal_write_timer_fired = 0; + +/* TML Context */ +extern phTmlNfc_Context_t* gpphTmlNfc_Context; + +/* Global HAL Ref */ +extern phNxpNciHal_Control_t nxpncihal_ctrl; + +/* Driver parameters */ +phLibNfc_sConfig_t gDrvCfg; + +NFCSTATUS gtxldo_status = NFCSTATUS_FAILED; +NFCSTATUS gagc_value_status = NFCSTATUS_FAILED; +NFCSTATUS gagc_nfcld_status = NFCSTATUS_FAILED; +NFCSTATUS gagc_differential_status = NFCSTATUS_FAILED; + +static uint8_t st_validator_testEquals(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act); +static uint8_t st_validator_null(nci_data_t* exp, phTmlNfc_TransactInfo_t* act); +static uint8_t st_validator_testSWP1_vltg(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act); +static uint8_t st_validator_testAntenna_Txldo(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act); +static uint8_t st_validator_testAntenna_AgcVal(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act); +static uint8_t st_validator_testAntenna_AgcVal_FixedNfcLd( + nci_data_t* exp, phTmlNfc_TransactInfo_t* act); +static uint8_t st_validator_testAntenna_AgcVal_Differential( + nci_data_t* exp, phTmlNfc_TransactInfo_t* act); + +#if (NFC_NXP_CHIP_TYPE != PN547C2) +NFCSTATUS phNxpNciHal_getPrbsCmd(phNxpNfc_PrbsType_t prbs_type, + phNxpNfc_PrbsHwType_t hw_prbs_type, + uint8_t tech, uint8_t bitrate, + uint8_t* prbs_cmd, uint8_t prbs_cmd_len); +#else +NFCSTATUS phNxpNciHal_getPrbsCmd(uint8_t tech, uint8_t bitrate, + uint8_t* prbs_cmd, uint8_t prbs_cmd_len); +#endif +/* Test data to validate SWP line 2*/ +static nci_test_data_t swp2_test_data[] = { + {{ + 0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */ + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x06, {0x40, 0x00, 0x03, 0x00, 0x11, 0x00} /* exp_rsp */ +#else + 0x06, {0x40, 0x00, 0x03, 0x00, 0x10, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */ +#else + 0x03, {0x20, 0x01, 0x00} +#endif + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */ +#else + 0x4, {0x40, 0x01, 0x17, 0x00} +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ + 0x03, {0x2F, 0x02, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x02, 0x05, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ + 0x04, {0x2F, 0x3E, 0x01, 0x01} /* cmd */ + }, + { + 0x04, {0x4F, 0x3E, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x04, {0x6F, 0x3E, 0x02, 0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_testEquals}, + +}; + +/* Test data to validate SWP line 1*/ +static nci_test_data_t swp1_test_data[] = { + + {{ + 0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */ + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x06, {0x40, 0x00, 0x03, 0x00, 0x11, 0x00} /* exp_rsp */ +#else + 0x06, {0x40, 0x00, 0x03, 0x00, 0x10, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */ +#else + 0x03, {0x20, 0x01, 0x00} +#endif + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */ +#else + 0x4, {0x40, 0x01, 0x17, 0x00} +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ + 0x03, {0x2F, 0x02, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x02, 0x05, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ + 0x04, {0x2F, 0x3E, 0x01, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x3E, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x04, {0x6F, 0x3E, 0x02, 0x00} /* ext_ntf */ + }, + + st_validator_testEquals, /* validator */ + st_validator_testSWP1_vltg}, +}; + +static nci_test_data_t prbs_test_data[] = { + {{ + 0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */ + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x06, {0x40, 0x00, 0x03, 0x00, 0x11, 0x00} /* exp_rsp */ +#else + 0x06, {0x40, 0x00, 0x03, 0x00, 0x10, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */ +#else + 0x03, {0x20, 0x01, 0x00} /* cmd */ +#endif + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */ +#else + 0x4, {0x40, 0x01, 0x17, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null +#if (NFC_NXP_CHIP_TYPE != PN547C2) + }, + {{ + 0x04, {0x2F, 0x00, 0x01, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null +#endif + }}; + +/* for rf field test, first requires to disable the standby mode */ +static nci_test_data_t rf_field_on_test_data[] = { + {{ + 0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */ + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x06, {0x40, 0x00, 0x03, 0x00, 0x11, 0x00} /* exp_rsp */ +#else + 0x06, {0x40, 0x00, 0x03, 0x00, 0x10, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */ +#else + 0x03, {0x20, 0x01, 0x00} /* cmd */ +#endif + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */ +#else + 0x4, {0x40, 0x01, 0x17, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +#if (NFC_NXP_CHIP_TYPE != PN547C2) + {{ + 0x03, {0x2F, 0x02, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x02, 0x05, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ + 0x04, {0x2F, 0x00, 0x01, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +#endif + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x2F, 0x3D, 0x02, 0x20, 0x01} /* cmd */ +#else + 0x08, {0x2F, 0x3D, 0x05, 0x20, 0x01, 0x00, 0x00, 0x00} /* cmd */ +#endif + }, + { + 0x04, {0x4F, 0x3D, 0x05, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null +#if (NFC_NXP_CHIP_TYPE != PN547C2) + }, + {{ + 0x04, {0x2F, 0x00, 0x01, 0x01} /* cmd */ + }, + { + 0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null +#endif + }}; + +static nci_test_data_t rf_field_off_test_data[] = { + {{ + 0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */ + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x06, {0x40, 0x00, 0x03, 0x00, 0x11, 0x00} /* exp_rsp */ +#else + 0x06, {0x40, 0x00, 0x03, 0x00, 0x10, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */ +#else + 0x03, {0x20, 0x01, 0x00} /* cmd */ +#endif + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */ +#else + 0x4, {0x40, 0x01, 0x17, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +#if (NFC_NXP_CHIP_TYPE != PN547C2) + {{ + 0x03, {0x2F, 0x02, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x02, 0x05, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ + 0x04, {0x2F, 0x00, 0x01, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +#endif + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x2F, 0x3D, 0x02, 0x20, 0x00} /* cmd */ +#else + 0x08, {0x2F, 0x3D, 0x05, 0x20, 0x00, 0x00, 0x00, 0x00} /* cmd */ +#endif + }, + { + 0x04, {0x4F, 0x3D, 0x05, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null +#if (NFC_NXP_CHIP_TYPE != PN547C2) + }, + {{ + 0x04, {0x2F, 0x00, 0x01, 0x01} /* cmd */ + }, + { + 0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null +#endif + }}; + +/* Download pin test data 1 */ +static nci_test_data_t download_pin_test_data1[] = { + {{ + 0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */ + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x06, {0x40, 0x00, 0x03, 0x00, 0x11, 0x00} /* exp_rsp */ +#else + 0x06, {0x40, 0x00, 0x03, 0x00, 0x10, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +}; + +/* Download pin test data 2 */ +static nci_test_data_t download_pin_test_data2[] = { + {{ + 0x08, {0x00, 0x04, 0xD0, 0x11, 0x00, 0x00, 0x5B, 0x46} /* cmd */ + }, + { + 0x08, {0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x87, 0x16} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +}; +/* Antenna self test data*/ +static nci_test_data_t antenna_self_test_data[] = { + {{ + 0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */ + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x06, {0x40, 0x00, 0x03, 0x00, 0x11, 0x00} /* exp_rsp */ +#else + 0x06, {0x40, 0x00, 0x03, 0x00, 0x10, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */ +#else + 0x03, {0x20, 0x01, 0x00} /* cmd */ +#endif + }, + { +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */ +#else + 0x4, {0x40, 0x01, 0x17, 0x00} /* exp_rsp */ +#endif + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, + {{ + 0x03, {0x2F, 0x02, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x02, 0x05, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +#if (NFC_NXP_CHIP_TYPE != PN547C2) + {{ + 0x04, {0x2F, 0x00, 0x01, 0x00} /* cmd */ + }, + { + 0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null}, +#endif + {{ + 0x05, + {0x2F, 0x3D, 0x02, 0x01, 0x80} /* TxLDO cureent measurement cmd */ + }, + { + 0x03, {0x4F, 0x3D, 05} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testAntenna_Txldo, + st_validator_null}, + {{ +#if (NFC_NXP_CHIP_TYPE != PN547C2) + 0x07, + {0x2F, 0x3D, 0x04, 0x02, 0xC8, 0x60, 0x03} /* AGC measurement cmd */ +#else + 0x07, + {0x2F, 0x3D, 0x04, 0x02, 0xCD, 0x60, 0x03} /* AGC measurement cmd */ +#endif + }, + { + 0x03, {0x4F, 0x3D, 05} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testAntenna_AgcVal, + st_validator_null}, + {{ + 0x07, + {0x2F, 0x3D, 0x04, 0x04, 0x20, 0x08, + 0x20} /* AGC with NFCLD measurement cmd */ + }, + { + 0x03, {0x4F, 0x3D, 05} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testAntenna_AgcVal_FixedNfcLd, + st_validator_null}, + {{ + 0x07, + {0x2F, 0x3D, 0x04, 0x08, 0x8C, 0x60, + 0x03} /* AGC with NFCLD measurement cmd */ + }, + { + 0x03, {0x4F, 0x3D, 05} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testAntenna_AgcVal_Differential, + st_validator_null +#if (NFC_NXP_CHIP_TYPE != PN547C2) + }, + {{ + 0x04, {0x2F, 0x00, 0x01, 0x01} /* cmd */ + }, + { + 0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */ + }, + { + 0x00, {0x00} /* ext_ntf */ + }, + st_validator_testEquals, /* validator */ + st_validator_null +#endif + }}; + +/************** Self test functions ***************************************/ + +static uint8_t st_validator_testEquals(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act); +static void hal_write_cb(void* pContext, phTmlNfc_TransactInfo_t* pInfo); +static void hal_write_rsp_timeout_cb(uint32_t TimerId, void* pContext); +static void hal_read_cb(void* pContext, phTmlNfc_TransactInfo_t* pInfo); + +/******************************************************************************* +** +** Function st_validator_null +** +** Description Null Validator +** +** Returns One +** +*******************************************************************************/ +static uint8_t st_validator_null(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act) { + UNUSED(exp); + UNUSED(act); + return 1; +} + +/******************************************************************************* +** +** Function st_validator_testSWP1_vltg +** +** Description Validator function to validate swp1 connection. +** +** Returns One if successful otherwise Zero. +** +*******************************************************************************/ +static uint8_t st_validator_testSWP1_vltg(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act) { + uint8_t result = 0; + + if (NULL == exp || NULL == act) { + return result; + } + + if ((act->wLength == 0x05) && + (memcmp(exp->p_data, act->pBuff, exp->len) == 0)) { + if (act->pBuff[4] == 0x01 || act->pBuff[4] == 0x02) { + result = 1; + } + } + + return result; +} + +/******************************************************************************* +** +** Function st_validator_testAntenna_Txldo +** +** Description Validator function to validate Antenna TxLDO current +** measurement. +** +** Returns One if successful otherwise Zero. +** +*******************************************************************************/ +static uint8_t st_validator_testAntenna_Txldo(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act) { + uint8_t result = 0; + uint8_t mesuredrange = 0; + long measured_val = 0; + int tolerance = 0; + + if (NULL == exp || NULL == act) { + return result; + } + + NXPLOG_NCIHAL_D("st_validator_testAntenna_Txldo = 0x%x", act->pBuff[3]); + if (0x05 == act->pBuff[2]) { + if (NFCSTATUS_SUCCESS == act->pBuff[3]) { + result = 1; + NXPLOG_NCIHAL_D("Antenna: TxLDO current measured raw value in mA : 0x%x", + act->pBuff[4]); + if (0x00 == act->pBuff[5]) { + NXPLOG_NCIHAL_D("Measured range : 0x00 = 50 - 100 mA"); + measured_val = ((0.40 * act->pBuff[4]) + 50); + NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", + measured_val); + } else { + NXPLOG_NCIHAL_D("Measured range : 0x01 = 20 - 70 mA"); + measured_val = ((0.40 * act->pBuff[4]) + 20); + NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", + measured_val); + } + + tolerance = (phAntenna_resp.wTxdoMeasuredRangeMax * + phAntenna_resp.wTxdoMeasuredTolerance) / + 100; + if ((measured_val <= phAntenna_resp.wTxdoMeasuredRangeMax + tolerance)) { + tolerance = (phAntenna_resp.wTxdoMeasuredRangeMin * + phAntenna_resp.wTxdoMeasuredTolerance) / + 100; + if ((measured_val >= + phAntenna_resp.wTxdoMeasuredRangeMin - tolerance)) { + gtxldo_status = NFCSTATUS_SUCCESS; + NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement PASS"); + } else { + gtxldo_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL"); + } + } else { + gtxldo_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL"); + } + } else { + gtxldo_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E( + "Test Antenna Response for TxLDO measurement failed: Invalid status"); + } + + } else { + gtxldo_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E( + "Test Antenna Response for TxLDO measurement failed: Invalid payload " + "length"); + } + + return result; +} + +/******************************************************************************* +** +** Function st_validator_testAntenna_AgcVal +** +** Description Validator function reads AGC value of antenna and print the +** info +** +** Returns One if successful otherwise Zero. +** +*******************************************************************************/ +static uint8_t st_validator_testAntenna_AgcVal(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act) { + uint8_t result = 0; + int agc_tolerance = 0; + long agc_val = 0; + + if (NULL == exp || NULL == act) { + return result; + } + + if (0x05 == act->pBuff[2]) { + if (NFCSTATUS_SUCCESS == act->pBuff[3]) { + result = 1; + agc_tolerance = + (phAntenna_resp.wAgcValue * phAntenna_resp.wAgcValueTolerance) / 100; + agc_val = ((act->pBuff[5] << 8) | (act->pBuff[4])); + NXPLOG_NCIHAL_D("AGC value : %ld", agc_val); + if (((phAntenna_resp.wAgcValue - agc_tolerance) <= agc_val) && + (agc_val <= (phAntenna_resp.wAgcValue + agc_tolerance))) { + gagc_value_status = NFCSTATUS_SUCCESS; + NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values PASS"); + } else { + gagc_value_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values FAIL"); + } + } else { + gagc_value_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values FAIL"); + } + } else { + gagc_value_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC value failed: Invalid payload length"); + } + + return result; +} +/******************************************************************************* +** +** Function st_validator_testAntenna_AgcVal_FixedNfcLd +** +** Description Validator function reads and print AGC value of +** antenna with fixed NFCLD +** +** Returns One if successful otherwise Zero. +** +*******************************************************************************/ +static uint8_t st_validator_testAntenna_AgcVal_FixedNfcLd( + nci_data_t* exp, phTmlNfc_TransactInfo_t* act) { + uint8_t result = 0; + int agc_nfcld_tolerance = 0; + long agc_nfcld = 0; + + if (NULL == exp || NULL == act) { + return result; + } + + if (0x05 == act->pBuff[2]) { + if (NFCSTATUS_SUCCESS == act->pBuff[3]) { + result = 1; + agc_nfcld_tolerance = (phAntenna_resp.wAgcValuewithfixedNFCLD * + phAntenna_resp.wAgcValuewithfixedNFCLDTolerance) / + 100; + agc_nfcld = ((act->pBuff[5] << 8) | (act->pBuff[4])); + NXPLOG_NCIHAL_D("AGC value with Fixed Nfcld : %ld", agc_nfcld); + + if (((phAntenna_resp.wAgcValuewithfixedNFCLD - agc_nfcld_tolerance) <= + agc_nfcld) && + (agc_nfcld <= + (phAntenna_resp.wAgcValuewithfixedNFCLD + agc_nfcld_tolerance))) { + gagc_nfcld_status = NFCSTATUS_SUCCESS; + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC value with fixed NFCLD PASS"); + } else { + gagc_nfcld_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC value with fixed NFCLD FAIL"); + } + } else { + gagc_nfcld_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC value with fixed NFCLD failed: " + "Invalid status"); + } + } else { + gagc_nfcld_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC value with fixed NFCLD failed: Invalid " + "payload length"); + } + + return result; +} + +/******************************************************************************* +** +** Function st_validator_testAntenna_AgcVal_Differential +** +** Description Reads the AGC value with open/short RM from buffer and print +** +** Returns One if successful otherwise Zero. +** +*******************************************************************************/ +static uint8_t st_validator_testAntenna_AgcVal_Differential( + nci_data_t* exp, phTmlNfc_TransactInfo_t* act) { + uint8_t result = 0; + int agc_toleranceopne1 = 0; + int agc_toleranceopne2 = 0; + long agc_differentialOpne1 = 0; + long agc_differentialOpne2 = 0; + + if (NULL == exp || NULL == act) { + return result; + } + + if (0x05 == act->pBuff[2]) { + if (NFCSTATUS_SUCCESS == act->pBuff[3]) { + result = 1; + agc_toleranceopne1 = (phAntenna_resp.wAgcDifferentialWithOpen1 * + phAntenna_resp.wAgcDifferentialWithOpenTolerance1) / + 100; + agc_toleranceopne2 = (phAntenna_resp.wAgcDifferentialWithOpen2 * + phAntenna_resp.wAgcDifferentialWithOpenTolerance2) / + 100; + agc_differentialOpne1 = ((act->pBuff[5] << 8) | (act->pBuff[4])); + agc_differentialOpne2 = ((act->pBuff[7] << 8) | (act->pBuff[6])); + NXPLOG_NCIHAL_D("AGC value differential Opne 1 : %ld", + agc_differentialOpne1); + NXPLOG_NCIHAL_D("AGC value differentialOpne 2 : %ld", + agc_differentialOpne2); + + if (((agc_differentialOpne1 >= + phAntenna_resp.wAgcDifferentialWithOpen1 - agc_toleranceopne1) && + (agc_differentialOpne1 <= + phAntenna_resp.wAgcDifferentialWithOpen1 + agc_toleranceopne1)) && + ((agc_differentialOpne2 >= + phAntenna_resp.wAgcDifferentialWithOpen2 - agc_toleranceopne2) && + (agc_differentialOpne2 <= + phAntenna_resp.wAgcDifferentialWithOpen2 + agc_toleranceopne2))) { + gagc_differential_status = NFCSTATUS_SUCCESS; + NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential Open PASS"); + } else { + gagc_differential_status = NFCSTATUS_FAILED; + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC Differential Open FAIL"); + } + } else { + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC Differential failed: Invalid status"); + gagc_differential_status = NFCSTATUS_FAILED; + } + + } else { + NXPLOG_NCIHAL_E( + "Test Antenna Response for AGC Differential failed: Invalid payload " + "length"); + gagc_differential_status = NFCSTATUS_FAILED; + } + + return result; +} +/******************************************************************************* +** +** Function st_validator_testEquals +** +** Description Validator function to validate for equality between actual +** and expected values. +** +** Returns One if successful otherwise Zero. +** +*******************************************************************************/ +static uint8_t st_validator_testEquals(nci_data_t* exp, + phTmlNfc_TransactInfo_t* act) { + uint8_t result = 0; + + if (NULL == exp || NULL == act) { + return result; + } + if (exp->len <= act->wLength && + (memcmp(exp->p_data, act->pBuff, exp->len) == 0)) { + result = 1; + } + + return result; +} + +/******************************************************************************* +** +** Function hal_write_rsp_timeout_cb +** +** Description Callback function for hal write response timer. +** +** Returns None +** +*******************************************************************************/ +static void hal_write_rsp_timeout_cb(uint32_t timerId, void* pContext) { + UNUSED(timerId); + NXPLOG_NCIHAL_E("hal_write_rsp_timeout_cb - write timeout!!!"); + hal_write_timer_fired = 1; + hal_read_cb(pContext, NULL); +} + +/******************************************************************************* +** +** Function hal_write_cb +** +** Description Callback function for hal write. +** +** Returns None +** +*******************************************************************************/ +static void hal_write_cb(void* pContext, phTmlNfc_TransactInfo_t* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + + if (pInfo->wStatus == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus); + } else { + NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus); + } + + p_cb_data->status = pInfo->wStatus; + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function hal_read_cb +** +** Description Callback function for hal read. +** +** Returns None +** +*******************************************************************************/ +static void hal_read_cb(void* pContext, phTmlNfc_TransactInfo_t* pInfo) { + phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext; + NFCSTATUS status; + if (hal_write_timer_fired == 1) { + NXPLOG_NCIHAL_D("hal_read_cb - response timeout occurred"); + + hal_write_timer_fired = 0; + p_cb_data->status = NFCSTATUS_RESPONSE_TIMEOUT; + status = phTmlNfc_ReadAbort(); + } else { + NFCSTATUS status = phOsalNfc_Timer_Stop(timeoutTimerId); + + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("Response timer stopped"); + } else { + NXPLOG_NCIHAL_E("Response timer stop ERROR!!!"); + p_cb_data->status = NFCSTATUS_FAILED; + } + if (pInfo == NULL) { + NXPLOG_NCIHAL_E("Empty TransactInfo"); + p_cb_data->status = NFCSTATUS_FAILED; + } else { + if (pInfo->wStatus == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("hal_read_cb successful status = 0x%x", pInfo->wStatus); + p_cb_data->status = NFCSTATUS_SUCCESS; + } else { + NXPLOG_NCIHAL_E("hal_read_cb error status = 0x%x", pInfo->wStatus); + p_cb_data->status = NFCSTATUS_FAILED; + } + + p_cb_data->status = pInfo->wStatus; + nci_test_data_t* test_data = (nci_test_data_t*)p_cb_data->pContext; + + if (test_data->exp_rsp.len == 0) { + /* Compare the actual notification with expected notification.*/ + if (test_data->ntf_validator(&(test_data->exp_ntf), pInfo) == 1) { + p_cb_data->status = NFCSTATUS_SUCCESS; + } else { + p_cb_data->status = NFCSTATUS_FAILED; + } + } + + /* Compare the actual response with expected response.*/ + else if (test_data->rsp_validator(&(test_data->exp_rsp), pInfo) == 1) { + p_cb_data->status = NFCSTATUS_SUCCESS; + } else { + p_cb_data->status = NFCSTATUS_FAILED; + } + + test_data->exp_rsp.len = 0; + } + } + + SEM_POST(p_cb_data); + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_test_rx_thread +** +** Description Thread to fetch and process messages from message queue. +** +** Returns NULL +** +*******************************************************************************/ +static void* phNxpNciHal_test_rx_thread(void* arg) { + phLibNfc_Message_t msg; + UNUSED(arg); + NXPLOG_NCIHAL_D("Self test thread started"); + + thread_running = 1; + + while (thread_running == 1) { + /* Fetch next message from the NFC stack message queue */ + if (phDal4Nfc_msgrcv(gDrvCfg.nClientId, &msg, 0, 0) == -1) { + NXPLOG_NCIHAL_E("Received bad message"); + continue; + } + + if (thread_running == 0) { + break; + } + + switch (msg.eMsgType) { + case PH_LIBNFC_DEFERREDCALL_MSG: { + phLibNfc_DeferredCall_t* deferCall = + (phLibNfc_DeferredCall_t*)(msg.pMsgData); + + REENTRANCE_LOCK(); + deferCall->pCallback(deferCall->pParameter); + REENTRANCE_UNLOCK(); + + break; + } + } + } + + NXPLOG_NCIHAL_D("Self test thread stopped"); + + return NULL; +} + +/******************************************************************************* +** +** Function phNxpNciHal_readLocked +** +** Description Reads response and notification from NFCC and waits for +** read completion, for a definitive timeout value. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED, +** NFCSTATUS_RESPONSE_TIMEOUT in case of timeout. +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_readLocked(nci_test_data_t* pData) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + phNxpNciHal_Sem_t cb_data; + uint16_t read_len = 16; + /* RX Buffer */ + uint32_t rx_data[NCI_MAX_DATA_LEN]; + + /* Create the local semaphore */ + if (phNxpNciHal_init_cb_data(&cb_data, pData) != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phTmlNfc_Read Create cb data failed"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + + /* call read pending */ + status = + phTmlNfc_Read((uint8_t*)rx_data, (uint16_t)read_len, + (pphTmlNfc_TransactCompletionCb_t)&hal_read_cb, &cb_data); + + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("TML Read status error status = %x", status); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + + status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_WRITE_RSP_TIMEOUT, + &hal_write_rsp_timeout_cb, &cb_data); + + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("Response timer started"); + } else { + NXPLOG_NCIHAL_E("Response timer not started"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_NCIHAL_E("phTmlNfc_Read semaphore error"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status == NFCSTATUS_RESPONSE_TIMEOUT) { + NXPLOG_NCIHAL_E("Response timeout!!!"); + status = NFCSTATUS_RESPONSE_TIMEOUT; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("phTmlNfc_Read failed "); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_writeLocked +** +** Description Send command to NFCC and waits for cmd write completion, for +** a definitive timeout value. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED, +** NFCSTATUS_RESPONSE_TIMEOUT in case of timeout. +** +*******************************************************************************/ +static NFCSTATUS phNxpNciHal_writeLocked(nci_test_data_t* pData) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phNxpNciHal_Sem_t cb_data; + int retryCnt = 0; + + /* Create the local semaphore */ + if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phTmlNfc_Write Create cb data failed"); + goto clean_and_return; + } + +retry: + status = + phTmlNfc_Write(pData->cmd.p_data, pData->cmd.len, + (pphTmlNfc_TransactCompletionCb_t)&hal_write_cb, &cb_data); + + if (status != NFCSTATUS_PENDING) { + NXPLOG_NCIHAL_E("phTmlNfc_Write status error"); + goto clean_and_return; + } + + /* Wait for callback response */ + if (SEM_WAIT(cb_data)) { + NXPLOG_NCIHAL_E("write_unlocked semaphore error"); + status = NFCSTATUS_FAILED; + goto clean_and_return; + } + + if (cb_data.status != NFCSTATUS_SUCCESS && retryCnt < HAL_WRITE_MAX_RETRY) { + retryCnt++; + NXPLOG_NCIHAL_E( + "write_unlocked failed - PN54X Maybe in Standby Mode - Retry %d", + retryCnt); + goto retry; + } + + status = cb_data.status; + +clean_and_return: + phNxpNciHal_cleanup_cb_data(&cb_data); + + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_performTest +** +** Description Performs a single cycle of command,response and +** notification. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED, +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_performTest(nci_test_data_t* pData) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + + if (NULL == pData) { + return NFCSTATUS_FAILED; + } + + CONCURRENCY_LOCK(); + + status = phNxpNciHal_writeLocked(pData); + + if (status == NFCSTATUS_RESPONSE_TIMEOUT) { + goto clean_and_return; + } + if (status != NFCSTATUS_SUCCESS) { + goto clean_and_return; + } + + status = phNxpNciHal_readLocked(pData); + + if (status != NFCSTATUS_SUCCESS) { + goto clean_and_return; + } + + if (0 != pData->exp_ntf.len) { + status = phNxpNciHal_readLocked(pData); + + if (status != NFCSTATUS_SUCCESS) { + goto clean_and_return; + } + } + +clean_and_return: + CONCURRENCY_UNLOCK(); + return status; +} + +/******************************************************************************* + ** + ** Function phNxpNciHal_TestMode_open + ** + ** Description It opens the physical connection with NFCC (PN54X) and + ** creates required client thread for operation. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ +NFCSTATUS phNxpNciHal_TestMode_open(void) { + /* Thread */ + pthread_t test_rx_thread; + + phOsalNfc_Config_t tOsalConfig; + phTmlNfc_Config_t tTmlConfig; + char* nfc_dev_node = NULL; + const uint16_t max_len = 260; + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint16_t read_len = 255; + int8_t ret_val = 0x00; + /* initialize trace level */ + phNxpLog_InitializeLogLevel(); + + if (phNxpNciHal_init_monitor() == NULL) { + NXPLOG_NCIHAL_E("Init monitor failed"); + return NFCSTATUS_FAILED; + } + + CONCURRENCY_LOCK(); + + memset(&tOsalConfig, 0x00, sizeof(tOsalConfig)); + memset(&tTmlConfig, 0x00, sizeof(tTmlConfig)); + + /* Read the nfc device node name */ + nfc_dev_node = (char*)malloc(max_len * sizeof(char)); + if (nfc_dev_node == NULL) { + NXPLOG_NCIHAL_E("malloc of nfc_dev_node failed "); + goto clean_and_return; + } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node, + sizeof(nfc_dev_node))) { + NXPLOG_NCIHAL_E( + "Invalid nfc device node name keeping the default device node " + "/dev/pn54x"); + strcpy(nfc_dev_node, "/dev/pn54x"); + } + + gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600); + gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */ + tTmlConfig.pDevName = (int8_t*)nfc_dev_node; + tOsalConfig.dwCallbackThreadId = (uintptr_t)gDrvCfg.nClientId; + tOsalConfig.pLogFile = NULL; + tTmlConfig.dwGetMsgThreadId = (uintptr_t)gDrvCfg.nClientId; + nxpncihal_ctrl.gDrvCfg.nClientId = (uintptr_t)gDrvCfg.nClientId; + + /* Initialize TML layer */ + status = phTmlNfc_Init(&tTmlConfig); + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_E("phTmlNfc_Init Failed"); + goto clean_and_return; + } else { + if (nfc_dev_node != NULL) { + free(nfc_dev_node); + nfc_dev_node = NULL; + } + } + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ret_val = + pthread_create(&test_rx_thread, &attr, phNxpNciHal_test_rx_thread, NULL); + pthread_attr_destroy(&attr); + if (ret_val != 0) { + NXPLOG_NCIHAL_E("pthread_create failed"); + phTmlNfc_Shutdown(); + goto clean_and_return; + } + + timeoutTimerId = phOsalNfc_Timer_Create(); + + if (timeoutTimerId == 0xFFFF) { + NXPLOG_NCIHAL_E("phOsalNfc_Timer_Create failed"); + } else { + NXPLOG_NCIHAL_D("phOsalNfc_Timer_Create SUCCESS"); + } + CONCURRENCY_UNLOCK(); + + return NFCSTATUS_SUCCESS; + +clean_and_return: + CONCURRENCY_UNLOCK(); + if (nfc_dev_node != NULL) { + free(nfc_dev_node); + nfc_dev_node = NULL; + } + phNxpNciHal_cleanup_monitor(); + return NFCSTATUS_FAILED; +} + +/******************************************************************************* + ** + ** Function phNxpNciHal_TestMode_close + ** + ** Description This function close the NFCC interface and free all + ** resources. + ** + ** Returns None. + ** + ******************************************************************************/ + +void phNxpNciHal_TestMode_close() { + NFCSTATUS status = NFCSTATUS_SUCCESS; + + CONCURRENCY_LOCK(); + + if (NULL != gpphTmlNfc_Context->pDevHandle) { + /* Abort any pending read and write */ + status = phTmlNfc_ReadAbort(); + status = phTmlNfc_WriteAbort(); + + phOsalNfc_Timer_Cleanup(); + + status = phTmlNfc_Shutdown(); + + NXPLOG_NCIHAL_D("phNxpNciHal_close return status = %d", status); + + thread_running = 0; + + phDal4Nfc_msgrelease(gDrvCfg.nClientId); + + status = phOsalNfc_Timer_Delete(timeoutTimerId); + } + + CONCURRENCY_UNLOCK(); + + phNxpNciHal_cleanup_monitor(); + + /* Return success always */ + return; +} + +/******************************************************************************* + ** + ** Function phNxpNciHal_SwpTest + ** + ** Description Test function to validate the SWP line. SWP line number is + ** is sent as parameter to the API. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_SwpTest(uint8_t swp_line) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + int len = 0; + int cnt = 0; + + NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - start\n"); + + if (swp_line == 0x01) { + len = (sizeof(swp1_test_data) / sizeof(swp1_test_data[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(swp1_test_data[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + break; + } + } + } else if (swp_line == 0x02) { + len = (sizeof(swp2_test_data) / sizeof(swp2_test_data[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(swp2_test_data[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + break; + } + } + } else { + status = NFCSTATUS_FAILED; + } + + if (status == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - SUCCESSS\n"); + } else { + NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - FAILED\n"); + } + + NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - end\n"); + + return status; +} + +/******************************************************************************* + ** + ** Function phNxpNciHal_PrbsTestStart + ** + ** Description Test function start RF generation for RF technology and bit + ** rate. RF technology and bit rate are sent as parameter to + ** the API. + ** + ** Returns NFCSTATUS_SUCCESS if RF generation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +#if (NFC_NXP_CHIP_TYPE != PN547C2) +NFCSTATUS phNxpNciHal_PrbsTestStart(phNxpNfc_PrbsType_t prbs_type, + phNxpNfc_PrbsHwType_t hw_prbs_type, + phNxpNfc_Tech_t tech, + phNxpNfc_Bitrate_t bitrate) +#else +NFCSTATUS phNxpNciHal_PrbsTestStart(phNxpNfc_Tech_t tech, + phNxpNfc_Bitrate_t bitrate) +#endif +{ + NFCSTATUS status = NFCSTATUS_FAILED; + + nci_test_data_t prbs_cmd_data; + +#if (NFC_NXP_CHIP_TYPE != PN547C2) + uint8_t rsp_cmd_info[] = {0x4F, 0x30, 0x01, 0x00}; + prbs_cmd_data.cmd.len = 0x09; +#else + uint8_t rsp_cmd_info[] = {0x4F, 0x30, 0x01, 0x00}; + prbs_cmd_data.cmd.len = 0x07; +#endif + + memcpy(prbs_cmd_data.exp_rsp.p_data, &rsp_cmd_info[0], sizeof(rsp_cmd_info)); + prbs_cmd_data.exp_rsp.len = sizeof(rsp_cmd_info); + + // prbs_cmd_data.exp_rsp.len = 0x00; + prbs_cmd_data.exp_ntf.len = 0x00; + prbs_cmd_data.rsp_validator = st_validator_testEquals; + prbs_cmd_data.ntf_validator = st_validator_null; + + uint8_t len = 0; + uint8_t cnt = 0; + +// [NCI] -> [0x2F 0x30 0x04 0x00 0x00 0x01 0xFF] + +#if (NFC_NXP_CHIP_TYPE != PN547C2) + status = + phNxpNciHal_getPrbsCmd(prbs_type, hw_prbs_type, tech, bitrate, + prbs_cmd_data.cmd.p_data, prbs_cmd_data.cmd.len); +#else + status = phNxpNciHal_getPrbsCmd(tech, bitrate, prbs_cmd_data.cmd.p_data, + prbs_cmd_data.cmd.len); +#endif + + if (status == NFCSTATUS_FAILED) { + // Invalid Param. + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - INVALID_PARAM\n"); + + goto clean_and_return; + } + + len = (sizeof(prbs_test_data) / sizeof(prbs_test_data[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(prbs_test_data[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + break; + } + } + + /* Ignoring status, as there will be no response - Applicable till FW version + * 8.1.1*/ + status = phNxpNciHal_performTest(&prbs_cmd_data); +clean_and_return: + + if (status == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - SUCCESSS\n"); + } else { + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - FAILED\n"); + } + + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - end\n"); + + return status; +} + +/******************************************************************************* + ** + ** Function phNxpNciHal_PrbsTestStop + ** + ** Description Test function stop RF generation for RF technology started + ** by phNxpNciHal_PrbsTestStart. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ******************************************************************************/ + +NFCSTATUS phNxpNciHal_PrbsTestStop() { + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - Start\n"); + + NFCSTATUS status = NFCSTATUS_SUCCESS; + + status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice); + + if (NFCSTATUS_SUCCESS == status) { + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - SUCCESS\n"); + } else { + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - FAILED\n"); + } + NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - end\n"); + + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_getPrbsCmd +** +** Description Test function frames the PRBS command. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. +** +*******************************************************************************/ +#if (NFC_NXP_CHIP_TYPE != PN547C2) +NFCSTATUS phNxpNciHal_getPrbsCmd(phNxpNfc_PrbsType_t prbs_type, + phNxpNfc_PrbsHwType_t hw_prbs_type, + uint8_t tech, uint8_t bitrate, + uint8_t* prbs_cmd, uint8_t prbs_cmd_len) +#else +NFCSTATUS phNxpNciHal_getPrbsCmd(uint8_t tech, uint8_t bitrate, + uint8_t* prbs_cmd, uint8_t prbs_cmd_len) +#endif +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + int position_tech_param = 0; + int position_bit_param = 0; + + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - tech 0x%x bitrate = 0x%x", tech, + bitrate); + if (NULL == prbs_cmd || +#if (NFC_NXP_CHIP_TYPE != PN547C2) + prbs_cmd_len != 0x09) +#else + prbs_cmd_len != 0x07) +#endif + { + return status; + } + + prbs_cmd[0] = 0x2F; + prbs_cmd[1] = 0x30; +#if (NFC_NXP_CHIP_TYPE != PN547C2) + prbs_cmd[2] = 0x06; + prbs_cmd[3] = (uint8_t)prbs_type; + // 0xFF Error value used for validation. + prbs_cmd[4] = (uint8_t)hw_prbs_type; + prbs_cmd[5] = 0xFF; // TECH + prbs_cmd[6] = 0xFF; // BITRATE + prbs_cmd[7] = 0x01; + prbs_cmd[8] = 0xFF; + position_tech_param = 5; + position_bit_param = 6; +#else + prbs_cmd[2] = 0x04; + // 0xFF Error value used for validation. + prbs_cmd[3] = 0xFF; // TECH + // 0xFF Error value used for validation. + prbs_cmd[4] = 0xFF; // BITRATE + prbs_cmd[5] = 0x01; + prbs_cmd[6] = 0xFF; + position_tech_param = 3; + position_bit_param = 4; +#endif + + switch (tech) { + case NFC_RF_TECHNOLOGY_A: + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_A"); + prbs_cmd[position_tech_param] = 0x00; + break; + case NFC_RF_TECHNOLOGY_B: + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_B"); + prbs_cmd[position_tech_param] = 0x01; + break; + case NFC_RF_TECHNOLOGY_F: + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_F"); + prbs_cmd[position_tech_param] = 0x02; + break; + default: + break; + } + + switch (bitrate) { + case NFC_BIT_RATE_106: + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_106"); + if (prbs_cmd[position_tech_param] != 0x02) { + prbs_cmd[position_bit_param] = 0x00; + } + break; + case NFC_BIT_RATE_212: + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_212"); + prbs_cmd[position_bit_param] = 0x01; + break; + case NFC_BIT_RATE_424: + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_424"); + prbs_cmd[position_bit_param] = 0x02; + break; + case NFC_BIT_RATE_848: + NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_848"); + if (prbs_cmd[position_tech_param] != 0x02) { + prbs_cmd[position_bit_param] = 0x03; + } + break; + default: + break; + } + + if (prbs_cmd[position_tech_param] == 0xFF || + prbs_cmd[position_bit_param] == 0xFF) { + // Invalid Param. + status = NFCSTATUS_FAILED; + } + + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_RfFieldTest +** +** Description Test function performs RF filed test. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_RfFieldTest(uint8_t on) { + NFCSTATUS status = NFCSTATUS_SUCCESS; + int len = 0; + int cnt = 0; + + NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - start %x\n", on); + + if (on == 0x01) { + len = (sizeof(rf_field_on_test_data) / sizeof(rf_field_on_test_data[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(rf_field_on_test_data[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + break; + } + } + } else if (on == 0x00) { + len = (sizeof(rf_field_off_test_data) / sizeof(rf_field_off_test_data[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(rf_field_off_test_data[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + break; + } + } + } else { + status = NFCSTATUS_FAILED; + } + + if (status == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - SUCCESSS\n"); + } else { + NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - FAILED\n"); + } + + NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - end\n"); + + return status; +} + +/******************************************************************************* + ** + ** Function phNxpNciHal_AntennaTest + ** + ** Description + ** + ** Returns + ** + ******************************************************************************/ +NFCSTATUS phNxpNciHal_AntennaTest() { + NFCSTATUS status = NFCSTATUS_FAILED; + + return status; +} + +/******************************************************************************* +** +** Function phNxpNciHal_DownloadPinTest +** +** Description Test function to validate the FW download pin connection. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_DownloadPinTest(void) { + NFCSTATUS status = NFCSTATUS_FAILED; + int len = 0; + int cnt = 0; + + NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - start\n"); + + len = (sizeof(download_pin_test_data1) / sizeof(download_pin_test_data1[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(download_pin_test_data1[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + break; + } + } + + if (status != NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n"); + return status; + } + + status = NFCSTATUS_FAILED; + status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode); + if (NFCSTATUS_SUCCESS != status) { + NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n"); + return status; + } + + status = NFCSTATUS_FAILED; + len = (sizeof(download_pin_test_data2) / sizeof(download_pin_test_data2[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(download_pin_test_data2[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + break; + } + } + + if (status == NFCSTATUS_SUCCESS) { + NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - SUCCESSS\n"); + } else { + NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n"); + } + + NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - end\n"); + + return status; +} +/******************************************************************************* +** +** Function phNxpNciHal_AntennaSelfTest +** +** Description Test function to validate the Antenna's discrete +** components connection. +** +** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. +** +*******************************************************************************/ +NFCSTATUS phNxpNciHal_AntennaSelfTest(phAntenna_St_Resp_t* phAntenna_St_Resp) { + NFCSTATUS status = NFCSTATUS_FAILED; + NFCSTATUS antenna_st_status = NFCSTATUS_FAILED; + int len = 0; + int cnt = 0; + + NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - start\n"); + memcpy(&phAntenna_resp, phAntenna_St_Resp, sizeof(phAntenna_St_Resp_t)); + len = (sizeof(antenna_self_test_data) / sizeof(antenna_self_test_data[0])); + + for (cnt = 0; cnt < len; cnt++) { + status = phNxpNciHal_performTest(&(antenna_self_test_data[cnt])); + if (status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { + NXPLOG_NCIHAL_E( + "phNxpNciHal_AntennaSelfTest: commnad execution - FAILED\n"); + break; + } + } + + if (status == NFCSTATUS_SUCCESS) { + if ((gtxldo_status == NFCSTATUS_SUCCESS) && + (gagc_value_status == NFCSTATUS_SUCCESS) && + (gagc_nfcld_status == NFCSTATUS_SUCCESS) && + (gagc_differential_status == NFCSTATUS_SUCCESS)) { + antenna_st_status = NFCSTATUS_SUCCESS; + NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - SUCESS\n"); + } else { + NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n"); + } + } else { + NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n"); + } + + NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - end\n"); + + return antenna_st_status; +} + +#endif /*#ifdef NXP_HW_SELF_TEST*/ diff --git a/pn54x/tml/phDal4Nfc_messageQueueLib.c b/pn54x/tml/phDal4Nfc_messageQueueLib.c new file mode 100644 index 0000000..f43774d --- /dev/null +++ b/pn54x/tml/phDal4Nfc_messageQueueLib.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * DAL independent message queue implementation for Android (can be used under + * Linux too) + */ + +#include <errno.h> +#include <linux/ipc.h> +#include <phDal4Nfc_messageQueueLib.h> +#include <phNxpLog.h> +#include <pthread.h> +#include <semaphore.h> + +typedef struct phDal4Nfc_message_queue_item { + phLibNfc_Message_t nMsg; + struct phDal4Nfc_message_queue_item* pPrev; + struct phDal4Nfc_message_queue_item* pNext; +} phDal4Nfc_message_queue_item_t; + +typedef struct phDal4Nfc_message_queue { + phDal4Nfc_message_queue_item_t* pItems; + pthread_mutex_t nCriticalSectionMutex; + sem_t nProcessSemaphore; + +} phDal4Nfc_message_queue_t; + +/******************************************************************************* +** +** Function phDal4Nfc_msgget +** +** Description Allocates message queue +** +** Parameters Ignored, included only for Linux queue API compatibility +** +** Returns (int) value of pQueue if successful +** -1, if failed to allocate memory or to init mutex +** +*******************************************************************************/ +intptr_t phDal4Nfc_msgget(key_t key, int msgflg) { + phDal4Nfc_message_queue_t* pQueue; + UNUSED(key); + UNUSED(msgflg); + pQueue = + (phDal4Nfc_message_queue_t*)malloc(sizeof(phDal4Nfc_message_queue_t)); + if (pQueue == NULL) return -1; + memset(pQueue, 0, sizeof(phDal4Nfc_message_queue_t)); + if (pthread_mutex_init(&pQueue->nCriticalSectionMutex, NULL) == -1) { + free(pQueue); + return -1; + } + if (sem_init(&pQueue->nProcessSemaphore, 0, 0) == -1) { + free(pQueue); + return -1; + } + + return ((intptr_t)pQueue); +} + +/******************************************************************************* +** +** Function phDal4Nfc_msgrelease +** +** Description Releases message queue +** +** Parameters msqid - message queue handle +** +** Returns None +** +*******************************************************************************/ +void phDal4Nfc_msgrelease(intptr_t msqid) { + phDal4Nfc_message_queue_t* pQueue = (phDal4Nfc_message_queue_t*)msqid; + + if (pQueue != NULL) { + sem_post(&pQueue->nProcessSemaphore); + usleep(3000); + if (sem_destroy(&pQueue->nProcessSemaphore)) { + NXPLOG_TML_E("Failed to destroy semaphore (errno=0x%08x)", errno); + } + pthread_mutex_destroy(&pQueue->nCriticalSectionMutex); + + free(pQueue); + } + + return; +} + +/******************************************************************************* +** +** Function phDal4Nfc_msgctl +** +** Description Destroys message queue +** +** Parameters msqid - message queue handle +** cmd, buf - ignored, included only for Linux queue API +** compatibility +** +** Returns 0, if successful +** -1, if invalid handle is passed +** +*******************************************************************************/ +int phDal4Nfc_msgctl(intptr_t msqid, int cmd, void* buf) { + phDal4Nfc_message_queue_t* pQueue; + phDal4Nfc_message_queue_item_t* p; + UNUSED(cmd); + UNUSED(buf); + if (msqid == 0) return -1; + + pQueue = (phDal4Nfc_message_queue_t*)msqid; + pthread_mutex_lock(&pQueue->nCriticalSectionMutex); + if (pQueue->pItems != NULL) { + p = pQueue->pItems; + while (p->pNext != NULL) { + p = p->pNext; + } + while (p->pPrev != NULL) { + p = p->pPrev; + free(p->pNext); + p->pNext = NULL; + } + free(p); + } + pQueue->pItems = NULL; + pthread_mutex_unlock(&pQueue->nCriticalSectionMutex); + pthread_mutex_destroy(&pQueue->nCriticalSectionMutex); + free(pQueue); + + return 0; +} + +/******************************************************************************* +** +** Function phDal4Nfc_msgsnd +** +** Description Sends a message to the queue. The message will be added at +** the end of the queue as appropriate for FIFO policy +** +** Parameters msqid - message queue handle +** msgp - message to be sent +** msgsz - message size +** msgflg - ignored +** +** Returns 0, if successful +** -1, if invalid parameter passed or failed to allocate memory +** +*******************************************************************************/ +intptr_t phDal4Nfc_msgsnd(intptr_t msqid, phLibNfc_Message_t* msg, int msgflg) { + phDal4Nfc_message_queue_t* pQueue; + phDal4Nfc_message_queue_item_t* p; + phDal4Nfc_message_queue_item_t* pNew; + UNUSED(msgflg); + if ((msqid == 0) || (msg == NULL)) return -1; + + pQueue = (phDal4Nfc_message_queue_t*)msqid; + pNew = (phDal4Nfc_message_queue_item_t*)malloc( + sizeof(phDal4Nfc_message_queue_item_t)); + if (pNew == NULL) return -1; + memset(pNew, 0, sizeof(phDal4Nfc_message_queue_item_t)); + memcpy(&pNew->nMsg, msg, sizeof(phLibNfc_Message_t)); + pthread_mutex_lock(&pQueue->nCriticalSectionMutex); + + if (pQueue->pItems != NULL) { + p = pQueue->pItems; + while (p->pNext != NULL) { + p = p->pNext; + } + p->pNext = pNew; + pNew->pPrev = p; + } else { + pQueue->pItems = pNew; + } + pthread_mutex_unlock(&pQueue->nCriticalSectionMutex); + + sem_post(&pQueue->nProcessSemaphore); + + return 0; +} + +/******************************************************************************* +** +** Function phDal4Nfc_msgrcv +** +** Description Gets the oldest message from the queue. +** If the queue is empty the function waits (blocks on a mutex) +** until a message is posted to the queue with phDal4Nfc_msgsnd +** +** Parameters msqid - message queue handle +** msgp - message to be received +** msgsz - message size +** msgtyp - ignored +** msgflg - ignored +** +** Returns 0, if successful +** -1, if invalid parameter passed +** +*******************************************************************************/ +int phDal4Nfc_msgrcv(intptr_t msqid, phLibNfc_Message_t* msg, long msgtyp, + int msgflg) { + phDal4Nfc_message_queue_t* pQueue; + phDal4Nfc_message_queue_item_t* p; + UNUSED(msgflg); + UNUSED(msgtyp); + if ((msqid == 0) || (msg == NULL)) return -1; + + pQueue = (phDal4Nfc_message_queue_t*)msqid; + + sem_wait(&pQueue->nProcessSemaphore); + + pthread_mutex_lock(&pQueue->nCriticalSectionMutex); + + if (pQueue->pItems != NULL) { + memcpy(msg, &(pQueue->pItems)->nMsg, sizeof(phLibNfc_Message_t)); + p = pQueue->pItems->pNext; + free(pQueue->pItems); + pQueue->pItems = p; + } + pthread_mutex_unlock(&pQueue->nCriticalSectionMutex); + + return 0; +} diff --git a/pn54x/tml/phDal4Nfc_messageQueueLib.h b/pn54x/tml/phDal4Nfc_messageQueueLib.h new file mode 100644 index 0000000..1e0ede2 --- /dev/null +++ b/pn54x/tml/phDal4Nfc_messageQueueLib.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * DAL independent message queue implementation for Android + */ + +#ifndef PHDAL4NFC_MESSAGEQUEUE_H +#define PHDAL4NFC_MESSAGEQUEUE_H + +#include <linux/ipc.h> +#include <phNfcTypes.h> + +intptr_t phDal4Nfc_msgget(key_t key, int msgflg); +void phDal4Nfc_msgrelease(intptr_t msqid); +int phDal4Nfc_msgctl(intptr_t msqid, int cmd, void* buf); +intptr_t phDal4Nfc_msgsnd(intptr_t msqid, phLibNfc_Message_t* msg, int msgflg); +int phDal4Nfc_msgrcv(intptr_t msqid, phLibNfc_Message_t* msg, long msgtyp, + int msgflg); + +#endif /* PHDAL4NFC_MESSAGEQUEUE_H */ diff --git a/pn54x/tml/phOsalNfc_Timer.c b/pn54x/tml/phOsalNfc_Timer.c new file mode 100644 index 0000000..3f5269d --- /dev/null +++ b/pn54x/tml/phOsalNfc_Timer.c @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * OSAL Implementation for Timers. + */ + +#include <phNfcCommon.h> +#include <phNfcTypes.h> +#include <phNxpLog.h> +#include <phNxpNciHal.h> +#include <phOsalNfc_Timer.h> +#include <signal.h> + +#define PH_NFC_MAX_TIMER (5U) +static phOsalNfc_TimerHandle_t apTimerInfo[PH_NFC_MAX_TIMER]; + +extern phNxpNciHal_Control_t nxpncihal_ctrl; + +/* + * Defines the base address for generating timerid. + */ +#define PH_NFC_TIMER_BASE_ADDRESS (100U) + +/* + * Defines the value for invalid timerid returned during timeSetEvent + */ +#define PH_NFC_TIMER_ID_ZERO (0x00) + +/* + * Invalid timer ID type. This ID used indicate timer creation is failed */ +#define PH_NFC_TIMER_ID_INVALID (0xFFFF) + +/* Forward declarations */ +static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t* pMsg); +static void phOsalNfc_DeferredCall(void* pParams); +static void phOsalNfc_Timer_Expired(union sigval sv); + +/* + *************************** Function Definitions ****************************** + */ + +/******************************************************************************* +** +** Function phOsalNfc_Timer_Create +** +** Description Creates a timer which shall call back the specified function +** when the timer expires. Fails if OSAL module is not +** initialized or timers are already occupied +** +** Parameters None +** +** Returns TimerId +** TimerId value of PH_OSALNFC_TIMER_ID_INVALID indicates that +** timer is not created +** +*******************************************************************************/ +uint32_t phOsalNfc_Timer_Create(void) { + /* dwTimerId is also used as an index at which timer object can be stored */ + uint32_t dwTimerId = PH_OSALNFC_TIMER_ID_INVALID; + static struct sigevent se; + phOsalNfc_TimerHandle_t* pTimerHandle; + /* Timer needs to be initialized for timer usage */ + + se.sigev_notify = SIGEV_THREAD; + se.sigev_notify_function = phOsalNfc_Timer_Expired; + se.sigev_notify_attributes = NULL; + dwTimerId = phUtilNfc_CheckForAvailableTimer(); + + /* Check whether timers are available, if yes create a timer handle structure + */ + if ((PH_NFC_TIMER_ID_ZERO != dwTimerId) && (dwTimerId <= PH_NFC_MAX_TIMER)) { + pTimerHandle = (phOsalNfc_TimerHandle_t*)&apTimerInfo[dwTimerId - 1]; + /* Build the Timer Id to be returned to Caller Function */ + dwTimerId += PH_NFC_TIMER_BASE_ADDRESS; + se.sigev_value.sival_int = (int)dwTimerId; + /* Create POSIX timer */ + if (timer_create(CLOCK_REALTIME, &se, &(pTimerHandle->hTimerHandle)) == + -1) { + dwTimerId = PH_NFC_TIMER_ID_INVALID; + } else { + /* Set the state to indicate timer is ready */ + pTimerHandle->eState = eTimerIdle; + /* Store the Timer Id which shall act as flag during check for timer + * availability */ + pTimerHandle->TimerId = dwTimerId; + } + } else { + dwTimerId = PH_NFC_TIMER_ID_INVALID; + } + + /* Timer ID invalid can be due to Uninitialized state,Non availability of + * Timer */ + return dwTimerId; +} + +/******************************************************************************* +** +** Function phOsalNfc_Timer_Start +** +** Description Starts the requested, already created, timer. +** If the timer is already running, timer stops and restarts +** with the new timeout value and new callback function in case +** any ?????? +** Creates a timer which shall call back the specified function +** when the timer expires +** +** Parameters dwTimerId - valid timer ID obtained during timer creation +** dwRegTimeCnt - requested timeout in milliseconds +** pApplication_callback - application callback interface to be +** called when timer expires +** pContext - caller context, to be passed to the application +** callback function +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - the operation was successful +** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized +** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to +** the function +** PH_OSALNFC_TIMER_START_ERROR - timer could not be created +** due to system error +** +*******************************************************************************/ +NFCSTATUS phOsalNfc_Timer_Start(uint32_t dwTimerId, uint32_t dwRegTimeCnt, + pphOsalNfc_TimerCallbck_t pApplication_callback, + void* pContext) { + NFCSTATUS wStartStatus = NFCSTATUS_SUCCESS; + + struct itimerspec its; + uint32_t dwIndex; + phOsalNfc_TimerHandle_t* pTimerHandle; + /* Retrieve the index at which the timer handle structure is stored */ + dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01; + pTimerHandle = (phOsalNfc_TimerHandle_t*)&apTimerInfo[dwIndex]; + /* OSAL Module needs to be initialized for timer usage */ + /* Check whether the handle provided by user is valid */ + if ((dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) && + (NULL != pApplication_callback)) { + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + its.it_value.tv_sec = dwRegTimeCnt / 1000; + its.it_value.tv_nsec = 1000000 * (dwRegTimeCnt % 1000); + if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0) { + /* This would inadvertently stop the timer*/ + its.it_value.tv_nsec = 1; + } + pTimerHandle->Application_callback = pApplication_callback; + pTimerHandle->pContext = pContext; + pTimerHandle->eState = eTimerRunning; + /* Arm the timer */ + if ((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1) { + wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_START_ERROR); + } + } else { + wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER); + } + + return wStartStatus; +} + +/******************************************************************************* +** +** Function phOsalNfc_Timer_Stop +** +** Description Stops already started timer +** Allows to stop running timer. In case timer is stopped, +** timer callback will not be notified any more +** +** Parameters dwTimerId - valid timer ID obtained during timer creation +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - the operation was successful +** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized +** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to +** the function +** PH_OSALNFC_TIMER_STOP_ERROR - timer could not be stopped due +** to system error +** +*******************************************************************************/ +NFCSTATUS phOsalNfc_Timer_Stop(uint32_t dwTimerId) { + NFCSTATUS wStopStatus = NFCSTATUS_SUCCESS; + static struct itimerspec its = {{0, 0}, {0, 0}}; + + uint32_t dwIndex; + phOsalNfc_TimerHandle_t* pTimerHandle; + dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01; + pTimerHandle = (phOsalNfc_TimerHandle_t*)&apTimerInfo[dwIndex]; + /* OSAL Module and Timer needs to be initialized for timer usage */ + /* Check whether the TimerId provided by user is valid */ + if ((dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) && + (pTimerHandle->eState != eTimerIdle)) { + /* Stop the timer only if the callback has not been invoked */ + if (pTimerHandle->eState == eTimerRunning) { + if ((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1) { + wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_STOP_ERROR); + } else { + /* Change the state of timer to Stopped */ + pTimerHandle->eState = eTimerStopped; + } + } + } else { + wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER); + } + + return wStopStatus; +} + +/******************************************************************************* +** +** Function phOsalNfc_Timer_Delete +** +** Description Deletes previously created timer +** Allows to delete previously created timer. In case timer is +** running, it is first stopped and then deleted +** +** Parameters dwTimerId - valid timer ID obtained during timer creation +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - the operation was successful +** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized +** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to +** the function +** PH_OSALNFC_TIMER_DELETE_ERROR - timer could not be stopped +** due to system error +** +*******************************************************************************/ +NFCSTATUS phOsalNfc_Timer_Delete(uint32_t dwTimerId) { + NFCSTATUS wDeleteStatus = NFCSTATUS_SUCCESS; + + uint32_t dwIndex; + phOsalNfc_TimerHandle_t* pTimerHandle; + dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01; + pTimerHandle = (phOsalNfc_TimerHandle_t*)&apTimerInfo[dwIndex]; + /* OSAL Module and Timer needs to be initialized for timer usage */ + + /* Check whether the TimerId passed by user is valid and Deregistering of + * timer is successful */ + if ((dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) && + (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))) { + /* Cancel the timer before deleting */ + if (timer_delete(pTimerHandle->hTimerHandle) == -1) { + wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_DELETE_ERROR); + } + /* Clear Timer structure used to store timer related data */ + memset(pTimerHandle, (uint8_t)0x00, sizeof(phOsalNfc_TimerHandle_t)); + } else { + wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER); + } + return wDeleteStatus; +} + +/******************************************************************************* +** +** Function phOsalNfc_Timer_Cleanup +** +** Description Deletes all previously created timers +** Allows to delete previously created timers. In case timer is +** running, it is first stopped and then deleted +** +** Parameters None +** +** Returns None +** +*******************************************************************************/ +void phOsalNfc_Timer_Cleanup(void) { + /* Delete all timers */ + uint32_t dwIndex; + phOsalNfc_TimerHandle_t* pTimerHandle; + for (dwIndex = 0; dwIndex < PH_NFC_MAX_TIMER; dwIndex++) { + pTimerHandle = (phOsalNfc_TimerHandle_t*)&apTimerInfo[dwIndex]; + /* OSAL Module and Timer needs to be initialized for timer usage */ + + /* Check whether the TimerId passed by user is valid and Deregistering of + * timer is successful */ + if ((0x00 != pTimerHandle->TimerId) && + (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))) { + /* Cancel the timer before deleting */ + if (timer_delete(pTimerHandle->hTimerHandle) == -1) { + NXPLOG_TML_E("timer %d delete error!", dwIndex); + } + /* Clear Timer structure used to store timer related data */ + memset(pTimerHandle, (uint8_t)0x00, sizeof(phOsalNfc_TimerHandle_t)); + } + } + + return; +} + +/******************************************************************************* +** +** Function phOsalNfc_DeferredCall +** +** Description Invokes the timer callback function after timer expiration. +** Shall invoke the callback function registered by the timer +** caller function +** +** Parameters pParams - parameters indicating the ID of the timer +** +** Returns None - +** +*******************************************************************************/ +static void phOsalNfc_DeferredCall(void* pParams) { + /* Retrieve the timer id from the parameter */ + uint32_t dwIndex; + phOsalNfc_TimerHandle_t* pTimerHandle; + if (NULL != pParams) { + /* Retrieve the index at which the timer handle structure is stored */ + dwIndex = (uintptr_t)pParams - PH_NFC_TIMER_BASE_ADDRESS - 0x01; + pTimerHandle = (phOsalNfc_TimerHandle_t*)&apTimerInfo[dwIndex]; + if (pTimerHandle->Application_callback != NULL) { + /* Invoke the callback function with osal Timer ID */ + pTimerHandle->Application_callback((uintptr_t)pParams, + pTimerHandle->pContext); + } + } + + return; +} + +/******************************************************************************* +** +** Function phOsalNfc_PostTimerMsg +** +** Description Posts message on the user thread +** Shall be invoked upon expiration of a timer +** Shall post message on user thread through which timer +** callback function shall be invoked +** +** Parameters pMsg - pointer to the message structure posted on user +** thread +** +** Returns None +** +*******************************************************************************/ +static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t* pMsg) { + (void)phDal4Nfc_msgsnd( + nxpncihal_ctrl.gDrvCfg + .nClientId /*gpphOsalNfc_Context->dwCallbackThreadID*/, + pMsg, 0); + + return; +} + +/******************************************************************************* +** +** Function phOsalNfc_Timer_Expired +** +** Description posts message upon expiration of timer +** Shall be invoked when any one timer is expired +** Shall post message on user thread to invoke respective +** callback function provided by the caller of Timer function +** +** Returns None +** +*******************************************************************************/ +static void phOsalNfc_Timer_Expired(union sigval sv) { + uint32_t dwIndex; + phOsalNfc_TimerHandle_t* pTimerHandle; + + dwIndex = ((uint32_t)(sv.sival_int)) - PH_NFC_TIMER_BASE_ADDRESS - 0x01; + pTimerHandle = (phOsalNfc_TimerHandle_t*)&apTimerInfo[dwIndex]; + /* Timer is stopped when callback function is invoked */ + pTimerHandle->eState = eTimerStopped; + + pTimerHandle->tDeferedCallInfo.pDeferedCall = &phOsalNfc_DeferredCall; + pTimerHandle->tDeferedCallInfo.pParam = (void*)((intptr_t)(sv.sival_int)); + + pTimerHandle->tOsalMessage.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG; + pTimerHandle->tOsalMessage.pMsgData = (void*)&pTimerHandle->tDeferedCallInfo; + + /* Post a message on the queue to invoke the function */ + phOsalNfc_PostTimerMsg((phLibNfc_Message_t*)&pTimerHandle->tOsalMessage); + + return; +} + +/******************************************************************************* +** +** Function phUtilNfc_CheckForAvailableTimer +** +** Description Find an available timer id +** +** Parameters void +** +** Returns Available timer id +** +*******************************************************************************/ +uint32_t phUtilNfc_CheckForAvailableTimer(void) { + /* Variable used to store the index at which the object structure details + can be stored. Initialize it as not available. */ + uint32_t dwIndex = 0x00; + uint32_t dwRetval = 0x00; + + /* Check whether Timer object can be created */ + for (dwIndex = 0x00; ((dwIndex < PH_NFC_MAX_TIMER) && (0x00 == dwRetval)); + dwIndex++) { + if (!(apTimerInfo[dwIndex].TimerId)) { + dwRetval = (dwIndex + 0x01); + } + } + + return (dwRetval); +} + +/******************************************************************************* +** +** Function phOsalNfc_CheckTimerPresence +** +** Description Checks the requested timer is present or not +** +** Parameters pObjectHandle - timer context +** +** Returns NFCSTATUS_SUCCESS if found +** Other value if not found +** +*******************************************************************************/ +NFCSTATUS phOsalNfc_CheckTimerPresence(void* pObjectHandle) { + uint32_t dwIndex; + NFCSTATUS wRegisterStatus = NFCSTATUS_INVALID_PARAMETER; + + for (dwIndex = 0x00; + ((dwIndex < PH_NFC_MAX_TIMER) && (wRegisterStatus != NFCSTATUS_SUCCESS)); + dwIndex++) { + /* For Timer, check whether the requested handle is present or not */ + if (((&apTimerInfo[dwIndex]) == (phOsalNfc_TimerHandle_t*)pObjectHandle) && + (apTimerInfo[dwIndex].TimerId)) { + wRegisterStatus = NFCSTATUS_SUCCESS; + } + } + return wRegisterStatus; +} diff --git a/pn54x/tml/phOsalNfc_Timer.h b/pn54x/tml/phOsalNfc_Timer.h new file mode 100644 index 0000000..5315455 --- /dev/null +++ b/pn54x/tml/phOsalNfc_Timer.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * OSAL header files related to Timer functions. + */ + +#ifndef PHOSALNFC_TIMER_H +#define PHOSALNFC_TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +************************* Include Files **************************************** +*/ + +/* + * Timer callback interface which will be called once registered timer + * time out expires. + * TimerId - Timer Id for which callback is called. + * pContext - Parameter to be passed to the callback function + */ +typedef void (*pphOsalNfc_TimerCallbck_t)(uint32_t TimerId, void* pContext); + +/* + * The Timer could not be created due to a + * system error */ +#define PH_OSALNFC_TIMER_CREATE_ERROR (0X00E0) + +/* + * The Timer could not be started due to a + * system error or invalid handle */ +#define PH_OSALNFC_TIMER_START_ERROR (0X00E1) + +/* + * The Timer could not be stopped due to a + * system error or invalid handle */ +#define PH_OSALNFC_TIMER_STOP_ERROR (0X00E2) + +/* + * The Timer could not be deleted due to a + * system error or invalid handle */ +#define PH_OSALNFC_TIMER_DELETE_ERROR (0X00E3) + +/* + * Invalid timer ID type.This ID used indicate timer creation is failed */ +#define PH_OSALNFC_TIMER_ID_INVALID (0xFFFF) + +/* + * OSAL timer message .This message type will be posted to + * calling application thread.*/ +#define PH_OSALNFC_TIMER_MSG (0x315) + +/* +***************************Globals,Structure and Enumeration ****************** +*/ + +uint32_t phOsalNfc_Timer_Create(void); +NFCSTATUS phOsalNfc_Timer_Start(uint32_t dwTimerId, uint32_t dwRegTimeCnt, + pphOsalNfc_TimerCallbck_t pApplication_callback, + void* pContext); +NFCSTATUS phOsalNfc_Timer_Stop(uint32_t dwTimerId); +NFCSTATUS phOsalNfc_Timer_Delete(uint32_t dwTimerId); +void phOsalNfc_Timer_Cleanup(void); +uint32_t phUtilNfc_CheckForAvailableTimer(void); +NFCSTATUS phOsalNfc_CheckTimerPresence(void* pObjectHandle); + +#ifdef __cplusplus +} +#endif /* C++ Compilation guard */ +#endif /* PHOSALNFC_TIMER_H */ diff --git a/pn54x/tml/phTmlNfc.c b/pn54x/tml/phTmlNfc.c new file mode 100644 index 0000000..8aad810 --- /dev/null +++ b/pn54x/tml/phTmlNfc.c @@ -0,0 +1,949 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * TML Implementation. + */ + +#include <phDal4Nfc_messageQueueLib.h> +#include <phNxpLog.h> +#include <phNxpNciHal_utils.h> +#include <phOsalNfc_Timer.h> +#include <phTmlNfc.h> +#include <phTmlNfc_i2c.h> + +/* + * Duration of Timer to wait after sending an Nci packet + */ +#define PHTMLNFC_MAXTIME_RETRANSMIT (200U) +#define MAX_WRITE_RETRY_COUNT 0x03 +/* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */ +static uint8_t bCurrentRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1; + +/* Value to reset variables of TML */ +#define PH_TMLNFC_RESET_VALUE (0x00) + +/* Indicates a Initial or offset value */ +#define PH_TMLNFC_VALUE_ONE (0x01) + +/* Initialize Context structure pointer used to access context structure */ +phTmlNfc_Context_t* gpphTmlNfc_Context = NULL; +phTmlNfc_i2cfragmentation_t fragmentation_enabled = I2C_FRAGMENATATION_DISABLED; +/* Local Function prototypes */ +static NFCSTATUS phTmlNfc_StartThread(void); +static void phTmlNfc_CleanUp(void); +static void phTmlNfc_ReadDeferredCb(void* pParams); +static void phTmlNfc_WriteDeferredCb(void* pParams); +static void phTmlNfc_TmlThread(void* pParam); +static void phTmlNfc_TmlWriterThread(void* pParam); +static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void* pContext); +static NFCSTATUS phTmlNfc_InitiateTimer(void); + +/* Function definitions */ + +/******************************************************************************* +** +** Function phTmlNfc_Init +** +** Description Provides initialization of TML layer and hardware interface +** Configures given hardware interface and sends handle to the +** caller +** +** Parameters pConfig - TML configuration details as provided by the upper +** layer +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - initialization successful +** NFCSTATUS_INVALID_PARAMETER - at least one parameter is +** invalid +** NFCSTATUS_FAILED - initialization failed (for example, +** unable to open hardware interface) +** NFCSTATUS_INVALID_DEVICE - device has not been opened or has +** been disconnected +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig) { + NFCSTATUS wInitStatus = NFCSTATUS_SUCCESS; + + /* Check if TML layer is already Initialized */ + if (NULL != gpphTmlNfc_Context) { + /* TML initialization is already completed */ + wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_ALREADY_INITIALISED); + } + /* Validate Input parameters */ + else if ((NULL == pConfig) || + (PH_TMLNFC_RESET_VALUE == pConfig->dwGetMsgThreadId)) { + /*Parameters passed to TML init are wrong */ + wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER); + } else { + /* Allocate memory for TML context */ + gpphTmlNfc_Context = malloc(sizeof(phTmlNfc_Context_t)); + + if (NULL == gpphTmlNfc_Context) { + wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED); + } else { + /* Initialise all the internal TML variables */ + memset(gpphTmlNfc_Context, PH_TMLNFC_RESET_VALUE, + sizeof(phTmlNfc_Context_t)); + /* Make sure that the thread runs once it is created */ + gpphTmlNfc_Context->bThreadDone = 1; + + /* Open the device file to which data is read/written */ + wInitStatus = phTmlNfc_i2c_open_and_configure( + pConfig, &(gpphTmlNfc_Context->pDevHandle)); + + if (NFCSTATUS_SUCCESS != wInitStatus) { + wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_DEVICE); + gpphTmlNfc_Context->pDevHandle = NULL; + } else { + gpphTmlNfc_Context->tReadInfo.bEnable = 0; + gpphTmlNfc_Context->tWriteInfo.bEnable = 0; + gpphTmlNfc_Context->tReadInfo.bThreadBusy = false; + gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false; + + if (0 != sem_init(&gpphTmlNfc_Context->rxSemaphore, 0, 0)) { + wInitStatus = NFCSTATUS_FAILED; + } else if (0 != sem_init(&gpphTmlNfc_Context->txSemaphore, 0, 0)) { + wInitStatus = NFCSTATUS_FAILED; + } else if (0 != sem_init(&gpphTmlNfc_Context->postMsgSemaphore, 0, 0)) { + wInitStatus = NFCSTATUS_FAILED; + } else { + sem_post(&gpphTmlNfc_Context->postMsgSemaphore); + /* Start TML thread (to handle write and read operations) */ + if (NFCSTATUS_SUCCESS != phTmlNfc_StartThread()) { + wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED); + } else { + /* Create Timer used for Retransmission of NCI packets */ + gpphTmlNfc_Context->dwTimerId = phOsalNfc_Timer_Create(); + if (PH_OSALNFC_TIMER_ID_INVALID != gpphTmlNfc_Context->dwTimerId) { + /* Store the Thread Identifier to which Message is to be posted */ + gpphTmlNfc_Context->dwCallbackThreadId = + pConfig->dwGetMsgThreadId; + /* Enable retransmission of Nci packet & set retry count to + * default */ + gpphTmlNfc_Context->eConfig = phTmlNfc_e_DisableRetrans; + /* Retry Count = Standby Recovery time of NFCC / Retransmission + * time + 1 */ + gpphTmlNfc_Context->bRetryCount = + (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1; + gpphTmlNfc_Context->bWriteCbInvoked = false; + } else { + wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED); + } + } + } + } + } + } + /* Clean up all the TML resources if any error */ + if (NFCSTATUS_SUCCESS != wInitStatus) { + /* Clear all handles and memory locations initialized during init */ + phTmlNfc_CleanUp(); + } + + return wInitStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_ConfigNciPktReTx +** +** Description Provides Enable/Disable Retransmission of NCI packets +** Needed in case of Timeout between Transmission and Reception +** of NCI packets. Retransmission can be enabled only if +** standby mode is enabled +** +** Parameters eConfig - values from phTmlNfc_ConfigRetrans_t +** bRetryCount - Number of times Nci packets shall be +** retransmitted (default = 3) +** +** Returns None +** +*******************************************************************************/ +void phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfiguration, + uint8_t bRetryCounter) { + /* Enable/Disable Retransmission */ + + gpphTmlNfc_Context->eConfig = eConfiguration; + if (phTmlNfc_e_EnableRetrans == eConfiguration) { + /* Check whether Retry counter passed is valid */ + if (0 != bRetryCounter) { + gpphTmlNfc_Context->bRetryCount = bRetryCounter; + } + /* Set retry counter to its default value */ + else { + /* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 + */ + gpphTmlNfc_Context->bRetryCount = + (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1; + } + } + + return; +} + +/******************************************************************************* +** +** Function phTmlNfc_StartThread +** +** Description Initializes comport, reader and writer threads +** +** Parameters None +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - threads initialized successfully +** NFCSTATUS_FAILED - initialization failed due to system error +** +*******************************************************************************/ +static NFCSTATUS phTmlNfc_StartThread(void) { + NFCSTATUS wStartStatus = NFCSTATUS_SUCCESS; + void* h_threadsEvent = 0x00; + uint32_t dwEvent; + int pthread_create_status = 0; + + /* Create Reader and Writer threads */ + pthread_create_status = + pthread_create(&gpphTmlNfc_Context->readerThread, NULL, + (void*)&phTmlNfc_TmlThread, (void*)h_threadsEvent); + if (0 != pthread_create_status) { + wStartStatus = NFCSTATUS_FAILED; + } else { + /*Start Writer Thread*/ + pthread_create_status = + pthread_create(&gpphTmlNfc_Context->writerThread, NULL, + (void*)&phTmlNfc_TmlWriterThread, (void*)h_threadsEvent); + if (0 != pthread_create_status) { + wStartStatus = NFCSTATUS_FAILED; + } + } + + return wStartStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_ReTxTimerCb +** +** Description This is the timer callback function after timer expiration. +** +** Parameters dwThreadId - id of the thread posting message +** pContext - context provided by upper layer +** +** Returns None +** +*******************************************************************************/ +static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void* pContext) { + if ((gpphTmlNfc_Context->dwTimerId == dwTimerId) && (NULL == pContext)) { + /* If Retry Count has reached its limit,Retransmit Nci + packet */ + if (0 == bCurrentRetryCount) { + /* Since the count has reached its limit,return from timer callback + Upper layer Timeout would have happened */ + } else { + bCurrentRetryCount--; + gpphTmlNfc_Context->tWriteInfo.bThreadBusy = true; + gpphTmlNfc_Context->tWriteInfo.bEnable = 1; + } + sem_post(&gpphTmlNfc_Context->txSemaphore); + } + + return; +} + +/******************************************************************************* +** +** Function phTmlNfc_InitiateTimer +** +** Description Start a timer for Tx and Rx thread. +** +** Parameters void +** +** Returns NFC status +** +*******************************************************************************/ +static NFCSTATUS phTmlNfc_InitiateTimer(void) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + /* Start Timer once Nci packet is sent */ + wStatus = phOsalNfc_Timer_Start(gpphTmlNfc_Context->dwTimerId, + (uint32_t)PHTMLNFC_MAXTIME_RETRANSMIT, + phTmlNfc_ReTxTimerCb, NULL); + + return wStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_TmlThread +** +** Description Read the data from the lower layer driver +** +** Parameters pParam - parameters for Writer thread function +** +** Returns None +** +*******************************************************************************/ +static void phTmlNfc_TmlThread(void* pParam) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE; + uint8_t temp[260]; + /* Transaction info buffer to be passed to Callback Thread */ + static phTmlNfc_TransactInfo_t tTransactionInfo; + /* Structure containing Tml callback function and parameters to be invoked + by the callback thread */ + static phLibNfc_DeferredCall_t tDeferredInfo; + /* Initialize Message structure to post message onto Callback Thread */ + static phLibNfc_Message_t tMsg; + UNUSED(pParam); + NXPLOG_TML_D("PN54X - Tml Reader Thread Started................\n"); + + /* Writer thread loop shall be running till shutdown is invoked */ + while (gpphTmlNfc_Context->bThreadDone) { + /* If Tml write is requested */ + /* Set the variable to success initially */ + wStatus = NFCSTATUS_SUCCESS; + sem_wait(&gpphTmlNfc_Context->rxSemaphore); + + /* If Tml read is requested */ + if (1 == gpphTmlNfc_Context->tReadInfo.bEnable) { + NXPLOG_TML_D("PN54X - Read requested.....\n"); + /* Set the variable to success initially */ + wStatus = NFCSTATUS_SUCCESS; + + /* Variable to fetch the actual number of bytes read */ + dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE; + + /* Read the data from the file onto the buffer */ + if (NULL != gpphTmlNfc_Context->pDevHandle) { + NXPLOG_TML_D("PN54X - Invoking I2C Read.....\n"); + dwNoBytesWrRd = + phTmlNfc_i2c_read(gpphTmlNfc_Context->pDevHandle, temp, 260); + + if (-1 == dwNoBytesWrRd) { + NXPLOG_TML_E("PN54X - Error in I2C Read.....\n"); + sem_post(&gpphTmlNfc_Context->rxSemaphore); + } else if (dwNoBytesWrRd > 260) { + NXPLOG_TML_E("Numer of bytes read exceeds the limit 260.....\n"); + sem_post(&gpphTmlNfc_Context->rxSemaphore); + } else { + memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd); + + NXPLOG_TML_D("PN54X - I2C Read successful.....\n"); + /* This has to be reset only after a successful read */ + gpphTmlNfc_Context->tReadInfo.bEnable = 0; + if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) && + (0x00 != (gpphTmlNfc_Context->tReadInfo.pBuffer[0] & 0xE0))) { + NXPLOG_TML_D("PN54X - Retransmission timer stopped.....\n"); + /* Stop Timer to prevent Retransmission */ + uint32_t timerStatus = + phOsalNfc_Timer_Stop(gpphTmlNfc_Context->dwTimerId); + if (NFCSTATUS_SUCCESS != timerStatus) { + NXPLOG_TML_E("PN54X - timer stopped returned failure.....\n"); + } else { + gpphTmlNfc_Context->bWriteCbInvoked = false; + } + } + if (gpphTmlNfc_Context->tWriteInfo.bThreadBusy) { + NXPLOG_TML_D("Delay Read if write thread is busy"); + usleep(2000); /*2ms delay to give prio to write complete */ + } + /* Update the actual number of bytes read including header */ + gpphTmlNfc_Context->tReadInfo.wLength = (uint16_t)(dwNoBytesWrRd); + phNxpNciHal_print_packet("RECV", + gpphTmlNfc_Context->tReadInfo.pBuffer, + gpphTmlNfc_Context->tReadInfo.wLength); + + dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE; + + /* Fill the Transaction info structure to be passed to Callback + * Function */ + tTransactionInfo.wStatus = wStatus; + tTransactionInfo.pBuff = gpphTmlNfc_Context->tReadInfo.pBuffer; + /* Actual number of bytes read is filled in the structure */ + tTransactionInfo.wLength = gpphTmlNfc_Context->tReadInfo.wLength; + + /* Read operation completed successfully. Post a Message onto Callback + * Thread*/ + /* Prepare the message to be posted on User thread */ + tDeferredInfo.pCallback = &phTmlNfc_ReadDeferredCb; + tDeferredInfo.pParameter = &tTransactionInfo; + tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG; + tMsg.pMsgData = &tDeferredInfo; + tMsg.Size = sizeof(tDeferredInfo); + NXPLOG_TML_D("PN54X - Posting read message.....\n"); + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg); + } + } else { + NXPLOG_TML_D("PN54X -gpphTmlNfc_Context->pDevHandle is NULL"); + } + } else { + NXPLOG_TML_D("PN54X - read request NOT enabled"); + usleep(10 * 1000); + } + } /* End of While loop */ + + return; +} + +/******************************************************************************* +** +** Function phTmlNfc_TmlWriterThread +** +** Description Writes the requested data onto the lower layer driver +** +** Parameters pParam - context provided by upper layer +** +** Returns None +** +*******************************************************************************/ +static void phTmlNfc_TmlWriterThread(void* pParam) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE; + /* Transaction info buffer to be passed to Callback Thread */ + static phTmlNfc_TransactInfo_t tTransactionInfo; + /* Structure containing Tml callback function and parameters to be invoked + by the callback thread */ + static phLibNfc_DeferredCall_t tDeferredInfo; + /* Initialize Message structure to post message onto Callback Thread */ + static phLibNfc_Message_t tMsg; + /* In case of I2C Write Retry */ + static uint16_t retry_cnt; + UNUSED(pParam); + NXPLOG_TML_D("PN54X - Tml Writer Thread Started................\n"); + + /* Writer thread loop shall be running till shutdown is invoked */ + while (gpphTmlNfc_Context->bThreadDone) { + NXPLOG_TML_D("PN54X - Tml Writer Thread Running................\n"); + sem_wait(&gpphTmlNfc_Context->txSemaphore); + /* If Tml write is requested */ + if (1 == gpphTmlNfc_Context->tWriteInfo.bEnable) { + NXPLOG_TML_D("PN54X - Write requested.....\n"); + /* Set the variable to success initially */ + wStatus = NFCSTATUS_SUCCESS; + if (NULL != gpphTmlNfc_Context->pDevHandle) { + retry: + gpphTmlNfc_Context->tWriteInfo.bEnable = 0; + /* Variable to fetch the actual number of bytes written */ + dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE; + /* Write the data in the buffer onto the file */ + NXPLOG_TML_D("PN54X - Invoking I2C Write.....\n"); + dwNoBytesWrRd = + phTmlNfc_i2c_write(gpphTmlNfc_Context->pDevHandle, + gpphTmlNfc_Context->tWriteInfo.pBuffer, + gpphTmlNfc_Context->tWriteInfo.wLength); + + /* Try I2C Write Five Times, if it fails : Raju */ + if (-1 == dwNoBytesWrRd) { + if (getDownloadFlag() == true) { + if (retry_cnt++ < MAX_WRITE_RETRY_COUNT) { + NXPLOG_NCIHAL_E("PN54X - Error in I2C Write - Retry 0x%x", + retry_cnt); + // Add a 10 ms delay to ensure NFCC is not still in stand by mode. + usleep(10 * 1000); + goto retry; + } + } + NXPLOG_TML_E("PN54X - Error in I2C Write.....\n"); + wStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED); + } else { + phNxpNciHal_print_packet("SEND", + gpphTmlNfc_Context->tWriteInfo.pBuffer, + gpphTmlNfc_Context->tWriteInfo.wLength); + } + retry_cnt = 0; + if (NFCSTATUS_SUCCESS == wStatus) { + NXPLOG_TML_D("PN54X - I2C Write successful.....\n"); + dwNoBytesWrRd = PH_TMLNFC_VALUE_ONE; + } + /* Fill the Transaction info structure to be passed to Callback Function + */ + tTransactionInfo.wStatus = wStatus; + tTransactionInfo.pBuff = gpphTmlNfc_Context->tWriteInfo.pBuffer; + /* Actual number of bytes written is filled in the structure */ + tTransactionInfo.wLength = (uint16_t)dwNoBytesWrRd; + + /* Prepare the message to be posted on the User thread */ + tDeferredInfo.pCallback = &phTmlNfc_WriteDeferredCb; + tDeferredInfo.pParameter = &tTransactionInfo; + /* Write operation completed successfully. Post a Message onto Callback + * Thread*/ + tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG; + tMsg.pMsgData = &tDeferredInfo; + tMsg.Size = sizeof(tDeferredInfo); + + /* Check whether Retransmission needs to be started, + * If yes, Post message only if + * case 1. Message is not posted && + * case 11. Write status is success || + * case 12. Last retry of write is also failure + */ + if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) && + (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) { + if (gpphTmlNfc_Context->bWriteCbInvoked == false) { + if ((NFCSTATUS_SUCCESS == wStatus) || (bCurrentRetryCount == 0)) { + NXPLOG_TML_D("PN54X - Posting Write message.....\n"); + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, + &tMsg); + gpphTmlNfc_Context->bWriteCbInvoked = true; + } + } + } else { + NXPLOG_TML_D("PN54X - Posting Fresh Write message.....\n"); + phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg); + } + } else { + NXPLOG_TML_D("PN54X - gpphTmlNfc_Context->pDevHandle is NULL"); + } + + /* If Data packet is sent, then NO retransmission */ + if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) && + (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) { + NXPLOG_TML_D("PN54X - Starting timer for Retransmission case"); + wStatus = phTmlNfc_InitiateTimer(); + if (NFCSTATUS_SUCCESS != wStatus) { + /* Reset Variables used for Retransmission */ + NXPLOG_TML_D("PN54X - Retransmission timer initiate failed"); + gpphTmlNfc_Context->tWriteInfo.bEnable = 0; + bCurrentRetryCount = 0; + } + } + } else { + NXPLOG_TML_D("PN54X - Write request NOT enabled"); + usleep(10000); + } + + } /* End of While loop */ + + return; +} + +/******************************************************************************* +** +** Function phTmlNfc_CleanUp +** +** Description Clears all handles opened during TML initialization +** +** Parameters None +** +** Returns None +** +*******************************************************************************/ +static void phTmlNfc_CleanUp(void) { + NFCSTATUS wRetval = NFCSTATUS_SUCCESS; + + if (NULL == gpphTmlNfc_Context) { + return; + } + if (NULL != gpphTmlNfc_Context->pDevHandle) { + (void)phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0); + gpphTmlNfc_Context->bThreadDone = 0; + } + sem_destroy(&gpphTmlNfc_Context->rxSemaphore); + sem_destroy(&gpphTmlNfc_Context->txSemaphore); + sem_destroy(&gpphTmlNfc_Context->postMsgSemaphore); + phTmlNfc_i2c_close(gpphTmlNfc_Context->pDevHandle); + gpphTmlNfc_Context->pDevHandle = NULL; + /* Clear memory allocated for storing Context variables */ + free((void*)gpphTmlNfc_Context); + /* Set the pointer to NULL to indicate De-Initialization */ + gpphTmlNfc_Context = NULL; + + return; +} + +/******************************************************************************* +** +** Function phTmlNfc_Shutdown +** +** Description Uninitializes TML layer and hardware interface +** +** Parameters None +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - TML configuration released successfully +** NFCSTATUS_INVALID_PARAMETER - at least one parameter is +** invalid +** NFCSTATUS_FAILED - un-initialization failed (example: unable +** to close interface) +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_Shutdown(void) { + NFCSTATUS wShutdownStatus = NFCSTATUS_SUCCESS; + + /* Check whether TML is Initialized */ + if (NULL != gpphTmlNfc_Context) { + /* Reset thread variable to terminate the thread */ + gpphTmlNfc_Context->bThreadDone = 0; + usleep(1000); + /* Clear All the resources allocated during initialization */ + sem_post(&gpphTmlNfc_Context->rxSemaphore); + usleep(1000); + sem_post(&gpphTmlNfc_Context->txSemaphore); + usleep(1000); + sem_post(&gpphTmlNfc_Context->postMsgSemaphore); + usleep(1000); + sem_post(&gpphTmlNfc_Context->postMsgSemaphore); + usleep(1000); + if (0 != pthread_join(gpphTmlNfc_Context->readerThread, (void**)NULL)) { + NXPLOG_TML_E("Fail to kill reader thread!"); + } + if (0 != pthread_join(gpphTmlNfc_Context->writerThread, (void**)NULL)) { + NXPLOG_TML_E("Fail to kill writer thread!"); + } + NXPLOG_TML_D("bThreadDone == 0"); + + phTmlNfc_CleanUp(); + } else { + wShutdownStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED); + } + + return wShutdownStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_Write +** +** Description Asynchronously writes given data block to hardware +** interface/driver. Enables writer thread if there are no +** write requests pending. Returns successfully once writer +** thread completes write operation. Notifies upper layer using +** callback mechanism. +** +** NOTE: +** * it is important to post a message with id +** PH_TMLNFC_WRITE_MESSAGE to IntegrationThread after data +** has been written to PN54X +** * if CRC needs to be computed, then input buffer should be +** capable to store two more bytes apart from length of +** packet +** +** Parameters pBuffer - data to be sent +** wLength - length of data buffer +** pTmlWriteComplete - pointer to the function to be invoked +** upon completion +** pContext - context provided by upper layer +** +** Returns NFC status: +** NFCSTATUS_PENDING - command is yet to be processed +** NFCSTATUS_INVALID_PARAMETER - at least one parameter is +** invalid +** NFCSTATUS_BUSY - write request is already in progress +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_Write(uint8_t* pBuffer, uint16_t wLength, + pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete, + void* pContext) { + NFCSTATUS wWriteStatus; + + /* Check whether TML is Initialized */ + + if (NULL != gpphTmlNfc_Context) { + if ((NULL != gpphTmlNfc_Context->pDevHandle) && (NULL != pBuffer) && + (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlWriteComplete)) { + if (!gpphTmlNfc_Context->tWriteInfo.bThreadBusy) { + /* Setting the flag marks beginning of a Write Operation */ + gpphTmlNfc_Context->tWriteInfo.bThreadBusy = true; + /* Copy the buffer, length and Callback function, + This shall be utilized while invoking the Callback function in thread + */ + gpphTmlNfc_Context->tWriteInfo.pBuffer = pBuffer; + gpphTmlNfc_Context->tWriteInfo.wLength = wLength; + gpphTmlNfc_Context->tWriteInfo.pThread_Callback = pTmlWriteComplete; + gpphTmlNfc_Context->tWriteInfo.pContext = pContext; + + wWriteStatus = NFCSTATUS_PENDING; + // FIXME: If retry is going on. Stop the retry thread/timer + if (phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) { + /* Set retry count to default value */ + // FIXME: If the timer expired there, and meanwhile we have created + // a new request. The expired timer will think that retry is still + // ongoing. + bCurrentRetryCount = gpphTmlNfc_Context->bRetryCount; + gpphTmlNfc_Context->bWriteCbInvoked = false; + } + /* Set event to invoke Writer Thread */ + gpphTmlNfc_Context->tWriteInfo.bEnable = 1; + sem_post(&gpphTmlNfc_Context->txSemaphore); + } else { + wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY); + } + } else { + wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER); + } + } else { + wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED); + } + + return wWriteStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_Read +** +** Description Asynchronously reads data from the driver +** Number of bytes to be read and buffer are passed by upper +** layer. +** Enables reader thread if there are no read requests pending +** Returns successfully once read operation is completed +** Notifies upper layer using callback mechanism +** +** Parameters pBuffer - location to send read data to the upper layer via +** callback +** wLength - length of read data buffer passed by upper layer +** pTmlReadComplete - pointer to the function to be invoked +** upon completion of read operation +** pContext - context provided by upper layer +** +** Returns NFC status: +** NFCSTATUS_PENDING - command is yet to be processed +** NFCSTATUS_INVALID_PARAMETER - at least one parameter is +** invalid +** NFCSTATUS_BUSY - read request is already in progress +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength, + pphTmlNfc_TransactCompletionCb_t pTmlReadComplete, + void* pContext) { + NFCSTATUS wReadStatus; + + /* Check whether TML is Initialized */ + if (NULL != gpphTmlNfc_Context) { + if ((gpphTmlNfc_Context->pDevHandle != NULL) && (NULL != pBuffer) && + (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlReadComplete)) { + if (!gpphTmlNfc_Context->tReadInfo.bThreadBusy) { + /* Setting the flag marks beginning of a Read Operation */ + gpphTmlNfc_Context->tReadInfo.bThreadBusy = true; + /* Copy the buffer, length and Callback function, + This shall be utilized while invoking the Callback function in thread + */ + gpphTmlNfc_Context->tReadInfo.pBuffer = pBuffer; + gpphTmlNfc_Context->tReadInfo.wLength = wLength; + gpphTmlNfc_Context->tReadInfo.pThread_Callback = pTmlReadComplete; + gpphTmlNfc_Context->tReadInfo.pContext = pContext; + wReadStatus = NFCSTATUS_PENDING; + + /* Set event to invoke Reader Thread */ + gpphTmlNfc_Context->tReadInfo.bEnable = 1; + sem_post(&gpphTmlNfc_Context->rxSemaphore); + } else { + wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY); + } + } else { + wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER); + } + } else { + wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED); + } + + return wReadStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_ReadAbort +** +** Description Aborts pending read request (if any) +** +** Parameters None +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - ongoing read operation aborted +** NFCSTATUS_INVALID_PARAMETER - at least one parameter is +** invalid +** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized +** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel read +** operation +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_ReadAbort(void) { + NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER; + gpphTmlNfc_Context->tReadInfo.bEnable = 0; + + /*Reset the flag to accept another Read Request */ + gpphTmlNfc_Context->tReadInfo.bThreadBusy = false; + wStatus = NFCSTATUS_SUCCESS; + + return wStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_WriteAbort +** +** Description Aborts pending write request (if any) +** +** Parameters None +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - ongoing write operation aborted +** NFCSTATUS_INVALID_PARAMETER - at least one parameter is +** invalid +** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized +** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel write +** operation +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_WriteAbort(void) { + NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER; + + gpphTmlNfc_Context->tWriteInfo.bEnable = 0; + /* Stop if any retransmission is in progress */ + bCurrentRetryCount = 0; + + /* Reset the flag to accept another Write Request */ + gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false; + wStatus = NFCSTATUS_SUCCESS; + + return wStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_IoCtl +** +** Description Resets device when insisted by upper layer +** Number of bytes to be read and buffer are passed by upper +** layer +** Enables reader thread if there are no read requests pending +** Returns successfully once read operation is completed +** Notifies upper layer using callback mechanism +** +** Parameters eControlCode - control code for a specific operation +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - ioctl command completed successfully +** NFCSTATUS_FAILED - ioctl command request failed +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode) { + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if (NULL == gpphTmlNfc_Context) { + wStatus = NFCSTATUS_FAILED; + } else { + switch (eControlCode) { + case phTmlNfc_e_ResetDevice: { + /*Reset PN54X*/ + phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1); + usleep(100 * 1000); + phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0); + usleep(100 * 1000); + phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1); + break; + } + case phTmlNfc_e_EnableNormalMode: { + /*Reset PN54X*/ + phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0); + usleep(10 * 1000); + phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1); + usleep(100 * 1000); + break; + } + case phTmlNfc_e_EnableDownloadMode: { + phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0); + (void)phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 2); + usleep(100 * 1000); + break; + } + default: { + wStatus = NFCSTATUS_INVALID_PARAMETER; + break; + } + } + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phTmlNfc_DeferredCall +** +** Description Posts message on upper layer thread +** upon successful read or write operation +** +** Parameters dwThreadId - id of the thread posting message +** ptWorkerMsg - message to be posted +** +** Returns None +** +*******************************************************************************/ +void phTmlNfc_DeferredCall(uintptr_t dwThreadId, + phLibNfc_Message_t* ptWorkerMsg) { + intptr_t bPostStatus; + UNUSED(dwThreadId); + /* Post message on the user thread to invoke the callback function */ + sem_wait(&gpphTmlNfc_Context->postMsgSemaphore); + bPostStatus = + phDal4Nfc_msgsnd(gpphTmlNfc_Context->dwCallbackThreadId, ptWorkerMsg, 0); + sem_post(&gpphTmlNfc_Context->postMsgSemaphore); +} + +/******************************************************************************* +** +** Function phTmlNfc_ReadDeferredCb +** +** Description Read thread call back function +** +** Parameters pParams - context provided by upper layer +** +** Returns None +** +*******************************************************************************/ +static void phTmlNfc_ReadDeferredCb(void* pParams) { + /* Transaction info buffer to be passed to Callback Function */ + phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams; + + /* Reset the flag to accept another Read Request */ + gpphTmlNfc_Context->tReadInfo.bThreadBusy = false; + gpphTmlNfc_Context->tReadInfo.pThread_Callback( + gpphTmlNfc_Context->tReadInfo.pContext, pTransactionInfo); + + return; +} + +/******************************************************************************* +** +** Function phTmlNfc_WriteDeferredCb +** +** Description Write thread call back function +** +** Parameters pParams - context provided by upper layer +** +** Returns None +** +*******************************************************************************/ +static void phTmlNfc_WriteDeferredCb(void* pParams) { + /* Transaction info buffer to be passed to Callback Function */ + phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams; + + /* Reset the flag to accept another Write Request */ + gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false; + gpphTmlNfc_Context->tWriteInfo.pThread_Callback( + gpphTmlNfc_Context->tWriteInfo.pContext, pTransactionInfo); + + return; +} + +void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result) { + fragmentation_enabled = result; +} + +phTmlNfc_i2cfragmentation_t phTmlNfc_get_fragmentation_enabled() { + return fragmentation_enabled; +} diff --git a/pn54x/tml/phTmlNfc.h b/pn54x/tml/phTmlNfc.h new file mode 100644 index 0000000..3955354 --- /dev/null +++ b/pn54x/tml/phTmlNfc.h @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Transport Mapping Layer header files containing APIs related to initializing, + * reading + * and writing data into files provided by the driver interface. + * + * API listed here encompasses Transport Mapping Layer interfaces required to be + * mapped + * to different Interfaces and Platforms. + * + */ + +#ifndef PHTMLNFC_H +#define PHTMLNFC_H + +#include <phNfcCommon.h> + +/* + * Message posted by Reader thread upon + * completion of requested operation + */ +#define PH_TMLNFC_READ_MESSAGE (0xAA) + +/* + * Message posted by Writer thread upon + * completion of requested operation + */ +#define PH_TMLNFC_WRITE_MESSAGE (0x55) + +/* + * Value indicates to reset device + */ +#define PH_TMLNFC_RESETDEVICE (0x00008001) + +/* +***************************Globals,Structure and Enumeration ****************** +*/ + +/* + * Transaction (Tx/Rx) completion information structure of TML + * + * This structure holds the completion callback information of the + * transaction passed from the TML layer to the Upper layer + * along with the completion callback. + * + * The value of field wStatus can be interpreted as: + * + * - NFCSTATUS_SUCCESS Transaction performed + * successfully. + * - NFCSTATUS_FAILED Failed to wait on Read/Write + * operation. + * - NFCSTATUS_INSUFFICIENT_STORAGE Not enough memory to store data in + * case of read. + * - NFCSTATUS_BOARD_COMMUNICATION_ERROR Failure to Read/Write from the + * file or timeout. + */ + +typedef struct phTmlNfc_TransactInfo { + NFCSTATUS wStatus; /* Status of the Transaction Completion*/ + uint8_t* pBuff; /* Response Data of the Transaction*/ + uint16_t wLength; /* Data size of the Transaction*/ +} phTmlNfc_TransactInfo_t; /* Instance of Transaction structure */ + +/* + * TML transreceive completion callback to Upper Layer + * + * pContext - Context provided by upper layer + * pInfo - Transaction info. See phTmlNfc_TransactInfo + */ +typedef void (*pphTmlNfc_TransactCompletionCb_t)( + void* pContext, phTmlNfc_TransactInfo_t* pInfo); + +/* + * TML Deferred callback interface structure invoked by upper layer + * + * This could be used for read/write operations + * + * dwMsgPostedThread Message source identifier + * pParams Parameters for the deferred call processing + */ +typedef void (*pphTmlNfc_DeferFuncPointer_t)(uint32_t dwMsgPostedThread, + void* pParams); + +/* + * Enum definition contains supported ioctl control codes. + * + * phTmlNfc_IoCtl + */ +typedef enum { + phTmlNfc_e_Invalid = 0, + phTmlNfc_e_ResetDevice = PH_TMLNFC_RESETDEVICE, /* Reset the device */ + phTmlNfc_e_EnableDownloadMode, /* Do the hardware setting to enter into + download mode */ + phTmlNfc_e_EnableNormalMode /* Hardware setting for normal mode of operation + */ +} phTmlNfc_ControlCode_t; /* Control code for IOCTL call */ + +/* + * Enable / Disable Re-Transmission of Packets + * + * phTmlNfc_ConfigNciPktReTx + */ +typedef enum { + phTmlNfc_e_EnableRetrans = 0x00, /*Enable retransmission of Nci packet */ + phTmlNfc_e_DisableRetrans = 0x01 /*Disable retransmission of Nci packet */ +} phTmlNfc_ConfigRetrans_t; /* Configuration for Retransmission */ + +/* + * Structure containing details related to read and write operations + * + */ +typedef struct phTmlNfc_ReadWriteInfo { + volatile uint8_t bEnable; /*This flag shall decide whether to perform + Write/Read operation */ + uint8_t + bThreadBusy; /*Flag to indicate thread is busy on respective operation */ + /* Transaction completion Callback function */ + pphTmlNfc_TransactCompletionCb_t pThread_Callback; + void* pContext; /*Context passed while invocation of operation */ + uint8_t* pBuffer; /*Buffer passed while invocation of operation */ + uint16_t wLength; /*Length of data read/written */ + NFCSTATUS wWorkStatus; /*Status of the transaction performed */ +} phTmlNfc_ReadWriteInfo_t; + +/* + *Base Context Structure containing members required for entire session + */ +typedef struct phTmlNfc_Context { + pthread_t readerThread; /*Handle to the thread which handles write and read + operations */ + pthread_t writerThread; + volatile uint8_t + bThreadDone; /*Flag to decide whether to run or abort the thread */ + phTmlNfc_ConfigRetrans_t + eConfig; /*Retransmission of Nci Packet during timeout */ + uint8_t bRetryCount; /*Number of times retransmission shall happen */ + uint8_t bWriteCbInvoked; /* Indicates whether write callback is invoked during + retransmission */ + uint32_t dwTimerId; /* Timer used to retransmit nci packet */ + phTmlNfc_ReadWriteInfo_t tReadInfo; /*Pointer to Reader Thread Structure */ + phTmlNfc_ReadWriteInfo_t tWriteInfo; /*Pointer to Writer Thread Structure */ + void* pDevHandle; /* Pointer to Device Handle */ + uintptr_t dwCallbackThreadId; /* Thread ID to which message to be posted */ + uint8_t bEnableCrc; /*Flag to validate/not CRC for input buffer */ + sem_t rxSemaphore; + sem_t txSemaphore; /* Lock/Aquire txRx Semaphore */ + sem_t postMsgSemaphore; /* Semaphore to post message atomically by Reader & + writer thread */ +} phTmlNfc_Context_t; + +/* + * TML Configuration exposed to upper layer. + */ +typedef struct phTmlNfc_Config { + /* Port name connected to PN54X + * + * Platform specific canonical device name to which PN54X is connected. + * + * e.g. On Linux based systems this would be /dev/PN54X + */ + int8_t* pDevName; + /* Callback Thread ID + * + * This is the thread ID on which the Reader & Writer thread posts message. */ + uintptr_t dwGetMsgThreadId; + /* Communication speed between DH and PN54X + * + * This is the baudrate of the bus for communication between DH and PN54X */ + uint32_t dwBaudRate; +} phTmlNfc_Config_t, *pphTmlNfc_Config_t; /* pointer to phTmlNfc_Config_t */ + +/* + * TML Deferred Callback structure used to invoke Upper layer Callback function. + */ +typedef struct { + /* Deferred callback function to be invoked */ + pphTmlNfc_DeferFuncPointer_t pDef_call; + /* Source identifier + * + * Identifier of the source which posted the message + */ + uint32_t dwMsgPostedThread; + /** Actual Message + * + * This is passed as a parameter passed to the deferred callback function + * pDef_call. */ + void* pParams; +} phTmlNfc_DeferMsg_t; /* DeferMsg structure passed to User Thread */ + +typedef enum { + I2C_FRAGMENATATION_DISABLED, /*i2c fragmentation_disabled */ + I2C_FRAGMENTATION_ENABLED /*i2c_fragmentation_enabled */ +} phTmlNfc_i2cfragmentation_t; +/* Function declarations */ +NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig); +NFCSTATUS phTmlNfc_Shutdown(void); +NFCSTATUS phTmlNfc_Write(uint8_t* pBuffer, uint16_t wLength, + pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete, + void* pContext); +NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength, + pphTmlNfc_TransactCompletionCb_t pTmlReadComplete, + void* pContext); +NFCSTATUS phTmlNfc_WriteAbort(void); +NFCSTATUS phTmlNfc_ReadAbort(void); +NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode); +void phTmlNfc_DeferredCall(uintptr_t dwThreadId, + phLibNfc_Message_t* ptWorkerMsg); +void phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfig, + uint8_t bRetryCount); +void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t enable); +phTmlNfc_i2cfragmentation_t phTmlNfc_get_fragmentation_enabled(); +#endif /* PHTMLNFC_H */ diff --git a/pn54x/tml/phTmlNfc_i2c.c b/pn54x/tml/phTmlNfc_i2c.c new file mode 100644 index 0000000..781f19b --- /dev/null +++ b/pn54x/tml/phTmlNfc_i2c.c @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * DAL I2C port implementation for linux + * + * Project: Trusted NFC Linux + * + */ +#include <errno.h> +#include <fcntl.h> +#include <hardware/nfc.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/select.h> +#include <termios.h> +#include <unistd.h> + +#include <phNfcStatus.h> +#include <phNxpLog.h> +#include <phTmlNfc_i2c.h> +#include <string.h> +#include "phNxpNciHal_utils.h" + +#define CRC_LEN 2 +#define NORMAL_MODE_HEADER_LEN 3 +#define FW_DNLD_HEADER_LEN 2 +#define FW_DNLD_LEN_OFFSET 1 +#define NORMAL_MODE_LEN_OFFSET 2 +#define FRAGMENTSIZE_MAX PHNFC_I2C_FRAGMENT_SIZE +static bool_t bFwDnldFlag = false; +extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; + +/******************************************************************************* +** +** Function phTmlNfc_i2c_close +** +** Description Closes PN54X device +** +** Parameters pDevHandle - device handle +** +** Returns None +** +*******************************************************************************/ +void phTmlNfc_i2c_close(void* pDevHandle) { + if (NULL != pDevHandle) { + close((intptr_t)pDevHandle); + } + + return; +} + +/******************************************************************************* +** +** Function phTmlNfc_i2c_open_and_configure +** +** Description Open and configure PN54X device +** +** Parameters pConfig - hardware information +** pLinkHandle - device handle +** +** Returns NFC status: +** NFCSTATUS_SUCCESS - open_and_configure operation success +** NFCSTATUS_INVALID_DEVICE - device open operation failure +** +*******************************************************************************/ +NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig, + void** pLinkHandle) { + int nHandle; + + NXPLOG_TML_D("Opening port=%s\n", pConfig->pDevName); + /* open port */ + nHandle = open((const char*)pConfig->pDevName, O_RDWR); + if (nHandle < 0) { + NXPLOG_TML_E("_i2c_open() Failed: retval %x", nHandle); + *pLinkHandle = NULL; + return NFCSTATUS_INVALID_DEVICE; + } + + *pLinkHandle = (void*)((intptr_t)nHandle); + + /*Reset PN54X*/ + phTmlNfc_i2c_reset((void*)((intptr_t)nHandle), 0); + usleep(10 * 1000); + phTmlNfc_i2c_reset((void*)((intptr_t)nHandle), 1); + + return NFCSTATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function phTmlNfc_i2c_read +** +** Description Reads requested number of bytes from PN54X device into given +** buffer +** +** Parameters pDevHandle - valid device handle +** pBuffer - buffer for read data +** nNbBytesToRead - number of bytes requested to be read +** +** Returns numRead - number of successfully read bytes +** -1 - read operation failure +** +*******************************************************************************/ +int phTmlNfc_i2c_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) { + int ret_Read; + int ret_Select; + int numRead = 0; + struct timeval tv; + fd_set rfds; + uint16_t totalBtyesToRead = 0; + + int i; + UNUSED(nNbBytesToRead); + if (NULL == pDevHandle) { + return -1; + } + + if (bFwDnldFlag == false) { + totalBtyesToRead = NORMAL_MODE_HEADER_LEN; + } else { + totalBtyesToRead = FW_DNLD_HEADER_LEN; + } + + /* Read with 2 second timeout, so that the read thread can be aborted + when the PN54X does not respond and we need to switch to FW download + mode. This should be done via a control socket instead. */ + FD_ZERO(&rfds); + FD_SET((intptr_t)pDevHandle, &rfds); + tv.tv_sec = 2; + tv.tv_usec = 1; + + ret_Select = + select((int)((intptr_t)pDevHandle + (int)1), &rfds, NULL, NULL, &tv); + if (ret_Select < 0) { + NXPLOG_TML_E("i2c select() errno : %x", errno); + return -1; + } else if (ret_Select == 0) { + NXPLOG_TML_E("i2c select() Timeout"); + return -1; + } else { + ret_Read = read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead); + if (ret_Read > 0) { + numRead += ret_Read; + } else if (ret_Read == 0) { + NXPLOG_TML_E("_i2c_read() [hdr]EOF"); + return -1; + } else { + NXPLOG_TML_E("_i2c_read() [hdr] errno : %x", errno); + return -1; + } + + if (bFwDnldFlag == false) { + totalBtyesToRead = NORMAL_MODE_HEADER_LEN; + } else { + totalBtyesToRead = FW_DNLD_HEADER_LEN; + } + + if (numRead < totalBtyesToRead) { + ret_Read = + read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead); + if (ret_Read != totalBtyesToRead - numRead) { + NXPLOG_TML_E("_i2c_read() [hdr] errno : %x", errno); + return -1; + } else { + numRead += ret_Read; + } + } + if (bFwDnldFlag == true) { + totalBtyesToRead = + pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN; + } else { + totalBtyesToRead = + pBuffer[NORMAL_MODE_LEN_OFFSET] + NORMAL_MODE_HEADER_LEN; + } + if ((totalBtyesToRead - numRead) != 0) { + ret_Read = read((intptr_t)pDevHandle, (pBuffer + numRead), + totalBtyesToRead - numRead); + if (ret_Read > 0) { + numRead += ret_Read; + } else if (ret_Read == 0) { + NXPLOG_TML_E("_i2c_read() [pyld] EOF"); + return -1; + } else { + if (bFwDnldFlag == false) { + NXPLOG_TML_E("_i2c_read() [hdr] received"); + phNxpNciHal_print_packet("RECV", pBuffer, NORMAL_MODE_HEADER_LEN); + } + NXPLOG_TML_E("_i2c_read() [pyld] errno : %x", errno); + return -1; + } + } else { + NXPLOG_TML_E("_>>>>> Empty packet recieved !!"); + } + } + return numRead; +} + +/******************************************************************************* +** +** Function phTmlNfc_i2c_write +** +** Description Writes requested number of bytes from given buffer into +** PN54X device +** +** Parameters pDevHandle - valid device handle +** pBuffer - buffer for read data +** nNbBytesToWrite - number of bytes requested to be written +** +** Returns numWrote - number of successfully written bytes +** -1 - write operation failure +** +*******************************************************************************/ +int phTmlNfc_i2c_write(void* pDevHandle, uint8_t* pBuffer, + int nNbBytesToWrite) { + int ret; + int numWrote = 0; + int i; + int numBytes = nNbBytesToWrite; + if (NULL == pDevHandle) { + return -1; + } + if (fragmentation_enabled == I2C_FRAGMENATATION_DISABLED && + nNbBytesToWrite > FRAGMENTSIZE_MAX) { + NXPLOG_TML_E( + "i2c_write() data larger than maximum I2C size,enable I2C " + "fragmentation"); + return -1; + } + while (numWrote < nNbBytesToWrite) { + if (fragmentation_enabled == I2C_FRAGMENTATION_ENABLED && + nNbBytesToWrite > FRAGMENTSIZE_MAX) { + if (nNbBytesToWrite - numWrote > FRAGMENTSIZE_MAX) { + numBytes = numWrote + FRAGMENTSIZE_MAX; + } else { + numBytes = nNbBytesToWrite; + } + } + ret = write((intptr_t)pDevHandle, pBuffer + numWrote, numBytes - numWrote); + if (ret > 0) { + numWrote += ret; + if (fragmentation_enabled == I2C_FRAGMENTATION_ENABLED && + numWrote < nNbBytesToWrite) { + usleep(500); + } + } else if (ret == 0) { + NXPLOG_TML_E("_i2c_write() EOF"); + return -1; + } else { + NXPLOG_TML_E("_i2c_write() errno : %x", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + + return numWrote; +} + +/******************************************************************************* +** +** Function phTmlNfc_i2c_reset +** +** Description Reset PN54X device, using VEN pin +** +** Parameters pDevHandle - valid device handle +** level - reset level +** +** Returns 0 - reset operation success +** -1 - reset operation failure +** +*******************************************************************************/ +#define PN544_SET_PWR _IOW(0xe9, 0x01, unsigned int) +int phTmlNfc_i2c_reset(void* pDevHandle, long level) { + int ret; + NXPLOG_TML_D("phTmlNfc_i2c_reset(), VEN level %ld", level); + + if (NULL == pDevHandle) { + return -1; + } + + ret = ioctl((intptr_t)pDevHandle, PN544_SET_PWR, level); + if (level == 2 && ret == 0) { + bFwDnldFlag = true; + } else { + bFwDnldFlag = false; + } + return ret; +} + +/******************************************************************************* +** +** Function getDownloadFlag +** +** Description Returns the current mode +** +** Parameters none +** +** Returns Current mode download/NCI +*******************************************************************************/ +bool_t getDownloadFlag(void) { return bFwDnldFlag; } diff --git a/pn54x/tml/phTmlNfc_i2c.h b/pn54x/tml/phTmlNfc_i2c.h new file mode 100644 index 0000000..0949a72 --- /dev/null +++ b/pn54x/tml/phTmlNfc_i2c.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * TML I2C port implementation for linux + */ + +/* Basic type definitions */ +#include <phNfcTypes.h> +#include <phTmlNfc.h> + +/* Function declarations */ +void phTmlNfc_i2c_close(void* pDevHandle); +NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig, + void** pLinkHandle); +int phTmlNfc_i2c_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead); +int phTmlNfc_i2c_write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite); +int phTmlNfc_i2c_reset(void* pDevHandle, long level); +bool_t getDownloadFlag(void); diff --git a/pn54x/utils/phNxpConfig.cpp b/pn54x/utils/phNxpConfig.cpp new file mode 100644 index 0000000..9e8c7cb --- /dev/null +++ b/pn54x/utils/phNxpConfig.cpp @@ -0,0 +1,865 @@ +/****************************************************************************** + * + * Copyright (C) 2011-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/****************************************************************************** + * + * The original Work has been changed by NXP Semiconductors. + * + * Copyright (C) 2013-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include <stdio.h> +#include <sys/stat.h> +#include <list> +#include <string> +#include <vector> + +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include "sparse_crc32.h" + +#if GENERIC_TARGET +const char alternative_config_path[] = "/data/vendor/nfc/"; +#else +const char alternative_config_path[] = ""; +#endif + +#if 1 +const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"}; +#else +const char* transport_config_paths[] = {"res/"}; +#endif +const int transport_config_path_size = + (sizeof(transport_config_paths) / sizeof(transport_config_paths[0])); + +#define config_name "libnfc-nxp.conf" +#define extra_config_base "libnfc-nxp-" +#define extra_config_ext ".conf" +#define IsStringValue 0x80000000 + +const char config_timestamp_path[] = + "/data/vendor/nfc/libnfc-nxpConfigState.bin"; + +namespace { + +size_t readConfigFile(const char* fileName, uint8_t** p_data) { + FILE* fd = fopen(fileName, "rb"); + if (fd == nullptr) return 0; + + fseek(fd, 0L, SEEK_END); + const size_t file_size = ftell(fd); + rewind(fd); + + uint8_t* buffer = new uint8_t[file_size]; + size_t read = fread(buffer, file_size, 1, fd); + fclose(fd); + + if (read == 1) { + *p_data = buffer; + return file_size; + } + + return 0; +} + +} // namespace + +using namespace ::std; + +class CNfcParam : public string { + public: + CNfcParam(); + CNfcParam(const char* name, const string& value); + CNfcParam(const char* name, unsigned long value); + virtual ~CNfcParam(); + unsigned long numValue() const { return m_numValue; } + const char* str_value() const { return m_str_value.c_str(); } + size_t str_len() const { return m_str_value.length(); } + + private: + string m_str_value; + unsigned long m_numValue; +}; + +class CNfcConfig : public vector<const CNfcParam*> { + public: + virtual ~CNfcConfig(); + static CNfcConfig& GetInstance(); + friend void readOptionalConfig(const char* optional); + bool isModified(); + void resetModified(); + + bool getValue(const char* name, char* pValue, size_t len) const; + bool getValue(const char* name, unsigned long& rValue) const; + bool getValue(const char* name, unsigned short& rValue) const; + bool getValue(const char* name, char* pValue, long len, long* readlen) const; + const CNfcParam* find(const char* p_name) const; + void clean(); + + private: + CNfcConfig(); + bool readConfig(const char* name, bool bResetContent); + void moveFromList(); + void moveToList(); + void add(const CNfcParam* pParam); + list<const CNfcParam*> m_list; + bool mValidFile; + uint32_t config_crc32_; + + unsigned long state; + + inline bool Is(unsigned long f) { return (state & f) == f; } + inline void Set(unsigned long f) { state |= f; } + inline void Reset(unsigned long f) { state &= ~f; } +}; + +/******************************************************************************* +** +** Function: isPrintable() +** +** Description: determine if 'c' is printable +** +** Returns: 1, if printable, otherwise 0 +** +*******************************************************************************/ +inline bool isPrintable(char c) { + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || c == '/' || c == '_' || c == '-' || c == '.'; +} + +/******************************************************************************* +** +** Function: isDigit() +** +** Description: determine if 'c' is numeral digit +** +** Returns: true, if numerical digit +** +*******************************************************************************/ +inline bool isDigit(char c, int base) { + if ('0' <= c && c <= '9') return true; + if (base == 16) { + if (('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')) return true; + } + return false; +} + +/******************************************************************************* +** +** Function: getDigitValue() +** +** Description: return numerical value of a decimal or hex char +** +** Returns: numerical value if decimal or hex char, otherwise 0 +** +*******************************************************************************/ +inline int getDigitValue(char c, int base) { + if ('0' <= c && c <= '9') return c - '0'; + if (base == 16) { + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + else if ('a' <= c && c <= 'f') + return c - 'a' + 10; + } + return 0; +} + +/******************************************************************************* +** +** Function: findConfigFilePathFromTransportConfigPaths() +** +** Description: find a config file path with a given config name from transport +** config paths +** +** Returns: none +** +*******************************************************************************/ +void findConfigFilePathFromTransportConfigPaths(const string& configName, + string& filePath) { + for (int i = 0; i < transport_config_path_size - 1; i++) { + filePath.assign(transport_config_paths[i]); + filePath += configName; + struct stat file_stat; + if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) { + return; + } + } + filePath.assign(transport_config_paths[transport_config_path_size - 1]); + filePath += configName; +} + +/******************************************************************************* +** +** Function: CNfcConfig::readConfig() +** +** Description: read Config settings and parse them into a linked list +** move the element from linked list to a array at the end +** +** Returns: 1, if there are any config data, 0 otherwise +** +*******************************************************************************/ +bool CNfcConfig::readConfig(const char* name, bool bResetContent) { + enum { + BEGIN_LINE = 1, + TOKEN, + STR_VALUE, + NUM_VALUE, + BEGIN_HEX, + BEGIN_QUOTE, + END_LINE + }; + + uint8_t* p_config = nullptr; + size_t config_size = readConfigFile(name, &p_config); + if (p_config == nullptr) { + ALOGE("%s Cannot open config file %s\n", __func__, name); + if (bResetContent) { + ALOGE("%s Using default value for all settings\n", __func__); + mValidFile = false; + } + return false; + } + + string token; + string strValue; + unsigned long numValue = 0; + CNfcParam* pParam = NULL; + int i = 0; + int base = 0; + char c; + int bflag = 0; + state = BEGIN_LINE; + + config_crc32_ = sparse_crc32(0, p_config, config_size); + mValidFile = true; + if (size() > 0) { + if (bResetContent) + clean(); + else + moveToList(); + } + + for (size_t offset = 0; offset != config_size; ++offset) { + c = p_config[offset]; + switch (state & 0xff) { + case BEGIN_LINE: + if (c == '#') + state = END_LINE; + else if (isPrintable(c)) { + i = 0; + token.erase(); + strValue.erase(); + state = TOKEN; + token.push_back(c); + } + break; + case TOKEN: + if (c == '=') { + token.push_back('\0'); + state = BEGIN_QUOTE; + } else if (isPrintable(c)) + token.push_back(c); + else + state = END_LINE; + break; + case BEGIN_QUOTE: + if (c == '"') { + state = STR_VALUE; + base = 0; + } else if (c == '0') + state = BEGIN_HEX; + else if (isDigit(c, 10)) { + state = NUM_VALUE; + base = 10; + numValue = getDigitValue(c, base); + i = 0; + } else if (c == '{') { + state = NUM_VALUE; + bflag = 1; + base = 16; + i = 0; + Set(IsStringValue); + } else + state = END_LINE; + break; + case BEGIN_HEX: + if (c == 'x' || c == 'X') { + state = NUM_VALUE; + base = 16; + numValue = 0; + i = 0; + break; + } else if (isDigit(c, 10)) { + state = NUM_VALUE; + base = 10; + numValue = getDigitValue(c, base); + break; + } else if (c != '\n' && c != '\r') { + state = END_LINE; + break; + } + // fall through to numValue to handle numValue + + case NUM_VALUE: + if (isDigit(c, base)) { + numValue *= base; + numValue += getDigitValue(c, base); + ++i; + } else if (bflag == 1 && + (c == ' ' || c == '\r' || c == '\n' || c == '\t')) { + break; + } else if (base == 16 && + (c == ',' || c == ':' || c == '-' || c == ' ' || c == '}')) { + if (c == '}') { + bflag = 0; + } + if (i > 0) { + int n = (i + 1) / 2; + while (n-- > 0) { + numValue = numValue >> (n * 8); + unsigned char c = (numValue)&0xFF; + strValue.push_back(c); + } + } + + Set(IsStringValue); + numValue = 0; + i = 0; + } else { + if (c == '\n' || c == '\r') { + if (bflag == 0) { + state = BEGIN_LINE; + } + } else { + if (bflag == 0) { + state = END_LINE; + } + } + if (Is(IsStringValue) && base == 16 && i > 0) { + int n = (i + 1) / 2; + while (n-- > 0) strValue.push_back(((numValue >> (n * 8)) & 0xFF)); + } + if (strValue.length() > 0) + pParam = new CNfcParam(token.c_str(), strValue); + else + pParam = new CNfcParam(token.c_str(), numValue); + add(pParam); + strValue.erase(); + numValue = 0; + } + break; + case STR_VALUE: + if (c == '"') { + strValue.push_back('\0'); + state = END_LINE; + pParam = new CNfcParam(token.c_str(), strValue); + add(pParam); + } else if (isPrintable(c)) + strValue.push_back(c); + break; + case END_LINE: + if (c == '\n' || c == '\r') state = BEGIN_LINE; + break; + default: + break; + } + } + + delete[] p_config; + + moveFromList(); + return size() > 0; +} + +/******************************************************************************* +** +** Function: CNfcConfig::CNfcConfig() +** +** Description: class constructor +** +** Returns: none +** +*******************************************************************************/ +CNfcConfig::CNfcConfig() : mValidFile(true), state(0) {} + +/******************************************************************************* +** +** Function: CNfcConfig::~CNfcConfig() +** +** Description: class destructor +** +** Returns: none +** +*******************************************************************************/ +CNfcConfig::~CNfcConfig() {} + +/******************************************************************************* +** +** Function: CNfcConfig::GetInstance() +** +** Description: get class singleton object +** +** Returns: none +** +*******************************************************************************/ +CNfcConfig& CNfcConfig::GetInstance() { + static CNfcConfig theInstance; + + if (theInstance.size() == 0 && theInstance.mValidFile) { + string strPath; + if (alternative_config_path[0] != '\0') { + strPath.assign(alternative_config_path); + strPath += config_name; + theInstance.readConfig(strPath.c_str(), true); + if (!theInstance.empty()) { + return theInstance; + } + } + findConfigFilePathFromTransportConfigPaths(config_name, strPath); + theInstance.readConfig(strPath.c_str(), true); + } + + return theInstance; +} + +/******************************************************************************* +** +** Function: CNfcConfig::getValue() +** +** Description: get a string value of a setting +** +** Returns: true if setting exists +** false if setting does not exist +** +*******************************************************************************/ +bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const { + const CNfcParam* pParam = find(name); + if (pParam == NULL) return false; + + if (pParam->str_len() > 0) { + memset(pValue, 0, len); + memcpy(pValue, pParam->str_value(), pParam->str_len()); + return true; + } + return false; +} + +bool CNfcConfig::getValue(const char* name, char* pValue, long len, + long* readlen) const { + const CNfcParam* pParam = find(name); + if (pParam == NULL) return false; + + if (pParam->str_len() > 0) { + if (pParam->str_len() <= (unsigned long)len) { + memset(pValue, 0, len); + memcpy(pValue, pParam->str_value(), pParam->str_len()); + *readlen = pParam->str_len(); + } else { + *readlen = -1; + } + + return true; + } + return false; +} + +/******************************************************************************* +** +** Function: CNfcConfig::getValue() +** +** Description: get a long numerical value of a setting +** +** Returns: true if setting exists +** false if setting does not exist +** +*******************************************************************************/ +bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const { + const CNfcParam* pParam = find(name); + if (pParam == NULL) return false; + + if (pParam->str_len() == 0) { + rValue = static_cast<unsigned long>(pParam->numValue()); + return true; + } + return false; +} + +/******************************************************************************* +** +** Function: CNfcConfig::getValue() +** +** Description: get a short numerical value of a setting +** +** Returns: true if setting exists +** false if setting does not exist +** +*******************************************************************************/ +bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const { + const CNfcParam* pParam = find(name); + if (pParam == NULL) return false; + + if (pParam->str_len() == 0) { + rValue = static_cast<unsigned short>(pParam->numValue()); + return true; + } + return false; +} + +/******************************************************************************* +** +** Function: CNfcConfig::find() +** +** Description: search if a setting exist in the setting array +** +** Returns: pointer to the setting object +** +*******************************************************************************/ +const CNfcParam* CNfcConfig::find(const char* p_name) const { + if (size() == 0) return NULL; + + for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it) { + if (**it < p_name) { + continue; + } else if (**it == p_name) { + if ((*it)->str_len() > 0) { + NXPLOG_EXTNS_D("%s found %s=%s\n", __func__, p_name, + (*it)->str_value()); + } else { + NXPLOG_EXTNS_D("%s found %s=(0x%lx)\n", __func__, p_name, + (*it)->numValue()); + } + return *it; + } else + break; + } + return NULL; +} + +/******************************************************************************* +** +** Function: CNfcConfig::clean() +** +** Description: reset the setting array +** +** Returns: none +** +*******************************************************************************/ +void CNfcConfig::clean() { + if (size() == 0) return; + + for (iterator it = begin(), itEnd = end(); it != itEnd; ++it) delete *it; + clear(); +} + +/******************************************************************************* +** +** Function: CNfcConfig::Add() +** +** Description: add a setting object to the list +** +** Returns: none +** +*******************************************************************************/ +void CNfcConfig::add(const CNfcParam* pParam) { + if (m_list.size() == 0) { + m_list.push_back(pParam); + return; + } + for (list<const CNfcParam *>::iterator it = m_list.begin(), + itEnd = m_list.end(); + it != itEnd; ++it) { + if (**it < pParam->c_str()) continue; + m_list.insert(it, pParam); + return; + } + m_list.push_back(pParam); +} + +/******************************************************************************* +** +** Function: CNfcConfig::moveFromList() +** +** Description: move the setting object from list to array +** +** Returns: none +** +*******************************************************************************/ +void CNfcConfig::moveFromList() { + if (m_list.size() == 0) return; + + for (list<const CNfcParam *>::iterator it = m_list.begin(), + itEnd = m_list.end(); + it != itEnd; ++it) + push_back(*it); + m_list.clear(); +} + +/******************************************************************************* +** +** Function: CNfcConfig::moveToList() +** +** Description: move the setting object from array to list +** +** Returns: none +** +*******************************************************************************/ +void CNfcConfig::moveToList() { + if (m_list.size() != 0) m_list.clear(); + + for (iterator it = begin(), itEnd = end(); it != itEnd; ++it) + m_list.push_back(*it); + clear(); +} + +bool CNfcConfig::isModified() { + FILE* fd = fopen(config_timestamp_path, "r+"); + if (fd == nullptr) { + ALOGE("%s Unable to open file '%s' - assuming modified", __func__, + config_timestamp_path); + return true; + } + + uint32_t stored_crc32 = 0; + fread(&stored_crc32, sizeof(uint32_t), 1, fd); + fclose(fd); + + return stored_crc32 != config_crc32_; +} + +void CNfcConfig::resetModified() { + FILE* fd = fopen(config_timestamp_path, "w+"); + if (fd == nullptr) { + ALOGE("%s Unable to open file '%s' for writing", __func__, + config_timestamp_path); + return; + } + + fwrite(&config_crc32_, sizeof(uint32_t), 1, fd); + fclose(fd); +} + +/******************************************************************************* +** +** Function: CNfcParam::CNfcParam() +** +** Description: class constructor +** +** Returns: none +** +*******************************************************************************/ +CNfcParam::CNfcParam() : m_numValue(0) {} + +/******************************************************************************* +** +** Function: CNfcParam::~CNfcParam() +** +** Description: class destructor +** +** Returns: none +** +*******************************************************************************/ +CNfcParam::~CNfcParam() {} + +/******************************************************************************* +** +** Function: CNfcParam::CNfcParam() +** +** Description: class copy constructor +** +** Returns: none +** +*******************************************************************************/ +CNfcParam::CNfcParam(const char* name, const string& value) + : string(name), m_str_value(value), m_numValue(0) {} + +/******************************************************************************* +** +** Function: CNfcParam::CNfcParam() +** +** Description: class copy constructor +** +** Returns: none +** +*******************************************************************************/ +CNfcParam::CNfcParam(const char* name, unsigned long value) + : string(name), m_numValue(value) {} + +/******************************************************************************* +** +** Function: GetStrValue +** +** Description: API function for getting a string value of a setting +** +** Returns: True if found, otherwise False. +** +*******************************************************************************/ +extern "C" int GetNxpStrValue(const char* name, char* pValue, + unsigned long len) { + CNfcConfig& rConfig = CNfcConfig::GetInstance(); + + return rConfig.getValue(name, pValue, len); +} + +/******************************************************************************* +** +** Function: GetByteArrayValue() +** +** Description: Read byte array value from the config file. +** +** Parameters: +** name - name of the config param to read. +** pValue - pointer to input buffer. +** bufflen - input buffer length. +** len - out parameter to return the number of bytes read from +** config file, return -1 in case bufflen is not enough. +** +** Returns: TRUE[1] if config param name is found in the config file, else +** FALSE[0] +** +*******************************************************************************/ +extern "C" int GetNxpByteArrayValue(const char* name, char* pValue, + long bufflen, long* len) { + CNfcConfig& rConfig = CNfcConfig::GetInstance(); + + return rConfig.getValue(name, pValue, bufflen, len); +} + +/******************************************************************************* +** +** Function: GetNumValue +** +** Description: API function for getting a numerical value of a setting +** +** Returns: true, if successful +** +*******************************************************************************/ +extern "C" int GetNxpNumValue(const char* name, void* pValue, + unsigned long len) { + if (!pValue) return false; + + CNfcConfig& rConfig = CNfcConfig::GetInstance(); + const CNfcParam* pParam = rConfig.find(name); + + if (pParam == NULL) return false; + unsigned long v = pParam->numValue(); + if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4) { + const unsigned char* p = (const unsigned char*)pParam->str_value(); + for (unsigned int i = 0; i < pParam->str_len(); ++i) { + v *= 256; + v += *p++; + } + } + switch (len) { + case sizeof(unsigned long): + *(static_cast<unsigned long*>(pValue)) = (unsigned long)v; + break; + case sizeof(unsigned short): + *(static_cast<unsigned short*>(pValue)) = (unsigned short)v; + break; + case sizeof(unsigned char): + *(static_cast<unsigned char*>(pValue)) = (unsigned char)v; + break; + default: + return false; + } + return true; +} + +/******************************************************************************* +** +** Function: resetConfig +** +** Description: reset settings array +** +** Returns: none +** +*******************************************************************************/ +extern "C" void resetNxpConfig() + +{ + CNfcConfig& rConfig = CNfcConfig::GetInstance(); + + rConfig.clean(); +} + +/******************************************************************************* +** +** Function: readOptionalConfig() +** +** Description: read Config settings from an optional conf file +** +** Returns: none +** +*******************************************************************************/ +void readOptionalConfig(const char* extra) { + string strPath; + string configName(extra_config_base); + configName += extra; + configName += extra_config_ext; + + if (alternative_config_path[0] != '\0') { + strPath.assign(alternative_config_path); + strPath += configName; + } else { + findConfigFilePathFromTransportConfigPaths(configName, strPath); + } + + CNfcConfig::GetInstance().readConfig(strPath.c_str(), false); +} + +/******************************************************************************* +** +** Function: isNxpConfigModified() +** +** Description: check if config file has modified +** +** Returns: 0 if not modified, 1 otherwise. +** +*******************************************************************************/ +extern "C" int isNxpConfigModified() { + CNfcConfig& rConfig = CNfcConfig::GetInstance(); + return rConfig.isModified(); +} + +/******************************************************************************* +** +** Function: updateNxpConfigTimestamp() +** +** Description: update if config file has modified +** +** Returns: 0 if not modified, 1 otherwise. +** +*******************************************************************************/ +extern "C" int updateNxpConfigTimestamp() { + CNfcConfig& rConfig = CNfcConfig::GetInstance(); + rConfig.resetModified(); + return 0; +} diff --git a/pn54x/utils/phNxpConfig.h b/pn54x/utils/phNxpConfig.h new file mode 100644 index 0000000..9488ecc --- /dev/null +++ b/pn54x/utils/phNxpConfig.h @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * Copyright (C) 1999-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/****************************************************************************** + * + * The original Work has been changed by NXP Semiconductors. + * + * Copyright (C) 2013-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +int GetNxpStrValue(const char* name, char* p_value, unsigned long len); +int GetNxpNumValue(const char* name, void* p_value, unsigned long len); +int GetNxpByteArrayValue(const char* name, char* pValue, long bufflen, + long* len); +void resetNxpConfig(void); +int isNxpConfigModified(); +int updateNxpConfigTimestamp(); + +#ifdef __cplusplus +}; +#endif + +#define NAME_NXPLOG_EXTNS_LOGLEVEL "NXPLOG_EXTNS_LOGLEVEL" +#define NAME_NXPLOG_NCIHAL_LOGLEVEL "NXPLOG_NCIHAL_LOGLEVEL" +#define NAME_NXPLOG_NCIX_LOGLEVEL "NXPLOG_NCIX_LOGLEVEL" +#define NAME_NXPLOG_NCIR_LOGLEVEL "NXPLOG_NCIR_LOGLEVEL" +#define NAME_NXPLOG_FWDNLD_LOGLEVEL "NXPLOG_FWDNLD_LOGLEVEL" +#define NAME_NXPLOG_TML_LOGLEVEL "NXPLOG_TML_LOGLEVEL" + +#define NAME_MIFARE_READER_ENABLE "MIFARE_READER_ENABLE" +#define NAME_FW_STORAGE "FW_STORAGE" +#define NAME_NXP_NFC_DEV_NODE "NXP_NFC_DEV_NODE" +#define NAME_NXP_FW_NAME "NXP_FW_NAME" +#define NAME_NXP_FW_PROTECION_OVERRIDE "NXP_FW_PROTECION_OVERRIDE" +#define NAME_NXP_SYS_CLK_SRC_SEL "NXP_SYS_CLK_SRC_SEL" +#define NAME_NXP_SYS_CLK_FREQ_SEL "NXP_SYS_CLK_FREQ_SEL" +#define NAME_NXP_SYS_CLOCK_TO_CFG "NXP_SYS_CLOCK_TO_CFG" +#define NAME_NXP_ACT_PROP_EXTN "NXP_ACT_PROP_EXTN" +#define NAME_NXP_EXT_TVDD_CFG "NXP_EXT_TVDD_CFG" +#define NAME_NXP_EXT_TVDD_CFG_1 "NXP_EXT_TVDD_CFG_1" +#define NAME_NXP_EXT_TVDD_CFG_2 "NXP_EXT_TVDD_CFG_2" +#define NAME_NXP_EXT_TVDD_CFG_3 "NXP_EXT_TVDD_CFG_3" +#define NAME_NXP_RF_CONF_BLK_1 "NXP_RF_CONF_BLK_1" +#define NAME_NXP_RF_CONF_BLK_2 "NXP_RF_CONF_BLK_2" +#define NAME_NXP_RF_CONF_BLK_3 "NXP_RF_CONF_BLK_3" +#define NAME_NXP_RF_CONF_BLK_4 "NXP_RF_CONF_BLK_4" +#define NAME_NXP_RF_CONF_BLK_5 "NXP_RF_CONF_BLK_5" +#define NAME_NXP_RF_CONF_BLK_6 "NXP_RF_CONF_BLK_6" +#define NAME_NXP_CORE_CONF_EXTN "NXP_CORE_CONF_EXTN" +#define NAME_NXP_CORE_CONF "NXP_CORE_CONF" +#define NAME_NXP_CORE_MFCKEY_SETTING "NXP_CORE_MFCKEY_SETTING" +#define NAME_NXP_CORE_STANDBY "NXP_CORE_STANDBY" +#define NAME_NXP_NFC_PROFILE_EXTN "NXP_NFC_PROFILE_EXTN" +#define NAME_NXP_CHINA_TIANJIN_RF_ENABLED "NXP_CHINA_TIANJIN_RF_ENABLED" +#define NAME_NXP_SWP_SWITCH_TIMEOUT "NXP_SWP_SWITCH_TIMEOUT" +#define NAME_NXP_SWP_FULL_PWR_ON "NXP_SWP_FULL_PWR_ON" +#define NAME_NXP_CORE_RF_FIELD "NXP_CORE_RF_FIELD" +#define NAME_NXP_NFC_MERGE_RF_PARAMS "NXP_NFC_MERGE_RF_PARAMS" +#define NAME_NXP_I2C_FRAGMENTATION_ENABLED "NXP_I2C_FRAGMENTATION_ENABLED" +#define NAME_AID_MATCHING_PLATFORM "AID_MATCHING_PLATFORM" + +/* default configuration */ +#define default_storage_location "/data/vendor/nfc" + +#endif diff --git a/pn54x/utils/phNxpNciHal_utils.c b/pn54x/utils/phNxpNciHal_utils.c new file mode 100644 index 0000000..46e4908 --- /dev/null +++ b/pn54x/utils/phNxpNciHal_utils.c @@ -0,0 +1,477 @@ +/* + * + * Copyright (C) 2013-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ +#include <errno.h> +#include <pthread.h> + +#include <phNxpLog.h> +#include <phNxpNciHal.h> +#include <phNxpNciHal_utils.h> + +#if (NFC_NXP_CHIP_TYPE == PN548C2) +extern uint8_t discovery_cmd[50]; +extern uint8_t discovery_cmd_len; +extern uint8_t nfcdep_detected; +#endif + +/*********************** Link list functions **********************************/ + +/******************************************************************************* +** +** Function listInit +** +** Description List initialization +** +** Returns 1, if list initialized, 0 otherwise +** +*******************************************************************************/ +int listInit(struct listHead* pList) { + pList->pFirst = NULL; + if (pthread_mutex_init(&pList->mutex, NULL) == -1) { + NXPLOG_NCIHAL_E("Mutex creation failed (errno=0x%08x)", errno); + return 0; + } + + return 1; +} + +/******************************************************************************* +** +** Function listDestroy +** +** Description List destruction +** +** Returns 1, if list destroyed, 0 if failed +** +*******************************************************************************/ +int listDestroy(struct listHead* pList) { + int bListNotEmpty = 1; + while (bListNotEmpty) { + bListNotEmpty = listGetAndRemoveNext(pList, NULL); + } + + if (pthread_mutex_destroy(&pList->mutex) == -1) { + NXPLOG_NCIHAL_E("Mutex destruction failed (errno=0x%08x)", errno); + return 0; + } + + return 1; +} + +/******************************************************************************* +** +** Function listAdd +** +** Description Add a node to the list +** +** Returns 1, if added, 0 if otherwise +** +*******************************************************************************/ +int listAdd(struct listHead* pList, void* pData) { + struct listNode* pNode; + struct listNode* pLastNode; + int result; + + /* Create node */ + pNode = (struct listNode*)malloc(sizeof(struct listNode)); + if (pNode == NULL) { + result = 0; + NXPLOG_NCIHAL_E("Failed to malloc"); + goto clean_and_return; + } + pNode->pData = pData; + pNode->pNext = NULL; + + pthread_mutex_lock(&pList->mutex); + + /* Add the node to the list */ + if (pList->pFirst == NULL) { + /* Set the node as the head */ + pList->pFirst = pNode; + } else { + /* Seek to the end of the list */ + pLastNode = pList->pFirst; + while (pLastNode->pNext != NULL) { + pLastNode = pLastNode->pNext; + } + + /* Add the node to the current list */ + pLastNode->pNext = pNode; + } + + result = 1; + +clean_and_return: + pthread_mutex_unlock(&pList->mutex); + return result; +} + +/******************************************************************************* +** +** Function listRemove +** +** Description Remove node from the list +** +** Returns 1, if removed, 0 if otherwise +** +*******************************************************************************/ +int listRemove(struct listHead* pList, void* pData) { + struct listNode* pNode; + struct listNode* pRemovedNode; + int result; + + pthread_mutex_lock(&pList->mutex); + + if (pList->pFirst == NULL) { + /* Empty list */ + NXPLOG_NCIHAL_E("Failed to deallocate (list empty)"); + result = 0; + goto clean_and_return; + } + + pNode = pList->pFirst; + if (pList->pFirst->pData == pData) { + /* Get the removed node */ + pRemovedNode = pNode; + + /* Remove the first node */ + pList->pFirst = pList->pFirst->pNext; + } else { + while (pNode->pNext != NULL) { + if (pNode->pNext->pData == pData) { + /* Node found ! */ + break; + } + pNode = pNode->pNext; + } + + if (pNode->pNext == NULL) { + /* Node not found */ + result = 0; + NXPLOG_NCIHAL_E("Failed to deallocate (not found %8p)", pData); + goto clean_and_return; + } + + /* Get the removed node */ + pRemovedNode = pNode->pNext; + + /* Remove the node from the list */ + pNode->pNext = pNode->pNext->pNext; + } + + /* Deallocate the node */ + free(pRemovedNode); + + result = 1; + +clean_and_return: + pthread_mutex_unlock(&pList->mutex); + return result; +} + +/******************************************************************************* +** +** Function listGetAndRemoveNext +** +** Description Get next node on the list and remove it +** +** Returns 1, if successful, 0 if otherwise +** +*******************************************************************************/ +int listGetAndRemoveNext(struct listHead* pList, void** ppData) { + struct listNode* pNode; + int result; + + pthread_mutex_lock(&pList->mutex); + + if (pList->pFirst == NULL) { + /* Empty list */ + NXPLOG_NCIHAL_D("Failed to deallocate (list empty)"); + result = 0; + goto clean_and_return; + } + + /* Work on the first node */ + pNode = pList->pFirst; + + /* Return the data */ + if (ppData != NULL) { + *ppData = pNode->pData; + } + + /* Remove and deallocate the node */ + pList->pFirst = pNode->pNext; + free(pNode); + + result = 1; + +clean_and_return: + listDump(pList); + pthread_mutex_unlock(&pList->mutex); + return result; +} + +/******************************************************************************* +** +** Function listDump +** +** Description Dump list information +** +** Returns None +** +*******************************************************************************/ +void listDump(struct listHead* pList) { + struct listNode* pNode = pList->pFirst; + + NXPLOG_NCIHAL_D("Node dump:"); + while (pNode != NULL) { + NXPLOG_NCIHAL_D("- %8p (%8p)", pNode, pNode->pData); + pNode = pNode->pNext; + } + + return; +} + +/* END Linked list source code */ + +/****************** Semaphore and mutex helper functions **********************/ + +static phNxpNciHal_Monitor_t* nxpncihal_monitor = NULL; + +/******************************************************************************* +** +** Function phNxpNciHal_init_monitor +** +** Description Initialize the semaphore monitor +** +** Returns Pointer to monitor, otherwise NULL if failed +** +*******************************************************************************/ +phNxpNciHal_Monitor_t* phNxpNciHal_init_monitor(void) { + NXPLOG_NCIHAL_D("Entering phNxpNciHal_init_monitor"); + + if (nxpncihal_monitor == NULL) { + nxpncihal_monitor = + (phNxpNciHal_Monitor_t*)malloc(sizeof(phNxpNciHal_Monitor_t)); + } + + if (nxpncihal_monitor != NULL) { + memset(nxpncihal_monitor, 0x00, sizeof(phNxpNciHal_Monitor_t)); + + if (pthread_mutex_init(&nxpncihal_monitor->reentrance_mutex, NULL) == -1) { + NXPLOG_NCIHAL_E("reentrance_mutex creation returned 0x%08x", errno); + goto clean_and_return; + } + + if (pthread_mutex_init(&nxpncihal_monitor->concurrency_mutex, NULL) == -1) { + NXPLOG_NCIHAL_E("concurrency_mutex creation returned 0x%08x", errno); + pthread_mutex_destroy(&nxpncihal_monitor->reentrance_mutex); + goto clean_and_return; + } + + if (listInit(&nxpncihal_monitor->sem_list) != 1) { + NXPLOG_NCIHAL_E("Semaphore List creation failed"); + pthread_mutex_destroy(&nxpncihal_monitor->concurrency_mutex); + pthread_mutex_destroy(&nxpncihal_monitor->reentrance_mutex); + goto clean_and_return; + } + } else { + NXPLOG_NCIHAL_E("nxphal_monitor creation failed"); + goto clean_and_return; + } + + NXPLOG_NCIHAL_D("Returning with SUCCESS"); + + return nxpncihal_monitor; + +clean_and_return: + NXPLOG_NCIHAL_D("Returning with FAILURE"); + + if (nxpncihal_monitor != NULL) { + free(nxpncihal_monitor); + nxpncihal_monitor = NULL; + } + + return NULL; +} + +/******************************************************************************* +** +** Function phNxpNciHal_cleanup_monitor +** +** Description Clean up semaphore monitor +** +** Returns None +** +*******************************************************************************/ +void phNxpNciHal_cleanup_monitor(void) { + if (nxpncihal_monitor != NULL) { + pthread_mutex_destroy(&nxpncihal_monitor->concurrency_mutex); + REENTRANCE_UNLOCK(); + pthread_mutex_destroy(&nxpncihal_monitor->reentrance_mutex); + phNxpNciHal_releaseall_cb_data(); + listDestroy(&nxpncihal_monitor->sem_list); + } + + free(nxpncihal_monitor); + nxpncihal_monitor = NULL; + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_get_monitor +** +** Description Get monitor +** +** Returns Pointer to monitor +** +*******************************************************************************/ +phNxpNciHal_Monitor_t* phNxpNciHal_get_monitor(void) { + return nxpncihal_monitor; +} + +/* Initialize the callback data */ +NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t* pCallbackData, + void* pContext) { + /* Create semaphore */ + if (sem_init(&pCallbackData->sem, 0, 0) == -1) { + NXPLOG_NCIHAL_E("Semaphore creation failed (errno=0x%08x)", errno); + return NFCSTATUS_FAILED; + } + + /* Set default status value */ + pCallbackData->status = NFCSTATUS_FAILED; + + /* Copy the context */ + pCallbackData->pContext = pContext; + + /* Add to active semaphore list */ + if (listAdd(&phNxpNciHal_get_monitor()->sem_list, pCallbackData) != 1) { + NXPLOG_NCIHAL_E("Failed to add the semaphore to the list"); + } + + return NFCSTATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function phNxpNciHal_cleanup_cb_data +** +** Description Clean up callback data +** +** Returns None +** +*******************************************************************************/ +void phNxpNciHal_cleanup_cb_data(phNxpNciHal_Sem_t* pCallbackData) { + /* Destroy semaphore */ + if (sem_destroy(&pCallbackData->sem)) { + NXPLOG_NCIHAL_E( + "phNxpNciHal_cleanup_cb_data: Failed to destroy semaphore " + "(errno=0x%08x)", + errno); + } + + /* Remove from active semaphore list */ + if (listRemove(&phNxpNciHal_get_monitor()->sem_list, pCallbackData) != 1) { + NXPLOG_NCIHAL_E( + "phNxpNciHal_cleanup_cb_data: Failed to remove semaphore from the " + "list"); + } + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_releaseall_cb_data +** +** Description Release all callback data +** +** Returns None +** +*******************************************************************************/ +void phNxpNciHal_releaseall_cb_data(void) { + phNxpNciHal_Sem_t* pCallbackData; + + while (listGetAndRemoveNext(&phNxpNciHal_get_monitor()->sem_list, + (void**)&pCallbackData)) { + pCallbackData->status = NFCSTATUS_FAILED; + sem_post(&pCallbackData->sem); + } + + return; +} + +/* END Semaphore and mutex helper functions */ + +/**************************** Other functions *********************************/ + +/******************************************************************************* +** +** Function phNxpNciHal_print_packet +** +** Description Print packet +** +** Returns None +** +*******************************************************************************/ +void phNxpNciHal_print_packet(const char* pString, const uint8_t* p_data, + uint16_t len) { + uint32_t i, j; + char print_buffer[len * 3 + 1]; + + memset(print_buffer, 0, sizeof(print_buffer)); + for (i = 0; i < len; i++) { + snprintf(&print_buffer[i * 2], 3, "%02X", p_data[i]); + } + if (0 == memcmp(pString, "SEND", 0x04)) { + NXPLOG_NCIX_D("len = %3d > %s", len, print_buffer); + } else if (0 == memcmp(pString, "RECV", 0x04)) { + NXPLOG_NCIR_D("len = %3d > %s", len, print_buffer); + } + + return; +} + +/******************************************************************************* +** +** Function phNxpNciHal_emergency_recovery +** +** Description Emergency recovery in case of no other way out +** +** Returns None +** +*******************************************************************************/ + +void phNxpNciHal_emergency_recovery(void) { +#if (NFC_NXP_CHIP_TYPE == PN548C2) + if (nfcdep_detected && discovery_cmd_len != 0) { + pthread_t pthread; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&pthread, &attr, (void*)phNxpNciHal_core_reset_recovery, + NULL) == 0) { + return; + } + } +#endif + NXPLOG_NCIHAL_E("%s: abort()", __func__); + abort(); +} diff --git a/pn54x/utils/phNxpNciHal_utils.h b/pn54x/utils/phNxpNciHal_utils.h new file mode 100644 index 0000000..3ea33e4 --- /dev/null +++ b/pn54x/utils/phNxpNciHal_utils.h @@ -0,0 +1,106 @@ +/* + * + * Copyright (C) 2013-2014 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef _PHNXPNCIHAL_UTILS_H_ +#define _PHNXPNCIHAL_UTILS_H_ + +#include <assert.h> +#include <phNfcStatus.h> +#include <pthread.h> +#include <semaphore.h> + +/********************* Definitions and structures *****************************/ + +/* List structures */ +struct listNode { + void* pData; + struct listNode* pNext; +}; + +struct listHead { + struct listNode* pFirst; + pthread_mutex_t mutex; +}; + +/* Semaphore handling structure */ +typedef struct phNxpNciHal_Sem { + /* Semaphore used to wait for callback */ + sem_t sem; + + /* Used to store the status sent by the callback */ + NFCSTATUS status; + + /* Used to provide a local context to the callback */ + void* pContext; + +} phNxpNciHal_Sem_t; + +/* Semaphore helper macros */ +#define SEM_WAIT(cb_data) sem_wait(&((cb_data).sem)) +#define SEM_POST(p_cb_data) sem_post(&((p_cb_data)->sem)) + +/* Semaphore and mutex monitor */ +typedef struct phNxpNciHal_Monitor { + /* Mutex protecting native library against reentrance */ + pthread_mutex_t reentrance_mutex; + + /* Mutex protecting native library against concurrency */ + pthread_mutex_t concurrency_mutex; + + /* List used to track pending semaphores waiting for callback */ + struct listHead sem_list; + +} phNxpNciHal_Monitor_t; + +/************************ Exposed functions ***********************************/ +/* List functions */ +int listInit(struct listHead* pList); +int listDestroy(struct listHead* pList); +int listAdd(struct listHead* pList, void* pData); +int listRemove(struct listHead* pList, void* pData); +int listGetAndRemoveNext(struct listHead* pList, void** ppData); +void listDump(struct listHead* pList); + +/* NXP NCI HAL utility functions */ +phNxpNciHal_Monitor_t* phNxpNciHal_init_monitor(void); +void phNxpNciHal_cleanup_monitor(void); +phNxpNciHal_Monitor_t* phNxpNciHal_get_monitor(void); +NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t* pCallbackData, + void* pContext); +void phNxpNciHal_cleanup_cb_data(phNxpNciHal_Sem_t* pCallbackData); +void phNxpNciHal_releaseall_cb_data(void); +void phNxpNciHal_print_packet(const char* pString, const uint8_t* p_data, + uint16_t len); +void phNxpNciHal_emergency_recovery(void); + +/* Lock unlock helper macros */ +/* Lock unlock helper macros */ +#define REENTRANCE_LOCK() \ + if (phNxpNciHal_get_monitor()) \ + pthread_mutex_lock(&phNxpNciHal_get_monitor()->reentrance_mutex) +#define REENTRANCE_UNLOCK() \ + if (phNxpNciHal_get_monitor()) \ + pthread_mutex_unlock(&phNxpNciHal_get_monitor()->reentrance_mutex) +#define CONCURRENCY_LOCK() \ + if (phNxpNciHal_get_monitor()) \ + pthread_mutex_lock(&phNxpNciHal_get_monitor()->concurrency_mutex) +#define CONCURRENCY_UNLOCK() \ + if (phNxpNciHal_get_monitor()) \ + pthread_mutex_unlock(&phNxpNciHal_get_monitor()->concurrency_mutex) + +#endif /* _PHNXPNCIHAL_UTILS_H_ */ diff --git a/pn54x/utils/sparse_crc32.c b/pn54x/utils/sparse_crc32.c new file mode 100644 index 0000000..1ce4c63 --- /dev/null +++ b/pn54x/utils/sparse_crc32.c @@ -0,0 +1,107 @@ +/*- + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + */ + +/* + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + * + * + * CRC32 code derived from work by Gary S. Brown. + */ + +/* Code taken from FreeBSD 8 */ +#include <stdint.h> + +static uint32_t crc32_tab[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; + +/* + * A function that calculates the CRC-32 based on the table above is + * given below for documentation purposes. An equivalent implementation + * of this function that's actually used in the kernel can be found + * in sys/libkern.h, where it can be inlined. + */ + +uint32_t sparse_crc32(uint32_t crc_in, const void* buf, int size) { + const uint8_t* p = buf; + uint32_t crc; + + crc = crc_in ^ ~0U; + while (size--) crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); + return crc ^ ~0U; +} diff --git a/pn54x/utils/sparse_crc32.h b/pn54x/utils/sparse_crc32.h new file mode 100644 index 0000000..a776921 --- /dev/null +++ b/pn54x/utils/sparse_crc32.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBSPARSE_SPARSE_CRC32_H_ +#define _LIBSPARSE_SPARSE_CRC32_H_ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t sparse_crc32(uint32_t crc, const void* buf, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif |