X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fcommon%2Fserial.c;h=e181f2338562386327bc1e18e71c8a44b2cf651b;hb=987a053084b521f3f2af7beb2da68a24a24da363;hp=7cc81c64213e95b67f5949dc6998b5abdf1a4721;hpb=3182932d360303df459abce20dbe093ce9c453e8;p=libsigrok.git diff --git a/hardware/common/serial.c b/hardware/common/serial.c index 7cc81c64..e181f233 100644 --- a/hardware/common/serial.c +++ b/hardware/common/serial.c @@ -66,8 +66,8 @@ SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags) sp_flags = (SP_MODE_READ | SP_MODE_WRITE); else if (flags & SERIAL_RDONLY) sp_flags = SP_MODE_READ; - if (flags & SERIAL_NONBLOCK) - sp_flags |= SP_MODE_NONBLOCK; + + serial->nonblocking = (flags & SERIAL_NONBLOCK) ? 1 : 0; ret = sp_open(serial->data, sp_flags); @@ -203,7 +203,10 @@ SR_PRIV int serial_write(struct sr_serial_dev_inst *serial, return SR_ERR; } - ret = sp_write(serial->data, buf, count); + if (serial->nonblocking) + ret = sp_nonblocking_write(serial->data, buf, count); + else + ret = sp_blocking_write(serial->data, buf, count, 0); switch (ret) { case SP_ERR_ARG: @@ -234,7 +237,7 @@ SR_PRIV int serial_read(struct sr_serial_dev_inst *serial, void *buf, size_t count) { ssize_t ret; - //char *error; + char *error; if (!serial) { sr_dbg("Invalid serial port."); @@ -247,21 +250,23 @@ SR_PRIV int serial_read(struct sr_serial_dev_inst *serial, void *buf, return SR_ERR; } - ret = sp_read(serial->data, buf, count); + if (serial->nonblocking) + ret = sp_nonblocking_read(serial->data, buf, count); + else + ret = sp_blocking_read(serial->data, buf, count, 0); switch (ret) { case SP_ERR_ARG: sr_err("Attempted serial port read with invalid arguments."); return SR_ERR_ARG; - // Temporarily disabled, will come back later. - // case SP_ERR_FAIL: - // error = sp_last_error_message(); - // sr_err("Read error: %s.", error); - // sp_free_error_message(error); - // return SR_ERR; + case SP_ERR_FAIL: + error = sp_last_error_message(); + sr_err("Read error: %s.", error); + sp_free_error_message(error); + return SR_ERR; } - if (ret >= 0) + if (ret > 0) sr_spew("Read %d/%d bytes (fd %d).", ret, count, serial->fd); return ret; @@ -286,7 +291,7 @@ SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate, { int ret; char *error; - struct sp_port_config config; + struct sp_port_config *config; if (!serial) { sr_dbg("Invalid serial port."); @@ -302,29 +307,31 @@ SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate, sr_spew("Setting serial parameters on port %s (fd %d).", serial->port, serial->fd); - config.baudrate = baudrate; - config.bits = bits; + sp_new_config(&config); + sp_set_config_baudrate(config, baudrate); + sp_set_config_bits(config, bits); switch (parity) { case 0: - config.parity = SP_PARITY_NONE; + sp_set_config_parity(config, SP_PARITY_NONE); break; case 1: - config.parity = SP_PARITY_EVEN; + sp_set_config_parity(config, SP_PARITY_EVEN); break; case 2: - config.parity = SP_PARITY_ODD; + sp_set_config_parity(config, SP_PARITY_ODD); break; default: return SR_ERR_ARG; } - config.stopbits = stopbits; - config.rts = flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts; - config.cts = flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE; - config.dtr = dtr; - config.dsr = SP_DSR_IGNORE; - config.xon_xoff = flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED; + sp_set_config_stopbits(config, stopbits); + sp_set_config_rts(config, flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts); + sp_set_config_cts(config, flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE); + sp_set_config_dtr(config, dtr); + sp_set_config_dsr(config, SP_DSR_IGNORE); + sp_set_config_xon_xoff(config, flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED); - ret = sp_set_config(serial->data, &config); + ret = sp_set_config(serial->data, config); + sp_free_config(config); switch (ret) { case SP_ERR_ARG: @@ -589,3 +596,45 @@ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, return SR_ERR; } + +/** + * Extract the serial device and options from the options linked list. + * + * @param options List of options passed from the command line. + * @param serial_device Pointer where to store the exctracted serial device. + * @param serial_options Pointer where to store the optional extracted serial + * options. + * + * @return SR_OK if a serial_device is found, SR_ERR if no device is found. The + * returned string should not be freed by the caller. + */ +SR_PRIV int sr_serial_extract_options(GSList *options, const char **serial_device, + const char **serial_options) +{ + GSList *l; + struct sr_config *src; + + *serial_device = NULL; + + for (l = options; l; l = l->next) { + src = l->data; + switch (src->key) { + case SR_CONF_CONN: + *serial_device = g_variant_get_string(src->data, NULL); + sr_dbg("Parsed serial device: %s", *serial_device); + break; + + case SR_CONF_SERIALCOMM: + *serial_options = g_variant_get_string(src->data, NULL); + sr_dbg("Parsed serial options: %s", *serial_options); + break; + } + } + + if (!*serial_device) { + sr_dbg("No serial device specified"); + return SR_ERR; + } + + return SR_OK; +}