26 #include "libsigrok-internal.h"
27 #ifdef HAVE_LIBSERIALPORT
28 #include <libserialport.h>
35 #define LOG_PREFIX "serial-libsp"
44 #ifdef HAVE_LIBSERIALPORT
54 static int sr_ser_libsp_open(
struct sr_serial_dev_inst *serial,
int flags)
60 sp_get_port_by_name(serial->port, &serial->sp_data);
63 if (flags & SERIAL_RDWR)
64 sp_flags = (SP_MODE_READ | SP_MODE_WRITE);
65 else if (flags & SERIAL_RDONLY)
66 sp_flags = SP_MODE_READ;
68 ret = sp_open(serial->sp_data, sp_flags);
72 sr_err(
"Attempt to open serial port with invalid parameters.");
75 error = sp_last_error_message();
76 sr_err(
"Error opening port (%d): %s.",
77 sp_last_error_code(), error);
78 sp_free_error_message(error);
85 static int sr_ser_libsp_close(
struct sr_serial_dev_inst *serial)
90 if (!serial->sp_data) {
91 sr_dbg(
"Cannot close unopened serial port %s.", serial->port);
95 ret = sp_close(serial->sp_data);
99 sr_err(
"Attempt to close an invalid serial port.");
102 error = sp_last_error_message();
103 sr_err(
"Error closing port (%d): %s.",
104 sp_last_error_code(), error);
105 sp_free_error_message(error);
109 sp_free_port(serial->sp_data);
110 serial->sp_data = NULL;
115 static int sr_ser_libsp_flush(
struct sr_serial_dev_inst *serial)
120 if (!serial->sp_data) {
121 sr_dbg(
"Cannot flush unopened serial port %s.", serial->port);
125 ret = sp_flush(serial->sp_data, SP_BUF_BOTH);
129 sr_err(
"Attempt to flush an invalid serial port.");
132 error = sp_last_error_message();
133 sr_err(
"Error flushing port (%d): %s.",
134 sp_last_error_code(), error);
135 sp_free_error_message(error);
142 static int sr_ser_libsp_drain(
struct sr_serial_dev_inst *serial)
147 if (!serial->sp_data) {
148 sr_dbg(
"Cannot drain unopened serial port %s.", serial->port);
152 ret = sp_drain(serial->sp_data);
154 if (ret == SP_ERR_FAIL) {
155 error = sp_last_error_message();
156 sr_err(
"Error draining port (%d): %s.",
157 sp_last_error_code(), error);
158 sp_free_error_message(error);
165 static int sr_ser_libsp_write(
struct sr_serial_dev_inst *serial,
166 const void *buf,
size_t count,
167 int nonblocking,
unsigned int timeout_ms)
172 if (!serial->sp_data) {
173 sr_dbg(
"Cannot use unopened serial port %s.", serial->port);
178 ret = sp_nonblocking_write(serial->sp_data, buf, count);
180 ret = sp_blocking_write(serial->sp_data, buf, count, timeout_ms);
184 sr_err(
"Attempted serial port write with invalid arguments.");
187 error = sp_last_error_message();
188 sr_err(
"Write error (%d): %s.", sp_last_error_code(), error);
189 sp_free_error_message(error);
196 static int sr_ser_libsp_read(
struct sr_serial_dev_inst *serial,
197 void *buf,
size_t count,
198 int nonblocking,
unsigned int timeout_ms)
203 if (!serial->sp_data) {
204 sr_dbg(
"Cannot use unopened serial port %s.", serial->port);
209 ret = sp_nonblocking_read(serial->sp_data, buf, count);
211 ret = sp_blocking_read(serial->sp_data, buf, count, timeout_ms);
215 sr_err(
"Attempted serial port read with invalid arguments.");
218 error = sp_last_error_message();
219 sr_err(
"Read error (%d): %s.", sp_last_error_code(), error);
220 sp_free_error_message(error);
227 static int sr_ser_libsp_set_params(
struct sr_serial_dev_inst *serial,
228 int baudrate,
int bits,
int parity,
int stopbits,
229 int flowcontrol,
int rts,
int dtr)
233 struct sp_port_config *config;
236 if (!serial->sp_data) {
237 sr_dbg(
"Cannot configure unopened serial port %s.", serial->port);
241 sp_new_config(&config);
242 sp_set_config_baudrate(config, baudrate);
243 sp_set_config_bits(config, bits);
246 sp_set_config_parity(config, SP_PARITY_NONE);
249 sp_set_config_parity(config, SP_PARITY_EVEN);
252 sp_set_config_parity(config, SP_PARITY_ODD);
257 sp_set_config_stopbits(config, stopbits);
258 rts = flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts;
259 sp_set_config_rts(config, rts);
260 cts = flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
261 sp_set_config_cts(config, cts);
262 sp_set_config_dtr(config, dtr);
263 sp_set_config_dsr(config, SP_DSR_IGNORE);
264 xonoff = flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED;
265 sp_set_config_xon_xoff(config, xonoff);
267 ret = sp_set_config(serial->sp_data, config);
268 sp_free_config(config);
272 sr_err(
"Invalid arguments for setting serial port parameters.");
275 error = sp_last_error_message();
276 sr_err(
"Error setting serial port parameters (%d): %s.",
277 sp_last_error_code(), error);
278 sp_free_error_message(error);
287 typedef HANDLE event_handle;
289 typedef int event_handle;
293 static int sr_ser_libsp_source_add_int(
struct sr_serial_dev_inst *serial,
295 void **keyptr, gintptr *fdptr,
unsigned int *pollevtptr)
297 struct sp_event_set *event_set;
299 unsigned int poll_events;
302 if ((events & (G_IO_IN | G_IO_ERR)) && (events & G_IO_OUT)) {
303 sr_err(
"Cannot poll input/error and output simultaneously.");
306 if (!serial->sp_data) {
307 sr_err(
"Invalid serial port.");
311 if (sp_new_event_set(&event_set) != SP_OK)
315 if (events & G_IO_IN)
316 mask |= SP_EVENT_RX_READY;
317 if (events & G_IO_OUT)
318 mask |= SP_EVENT_TX_READY;
319 if (events & G_IO_ERR)
320 mask |= SP_EVENT_ERROR;
322 if (sp_add_port_events(event_set, serial->sp_data, mask) != SP_OK) {
323 sp_free_event_set(event_set);
326 if (event_set->count != 1) {
327 sr_err(
"Unexpected number (%u) of event handles to poll.",
329 sp_free_event_set(event_set);
333 poll_fd = (gintptr) ((event_handle *)event_set->handles)[0];
334 mask = event_set->masks[0];
336 sp_free_event_set(event_set);
339 if (mask & SP_EVENT_RX_READY)
340 poll_events |= G_IO_IN;
341 if (mask & SP_EVENT_TX_READY)
342 poll_events |= G_IO_OUT;
343 if (mask & SP_EVENT_ERROR)
344 poll_events |= G_IO_ERR;
352 *keyptr = serial->sp_data;
354 *pollevtptr = poll_events;
359 static int sr_ser_libsp_source_add(
struct sr_session *session,
360 struct sr_serial_dev_inst *serial,
int events,
int timeout,
366 unsigned int poll_events;
368 ret = sr_ser_libsp_source_add_int(serial, events,
369 &key, &poll_fd, &poll_events);
373 return sr_session_fd_source_add(session,
374 key, poll_fd, poll_events,
375 timeout, cb, cb_data);
378 static int sr_ser_libsp_source_remove(
struct sr_session *session,
379 struct sr_serial_dev_inst *serial)
383 key = serial->sp_data;
384 return sr_session_source_remove_internal(session, key);
387 static GSList *sr_ser_libsp_list(GSList *list, sr_ser_list_append_t append)
389 struct sp_port **ports;
394 if (sp_list_ports(&ports) != SP_OK)
397 for (i = 0; ports[i]; i++) {
398 name = sp_get_port_name(ports[i]);
399 desc = sp_get_port_description(ports[i]);
400 list = append(list, name, desc);
403 sp_free_port_list(ports);
408 static GSList *sr_ser_libsp_find_usb(GSList *list, sr_ser_find_append_t append,
409 uint16_t vendor_id, uint16_t product_id)
411 struct sp_port **ports;
414 if (sp_list_ports(&ports) != SP_OK)
417 for (i = 0; ports[i]; i++) {
418 if (sp_get_port_transport(ports[i]) != SP_TRANSPORT_USB)
420 if (sp_get_port_usb_vid_pid(ports[i], &vid, &pid) != SP_OK)
422 if (vendor_id && vid != vendor_id)
424 if (product_id && pid != product_id)
426 list = append(list, sp_get_port_name(ports[i]));
429 sp_free_port_list(ports);
434 static int sr_ser_libsp_get_frame_format(
struct sr_serial_dev_inst *serial,
435 int *baud,
int *bits)
437 struct sp_port_config *config;
439 enum sp_parity parity;
441 if (sp_new_config(&config) < 0)
446 if (sp_get_config(serial->sp_data, config) < 0) {
451 if (sp_get_config_baudrate(config, &tmp) < 0) {
458 if (sp_get_config_bits(config, &tmp) < 0) {
463 if (sp_get_config_parity(config, &parity) < 0) {
467 *bits += (parity != SP_PARITY_NONE) ? 1 : 0;
468 if (sp_get_config_stopbits(config, &tmp) < 0) {
474 sp_free_config(config);
479 static size_t sr_ser_libsp_get_rx_avail(
struct sr_serial_dev_inst *serial)
486 rc = sp_input_waiting(serial->sp_data);
493 static struct ser_lib_functions serlib_sp = {
494 .open = sr_ser_libsp_open,
495 .close = sr_ser_libsp_close,
496 .flush = sr_ser_libsp_flush,
497 .drain = sr_ser_libsp_drain,
498 .write = sr_ser_libsp_write,
499 .read = sr_ser_libsp_read,
500 .set_params = sr_ser_libsp_set_params,
501 .setup_source_add = sr_ser_libsp_source_add,
502 .setup_source_remove = sr_ser_libsp_source_remove,
503 .list = sr_ser_libsp_list,
504 .find_usb = sr_ser_libsp_find_usb,
505 .get_frame_format = sr_ser_libsp_get_frame_format,
506 .get_rx_avail = sr_ser_libsp_get_rx_avail,
512 SR_PRIV struct ser_lib_functions *ser_lib_funcs_libsp = NULL;
Generic/unspecified error.
The public libsigrok header file to be used by frontends.
int(* sr_receive_data_callback)(int fd, int revents, void *cb_data)
Type definition for callback function for data reception.
Malloc/calloc/realloc error.
SR_PRIV struct ser_lib_functions * ser_lib_funcs_libsp
Opaque structure representing a libsigrok session.