From eae07f19774616029fb9cc8ceb5408dbc4078d97 Mon Sep 17 00:00:00 2001 From: Emanuele Bertoldi Date: Tue, 18 Jan 2011 11:35:23 +0000 Subject: [PATCH] Improved UART communication on POSIX systems: - Added "dynamic timeout" to "uart_send" function. - Added "static timeout" to each iteration of the while loop (it seems to solve a lot of sync troubles during read operation). (Tested with PN532). --- libnfc/buses/uart_posix.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libnfc/buses/uart_posix.c b/libnfc/buses/uart_posix.c index 28e47ef..f21e948 100644 --- a/libnfc/buses/uart_posix.c +++ b/libnfc/buses/uart_posix.c @@ -261,7 +261,8 @@ uart_receive (serial_port sp, byte_t * pbtRx, size_t * pszRx) } *pszRx += res; - tv.tv_usec = uiTimeoutPerByte * MIN( iExpectedByteCount, 16 ); // Reload timeout with a low value to prevent from waiting too long on slow devices (16x is enought to took at least 1 byte) + // Reload timeout with a low value to prevent from waiting too long on slow devices (16x is enought to took at least 1 byte) + tv.tv_usec = uiTimeoutStatic + uiTimeoutPerByte * MIN( iExpectedByteCount, 16 ); // DBG("Timeout reloaded at: %d µs", tv.tv_usec); } while (byteCount && (iExpectedByteCount > 0)); @@ -279,14 +280,16 @@ uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx) int32_t res; size_t szPos = 0; fd_set rfds; - struct timeval tv; - const struct timeval tvDefault = { .tv_sec = 0, .tv_usec = 20000 }; + struct timeval tvTimeout = { + .tv_sec = 0, + .tv_usec = uiTimeoutStatic + (uiTimeoutPerByte * szTx), + }; + struct timeval tv = tvTimeout; while (szPos < szTx) { // Reset file descriptor FD_ZERO (&rfds); FD_SET (((serial_port_unix *) sp)->fd, &rfds); - tv = tvDefault; res = select (((serial_port_unix *) sp)->fd + 1, NULL, &rfds, NULL, &tv); // Write error @@ -308,6 +311,9 @@ uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx) } szPos += res; + + // Reload timeout with a low value to prevent from waiting too long on slow devices (16x is enought to took at least 1 byte) + tv.tv_usec = uiTimeoutStatic + uiTimeoutPerByte * MIN( szTx - szPos, 16 ); } return 0; }