serial: add routine to manipulate handshake state (RTS, DTR)
authorGerhard Sittig <gerhard.sittig@gmx.net>
Sun, 20 Sep 2020 07:14:01 +0000 (09:14 +0200)
committerGerhard Sittig <gerhard.sittig@gmx.net>
Sun, 20 Sep 2020 08:44:20 +0000 (10:44 +0200)
Introduce a routine in libsigrok's internal serial layer which lets
applications manipulate the state of handshake signals (RTS and DTR)
after the serial port got opened and configured. This allows for timed
pulses which cannot get expressed with static "rts=1" etc phrases in
parameter strings, and allows handshake signal control while leaving
bitrate and frame format untouched. Applications specify which signals
to modify while other signals remain as they are (ternary input).

Do implement the signal manipulation in the libserialport transport,
do nothing and silently pass in the HID and BT transports. These can
get extended later as the need arises, depending on the HID chips' and
RFCOMM peers' capability to control these signals. This extension is
transparent to application code (acquisition device drivers).

src/libsigrok-internal.h
src/serial.c
src/serial_bt.c
src/serial_hid.c
src/serial_libsp.c
src/std.c

index 75c91e92b7e6da482ac885540daf53e978605df7..b614c93d0bdc039407a345cdc0db0d844103abcf 100644 (file)
@@ -1759,6 +1759,8 @@ SR_PRIV int std_cg_idx(const struct sr_channel_group *cg, struct sr_channel_grou
 SR_PRIV int std_dummy_set_params(struct sr_serial_dev_inst *serial,
        int baudrate, int bits, int parity, int stopbits,
        int flowcontrol, int rts, int dtr);
+SR_PRIV int std_dummy_set_handshake(struct sr_serial_dev_inst *serial,
+       int rts, int dtr);
 
 /*--- resource.c ------------------------------------------------------------*/
 
@@ -1843,6 +1845,8 @@ SR_PRIV int serial_set_read_chunk_cb(struct sr_serial_dev_inst *serial,
                serial_rx_chunk_callback cb, void *cb_data);
 SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
                int bits, int parity, int stopbits, int flowcontrol, int rts, int dtr);
+SR_PRIV int serial_set_handshake(struct sr_serial_dev_inst *serial,
+               int rts, int dtr);
 SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial,
                const char *paramstr);
 SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf,
@@ -1883,6 +1887,8 @@ struct ser_lib_functions {
        int (*set_params)(struct sr_serial_dev_inst *serial,
                        int baudrate, int bits, int parity, int stopbits,
                        int flowcontrol, int rts, int dtr);
+       int (*set_handshake)(struct sr_serial_dev_inst *serial,
+                       int rts, int dtr);
        int (*setup_source_add)(struct sr_session *session,
                        struct sr_serial_dev_inst *serial,
                        int events, int timeout,
index 8ffba7956b09cd4e248627528d72bd56c674fd0a..34d7cbea3f9b40b965d588b8c4a6003a8d54cc24 100644 (file)
@@ -561,6 +561,37 @@ SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial,
        return ret;
 }
 
+/**
+ * Manipulate handshake state for the specified serial port.
+ *
+ * @param serial Previously initialized serial port structure.
+ * @param[in] rts Status of RTS line (0 or 1; or -1 to ignore).
+ * @param[in] dtr Status of DTR line (0 or 1; or -1 to ignore).
+ *
+ * @retval SR_OK Success.
+ * @retval SR_ERR Failure.
+ *
+ * @private
+ */
+SR_PRIV int serial_set_handshake(struct sr_serial_dev_inst *serial,
+       int rts, int dtr)
+{
+       int ret;
+
+       if (!serial) {
+               sr_dbg("Invalid serial port.");
+               return SR_ERR;
+       }
+
+       sr_spew("Modifying serial parameters on port %s.", serial->port);
+
+       if (!serial->lib_funcs || !serial->lib_funcs->set_handshake)
+               return SR_ERR_NA;
+       ret = serial->lib_funcs->set_handshake(serial, rts, dtr);
+
+       return ret;
+}
+
 /**
  * Set serial parameters for the specified serial port from parameter string.
  *
index 42d6289a51126b9f10db2d55e978add48404eaa4..9d7cfb2b2699fbedbddd8348ff6fa0a1a13f8eba 100644 (file)
@@ -816,6 +816,7 @@ static struct ser_lib_functions serlib_bt = {
         * here, since the caller will cache/register them already.
         */
        .set_params = std_dummy_set_params,
+       .set_handshake = std_dummy_set_handshake,
        .setup_source_add = ser_bt_setup_source_add,
        .setup_source_remove = ser_bt_setup_source_remove,
        .list = ser_bt_list,
index 0db5cab56e69970f9b3976e92da4fa3d9ad1ca66..eccdf0f22ef5a0c1c5274d0931db98685aec3294 100644 (file)
@@ -1340,6 +1340,7 @@ static struct ser_lib_functions serlib_hid = {
        .write = ser_hid_write,
        .read = ser_hid_read,
        .set_params = ser_hid_set_params,
+       .set_handshake = std_dummy_set_handshake,
        .setup_source_add = ser_hid_setup_source_add,
        .setup_source_remove = ser_hid_setup_source_remove,
        .list = ser_hid_list,
index f5a2b74b59f477ce3a4499f8eea024795eb5d854..bfdc3202261c8adfb198fff28a8c80a29ccf07fe 100644 (file)
@@ -280,6 +280,30 @@ static int sr_ser_libsp_set_params(struct sr_serial_dev_inst *serial,
        return SR_OK;
 }
 
+static int sr_ser_libsp_set_handshake(struct sr_serial_dev_inst *serial,
+       int rts, int dtr)
+{
+       int ret;
+
+       if (!serial->sp_data) {
+               sr_dbg("Cannot configure unopened serial port %s.", serial->port);
+               return SR_ERR;
+       }
+
+       if (rts >= 0) {
+               ret = sp_set_rts(serial->sp_data, rts ? SP_RTS_ON : SP_RTS_OFF);
+               if (ret != SP_OK)
+                       return SR_ERR;
+       }
+       if (dtr >= 0) {
+               ret = sp_set_dtr(serial->sp_data, dtr ? SP_DTR_ON : SP_DTR_OFF);
+               if (ret != SP_OK)
+                       return SR_ERR;
+       }
+
+       return SR_OK;
+}
+
 #ifdef G_OS_WIN32
 typedef HANDLE event_handle;
 #else
@@ -494,6 +518,7 @@ static struct ser_lib_functions serlib_sp = {
        .write = sr_ser_libsp_write,
        .read = sr_ser_libsp_read,
        .set_params = sr_ser_libsp_set_params,
+       .set_handshake = sr_ser_libsp_set_handshake,
        .setup_source_add = sr_ser_libsp_source_add,
        .setup_source_remove = sr_ser_libsp_source_remove,
        .list = sr_ser_libsp_list,
index d1e2eedf784289eeaf72323e608a84ba99956ab2..81f269fa92dc26ee73b9ca90081dc27039d010d9 100644 (file)
--- a/src/std.c
+++ b/src/std.c
@@ -928,3 +928,12 @@ SR_PRIV int std_dummy_set_params(struct sr_serial_dev_inst *serial,
        return SR_OK;
 }
 
+SR_PRIV int std_dummy_set_handshake(struct sr_serial_dev_inst *serial,
+       int rts, int dtr)
+{
+       (void)serial;
+       (void)rts;
+       (void)dtr;
+
+       return SR_OK;
+}