PN7462 CCID card read failure

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

PN7462 CCID card read failure

Jump to solution
2,853 Views
Monica_Li
Contributor I

Hi,

We are building USB card reader using PN7462AU.

SDK: PN7462AU_ex_phExNFCCcid

We've run into issue, Intermittent card read failures occur, and the system can only be recovered by rebooting .

After the card reading fails, the following phenomenon occurs:

 1. The TX port is transmitting the carrier wave;

2. And the code is located at a certain position in the image.

code location.jpg

 

 

 

 

 

 

 

 

3. At this time, the error message seen on the Windows end is as shown in the following figure.

1.jpg2.jpg3.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Can you help analyze what caused this and how can we should handle it?

Thanks very much!

0 Kudos
Reply
1 Solution
2,695 Views
vrm2805
Contributor III

I don't know if this will work for you. I have faced similar issue and managed to fix it somehow.

In function to handle CCID command events based on the Card detected, I have added timer to get tick count of 250.


/**
 * @brief Function to handle CCID command events based on the Card detected
 * @Param psDiscLoopParams - Discovery Loop Parameters used for processing
 */
static void phExNFCCcid_Handle_USB_Process(phacDiscLoop_Sw_DataParams_t *psDiscLoopParams)
{
    uint8_t *pp;
    uint16_t wOutLen;
    uint8_t  bDeactivateFlag = PH_OFF;

    static phStatus_t status = PH_ERR_FAILED;
    volatile uint32_t dwBits = 0;
    uint32_t dwEventTimeOut = 0xF;
    uint16_t wOptions = 0;
    uint8_t bErrorAPDU[2] = { 0x6A, 0x81 };
    static TickType_t timeinsert = 0;

    if (gphExNFCCcid_sUsb_SlotInfo.bCardPresent != PH_EXNFCCCID_USBCCID_CCID_CARD_PRESENT_IN_SLOT)
    {
        /** Send the Card Inserted Information to the host. */
        phExNFCCcid_UsbCcid_CardInserted();
        timeinsert = xTaskGetTickCount();
    }
    else
    {
        /** Copy the ATR Information in the Transmission Buffer. */
        phUser_MemCpy(&gphExNFCCcid_sUsb_BulkInMsg.aTxBuff[PH_EXNFCCCID_USBCCID_CCID_HEADER_LENGTH], &gphExNFCCcid_sUsb_SlotInfo.aAtr[0], gphExNFCCcid_sUsb_SlotInfo.bAtrSize);

        phExNFCCcid_UsbCcid_Set_Output_Payload_Length(gphExNFCCcid_sUsb_SlotInfo.bAtrSize);
        phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x00);
    }

    while (true)
    {

        /** Check for the General Slot Type and CL Slot Type
         *  If nothing set exit the loop
         */
        if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == 0x00) &&
            (gphExNFCCcid_sUsb_SlotInfo.bSlotType == PH_EXNFCCCID_USBCCID_CHANNEL_NONE))
        {
            break;
        }
#ifdef  PH_EXNFCCCID_USB_IF_COMPLIANCY
        if (gphExNFCCcid_sUsb_Bus_Status.bAddressed == 0)
        {
          	break;
        }
