serial: add routine to manipulate handshake state (RTS, DTR)

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).
This commit is contained in:
Gerhard Sittig 2020-09-20 09:14:01 +02:00
parent b1184024fe
commit 3ad30b4e19
6 changed files with 73 additions and 0 deletions

View 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, SR_PRIV int std_dummy_set_params(struct sr_serial_dev_inst *serial,
int baudrate, int bits, int parity, int stopbits, int baudrate, int bits, int parity, int stopbits,
int flowcontrol, int rts, int dtr); 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 ------------------------------------------------------------*/ /*--- 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); serial_rx_chunk_callback cb, void *cb_data);
SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate, 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); 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, SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial,
const char *paramstr); const char *paramstr);
SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf, 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 (*set_params)(struct sr_serial_dev_inst *serial,
int baudrate, int bits, int parity, int stopbits, int baudrate, int bits, int parity, int stopbits,
int flowcontrol, int rts, int dtr); 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, int (*setup_source_add)(struct sr_session *session,
struct sr_serial_dev_inst *serial, struct sr_serial_dev_inst *serial,
int events, int timeout, int events, int timeout,

View File

@ -561,6 +561,37 @@ SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial,
return ret; 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. * Set serial parameters for the specified serial port from parameter string.
* *

View File

@ -816,6 +816,7 @@ static struct ser_lib_functions serlib_bt = {
* here, since the caller will cache/register them already. * here, since the caller will cache/register them already.
*/ */
.set_params = std_dummy_set_params, .set_params = std_dummy_set_params,
.set_handshake = std_dummy_set_handshake,
.setup_source_add = ser_bt_setup_source_add, .setup_source_add = ser_bt_setup_source_add,
.setup_source_remove = ser_bt_setup_source_remove, .setup_source_remove = ser_bt_setup_source_remove,
.list = ser_bt_list, .list = ser_bt_list,

View File

@ -1340,6 +1340,7 @@ static struct ser_lib_functions serlib_hid = {
.write = ser_hid_write, .write = ser_hid_write,
.read = ser_hid_read, .read = ser_hid_read,
.set_params = ser_hid_set_params, .set_params = ser_hid_set_params,
.set_handshake = std_dummy_set_handshake,
.setup_source_add = ser_hid_setup_source_add, .setup_source_add = ser_hid_setup_source_add,
.setup_source_remove = ser_hid_setup_source_remove, .setup_source_remove = ser_hid_setup_source_remove,
.list = ser_hid_list, .list = ser_hid_list,

View File

@ -280,6 +280,30 @@ static int sr_ser_libsp_set_params(struct sr_serial_dev_inst *serial,
return SR_OK; 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 #ifdef G_OS_WIN32
typedef HANDLE event_handle; typedef HANDLE event_handle;
#else #else
@ -494,6 +518,7 @@ static struct ser_lib_functions serlib_sp = {
.write = sr_ser_libsp_write, .write = sr_ser_libsp_write,
.read = sr_ser_libsp_read, .read = sr_ser_libsp_read,
.set_params = sr_ser_libsp_set_params, .set_params = sr_ser_libsp_set_params,
.set_handshake = sr_ser_libsp_set_handshake,
.setup_source_add = sr_ser_libsp_source_add, .setup_source_add = sr_ser_libsp_source_add,
.setup_source_remove = sr_ser_libsp_source_remove, .setup_source_remove = sr_ser_libsp_source_remove,
.list = sr_ser_libsp_list, .list = sr_ser_libsp_list,

View File

@ -928,3 +928,12 @@ SR_PRIV int std_dummy_set_params(struct sr_serial_dev_inst *serial,
return SR_OK; 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;
}