summaryrefslogtreecommitdiffstats
path: root/Linux_x86
diff options
context:
space:
mode:
Diffstat (limited to 'Linux_x86')
-rw-r--r--Linux_x86/phDal4Nfc.c56
-rw-r--r--Linux_x86/phDal4Nfc_i2c.c122
-rw-r--r--Linux_x86/phDal4Nfc_uart.c186
-rw-r--r--Linux_x86/phOsalNfc.c17
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);
}
-