libftdi Archives

Subject: Re: Short example showing async read and write

From: Uwe Bonnes <bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Fri, 1 Jun 2018 11:26:52 +0200
Hello Thomas,

>>>>> "Thomas" == Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx> writes:
    ...
    Thomas> May I ask for a small follow up patch as this is an example code
    Thomas> others could learn from?

    Thomas> - Replace magic numbers "15" and "3" in the code with constants.

    Thomas> - Have a short description what the code does at the beginning
    Thomas> of the file. Ideally describe that it's using MPSEE mode or
    Thomas> actually why it's using that.


    Thomas>   In fact it currently states:

    Thomas>   "LIBFTDI EEPROM access example"

    Thomas>   :D

    Thomas> - Regarding the "while (index < 3)" loop: Here's a part that I'm
    Thomas> a bit unsure about: Should we add a safety exit condition to the
    Thomas> loop?

    Thomas>   [Just a few days ago I debugged a full spool partiton on a
    Thomas> customer machine because the fax subsystem was stuck in an
    Thomas> endless loop outputting five log messages per second. The code
    Thomas> in question included a newly added rate limiting code and other
    Thomas> safety measures, but somehow the exit condition of the loop
    Thomas> still wasn't triggered]
 
    Thomas>   NASA "code rule" number two comes to mind:
    Thomas> 
https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Developing_Safety-Critical_Code

    Thomas>   "2. All loops must have fixed bounds. This prevents runaway
    Thomas> code."

    Are checks and a resulting break allowed inside an infinit loop?

Please find a code cleanup appended.

Bye
-- 
Uwe Bonnes                bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 1623569 ------- Fax. 06151 1623305 ---------
>From 687cd1de886b40a70c3d1998463505e9c6db8916 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 1 Jun 2018 11:18:01 +0200
Subject: examples/async.c: Cleanup and explanations.

---
 examples/async.c | 56 ++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 12 deletions(-)

diff --git a/examples/async.c b/examples/async.c
index 08457b9..0589479 100644
--- a/examples/async.c
+++ b/examples/async.c
@@ -1,8 +1,22 @@
-/* LIBFTDI EEPROM access example
+/* Libftdi example for asynchronous read/write.
 
    This program is distributed under the GPL, version 2
 */
 
+/* This programm switches to MPSSE mode, and sets and then reads back
+ * the high byte 3 times with three different values.
+ * The expected read values are hard coded in ftdi_init
+ * with 0x00, 0x55 and 0xaa
+ *
+ * Make sure that that nothing else drives some bit of the high byte
+ * or expect a collision for a very short time and some differences
+ * in the data read back.
+ *
+ * Result should be the same without any option or with either
+ * -r or -w or -b.
+ */
+
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -49,7 +63,7 @@ int main(int argc, char **argv)
         }
     }
 
-    // Select first interface
+    /* Select first free interface */
     ftdi_set_interface(ftdi, INTERFACE_ANY);
 
     struct ftdi_device_list *devlist;
@@ -101,41 +115,59 @@ int main(int argc, char **argv)
                 err, ftdi_get_error_string(ftdi));
         return -1;
     }
-    uint8_t ftdi_init[15] = {TCK_DIVISOR, 0x00, 0x00,
+#define DATA_TO_READ 3
+    uint8_t ftdi_init[] = {TCK_DIVISOR, 0x00, 0x00,
+                             /* Set High byte to zero.*/
                              SET_BITS_HIGH, 0, 0xff,
                              GET_BITS_HIGH,
+                             /* Set High byte to 0x55.*/
                              SET_BITS_HIGH, 0x55, 0xff,
                              GET_BITS_HIGH,
+                             /* Set High byte to 0xaa.*/
                              SET_BITS_HIGH, 0xaa, 0xff,
-                             GET_BITS_HIGH};
+                             GET_BITS_HIGH,
+                             /* Set back to high impedance.*/
+                             SET_BITS_HIGH, 0x00, 0x00 };
     struct ftdi_transfer_control *tc_read;
     struct ftdi_transfer_control *tc_write;
     uint8_t data[3];
     if (do_read) {
-        tc_read = ftdi_read_data_submit(ftdi, data, 3);
+        tc_read = ftdi_read_data_submit(ftdi, data, DATA_TO_READ);
     }
     if (do_write) {
-        tc_write = ftdi_write_data_submit(ftdi, ftdi_init, 15);
+        tc_write = ftdi_write_data_submit(ftdi, ftdi_init, sizeof(ftdi_init));
         int transfer = ftdi_transfer_data_done(tc_write);
-        printf("Async write %d\n", transfer);
+        if (transfer != sizeof(ftdi_init)) {
+            printf("Async write failed : %d\n", transfer);
+        }
     } else {
-        int written = ftdi_write_data(ftdi, ftdi_init, 15);
-        if (written != 15) {
-            printf("Sync write failed\n");
+        int written = ftdi_write_data(ftdi, ftdi_init, sizeof(ftdi_init));
+        if (written != sizeof(ftdi_init)) {
+            printf("Sync write failed: %d\n", written);
         }
     }
     if (do_read) {
         int transfer = ftdi_transfer_data_done(tc_read);
-        printf("Async Read %d\n", transfer);
+        if (transfer != DATA_TO_READ) {
+            printf("Async Read failed:%d\n", transfer);
+        }
     } else {
         int index = 0;
-        while (index < 3) {
+        ftdi->usb_read_timeout = 1;
+        int i = 1000; /* Fail if read did not succeed in 1 second.*/
+        while (i--) {
             int res = ftdi_read_data(ftdi, data + index, 3 - index);
             if (res < 0) {
                 printf("Async read failure at %d\n", index);
             } else {
                 index += res;
             }
+            if (res == 3) {
+                break;
+            }
+        }
+        if (i < 1) {
+            printf("Async read unsuccessfull\n");
         }
     }
     printf("Read %02x %02x %02x\n", data[0], data[1], data[2]);
-- 
2.13.6


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

Current Thread