From 8362c28e3a7bf27324ddb0a85fa2147399ac1273 Mon Sep 17 00:00:00 2001 From: Nathael Pajani Date: Sat, 25 Aug 2012 22:45:41 +0200 Subject: [PATCH] Modifications to drop input buffer content rather than trying to read the axact amount of data. --- isp_commands.c | 6 +++--- isp_utils.c | 39 +++++++++++++++++++++++++++++++++++++++ isp_utils.h | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/isp_commands.c b/isp_commands.c index e43f518..7ee167a 100644 --- a/isp_commands.c +++ b/isp_commands.c @@ -126,7 +126,7 @@ int isp_connect(unsigned int crystal_freq, int quiet) return -3; } /* Empty read buffer (echo is on) */ - isp_serial_read(buf, strlen(SYNCHRO), strlen(SYNCHRO)); + isp_serial_empty_buffer(); /* Read reply (OK) */ isp_serial_read(buf, REP_BUFSIZE, strlen(SYNCHRO_OK)); if (strncmp(SYNCHRO_OK, buf, strlen(SYNCHRO_OK)) != 0) { @@ -137,7 +137,7 @@ int isp_connect(unsigned int crystal_freq, int quiet) /* Documentation says we should send crystal frequency .. sending anything is OK */ isp_serial_write(freq, strlen(freq)); /* Empty read buffer (echo is on) */ - isp_serial_read(buf, strlen(freq), strlen(freq)); + isp_serial_empty_buffer(); /* Read reply (OK) */ isp_serial_read(buf, REP_BUFSIZE, strlen(SYNCHRO_OK)); if (strncmp(SYNCHRO_OK, buf, strlen(SYNCHRO_OK)) != 0) { @@ -148,7 +148,7 @@ int isp_connect(unsigned int crystal_freq, int quiet) /* Turn off echo */ isp_serial_write(SYNCHRO_ECHO_OFF, strlen(SYNCHRO_ECHO_OFF)); /* Empty read buffer (echo still on) */ - isp_serial_read(buf, strlen(SYNCHRO_ECHO_OFF), strlen(SYNCHRO_ECHO_OFF)); + isp_serial_empty_buffer(); /* Read eror code for command */ isp_serial_read(buf, REP_BUFSIZE, 3); diff --git a/isp_utils.c b/isp_utils.c index 6409375..4bd075d 100644 --- a/isp_utils.c +++ b/isp_utils.c @@ -143,6 +143,41 @@ int isp_serial_write(const char* buf, unsigned int buf_size) return nb; } +static char next_read_char = 0; +void isp_serial_empty_buffer() +{ + int nb = 0; + char unused = 0; + unsigned int loops = 0; /* Used to create a timeout */ + + do { + nb = read(serial_fd, &unused, 1); + if (nb < 0) { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + if (loops++ > 100) { + break; /* timeout at 500ms */ + } + usleep( 5000 ); + continue; + } + perror("Serial read error"); + return; + } else if (nb == 0) { + printf("serial_read: end of file !!!!\n"); + return; + } + } while ((unused != '\r') && (unused != '\n')); + + /* This should be improved by reading ALL \r and \n */ + if (unused == '\r') { + nb = read(serial_fd, &unused, 1); + } + if (unused == '\n') { + return; + } + next_read_char = unused; +} + /* Try to read at least "min_read" characters from the serial line. * Returns -1 on error, 0 on end of file, or read count otherwise. */ @@ -156,6 +191,10 @@ int isp_serial_read(char* buf, unsigned int buf_size, unsigned int min_read) printf("serial_read: buffer too small for min read value.\n"); return -3; } + if (next_read_char != 0) { + buf[count++] = next_read_char; + next_read_char = 0; + } do { nb = read(serial_fd, &buf[count], (buf_size - count)); diff --git a/isp_utils.h b/isp_utils.h index 5a59186..521ae69 100644 --- a/isp_utils.h +++ b/isp_utils.h @@ -30,6 +30,7 @@ void isp_serial_close(void); /* Simple write() wrapper, with trace if enabled */ int isp_serial_write(const char* buf, unsigned int buf_size); +void isp_serial_empty_buffer(); /* Try to read at least "min_read" characters from the serial line. * Returns -1 on error, 0 on end of file, or read count otherwise. */ -- 2.43.0