#endif
        if ((xTaskGetTickCount() - timeinsert) > 250)
        {

#if (PH_EXNFCCCID_USB_IF_USB_SUSPEND_RESUME_FTR == 1)
        /** If Suspend is initiated by the host
         *  Exit the loop and send the card removal information
         */
        if (gphExNFCCcid_sUsb_Bus_Status.bSuspendEnable == 1)
        {
            gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
            phExNFCCcid_UsbCcid_CardRemoved();
            break;
        }
#endif

        if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_B) ||
            (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_L4))
        {
            /* Check for the Card Presence and Exit the loop if not presence is detected */
            status = phExNFCCcid_Check_Presence_L4_Card(psDiscLoopParams);
            if (status != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phpalI14443p4_ResetProtocol(psDiscLoopParams->pPal14443p4DataParams);
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC))
        {
            /* Check for the Card Presence and Exit the loop if not presence is detected */
            status = phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams);
            if ((status!= PH_ERR_SUCCESS) && (status != PH_ERR_INTEGRITY_ERROR))
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT) ||
                 (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_NS))
        {
            /* Check for the Card Presence and Exit the loop if not presence is detected */
        	status = phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams);
            if ((status!= PH_ERR_SUCCESS) && (status != PH_ERR_INTEGRITY_ERROR))
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_V)
        {
            if (phExNFCCcid_Check_Presence_TypeV_Card(psDiscLoopParams) != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_FELICA)
        {
            if (phExNFCCcid_Check_Presence_TypeF_Card(psDiscLoopParams) != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
#ifdef NXPBUILD__PHAC_DISCLOOP_I18000P3M3_TAGS
        else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_18000P3M3)
        {
            if (phExNFCCcid_Check_Presence_Type18000P3M3_Tag_Read(psDiscLoopParams) != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
#endif
        }
        /** Wait for the Events for the CL Cards. */
        dwBits = phRtos_EventGroupWaitBits(gphExNFCCcid_sUsb_SlotInfo.xCL_Events,
                                           PH_EXNFCCCID_USBCCID_CL_TRNSP_EX_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_DEACTIVATE_CARD_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_AUTH_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_READ_CARD_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_WRITE_CARD_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_ACTIVATE_CARD_CMD,
                                           true, /* status bits should be cleared before returning. */
                                           false, /* wait for any status bit being set. */
                                           dwEventTimeOut); /* wait until the time expires. */

      /** Deactivate Card Command Event - ICC POWER OFF. */
      if ((dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_DEACTIVATE_CARD_CMD))
      {
         if (bDeactivateFlag == PH_ON)
         {
            if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_L4) ||
                (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_B))
            {
               (void)phpalI14443p4_Deselect(psDiscLoopParams->pPal14443p4DataParams);
               (void)phpalI14443p4_ResetProtocol(psDiscLoopParams->pPal14443p4DataParams);
            }
            else if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC) ||
                  (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT))
            {
               (void)phpalI14443p3a_HaltA(psDiscLoopParams->pPal1443p3aDataParams);
            }
         }

         /** Return the Status for the Request when no exchange is performed */
         phExNFCCcid_UsbCcid_Set_Output_Payload_Length(0);
         phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_SLOTSTATUS, 0x00, 0x00, 0x00);

         if (bDeactivateFlag == PH_ON)
         {
            /* Reset the Global variables */
            gphExNFCCcid_sUsb_SlotInfo.bCLSlotType = 0x00;
            gphExNFCCcid_sUsb_SlotInfo.bSlotType = PH_EXNFCCCID_USBCCID_CHANNEL_NONE;
            gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;

            bDeactivateFlag = PH_OFF;
         }
         else
         {
            bDeactivateFlag = PH_ON;
         }
      } /* - PH_EXNFCCCID_USBCCID_CL_DEACTIVATE_CARD_CMD */
      else
      {
          bDeactivateFlag = PH_OFF;
      }

      if ((dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_ACTIVATE_CARD_CMD))
      {
          /**/
          phExNFCCcid_ClifPostMsg(PHAC_DISCLOOP_ENTRY_POINT_POLL, E_PHEXNFCCCID_CLIF_CMD_START, gphExNFCCcid_SysTask_Queue);
      }

       /* APDU command from HOST, do transparent exchange and send
        * response to host*/
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_TRNSP_EX_CMD)
       {
           if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_L4) ||
               (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_B))
           {
        	   switch (phExNFCCcid_UsbCcid_CCID_InHdr_Get_Byte(PH_EXNFCCCID_USBCCID_PN7462AU_CCID_HEADER_MSG_BYTE_2))
			   {
			   case 0x01:
			   case 0x03:
			        wOptions = PH_EXCHANGE_TXCHAINING;
			        break;
			   case 0x10:
			        wOptions = PH_EXCHANGE_RXCHAINING;
			        break;
			   case 0x00:
			   case 0x02:
			   default:
			        wOptions = 0;
			        break;
			   }
        	   status = phpalI14443p4_Exchange(psDiscLoopParams->pPal14443p4DataParams,
        			                           wOptions,
                                               phExNFCCcid_UsbCcid_Get_Input_Payload_Buffer(),
                                               (uint16_t)phExNFCCcid_UsbCcid_Get_Input_Payload_Length(),
                                               (uint8_t **)&pp,
                                               &wOutLen);

               if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS)
               {
                   /*APDU exchange success, send response to host*/
                   phUser_MemCpy(phExNFCCcid_UsbCcid_Get_Output_Payload_Buffer(), pp, (uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Set_Output_Payload_Length((uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x00);
                   phExNFCCcid_LED_TxnPass(gphExNFCCcid_sUsb_SlotInfo.bSlotType);
               }
               else if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING)
               {
                   /*APDU exchange success, send response to host*/
                   phUser_MemCpy(phExNFCCcid_UsbCcid_Get_Output_Payload_Buffer(), pp, (uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Set_Output_Payload_Length((uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x03);
                   phExNFCCcid_LED_TxnPass(gphExNFCCcid_sUsb_SlotInfo.bSlotType);
               }
               else
               {
                   /** Timeout Error Occurred. */
                   /** Send Card Removal Event and Mark the Transaction as Failure. */
                   gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                   phExNFCCcid_UsbCcid_PCSC_Send_APDU((status & 0x00ff), ((0xff00 & status) >> 8), 0);
                   gphExNFCCcid_sUsb_SlotInfo.bCLSlotType = 0x00;
                   phExNFCCcid_UsbCcid_CardRemoved();
                   phExNFCCcid_LED_TxnFail(gphExNFCCcid_sUsb_SlotInfo.bSlotType);
                   break;
               }
           }
           else
           {
               /** Exchange Not Supported for the Cards. */
               phUser_MemCpy(phExNFCCcid_UsbCcid_Get_Output_Payload_Buffer(), &bErrorAPDU[0], 2);
               phExNFCCcid_UsbCcid_Set_Output_Payload_Length(0x2);
               phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x00);
           }
       } /* - PH_EXNFCCCID_USBCCID_CL_TRNSP_EX_CMD */

       /** Card Read Command Events. */
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_READ_CARD_CMD)
       {
            /** Check for the CL type as Mifare Classic. */
            if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC)
            {
            	/* Put the Card in the known state */
				if (PH_ERR_SUCCESS != phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams))
				{
					/** Authentication Failure. */
					phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x6A, 0x82, 0);
					return;
				}
            	/** Check for the Authentication. */
                if (PH_ERR_SUCCESS != phExNFCCcid_Mifare_Do_Auth(PH_EXNFCCCID_MIFARE_AUTHENTICATE_P2))
                {
                    /** Authentication Failure. */
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x69, 0x82, 0);
                    return;
                }

                /** Perform the Read Operation on the Mifare Classic Card. */
                phExNFCCcid_Mifare_Read_Operations();
            }
            else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT)
            {
                /** Perform the Read Operation on the Mifare Ultralight Card. */
                phExNFCCcid_Mifare_Read_Operations();
            }
       } /* - PH_EXNFCCCID_USBCCID_CL_READ_CARD_CMD */

       /** Card Write Command Events. */
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_WRITE_CARD_CMD)
       {
            if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC)
            {
            	/* Put the Card in the known state */
				if (PH_ERR_SUCCESS != phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams))
				{
					/** Authentication Failure. */
					phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x6A, 0x82, 0);
					return;
				}
            	/** Check for Authentication for Mifare Classic Cards. */
                if (PH_ERR_SUCCESS != phExNFCCcid_Mifare_Do_Auth(PH_EXNFCCCID_MIFARE_AUTHENTICATE_P2))
                {
                    /** Authentication Failure. */
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x69, 0x82, 0);
                    return;
                }

                /** Perform the Write Operation in the Mifare Classic Card. */
                phExNFCCcid_Mifare_Write_Operations(PH_EXNFCCCID_MIFARE_CLASSIC_APDU_LC);
            }
            else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT)
            {
                /** Perform the Write Operation in the Mifare Ultralight Card. */
                phExNFCCcid_Mifare_Write_Operations(PH_EXNFCCCID_MIFARE_ULTRALIGHT_APDU_LC);
            }
       } /* - PH_EXNFCCCID_USBCCID_CL_WRITE_CARD_CMD */

       /** Authentication Command Events. */
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_AUTH_CMD )
       {
            if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC))
            {
            	/* Put the Card in the known state */
				if (PH_ERR_SUCCESS != phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams))
				{
					/** Authentication Failure. */
					phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x6A, 0x82, 0);
					return;
				}
            	/** Perform the Authentication in the Mifare Classic Card. */
                status = phExNFCCcid_Mifare_Do_Auth(PH_EXNFCCCID_MIFARE_AUTHENTICATE_LC);

                if (status == PH_ERR_SUCCESS)
                {
                    /** Send the Success Status on Successful Authentication. */
                    gphExNFCCcid_sUsb_MifareInfo.bAuth = 1;
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x90, 0x00, 0);
                }
                else
                {
                    /** Send the Failure Status on Authentication failure. */
                    gphExNFCCcid_sUsb_MifareInfo.bAuth = 0;
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x69, 0x82, 0);
                }
            }
       } /* - PH_EXNFCCCID_USBCCID_CL_AUTH_CMD */
    } /* - While */
}



