Changes between Version 1 and Version 2 of serial


Ignore:
Timestamp:
10/21/2017 11:24:15 PM (3 months ago)
Author:
Chris Lang
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • serial

    v1 v2  
    1818
    1919The following table describes the various on-board UARTs for standard Gateworks products. Please consult the board specific hardware user manual for additional details:
    20 ||= Family =||= Board =||= Device =||= Function         =||
    21 || Avila    || GW2347  || ttyS0    || console: 3.3V TTL JTAG J2 / RS232 J5   ||
    22 ||          ||         || ttyS1    || UART: RS232 J3                         ||
    23 ||          || GW2348  || ttyS0    || console: 3.3V TTL JTAG J7 / RS232 J13  ||
    24 ||          ||         || ttyS1    || UART: RS232 J6                         ||
    25 ||          || GW2355  || ttyS0    || console: 3.3V TTL JTAG J3 / RS232 J5   ||
    26 ||          ||         || ttyS1    || GPS                                    ||
    27 ||          || GW2357  || ttyS0    || console: 3.3V TTL JTAG J2 / RS232 J6   ||
    28 ||          ||         || ttyS1    || UART: RS232 J36                        ||
    29 || Cambria  || GW2350  || ttyS0    || console: 3.3V TTL JTAG J1/J10          ||
    30 ||          ||         || ttyS1    || GPS                                    ||
    31 ||          ||         || ttyS2    || RS485 J6                               ||
    32 ||          || GW2358  || ttyS0    || console: 3.3V TTL JTAG J10 / RS232 J17 ||
    33 ||          ||         || ttyS1    || GPS                                    ||
    34 ||          ||         || ttyS2    || RS485 J3                               ||
    35 || Rincon   || GW2361  || ttyS0    || console: 3.3V TTL JTAG J2              ||
    36 ||          ||         || ttyS1    || RS232 J7                               ||
    37 ||          ||         || ttyS2    || RS485 J6                               ||
    38 || Laguna   || GW2380/2/3 || ttyS0    || console: 3.3V TTL JTAG J2 / 3.3V TTL J4 ||                           
    39 ||          ||         || ttyS1    || GPS                                        ||
    40 ||          ||         || ttyS2    || UART: 3.3V TTL J8                          ||
    41 ||          || GW2387  || ttyS0    || console: 3.3V TTL JTAG J3/J7 / RS232 J13   ||
    42 ||          ||         || ttyS1    || RS232 J13 / 3.3V TTL J7                    ||
    43 ||          ||         || ttyS2    || GPS                                        ||
    44 ||          || GW2388  || ttyS0    || console: 3.3V TTL JTAG J8 / RS232 J21      ||
    45 ||          ||         || ttyS1    || RS232 J21                                  ||
    46 ||          ||         || ttyS2    || GPS                                        ||
    47 ||          || GW2391  || ttyS0    || console: 3.3V TTL JTAG J1 / RS232 J15      ||
    48 ||          ||         || ttyS1    || RS232 J15                                  ||
    49 ||          ||         || ttyS2    || GPS                                        ||
    50 || Ventana  || GW51xx  || ttymxc0  || GPS ||
    51 ||          ||         || ttymxc1  || console: 3.3V TTL JTAG J10/J11 ||
    52 ||          ||         || ttymxc4  || TTL J11 ||
    53 ||          || GW52xx  || ttymxc0  || RS485/CAN/TTL J12 / RS232 J10 ||
    54 ||          ||         || ttymxc1  || console: 3.3V TTL JTAG J14 / RS232 J10 ||
    55 ||          ||         || ttymxc4  || GPS ||
    56 ||          || GW53xx  || ttymxc0  || RS485/CAN/TTL J11 / RS232 J12 ||
    57 ||          ||         || ttymxc1  || console: 3.3V TTL JTAG J14 / RS232 J12 ||
    58 ||          ||         || ttymxc4  || GPS ||
    59 ||          || GW54xx  || ttymxc0  || RS485 J13 ||
    60 ||          ||         || ttymxc1  || console: 3.3V TTL JTAG J17 / RS232 J15 ||
    61 ||          ||         || ttymxc4  || GPS ||
    62 ||          || GW551x  || ttymxc1  || console: exp 3.3V TTL J3             ||
    63 ||          ||         || ttymxc2  || exp 3.3V TTL J3           ||
    64 ||          || GW552x  || ttymxc1  || console: 3.3V TTL JTAG J7 ||
    65 ||          ||         || ttymxc2  || exp 3.3V TTL J5           ||
    66 ||          ||         || ttymxc4  || exp 3.3V TTL J5           ||
    67 ||          || GW553x  || ttymxc1  || console: 3.3V TTL JTAG J11 ||
    68 ||          ||         || ttymxc2  || exp 3.3V TTL JTAG J10 ||
    69 ||          ||         || ttymxc3  || GPS ||
    70 ||          ||         || ttymxc4  || exp 3.3V TTL JTAG J10 ||
    71 ||          || GW16111 || ttymxc1  || console: 3.3V TTL JTAG J8 / RS232 J16 / RS485 J20 ||
    72 ||          ||         || ttymxc2  || RS232 J16 ||
     20||= Family =||= Board =||= HW Dev =|| SW Dev =||= Function         =||
     21|| Avila    || GW2347  || UART0    || ttyS0    || console: 3.3V TTL JTAG J2 / RS232 J5   ||
     22||          ||         || UART1    || ttyS1    || UART: RS232 J3                         ||
     23||          || GW2348  || UART0    || ttyS0    || console: 3.3V TTL JTAG J7 / RS232 J13  ||
     24||          ||         || UART1    || ttyS1    || UART: RS232 J6                         ||
     25||          || GW2355  || UART0    || ttyS0    || console: 3.3V TTL JTAG J3 / RS232 J5   ||
     26||          ||         || UART1    || ttyS1    || GPS                                    ||
     27||          || GW2357  || UART0    || ttyS0    || console: 3.3V TTL JTAG J2 / RS232 J6   ||
     28||          ||         || UART1    || ttyS1    || UART: RS232 J36                        ||
     29|| Cambria  || GW2350  || UART0    || ttyS0    || console: 3.3V TTL JTAG J1/J10          ||
     30||          ||         || UART1    || ttyS1    || GPS                                    ||
     31||          ||         || UART2    || ttyS2    || RS485 J6                               ||
     32||          || GW2358  || UART0    || ttyS0    || console: 3.3V TTL JTAG J10 / RS232 J17 ||
     33||          ||         || UART1    || ttyS1    || GPS                                    ||
     34||          ||         || UART2    || ttyS2    || RS485 J3                               ||
     35|| Rincon   || GW2361  || UART0    || ttyS0    || console: 3.3V TTL JTAG J2              ||
     36||          ||         || UART1    || ttyS1    || RS232 J7                               ||
     37||          ||         || UART2    || ttyS2    || RS485 J6                               ||
     38|| Laguna   || GW2380/2/3 || UART0    || ttyS0    || console: 3.3V TTL JTAG J2 / 3.3V TTL J4 ||                           
     39||          ||         || UART1    || ttyS1    || GPS                                        ||
     40||          ||         || UART2    || ttyS2    || UART: 3.3V TTL J8                          ||
     41||          || GW2387  || UART0    || ttyS0    || console: 3.3V TTL JTAG J3/J7 / RS232 J13   ||
     42||          ||         || UART1    || ttyS1    || RS232 J13 / 3.3V TTL J7                    ||
     43||          ||         || UART2    || ttyS2    || GPS                                        ||
     44||          || GW2388  || UART0    || ttyS0    || console: 3.3V TTL JTAG J8 / RS232 J21      ||
     45||          ||         || UART1    || ttyS1    || RS232 J21                                  ||
     46||          ||         || UART2    || ttyS2    || GPS                                        ||
     47||          || GW2391  || UART0    || ttyS0    || console: 3.3V TTL JTAG J1 / RS232 J15      ||
     48||          ||         || UART1    || ttyS1    || RS232 J15                                  ||
     49||          ||         || UART2    || ttyS2    || GPS                                        ||
     50|| Ventana  || GW51xx  || UART1    || ttymxc0  || GPS ||
     51||          ||         || UART2    || ttymxc1  || console: 3.3V TTL JTAG J10/J11 ||
     52||          ||         || UART5    || ttymxc4  || TTL J11 ||
     53||          || GW52xx  || UART1    || ttymxc0  || RS485/CAN/TTL J12 / RS232 J10 ||
     54||          ||         || UART2    || ttymxc1  || console: 3.3V TTL JTAG J14 / RS232 J10 ||
     55||          ||         || UART5    || ttymxc4  || GPS ||
     56||          || GW53xx  || UART1    || ttymxc0  || RS485/CAN/TTL J11 / RS232 J12 ||
     57||          ||         || UART2    || ttymxc1  || console: 3.3V TTL JTAG J14 / RS232 J12 ||
     58||          ||         || UART5    || ttymxc4  || GPS ||
     59||          || GW54xx  || UART1    || ttymxc0  || RS485 J13 / RS232 J15 ||
     60||          ||         || UART2    || ttymxc1  || console: 3.3V TTL JTAG J17 / RS232 J15 ||
     61||          ||         || UART5    || ttymxc4  || GPS ||
     62||          || GW551x  || UART2    || ttymxc1  || console: exp 3.3V TTL J3             ||
     63||          ||         || UART3    || ttymxc2  || exp 3.3V TTL J3           ||
     64||          || GW552x  || UART2    || ttymxc1  || console: 3.3V TTL JTAG J7 ||
     65||          ||         || UART3    || ttymxc2  || exp 3.3V TTL J5           ||
     66||          ||         || UART5    || ttymxc4  || exp 3.3V TTL J5           ||
     67||          || GW553x  || UART2    || ttymxc1  || console: 3.3V TTL JTAG J11 ||
     68||          ||         || UART3    || ttymxc2  || exp 3.3V TTL JTAG J10 ||
     69||          ||         || UART4    || ttymxc3  || GPS ||
     70||          ||         || UART5    || ttymxc4  || exp 3.3V TTL JTAG J10 ||
     71||          || GW16111 || UART2    || ttymxc1  || console: 3.3V TTL JTAG J8 / RS232 J16 / RS485 J20 ||
     72||          ||         || UART3    || ttymxc2  || RS232 J16 ||
     73
    7374
    7475
     
    9394
    9495== Serial Port Types (DCE vs DTE) ==
    95 The Data Communication Equipment (DCE) (Typically used on a Gateworks board) pin assignments permit direct connection to a standard Data Terminal Equipment (DTE) PC running terminal emulation software.
     96The Data Communication Equipment (DCE) pin assignments permit direct connection to a standard Data Terminal Equipment (DTE) PC running terminal emulation software. The inputs and outputs are swapped between DCE and DTE. Please pay careful attention to the connector pinout of any UART from the board's hardware user manual, specifically the TX/RX/RTS/CTS pin's direction (input vs output) to ensure proper interconnect with off-board equipment.
    9697
    9798In certain scenarios, a null modem cable may be needed [http://en.wikipedia.org/wiki/Null_modem Null Modem Information]
     
    134135
    135136
     137[=#flowcontrol]
     138== Hardware Flow Control ==
     139A few Gateworks products that provide TTL level and/or RS232 serial can optionally provide hardware flow control via RTS# and CTS# pins. In this configuration. All Gateworks products present serial from the Data Terminal Equipment (DTE) perspective where TX and RTS are outputs, and RX and CTS are inputs with one exception:
     140 * Ventana UART's are in DCE mode by default however TX is still an output and RX is an input. Therefore Ventana UART's with flow control are pinned out as follows:
     141  - TX (output)
     142  - RX (input)
     143  - RTS (input)
     144  - CTS (output)
     145
     146
    136147[=#rs323]
    137148== RS232 ==
     
    168179        -g              Print in stty-readable form
    169180        [SETTING]       See manpage
    170 
     181}}}
     182
     183Set the baud rate, example shown below for 115200:
     184{{{
    171185root@OpenWrt:/# stty -F /dev/ttyS1 115200
     186}}}
     187
     188'''Also''' Verify Flow Control: (adjust below example to exact application)
     189{{{
     190stty -crtscts -F /dev/ttyS1
    172191}}}
    173192
     
    190209
    191210Troubleshooting:
    192  * make sure you are either not using hardware/software flow control, or in the case that you do have hardware flow control (CTS/RTS or DTR/DSR) they are properly connected.
     211 * make sure you are either not using hardware/software flow control, or in the case that you do have hardware flow control (CTS/RTS or DTR/DSR) they are properly connected.[#Flowcontrol See Link Here]
    193212 * use a null-modem if needed (DTE vs DCE)
    194213 * make sure both ends are RS232 compliant (as opposed to TTL level logic)
     
    225244 * implement a protocol such that multiple masters know when it is there turn to transmit
    226245
    227 RS485 Networks also require termination. Most Gateworks boards which have RS485 have on-board 4.75Kohm pulls and an optional on-board 121ohm load termination resistor.
    228 
    229246In a typical scenario you may have two devices on an RS485 half-duplex bus, NodeA and NodeB and a conversation would look like this:
    230247 1. NodeA enables its transmitter, sends out a request packet, then disables its transmitter and waits for a response
     
    233250
    234251The following table and sections below provides per-board details of RS485:
    235 ||= Family  =||= Board        =||= TXEN =||= Termination =||= Notes =||
    236 || Cambria   || GW235x         || DTR    || optional      || use tcdrain() and TIOCMBIC/TIOCMBIS ioctl ||
    237 ||                 ||
    238 || Rincon    || GW2361         || RTS    || off-board    || use tcdrain() and TIOCMBIC/TIOCMBIS ioctl ||
    239 ||                 ||
    240 || Laguna    || GW2380+GW16067 || gpio3  || optional      || use tcdrain() and userspace /sys/class/gpio/gpio3 ||
    241 ||                 ||
    242 || Ventana   || GW551x+GW16111 || gpio19  || optional     || see [#ventana-rs485 below] ||
    243 || Ventana   || GW52xx '''(optional)''' || gpio193 || optional    || TIOCSRS485 support ||
    244 || Ventana   || GW53xx '''(optional)'''         || gpio193 || optional    || TIOCSRS485 support ||
    245 || Ventana   || GW54xx '''(optional)'''         || gpio193 || optional    || TIOCSRS485 support ||
     252||= Family  =||= Board                 =||= TXEN  =||= Transceiver =||= Termination =||= Fail-Safe Bias =||= Notes =||
     253|| Cambria   || GW235x '''(optional)''' || DTR     || [http://dev.gateworks.com/datasheets/MAX3483-MAX3491.pdf MAX3485] || optional      || optional  || use tcdrain() and TIOCMBIC/TIOCMBIS ioctl ||
     254|| ||
     255|| Rincon    || GW2361 '''(optional)''' || RTS     || [http://dev.gateworks.com/datasheets/MAX3483-MAX3491.pdf MAX3485] || off-board     || off-board || use tcdrain() and TIOCMBIC/TIOCMBIS ioctl ||
     256|| ||
     257|| Laguna    || GW238x+GW16067          || gpio3   || [http://dev.gateworks.com/datasheets/MAX3483-MAX3491.pdf MAX3485] || optional      || 4.75k pull up/down || use tcdrain() and userspace /sys/class/gpio/gpio3 ||
     258|| ||
     259|| Ventana   || GW551x+GW16111          || gpio19  || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional      || 4.75k pull up/down || see [#ventana-rs485 ventana RS485 below] ||
     260|| Ventana   || GW52xx '''(optional)''' || gpio193 || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional      || optional || TIOCSRS485 support ||
     261|| Ventana   || GW53xx '''(optional)''' || gpio193 || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional      || optional || TIOCSRS485 support ||
     262|| Ventana   || GW54xx '''(optional)''' || gpio193 || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional      || optional || TIOCSRS485 support ||
    246263
    247264Note that if a driver supports TIOCSRS485 (in other words it handles the assertion/de-assertion of TXEN in the driver) this is preferred over using tcdrain() to determine when the FIFO is empty as tcdrain() can have considerable latency at small transmit sizes.
     
    251268 * https://en.wikipedia.org/wiki/RS-485
    252269
     270
     271[=#rs485-termination]
     272=== RS485 Termination ===
     273As a general rule, termination resistors should be placed at both far ends of the RS485 network. Without termination resistors reflections of fast driver edges can cause data corruption. Termination resistors also reduce electrical noise sensitivity due to lower impedance. The value of each termination resistor should be equal to the cable characteristic impedance (typically 120 ohms for twisted pairs).
     274
     275Some boards with RS485 capability may have transceivers with specific fail-safe features within the transceiver however optional on-board termination resistors typically exist as well and it is the responsibility of the system designer to determine where termination needs to go and what values should be used. In general, gateworks boards with RS485 transceivers have an optional resistor for termination that can be loaded with a customer specified value. Contact sales@gateworks.com via e-mail for more information.
     276
     277References:
     278 * [https://www.maximintegrated.com/en/app-notes/index.mvp/id/763 Maxium Tutorial 763 - Guidelines for Proper Wiring of an RS-485 Network]
     279 * https://en.wikipedia.org/wiki/RS-485
     280
     281
     282[=#rs485-failsafebias]
     283=== RS485 Failsafe Bias Resistors ===
     284When inputs are between -200mV and +200mV the receiver output is 'undefined'. There are four common fault conditions that result in this undefined receiver output that can cause erroneous data:
     285 * All transmitters in a system are not driving
     286 * The receiver is not connected to the cable
     287 * The cable has an open
     288 * The cable has a short
     289
     290Fail-safe biasing is used to keep the receiver's output in a defined state when one of these conditions occur. The biasing consists of a pull-up resistor on the noninverting line and a pull-down resistor on the inverting line. With proper biasing, the receiver will output a valid high when any one of the fault conditions occur. These fail-safe bias resistors should be placed at the receiver end of the transmission line.
     291
     292Some boards with RS485 capability may have on-board termination resistor options and it is the responsibility of the system designer to determine where termination needs to go and what values should be used. In general, gateworks boards with RS485 transceivers have an optional resistor for termination that can be loaded with a customer specified value. Contact sales@gateworks.com via e-mail for more information.
     293
     294on-board failsafe bias resistors 4.75Kohm pulls and an optional on-board 121ohm load termination resistor.
     295
     296References:
     297 * [https://www.maximintegrated.com/en/app-notes/index.mvp/id/763 Maxium Tutorial 763 - Guidelines for Proper Wiring of an RS-485 Network]
     298 * https://en.wikipedia.org/wiki/RS-485
    253299
    254300[=#cambria-rs485]
     
    258304 * MAX3485 transceiver
    259305 * TXEN connected to DTR
    260  * '''optional termination
     306 * '''optional on-board termination resistor'''
     307 * '''optional on-board fail-safe bias resistors'''
    261308
    262309By 'optional' this means the baseboard design supports this, but it is not loaded on standard product therefore would be a Gateworks Special. Contact sales@gateworks.com if interested to see if a configuration already exists.
     
    281328 * MAX3485 transceiver
    282329 * TXEN connected to gpio3
    283  * '''optional termination (R5)
    284  * 4.75k pull-up on D+, 4.75k pull-down on D- (bus defaults to logic 1 - never idle)
     330 * '''optional on-board termination resistor (R5)'''
     331 * '''on-board fail-safe bias resistors (R3/R7) by default are 4.75k pull-up on D+, 4.75k pull-down on D-''' (bus defaults to logic 1 - never idle)
    285332
    286333By 'optional' this means the baseboard design supports this, but it is not loaded on standard product therefore would be a Gateworks Special. Contact sales@gateworks.com if interested to see if a configuration already exists.
     
    295342 * MAX14840 transceiver
    296343 * TXEN connected to gpio193
    297  * '''optional termination
    298  * '''optional D+ pull-up and D- pull-down
     344 * '''optional on-board termination resistor'''
     345 * '''optional on-board fail-safe resistors (D+ pull-up and D- pull-down)'''
    299346
    300347By 'optional' this means the baseboard design supports this, but it is not loaded on standard product therefore would be a Gateworks Special. Contact sales@gateworks.com if interested to see if a configuration already exists.
     
    311358  - '''TXD drive mode''' - jumpers placed on '''J10:2-3''' and '''J10:7-8''' will cause the transceiver to be enabled only when TX is asserted. Because there are 4.75k pull's on D+/D- the bus is never 'idle'. This is useful for multi-master scenarios but could pose issues with fast/large busses if the 4.75pull's are not strong enough to switch the signals quick enough.
    312359  - '''DIO-drive mode''' - jumpers placed on '''J10:2-3''' and '''J10:7-8''' will cause the transceiver to be enabled only when IMX_DIO1 (gpio19) is asserted high. This is useful for fast/large busses where the TXD drive mode doesn't provide fast enough switching. If using this mode you either need to manage the assertion/de-assertion of gpio19 in usersapce or modify the GW551x device-tree to configure rs485-txen for TIOCSRS485 support by adding '''fsl,rs485-gpio-txen = <&gpio1 19 GPIO_ACTIVE_HIGH>;''' to the uart2 device-tree node in arch/arm/boot/dts/imx6qdl-gw551x.dtsi
    313  * 121ohm termination can be enabled by placing a jumper on '''J10:9-10'''
    314  * 4.75k pull-up on D+, 4.75k pull-down on D- (bus defaults to logic 1 - never idle)
     360 * 121ohm termination (R38) is loaded and can be enabled by placing a jumper on '''J10:9-10'''
     361 * 4.75k pull-up on D+, 4.75k pull-down on D- fail-safe bias resistors are loaded (R37/R40) (bus defaults to logic 1 - never idle)
    315362
    316363
     
    326373#include <termios.h>
    327374#include <time.h>
     375#include <unistd.h>
    328376#include <fcntl.h>
    329377#include <sys/ioctl.h>
    330378#include <linux/serial.h>
     379
     380#ifndef TIOCSRS485
     381#define TIOCSRS485        0x542F
     382#endif
    331383
    332384/** main function
     
    337389        int fd, sz, rz, bytes;
    338390        speed_t speed;
    339         const char *baud, *mode, *dev, *txen = NULL;
     391        const char *baud, *mode, *dev;
    340392        int timeout = 2; // time in seconds to wait for response
    341         char *msg;
     393        char *msg = NULL;
    342394        char buf[8192];
    343395        time_t start;
    344396
    345         if (argc < 5) {
     397        if (argc < 4) {
    346398                fprintf(stderr,
    347                         "usage: %s <device> <baud> <mode> <message> [<txen>]\n",
     399                        "usage: %s <device> <baud> <mode> [<message>]\n",
    348400                        argv[0]);
    349401                exit(1);
     
    353405        baud = argv[2];
    354406        mode = argv[3];
    355         msg = argv[4];
    356         if (argc > 5)
    357                 txen = argv[5];
     407        if (argc > 4)
     408                msg = argv[4];
    358409
    359410        // open device
     
    425476
    426477        // configure rs485
    427         if (txen) {
     478        {
    428479                struct serial_rs485 rs485;
    429480
    430                 printf("enabling rs485 for %s txen\n", txen);
     481                printf("enabling rs485 via TIOCSRS485\n");
    431482                memset(&rs485, 0, sizeof(rs485));
    432483                rs485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
     
    438489        tcflush(fd, TCIOFLUSH);
    439490
    440         sz = atoi(msg);
    441         if (!sz) {
    442                 sprintf(buf, "%s", msg);
    443                 sz = strlen(msg) + 1;
    444         }
    445         printf("transmitting %d bytes...\n", sz);
    446         if (write(fd, buf, sz) != sz)
    447                 perror("tx");
     491        // transmit data
     492        if (msg) {
     493                printf("sending...\n");
     494                if (strcmp("STDIN", msg) == 0) {
     495                        while (1) {
     496                                sz = read(0, buf, sizeof(buf));
     497                                printf("transmitting %d bytes...\n", sz);
     498                                if (write(fd, buf, sz) != sz) {
     499                                        perror("tx");
     500                                        break;
     501                                }
     502                        }
     503                } else {
     504                        sz = strlen(msg) + 1;
     505                        printf("transmitting %d bytes...\n", sz);
     506                        if (write(fd, msg, sz) != sz)
     507                                perror("tx");
     508                }
     509        }
    448510
    449511        // receive data
    450512        printf("reading...\n");
    451         bytes = 0;
    452         memset(buf, 0, sizeof(buf));
    453         start = time(NULL);
    454513        while (1) {
    455                 rz = read(fd, buf + bytes, sz - bytes);
     514                memset(buf, 0, sizeof(buf));
     515                rz = read(fd, buf, sizeof(buf) - 1);
    456516                if (rz < 0) {
    457517                        perror("read failed");
    458518                        break;
    459519                }
    460                 bytes += rz;
    461 
    462                 if (bytes >= sz)
    463                         break;
    464 
    465                 if ((int)(time(NULL) - start) >= timeout) {
    466                         printf("timeout\n");
    467                         break;
    468                 }
    469 
    470                 usleep(100000);
    471         }
    472         printf("received %d bytes in %ds\n", bytes, (int)(time(NULL) - start));
    473         if (!atoi(msg))
    474                 printf("%s\n", buf);
     520                if (rz == 0)
     521                        continue;
     522                printf("rx %d(%d): '%s'\n", rz, strlen(buf), buf);
     523        }
    475524
    476525        // restore terminal state