C++ flush() Never Flushes RX

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

C++ flush() Never Flushes RX

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;
  }

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 [hidden email]  

Reply | Threaded
Open this post in threaded view
|

Re: C++ flush() Never Flushes RX

Eric S.
On Mon, Jan 16, 2017 at 2:46PM, Eric Schott <[hidden email]> wrote


The two additional changes (below) make for a better solution.

> 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;
    }
}

> 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 [hidden email]  

Reply | Threaded
Open this post in threaded view
|

Re: Re: C++ flush() Never Flushes RX

Thomas Jarosch
Hi Eric,

On Monday, 16. January 2017 16:51:55 Eric Schott wrote:
>                  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 [hidden email]  

Reply | Threaded
Open this post in threaded view
|

[PATCH 1/1] Fix Direction and ModemCtl enumerations to not use 0 for, bit mask.

Eric Schott
In reply to this post by Eric S.
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 [hidden email]