Discussion:
C++ flush() Never Flushes RX
Eric S.
2017-01-16 19:46:23 UTC
Permalink
The file ftdi.hpp contains
enum Direction
{
Input,
Output
};

The file ftdi.cpp contains
int Context::flush(int mask)
{
int ret = 1;

if (mask & Input)
ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
if (mask & Output)
ret &= ftdi_usb_purge_tx_buffer(d->ftdi);

return ret;
}

Since the enumeration assigns the value "0" to Input, the input queue is
never flushed.
The enumeration should be something like

The file ftdi.hpp contains
enum Direction
{
Input = 0x1,
Output = 0x2
};


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com
Eric Schott
2017-01-16 21:51:55 UTC
Permalink
On Mon, Jan 16, 2017 at 2:46PM, Eric Schott <***@morningjoy.com> wrote


The two additional changes (below) make for a better solution.
Post by Eric S.
The file ftdi.hpp contains
enum Direction
{
Input,
Output
};
The file ftdi.cpp contains
int Context::flush(int mask)
{
int ret = 1;
if (mask & Input)
ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
if (mask & Output)
ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
return ret;
}
The "&=" is inappropriate as a failure with the rx flush would be
masked if the tx flush was successful. A better fix is to use the
additional purge function in libftdi.c like:

int Context::flush(int mask)
{
switch (mask)
{

case Input:
return ftdi_usb_purge_rx_buffer(d->ftdi);

case Output:
return ftdi_usb_purge_tx_buffer(d->ftdi);

case Input | Output:
return ftdi_usb_purge_buffers(d->ftdi);

case 0:
return 0;

default:
d->ftdi->error_str = "Wrong arguments";
return -101;
}
}
Post by Eric S.
Since the enumeration assigns the value "0" to Input, the input queue is
never flushed.
The enumeration should be something like
The file ftdi.hpp contains
enum Direction
{
Input = 0x1,
Output = 0x2
};
To allow previously compiled programs to work with a corrected shared
library, the enumeration should be

enum Direction
{
Input = 0x2,
Output = 0x1
};


Old API New API
---------------- -----------------
Arg as coded Val Behavior Val Behavior
-------------- --- ----------- --- ------------
<zero> 0x0 No action 0x0 No action
Input 0x0 No action 0x2 Rx Flushed
Output 0x1 Out Flushed 0x1 Tx Flushed
Input | Output 0x1 Out Flushed 0x3 Both Flushed


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com
Thomas Jarosch
2017-01-23 10:03:00 UTC
Permalink
Hi Eric,
Post by Eric Schott
Old API New API
---------------- -----------------
Arg as coded Val Behavior Val Behavior
-------------- --- ----------- --- ------------
<zero> 0x0 No action 0x0 No action
Input 0x0 No action 0x2 Rx Flushed
Output 0x1 Out Flushed 0x1 Tx Flushed
Input | Output 0x1 Out Flushed 0x3 Both Flushed
good catch! :)

Also thanks for the state table. We can also increase the .so version of the
C++ library. This means people need to recompile and then the code will
automatically use the new and correct value for the enum.

Care to send a (git) patch? Then I can give proper credit to you
and also there will be no copy and paste errors from grabbing
the puzzle pieces via email.

Thanks,
Thomas


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com
Eric Schott
2017-07-21 00:29:29 UTC
Permalink
For FTDI1 C++ implementation, correct the purge Direction and
ModemCtl enumerations definitions to not use value of zero for bit
masks. The new enumeration values are defined so programs compiled
with the old ftdi.hpp include would work as previously (doing nothing
when the enumeration with the zero value was bit-or'ed into the
argument).
---
ftdipp/ftdi.cpp | 24 +++++++++++++++++++-----
ftdipp/ftdi.hpp | 8 ++++----
2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/ftdipp/ftdi.cpp b/ftdipp/ftdi.cpp
index aca686a..ff10a84 100644
--- a/ftdipp/ftdi.cpp
+++ b/ftdipp/ftdi.cpp
@@ -144,12 +144,26 @@ int Context::reset()

int Context::flush(int mask)
{
- int ret = 1;
+ int ret;

- if (mask & Input)
- ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
- if (mask & Output)
- ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
+ switch (mask & (Input | Output)) {
+ case Input:
+ ret = ftdi_usb_purge_rx_buffer(d->ftdi);
+ break;
+
+ case Output:
+ ret = ftdi_usb_purge_tx_buffer(d->ftdi);
+ break;
+
+ case Input | Output:
+ ret = ftdi_usb_purge_buffers(d->ftdi);
+ break;
+
+ default:
+ // Emulate behavior of previous version.
+ ret = 1;
+ break;
+ }

return ret;
}
diff --git a/ftdipp/ftdi.hpp b/ftdipp/ftdi.hpp
index dc035cc..2241bf3 100644
--- a/ftdipp/ftdi.hpp
+++ b/ftdipp/ftdi.hpp
@@ -55,16 +55,16 @@ public:
*/
enum Direction
{
- Input,
- Output
+ Input = 0x2,
+ Output = 0x1,
};

/*! \brief Modem control flags.
*/
enum ModemCtl
{
- Dtr,
- Rts
+ Dtr = 0x2,
+ Rts = 0x1,
};

/* Constructor, Destructor */
--
2.12.3


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com
Loading...