diff options
Diffstat (limited to 'Linux_x86')
-rw-r--r-- | Linux_x86/phDal4Nfc.c | 56 | ||||
-rw-r--r-- | Linux_x86/phDal4Nfc_i2c.c | 122 | ||||
-rw-r--r-- | Linux_x86/phDal4Nfc_uart.c | 186 | ||||
-rw-r--r-- | Linux_x86/phOsalNfc.c | 17 |
4 files changed, 237 insertions, 144 deletions
diff --git a/Linux_x86/phDal4Nfc.c b/Linux_x86/phDal4Nfc.c index ec92566..9bedaf9 100644 --- a/Linux_x86/phDal4Nfc.c +++ b/Linux_x86/phDal4Nfc.c @@ -33,6 +33,8 @@ #include <stdlib.h> #ifdef ANDROID #include <linux/ipc.h> +#include <cutils/log.h> +#include <cutils/properties.h> // for property_get #else #include <sys/msg.h> #endif @@ -98,6 +100,7 @@ static phDal4Nfc_SContext_t gDalContext; static pphDal4Nfc_SContext_t pgDalContext; static phHal_sHwReference_t * pgDalHwContext; static sem_t nfc_read_sem; +static int low_level_traces; #ifdef USE_MQ_MESSAGE_QUEUE static phDal4Nfc_DeferredCall_Msg_t nDeferedMessage; static mqd_t nDeferedCallMessageQueueId; @@ -117,6 +120,31 @@ static void phDal4Nfc_FillMsg (phDal4Nfc_Message_t *pDalMsg, phOsalN DAL API IMPLEMENTATION ------------------------------------------------------------------------------------*/ +static void refresh_low_level_traces() { +#ifdef LOW_LEVEL_TRACES + low_level_traces = 1; + return; +#else + +#ifdef ANDROID + char value[PROPERTY_VALUE_MAX]; + + property_get("ro.debuggable", value, ""); + if (!value[0] || !atoi(value)) { + low_level_traces = 0; // user build, do not allow debug + return; + } + + property_get("debug.nfc.LOW_LEVEL_TRACES", value, ""); + if (value[0]) { + low_level_traces = atoi(value) ? 1 : 0; + return; + } +#endif + low_level_traces = 0; +#endif +} + /*----------------------------------------------------------------------------- FUNCTION: phDal4Nfc_Register @@ -216,6 +244,8 @@ NFCSTATUS phDal4Nfc_Init(void *pContext, void *pHwRef ) { NFCSTATUS result = NFCSTATUS_SUCCESS; + refresh_low_level_traces(); + if ((NULL != pContext) && (NULL != pHwRef)) { pContext = pgDalContext; @@ -530,7 +560,6 @@ NFCSTATUS phDal4Nfc_Config(pphDal4Nfc_sConfig_t config,void **phwref) gLinkFunc.open_and_configure = phDal4Nfc_uart_open_and_configure; gLinkFunc.read = phDal4Nfc_uart_read; gLinkFunc.write = phDal4Nfc_uart_write; - gLinkFunc.download = phDal4Nfc_uart_download; gLinkFunc.reset = phDal4Nfc_uart_reset; } break; @@ -605,7 +634,7 @@ NFCSTATUS phDal4Nfc_Reset(long level) { NFCSTATUS retstatus = NFCSTATUS_SUCCESS; - DAL_DEBUG("phDal4Nfc_Reset: VEN to %d",level); + DAL_DEBUG("phDal4Nfc_Reset: VEN to %ld",level); retstatus = gLinkFunc.reset(level); @@ -720,17 +749,19 @@ retry: else { i2c_error_count = 0; -#ifdef LOW_LEVEL_TRACES - phOsalNfc_PrintData("Received buffer", (uint16_t)gReadWriteContext.nNbOfBytesRead, gReadWriteContext.pReadBuffer); -#endif + + if (low_level_traces) + { + phOsalNfc_PrintData("RECV", (uint16_t)gReadWriteContext.nNbOfBytesRead, gReadWriteContext.pReadBuffer); + } DAL_DEBUG("RX Thread Read ok. nbToRead=%d\n", gReadWriteContext.nNbOfBytesToRead); DAL_DEBUG("RX Thread NbReallyRead=%d\n", gReadWriteContext.nNbOfBytesRead); - DAL_PRINT("RX Thread ReadBuff[]={ "); +/* DAL_PRINT("RX Thread ReadBuff[]={ "); for (i = 0; i < gReadWriteContext.nNbOfBytesRead; i++) { DAL_DEBUG("RX Thread 0x%x ", gReadWriteContext.pReadBuffer[i]); } - DAL_PRINT("RX Thread }\n"); + DAL_PRINT("RX Thread }\n"); */ /* read completed immediately */ sMsg.eMsgType= PHDAL4NFC_READ_MESSAGE; @@ -867,9 +898,10 @@ void phDal4Nfc_DeferredCb (void *params) case PHDAL4NFC_WRITE_MESSAGE: DAL_PRINT(" Dal deferred write called \n"); -#ifdef LOW_LEVEL_TRACES - phOsalNfc_PrintData("Send buffer", (uint16_t)gReadWriteContext.nNbOfBytesToWrite, gReadWriteContext.pWriteBuffer); -#endif + if(low_level_traces) + { + phOsalNfc_PrintData("SEND", (uint16_t)gReadWriteContext.nNbOfBytesToWrite, gReadWriteContext.pWriteBuffer); + } /* DAL_DEBUG("dalMsg->transactInfo.length : %d\n", dalMsg->transactInfo.length); */ /* Make a Physical WRITE */ @@ -894,12 +926,12 @@ void phDal4Nfc_DeferredCb (void *params) DAL_PRINT(" Physical Write Success \n"); TransactionInfo.length=(uint16_t)gReadWriteContext.nNbOfBytesWritten; TransactionInfo.status=NFCSTATUS_SUCCESS; - DAL_PRINT("WriteBuff[]={ "); +/* DAL_PRINT("WriteBuff[]={ "); for (i = 0; i < gReadWriteContext.nNbOfBytesWritten; i++) { DAL_DEBUG("0x%x ", gReadWriteContext.pWriteBuffer[i]); } - DAL_PRINT("}\n"); + DAL_PRINT("}\n"); */ // Free TempWriteBuffer if(gReadWriteContext.pTempWriteBuffer != NULL) diff --git a/Linux_x86/phDal4Nfc_i2c.c b/Linux_x86/phDal4Nfc_i2c.c index 2d0e113..72da8e7 100644 --- a/Linux_x86/phDal4Nfc_i2c.c +++ b/Linux_x86/phDal4Nfc_i2c.c @@ -23,7 +23,7 @@ */ #define LOG_TAG "NFC_i2c" -#include <utils/Log.h> +#include <cutils/log.h> #include <stdlib.h> #include <unistd.h> @@ -31,6 +31,7 @@ #include <termios.h> #include <sys/ioctl.h> #include <sys/select.h> +#include <errno.h> #include <phDal4Nfc_debug.h> #include <phDal4Nfc_i2c.h> @@ -188,20 +189,49 @@ PURPOSE: Reads nNbBytesToRead bytes and writes them in pBuffer. int phDal4Nfc_i2c_read(uint8_t * pBuffer, int nNbBytesToRead) { - int ret; - DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "read called but not opened!"); - - DAL_DEBUG("Reading %d bytes\n", nNbBytesToRead); - ret = read(gI2cPortContext.nHandle, pBuffer, nNbBytesToRead); - if (ret < 0) - { - DAL_DEBUG("Read failed: read() returned %d\n", ret); - } - else - { - DAL_DEBUG("Read succeed (%d bytes)\n", ret); - } - return ret; + int ret; + int numRead = 0; + struct timeval tv; + fd_set rfds; + + DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "read called but not opened!"); + DAL_DEBUG("_i2c_read() called to read %d bytes", nNbBytesToRead); + + // Read with 2 second timeout, so that the read thread can be aborted + // when the pn544 does not respond and we need to switch to FW download + // mode. This should be done via a control socket instead. + while (numRead < nNbBytesToRead) { + FD_ZERO(&rfds); + FD_SET(gI2cPortContext.nHandle, &rfds); + tv.tv_sec = 2; + tv.tv_usec = 0; + ret = select(gI2cPortContext.nHandle + 1, &rfds, NULL, NULL, &tv); + if (ret < 0) { + DAL_DEBUG("select() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } else if (ret == 0) { + DAL_PRINT("timeout!"); + return -1; + } + ret = read(gI2cPortContext.nHandle, pBuffer + numRead, nNbBytesToRead - numRead); + if (ret > 0) { + DAL_DEBUG("read %d bytes", ret); + numRead += ret; + } else if (ret == 0) { + DAL_PRINT("_i2c_read() EOF"); + return -1; + } else { + DAL_DEBUG("_i2c_read() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + return numRead; } /*----------------------------------------------------------------------------- @@ -215,23 +245,32 @@ PURPOSE: Writes nNbBytesToWrite bytes from pBuffer to the link int phDal4Nfc_i2c_write(uint8_t * pBuffer, int nNbBytesToWrite) { - int ret; - DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "write called but not opened!"); - - DAL_DEBUG("Writing %d bytes\n", nNbBytesToWrite); - ret = write(gI2cPortContext.nHandle, pBuffer, nNbBytesToWrite); - if (ret < 0) - { - DAL_DEBUG("Write failed: write() returned %d \n", ret); - } - else - { - DAL_DEBUG("Write succeed (%d bytes)\n", ret); - } - return ret; + int ret; + int numWrote = 0; + + DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "write called but not opened!"); + DAL_DEBUG("_i2c_write() called to write %d bytes\n", nNbBytesToWrite); + + while (numWrote < nNbBytesToWrite) { + ret = write(gI2cPortContext.nHandle, pBuffer + numWrote, nNbBytesToWrite - numWrote); + if (ret > 0) { + DAL_DEBUG("wrote %d bytes", ret); + numWrote += ret; + } else if (ret == 0) { + DAL_PRINT("_i2c_write() EOF"); + return -1; + } else { + DAL_DEBUG("_i2c_write() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + + return numWrote; } - /*----------------------------------------------------------------------------- FUNCTION: phDal4Nfc_i2c_reset @@ -241,26 +280,7 @@ PURPOSE: Reset the PN544, using the VEN pin -----------------------------------------------------------------------------*/ int phDal4Nfc_i2c_reset(long level) { - int ret = NFCSTATUS_SUCCESS; - - DAL_DEBUG("phDal4Nfc_i2c_reset, VEN level = %ld",level); - - ret = ioctl(gI2cPortContext.nHandle, PN544_SET_PWR, level); - - /* HACK to increase reset time - * TODO: move this to kernel - */ - if (level == 0) { - LOGW("sleeping a little longer..."); - usleep(50000); - } else { - usleep(10000); - } + DAL_DEBUG("phDal4Nfc_i2c_reset, VEN level = %ld", level); - return ret; + return ioctl(gI2cPortContext.nHandle, PN544_SET_PWR, level); } - - - - - diff --git a/Linux_x86/phDal4Nfc_uart.c b/Linux_x86/phDal4Nfc_uart.c index 30cb500..bb891e3 100644 --- a/Linux_x86/phDal4Nfc_uart.c +++ b/Linux_x86/phDal4Nfc_uart.c @@ -26,11 +26,17 @@ * */ +#define LOG_TAG "NFC_uart" +#include <cutils/log.h> + #include <unistd.h> #include <fcntl.h> #include <termios.h> +#include <errno.h> #include <sys/ioctl.h> #include <sys/select.h> +#include <stdio.h> +#include <errno.h> #include <phDal4Nfc_debug.h> #include <phDal4Nfc_uart.h> @@ -161,28 +167,28 @@ NFCSTATUS phDal4Nfc_uart_open_and_configure(pphDal4Nfc_sConfig_t pConfig, void * switch(pConfig->nLinkType) { case ENUM_DAL_LINK_TYPE_COM1: - pComPort = "/dev/ttyS0"; + pComPort = "/dev/ttyO0"; break; case ENUM_DAL_LINK_TYPE_COM2: - pComPort = "/dev/ttyS1"; + pComPort = "/dev/ttyO1"; break; case ENUM_DAL_LINK_TYPE_COM3: - pComPort = "/dev/ttyS2"; + pComPort = "/dev/ttyO2"; break; case ENUM_DAL_LINK_TYPE_COM4: - pComPort = "/dev/ttyS3"; + pComPort = "/dev/ttyO3"; break; case ENUM_DAL_LINK_TYPE_COM5: - pComPort = "/dev/ttyS4"; + pComPort = "/dev/ttyO4"; break; case ENUM_DAL_LINK_TYPE_COM6: - pComPort = "/dev/ttyS5"; + pComPort = "/dev/ttyO5"; break; case ENUM_DAL_LINK_TYPE_COM7: - pComPort = "/dev/ttyS6"; + pComPort = "/dev/ttyO6"; break; case ENUM_DAL_LINK_TYPE_COM8: - pComPort = "/dev/ttyS7"; + pComPort = "/dev/ttyO7"; break; case ENUM_DAL_LINK_TYPE_USB: pComPort = "/dev/ttyUSB0"; @@ -263,31 +269,51 @@ PURPOSE: Reads nNbBytesToRead bytes and writes them in pBuffer. Returns the number of bytes really read or -1 in case of error. -----------------------------------------------------------------------------*/ - int phDal4Nfc_uart_read(uint8_t * pBuffer, int nNbBytesToRead) { - fd_set rfds; - struct timeval tv; - int ret; - - DAL_ASSERT_STR(gComPortContext.nOpened == 1, "read called but not opened!"); - - FD_ZERO(&rfds); - FD_SET(gComPortContext.nHandle, &rfds); - - /* select will block for 10 sec */ - tv.tv_sec = 2; - tv.tv_usec = 0; - - ret = select(gComPortContext.nHandle + 1, &rfds, NULL, NULL, &tv); - - if (ret == -1) - return -1; - - if (ret) - return read(gComPortContext.nHandle, pBuffer, nNbBytesToRead); - - return 0; + int ret; + int numRead = 0; + struct timeval tv; + fd_set rfds; + + DAL_ASSERT_STR(gComPortContext.nOpened == 1, "read called but not opened!"); + DAL_DEBUG("_uart_read() called to read %d bytes", nNbBytesToRead); + + // Read with 2 second timeout, so that the read thread can be aborted + // when the pn544 does not respond and we need to switch to FW download + // mode. This should be done via a control socket instead. + while (numRead < nNbBytesToRead) { + FD_ZERO(&rfds); + FD_SET(gComPortContext.nHandle, &rfds); + tv.tv_sec = 2; + tv.tv_usec = 0; + ret = select(gComPortContext.nHandle + 1, &rfds, NULL, NULL, NULL); + if (ret < 0) { + DAL_DEBUG("select() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } else if (ret == 0) { + DAL_PRINT("timeout!"); + break; // return partial response + } + ret = read(gComPortContext.nHandle, pBuffer + numRead, nNbBytesToRead - numRead); + if (ret > 0) { + DAL_DEBUG("read %d bytes", ret); + numRead += ret; + } else if (ret == 0) { + DAL_PRINT("_uart_read() EOF"); + return 0; + } else { + DAL_DEBUG("_uart_read() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + return numRead; } /*----------------------------------------------------------------------------- @@ -301,28 +327,30 @@ PURPOSE: Writes nNbBytesToWrite bytes from pBuffer to the link int phDal4Nfc_uart_write(uint8_t * pBuffer, int nNbBytesToWrite) { - fd_set wfds; - struct timeval tv; - int ret; - - DAL_ASSERT_STR(gComPortContext.nOpened == 1, "write called but not opened!"); - - FD_ZERO(&wfds); - FD_SET(gComPortContext.nHandle, &wfds); - - /* select will block for 10 sec */ - tv.tv_sec = 2; - tv.tv_usec = 0; - - ret = select(gComPortContext.nHandle + 1, NULL, &wfds, NULL, &tv); - - if (ret == -1) - return -1; - - if (ret) - return write(gComPortContext.nHandle, pBuffer, nNbBytesToWrite); - - return 0; + int ret; + int numWrote = 0; + + DAL_ASSERT_STR(gComPortContext.nOpened == 1, "write called but not opened!"); + DAL_DEBUG("_uart_write() called to write %d bytes\n", nNbBytesToWrite); + + while (numWrote < nNbBytesToWrite) { + ret = write(gComPortContext.nHandle, pBuffer + numWrote, nNbBytesToWrite - numWrote); + if (ret > 0) { + DAL_DEBUG("wrote %d bytes", ret); + numWrote += ret; + } else if (ret == 0) { + DAL_PRINT("_uart_write() EOF"); + return -1; + } else { + DAL_DEBUG("_uart_write() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + + return numWrote; } /*----------------------------------------------------------------------------- @@ -332,24 +360,38 @@ FUNCTION: phDal4Nfc_uart_reset PURPOSE: Reset the PN544, using the VEN pin -----------------------------------------------------------------------------*/ -int phDal4Nfc_uart_reset() +int phDal4Nfc_uart_reset(long level) { - DAL_PRINT("phDal4Nfc_uart_reset"); - - return NFCSTATUS_FEATURE_NOT_SUPPORTED; + static const char NFC_POWER_PATH[] = "/sys/devices/platform/nfc-power/nfc_power"; + int sz; + int fd = -1; + int ret = NFCSTATUS_FAILED; + char buffer[2]; + + DAL_DEBUG("phDal4Nfc_uart_reset, VEN level = %ld", level); + + if (snprintf(buffer, sizeof(buffer), "%u", (unsigned int)level) != 1) { + LOGE("Bad nfc power level (%u)", (unsigned int)level); + goto out; + } + + fd = open(NFC_POWER_PATH, O_WRONLY); + if (fd < 0) { + LOGE("open(%s) for write failed: %s (%d)", NFC_POWER_PATH, + strerror(errno), errno); + goto out; + } + sz = write(fd, &buffer, sizeof(buffer) - 1); + if (sz < 0) { + LOGE("write(%s) failed: %s (%d)", NFC_POWER_PATH, strerror(errno), + errno); + goto out; + } + ret = NFCSTATUS_SUCCESS; + +out: + if (fd >= 0) { + close(fd); + } + return ret; } - -/*----------------------------------------------------------------------------- - -FUNCTION: phDal4Nfc_uart_write - -PURPOSE: Put the PN544 in download mode, using the GPIO4 pin - ------------------------------------------------------------------------------*/ -int phDal4Nfc_uart_download() -{ - DAL_PRINT("phDal4Nfc_uart_download"); - - return NFCSTATUS_FEATURE_NOT_SUPPORTED; -} - diff --git a/Linux_x86/phOsalNfc.c b/Linux_x86/phOsalNfc.c index 9765e2c..0544309 100644 --- a/Linux_x86/phOsalNfc.c +++ b/Linux_x86/phOsalNfc.c @@ -160,16 +160,15 @@ void phOsalNfc_RaiseException(phOsalNfc_ExceptionType_t eExceptionType, uint16_t */ void phOsalNfc_PrintData(const char *pString, uint32_t length, uint8_t *pBuffer) { - char print_buffer[512]; // Max length 512 for the download mode + char print_buffer[length * 3 + 1]; int i; - if(NULL!=pString && length > 1 && length < 34) - { - print_buffer[0] = '\0'; - for (i = 0; i < length; i++) { - snprintf(&print_buffer[i*5], 6, " 0x%02X", pBuffer[i]); - } - LOGD("> NFC I2C %s: %s", pString,print_buffer); + if (pString == NULL) { + pString = ""; + } + print_buffer[0] = '\0'; + for (i = 0; i < length; i++) { + snprintf(&print_buffer[i*3], 4, " %02X", pBuffer[i]); } + LOGD("> %s:%s", pString, print_buffer); } - |