/*******************************************************************************
**
** 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;
}
Exemplo n.º 3
0
/*******************************************************************************
**
** 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;
}