View solution in original post

0 Kudos
Reply
7 Replies
2,696 Views
vrm2805
Contributor III

I don't know if this will work for you. I have faced similar issue and managed to fix it somehow.

In function to handle CCID command events based on the Card detected, I have added timer to get tick count of 250.


/**
 * @brief Function to handle CCID command events based on the Card detected
 * @Param psDiscLoopParams - Discovery Loop Parameters used for processing
 */
static void phExNFCCcid_Handle_USB_Process(phacDiscLoop_Sw_DataParams_t *psDiscLoopParams)
{
    uint8_t *pp;
    uint16_t wOutLen;
    uint8_t  bDeactivateFlag = PH_OFF;

    static phStatus_t status = PH_ERR_FAILED;
    volatile uint32_t dwBits = 0;
    uint32_t dwEventTimeOut = 0xF;
    uint16_t wOptions = 0;
    uint8_t bErrorAPDU[2] = { 0x6A, 0x81 };
    static TickType_t timeinsert = 0;

    if (gphExNFCCcid_sUsb_SlotInfo.bCardPresent != PH_EXNFCCCID_USBCCID_CCID_CARD_PRESENT_IN_SLOT)
    {
        /** Send the Card Inserted Information to the host. */
        phExNFCCcid_UsbCcid_CardInserted();
        timeinsert = xTaskGetTickCount();
    }
    else
    {
        /** Copy the ATR Information in the Transmission Buffer. */
        phUser_MemCpy(&gphExNFCCcid_sUsb_BulkInMsg.aTxBuff[PH_EXNFCCCID_USBCCID_CCID_HEADER_LENGTH], &gphExNFCCcid_sUsb_SlotInfo.aAtr[0], gphExNFCCcid_sUsb_SlotInfo.bAtrSize);

        phExNFCCcid_UsbCcid_Set_Output_Payload_Length(gphExNFCCcid_sUsb_SlotInfo.bAtrSize);
        phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x00);
    }

    while (true)
    {

        /** Check for the General Slot Type and CL Slot Type
         *  If nothing set exit the loop
         */
        if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == 0x00) &&
            (gphExNFCCcid_sUsb_SlotInfo.bSlotType == PH_EXNFCCCID_USBCCID_CHANNEL_NONE))
        {
            break;
        }
