uart_flush_input() can now wait a bit

Calling ioctl flush too fast before actual garbage bytes arrive was useless.
It solves an issue e.g. when config asks for scanning for multiple incompatible serial devices:
One scan can mess up the reader and we've to wait & flush properly for the next driver to be able to scan correctly
This commit is contained in:
Philippe Teuwen 2013-10-01 14:09:14 +02:00
parent de1ca46066
commit 1d0d3c3b45
5 changed files with 36 additions and 12 deletions

View file

@ -57,6 +57,22 @@
#define LOG_GROUP NFC_LOG_GROUP_COM
#define LOG_CATEGORY "libnfc.bus.uart"
#ifndef _WIN32
// Needed by sleep() under Unix
# include <unistd.h>
# include <time.h>
# define msleep(x) do { \
struct timespec xsleep; \
xsleep.tv_sec = x / 1000; \
xsleep.tv_nsec = (x - xsleep.tv_sec * 1000) * 1000 * 1000; \
nanosleep(&xsleep, NULL); \
} while (0)
#else
// Needed by Sleep() under Windows
# include <winbase.h>
# define msleep Sleep
#endif
# if defined(__APPLE__)
const char *serial_ports_device_radix[] = { "tty.SLAB_USBtoUART", "tty.usbserial-", NULL };
# elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__FreeBSD_kernel__)
@ -122,8 +138,16 @@ uart_open(const char *pcPortName)
}
void
uart_flush_input(serial_port sp)
uart_flush_input(serial_port sp, bool wait)
{
// flush commands may seem to be without effect
// if asked too quickly after previous event, cf comments below
// therefore a "wait" argument allows now to wait before flushing
// I believe that now the byte-eater part is not required anymore --Phil
if (wait) {
msleep(50); // 50 ms
}
// This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35)
tcflush(UART_DATA(sp)->fd, TCIFLUSH);
// So, I wrote this byte-eater

View file

@ -49,7 +49,7 @@ typedef void *serial_port;
serial_port uart_open(const char *pcPortName);
void uart_close(const serial_port sp);
void uart_flush_input(const serial_port sp);
void uart_flush_input(const serial_port sp, bool wait);
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
uint32_t uart_get_speed(const serial_port sp);

View file

@ -426,7 +426,7 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input(sp);
uart_flush_input(sp, true);
uart_set_speed(sp, ACR122S_DEFAULT_SPEED);
nfc_connstring connstring;
@ -578,7 +578,7 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring)
return NULL;
}
uart_flush_input(sp);
uart_flush_input(sp, true);
uart_set_speed(sp, ndd.speed);
pnd = nfc_device_new(context, connstring);
@ -659,7 +659,7 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring)
static int
acr122s_send(nfc_device *pnd, const uint8_t *buf, const size_t buf_len, int timeout)
{
uart_flush_input(DRIVER_DATA(pnd)->port);
uart_flush_input(DRIVER_DATA(pnd)->port, false);
uint8_t cmd[MAX_FRAME_SIZE];
if (! acr122s_build_frame(pnd, cmd, sizeof(cmd), 0, 0, buf, buf_len, 1)) {

View file

@ -113,7 +113,7 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input(sp);
uart_flush_input(sp, true);
uart_set_speed(sp, ARYGON_DEFAULT_SPEED);
nfc_connstring connstring;
@ -266,7 +266,7 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring)
}
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input(sp);
uart_flush_input(sp, true);
uart_set_speed(sp, ndd.speed);
// We have a connection
@ -340,7 +340,7 @@ arygon_tama_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, i
{
int res = 0;
// Before sending anything, we need to discard from any junk bytes
uart_flush_input(DRIVER_DATA(pnd)->port);
uart_flush_input(DRIVER_DATA(pnd)->port, false);
uint8_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff"

View file

@ -86,7 +86,7 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input(sp);
uart_flush_input(sp, true);
// Serial port claimed but we need to check if a PN532_UART is opened.
uart_set_speed(sp, PN532_UART_DEFAULT_SPEED);
@ -237,7 +237,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
return NULL;
}
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input(sp);
uart_flush_input(sp, true);
uart_set_speed(sp, ndd.speed);
// We have a connection
@ -315,7 +315,7 @@ pn532_uart_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, in
{
int res = 0;
// Before sending anything, we need to discard from any junk bytes
uart_flush_input(DRIVER_DATA(pnd)->port);
uart_flush_input(DRIVER_DATA(pnd)->port, false);
switch (CHIP_DATA(pnd)->power_mode) {
case LOWVBAT: {
@ -494,7 +494,7 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
// The PN53x command is done and we successfully received the reply
return len;
error:
uart_flush_input(DRIVER_DATA(pnd)->port);
uart_flush_input(DRIVER_DATA(pnd)->port, true);
return pnd->last_error;
}