/******************************************************************************* ** ** 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 (NFCSTATUS_INVALID_DEVICE != (uintptr_t)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; } } /* 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 - NFCSTATUS_INVALID_DEVICE == gpphTmlNfc_Context->pDevHandle"); } } 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 (NFCSTATUS_INVALID_DEVICE != (uintptr_t)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); 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 (FALSE == gpphTmlNfc_Context->bWriteCbInvoked) { 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 - NFCSTATUS_INVALID_DEVICE != gpphTmlNfc_Context->pDevHandle"); } /* 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_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 numRead = 0; uint16_t totalBtyesToRead = 0; #ifdef PHFL_TML_ALT_NFC // Overwrite handle pDevHandle = (void*)iI2CFd; #endif int ret_Select; struct timeval tv; fd_set rfds; UNUSED(nNbBytesToRead); if (NULL == pDevHandle) { return -1; } if (FALSE == bFwDnldFlag) { 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 { #ifdef PHFL_TML_ALT_NFC wait4interrupt(); #endif 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 (FALSE == bFwDnldFlag) { totalBtyesToRead = NORMAL_MODE_HEADER_LEN; } else { totalBtyesToRead = FW_DNLD_HEADER_LEN; } if(numRead < totalBtyesToRead) { #ifdef PHFL_TML_ALT_NFC wait4interrupt(); #endif 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(TRUE == bFwDnldFlag) { totalBtyesToRead = pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN; } else { totalBtyesToRead = pBuffer[NORMAL_MODE_LEN_OFFSET] + NORMAL_MODE_HEADER_LEN; } #ifdef PHFL_TML_ALT_NFC wait4interrupt(); #endif 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(FALSE == bFwDnldFlag) { 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; } } return numRead; }