#ifdef  PH_EXNFCCCID_USB_IF_COMPLIANCY
        if (gphExNFCCcid_sUsb_Bus_Status.bAddressed == 0)
        {
          	break;
        }
#endif
        if ((xTaskGetTickCount() - timeinsert) > 250)
        {

#if (PH_EXNFCCCID_USB_IF_USB_SUSPEND_RESUME_FTR == 1)
        /** If Suspend is initiated by the host
         *  Exit the loop and send the card removal information
         */
        if (gphExNFCCcid_sUsb_Bus_Status.bSuspendEnable == 1)
        {
            gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
            phExNFCCcid_UsbCcid_CardRemoved();
            break;
        }
#endif

        if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_B) ||
            (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_L4))
        {
            /* Check for the Card Presence and Exit the loop if not presence is detected */
            status = phExNFCCcid_Check_Presence_L4_Card(psDiscLoopParams);
            if (status != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phpalI14443p4_ResetProtocol(psDiscLoopParams->pPal14443p4DataParams);
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC))
        {
            /* Check for the Card Presence and Exit the loop if not presence is detected */
            status = phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams);
            if ((status!= PH_ERR_SUCCESS) && (status != PH_ERR_INTEGRITY_ERROR))
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT) ||
                 (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_NS))
        {
            /* Check for the Card Presence and Exit the loop if not presence is detected */
        	status = phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams);
            if ((status!= PH_ERR_SUCCESS) && (status != PH_ERR_INTEGRITY_ERROR))
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_V)
        {
            if (phExNFCCcid_Check_Presence_TypeV_Card(psDiscLoopParams) != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
        else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_FELICA)
        {
            if (phExNFCCcid_Check_Presence_TypeF_Card(psDiscLoopParams) != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
#ifdef NXPBUILD__PHAC_DISCLOOP_I18000P3M3_TAGS
        else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_18000P3M3)
        {
            if (phExNFCCcid_Check_Presence_Type18000P3M3_Tag_Read(psDiscLoopParams) != PH_ERR_SUCCESS)
            {
                gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                phExNFCCcid_UsbCcid_CardRemoved();
                break;
            }
        }
#endif
        }
        /** Wait for the Events for the CL Cards. */
        dwBits = phRtos_EventGroupWaitBits(gphExNFCCcid_sUsb_SlotInfo.xCL_Events,
                                           PH_EXNFCCCID_USBCCID_CL_TRNSP_EX_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_DEACTIVATE_CARD_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_AUTH_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_READ_CARD_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_WRITE_CARD_CMD |
                                           PH_EXNFCCCID_USBCCID_CL_ACTIVATE_CARD_CMD,
                                           true, /* status bits should be cleared before returning. */
                                           false, /* wait for any status bit being set. */
                                           dwEventTimeOut); /* wait until the time expires. */

      /** Deactivate Card Command Event - ICC POWER OFF. */
      if ((dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_DEACTIVATE_CARD_CMD))
      {
         if (bDeactivateFlag == PH_ON)
         {
            if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_L4) ||
                (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_B))
            {
               (void)phpalI14443p4_Deselect(psDiscLoopParams->pPal14443p4DataParams);
               (void)phpalI14443p4_ResetProtocol(psDiscLoopParams->pPal14443p4DataParams);
            }
            else if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC) ||
                  (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT))
            {
               (void)phpalI14443p3a_HaltA(psDiscLoopParams->pPal1443p3aDataParams);
            }
         }

         /** Return the Status for the Request when no exchange is performed */
         phExNFCCcid_UsbCcid_Set_Output_Payload_Length(0);
         phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_SLOTSTATUS, 0x00, 0x00, 0x00);

         if (bDeactivateFlag == PH_ON)
         {
            /* Reset the Global variables */
            gphExNFCCcid_sUsb_SlotInfo.bCLSlotType = 0x00;
            gphExNFCCcid_sUsb_SlotInfo.bSlotType = PH_EXNFCCCID_USBCCID_CHANNEL_NONE;
            gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;

            bDeactivateFlag = PH_OFF;
         }
         else
         {
            bDeactivateFlag = PH_ON;
         }
      } /* - PH_EXNFCCCID_USBCCID_CL_DEACTIVATE_CARD_CMD */
      else
      {
          bDeactivateFlag = PH_OFF;
      }

      if ((dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_ACTIVATE_CARD_CMD))
      {
          /**/
          phExNFCCcid_ClifPostMsg(PHAC_DISCLOOP_ENTRY_POINT_POLL, E_PHEXNFCCCID_CLIF_CMD_START, gphExNFCCcid_SysTask_Queue);
      }

       /* APDU command from HOST, do transparent exchange and send
        * response to host*/
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_TRNSP_EX_CMD)
       {
           if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_A_L4) ||
               (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_TYPE_B))
           {
        	   switch (phExNFCCcid_UsbCcid_CCID_InHdr_Get_Byte(PH_EXNFCCCID_USBCCID_PN7462AU_CCID_HEADER_MSG_BYTE_2))
			   {
			   case 0x01:
			   case 0x03:
			        wOptions = PH_EXCHANGE_TXCHAINING;
			        break;
			   case 0x10:
			        wOptions = PH_EXCHANGE_RXCHAINING;
			        break;
			   case 0x00:
			   case 0x02:
			   default:
			        wOptions = 0;
			        break;
			   }
        	   status = phpalI14443p4_Exchange(psDiscLoopParams->pPal14443p4DataParams,
        			                           wOptions,
                                               phExNFCCcid_UsbCcid_Get_Input_Payload_Buffer(),
                                               (uint16_t)phExNFCCcid_UsbCcid_Get_Input_Payload_Length(),
                                               (uint8_t **)&pp,
                                               &wOutLen);

               if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS)
               {
                   /*APDU exchange success, send response to host*/
                   phUser_MemCpy(phExNFCCcid_UsbCcid_Get_Output_Payload_Buffer(), pp, (uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Set_Output_Payload_Length((uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x00);
                   phExNFCCcid_LED_TxnPass(gphExNFCCcid_sUsb_SlotInfo.bSlotType);
               }
               else if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING)
               {
                   /*APDU exchange success, send response to host*/
                   phUser_MemCpy(phExNFCCcid_UsbCcid_Get_Output_Payload_Buffer(), pp, (uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Set_Output_Payload_Length((uint32_t)wOutLen);
                   phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x03);
                   phExNFCCcid_LED_TxnPass(gphExNFCCcid_sUsb_SlotInfo.bSlotType);
               }
               else
               {
                   /** Timeout Error Occurred. */
                   /** Send Card Removal Event and Mark the Transaction as Failure. */
                   gphExNFCCcid_sUsb_SlotInfo.bAtrValid = 0;
                   phExNFCCcid_UsbCcid_PCSC_Send_APDU((status & 0x00ff), ((0xff00 & status) >> 8), 0);
                   gphExNFCCcid_sUsb_SlotInfo.bCLSlotType = 0x00;
                   phExNFCCcid_UsbCcid_CardRemoved();
                   phExNFCCcid_LED_TxnFail(gphExNFCCcid_sUsb_SlotInfo.bSlotType);
                   break;
               }
           }
           else
           {
               /** Exchange Not Supported for the Cards. */
               phUser_MemCpy(phExNFCCcid_UsbCcid_Get_Output_Payload_Buffer(), &bErrorAPDU[0], 2);
               phExNFCCcid_UsbCcid_Set_Output_Payload_Length(0x2);
               phExNFCCcid_UsbCcid_Send_Frame(PH_EXNFCCCID_USBCCID_RDR_TO_PC_DATABLOCK, 0x00, 0x00, 0x00);
           }
       } /* - PH_EXNFCCCID_USBCCID_CL_TRNSP_EX_CMD */

       /** Card Read Command Events. */
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_READ_CARD_CMD)
       {
            /** Check for the CL type as Mifare Classic. */
            if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC)
            {
            	/* Put the Card in the known state */
				if (PH_ERR_SUCCESS != phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams))
				{
					/** Authentication Failure. */
					phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x6A, 0x82, 0);
					return;
				}
            	/** Check for the Authentication. */
                if (PH_ERR_SUCCESS != phExNFCCcid_Mifare_Do_Auth(PH_EXNFCCCID_MIFARE_AUTHENTICATE_P2))
                {
                    /** Authentication Failure. */
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x69, 0x82, 0);
                    return;
                }

                /** Perform the Read Operation on the Mifare Classic Card. */
                phExNFCCcid_Mifare_Read_Operations();
            }
            else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT)
            {
                /** Perform the Read Operation on the Mifare Ultralight Card. */
                phExNFCCcid_Mifare_Read_Operations();
            }
       } /* - PH_EXNFCCCID_USBCCID_CL_READ_CARD_CMD */

       /** Card Write Command Events. */
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_WRITE_CARD_CMD)
       {
            if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC)
            {
            	/* Put the Card in the known state */
				if (PH_ERR_SUCCESS != phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams))
				{
					/** Authentication Failure. */
					phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x6A, 0x82, 0);
					return;
				}
            	/** Check for Authentication for Mifare Classic Cards. */
                if (PH_ERR_SUCCESS != phExNFCCcid_Mifare_Do_Auth(PH_EXNFCCCID_MIFARE_AUTHENTICATE_P2))
                {
                    /** Authentication Failure. */
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x69, 0x82, 0);
                    return;
                }

                /** Perform the Write Operation in the Mifare Classic Card. */
                phExNFCCcid_Mifare_Write_Operations(PH_EXNFCCCID_MIFARE_CLASSIC_APDU_LC);
            }
            else if (gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFAREULTRALIGHT)
            {
                /** Perform the Write Operation in the Mifare Ultralight Card. */
                phExNFCCcid_Mifare_Write_Operations(PH_EXNFCCCID_MIFARE_ULTRALIGHT_APDU_LC);
            }
       } /* - PH_EXNFCCCID_USBCCID_CL_WRITE_CARD_CMD */

       /** Authentication Command Events. */
       if (dwBits & (uint32_t) PH_EXNFCCCID_USBCCID_CL_AUTH_CMD )
       {
            if ((gphExNFCCcid_sUsb_SlotInfo.bCLSlotType == PH_EXNFCCCID_USBCCID_CL_MIFARECLASSIC))
            {
            	/* Put the Card in the known state */
				if (PH_ERR_SUCCESS != phExNFCCcid_Check_Presence_L3A_Card(psDiscLoopParams))
				{
					/** Authentication Failure. */
					phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x6A, 0x82, 0);
					return;
				}
            	/** Perform the Authentication in the Mifare Classic Card. */
                status = phExNFCCcid_Mifare_Do_Auth(PH_EXNFCCCID_MIFARE_AUTHENTICATE_LC);

                if (status == PH_ERR_SUCCESS)
                {
                    /** Send the Success Status on Successful Authentication. */
                    gphExNFCCcid_sUsb_MifareInfo.bAuth = 1;
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x90, 0x00, 0);
                }
                else
                {
                    /** Send the Failure Status on Authentication failure. */
                    gphExNFCCcid_sUsb_MifareInfo.bAuth = 0;
                    phExNFCCcid_UsbCcid_PCSC_Send_APDU(0x69, 0x82, 0);
                }
            }
       } /* - PH_EXNFCCCID_USBCCID_CL_AUTH_CMD */
    } /* - While */
}



