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 */
}