0 Kudos
Reply
2,685 Views
Monica_Li
Contributor I
Thanks a lot for sharing this. I'll try it out!
0 Kudos
Reply
2,827 Views
KaiLi
NXP TechSupport
NXP TechSupport

Hello @Monica_Li 

It's recommanded that you can use SCRTester tool to debug. This tool can be downloaded from PN7462 Family | NFC Cortex-M0 low-power microcontroller for access control | NXP Semiconductors

KaiLi_0-1747812671047.png

 After that, you can refer the chapter 8.2 of  UM10915 to build and debug.

0 Kudos
Reply
2,806 Views
Monica_Li
Contributor I
Hi Kaili,
Perhaps my expression was not detailed enough.
We have used the SCR Tester tool,the same problem reoccurs. Then to identify the cause, we used the IDE tool to check and found that every time the problem occurred, the code stopped at the same position,Like the first image described previously.
0 Kudos
Reply
2,784 Views
KaiLi
NXP TechSupport
NXP TechSupport

Hello @Monica_Li 

I would like to do the same test as you on my side, so could you tell me which driver do you select?

KaiLi_0-1747890747488.png

 

0 Kudos
Reply
2,760 Views
Monica_Li
Contributor I

we chosed the second one: PCSC

0 Kudos
Reply
2,702 Views
KaiLi
NXP TechSupport
NXP TechSupport

Hello @Monica_Li 

Unfortunately, I was unable to reproduce your problem. From the log you provided, it seems that the USB hardware interrupt was triggered by Improper operation. I don't know how you operated to trigger such an event, so is it possible to provide us with a video and let me try on my side?

0 Kudos
Reply