/** @private */ SR_PRIV int serial_source_add(struct sr_session *session, struct sr_serial_dev_inst *serial, int events, int timeout, sr_receive_data_callback cb, void *cb_data) { struct sp_event_set *event_set; gintptr poll_fd; unsigned int poll_events; enum sp_event mask = 0; if ((events & (G_IO_IN|G_IO_ERR)) && (events & G_IO_OUT)) { sr_err("Cannot poll input/error and output simultaneously."); return SR_ERR_ARG; } if (sp_new_event_set(&event_set) != SP_OK) return SR_ERR; if (events & G_IO_IN) mask |= SP_EVENT_RX_READY; if (events & G_IO_OUT) mask |= SP_EVENT_TX_READY; if (events & G_IO_ERR) mask |= SP_EVENT_ERROR; if (sp_add_port_events(event_set, serial->data, mask) != SP_OK) { sp_free_event_set(event_set); return SR_ERR; } if (event_set->count != 1) { sr_err("Unexpected number (%u) of event handles to poll.", event_set->count); sp_free_event_set(event_set); return SR_ERR; } poll_fd = (gintptr) ((event_handle *)event_set->handles)[0]; mask = event_set->masks[0]; sp_free_event_set(event_set); poll_events = 0; if (mask & SP_EVENT_RX_READY) poll_events |= G_IO_IN; if (mask & SP_EVENT_TX_READY) poll_events |= G_IO_OUT; if (mask & SP_EVENT_ERROR) poll_events |= G_IO_ERR; /* * Using serial->data as the key for the event source is not quite * proper, as it makes it impossible to create another event source * for the same serial port. However, these fixed keys will soon be * removed from the API anyway, so this is OK for now. */ return sr_session_fd_source_add(session, serial->data, poll_fd, poll_events, timeout, cb, cb_data); }
SR_PRIV int serial_source_remove(struct sr_serial_dev_inst *serial) { unsigned int i; for (i = 0; i < serial->event_set->count; i++) if (sr_session_source_remove_pollfd(&serial->pollfds[i]) != SR_OK) return SR_ERR; g_free(serial->pollfds); sp_free_event_set(serial->event_set); serial->pollfds = NULL; serial->event_set = NULL; return SR_OK; }
SR_PRIV int serial_source_add(struct sr_session *session, struct sr_serial_dev_inst *serial, int events, int timeout, sr_receive_data_callback cb, void *cb_data) { enum sp_event mask = 0; unsigned int i; if (sp_new_event_set(&serial->event_set) != SP_OK) return SR_ERR; if (events & G_IO_IN) mask |= SP_EVENT_RX_READY; if (events & G_IO_OUT) mask |= SP_EVENT_TX_READY; if (events & G_IO_ERR) mask |= SP_EVENT_ERROR; if (sp_add_port_events(serial->event_set, serial->data, mask) != SP_OK) { sp_free_event_set(serial->event_set); return SR_ERR; } serial->pollfds = (GPollFD *) g_malloc0(sizeof(GPollFD) * serial->event_set->count); for (i = 0; i < serial->event_set->count; i++) { serial->pollfds[i].fd = ((event_handle *) serial->event_set->handles)[i]; mask = serial->event_set->masks[i]; if (mask & SP_EVENT_RX_READY) serial->pollfds[i].events |= G_IO_IN; if (mask & SP_EVENT_TX_READY) serial->pollfds[i].events |= G_IO_OUT; if (mask & SP_EVENT_ERROR) serial->pollfds[i].events |= G_IO_ERR; if (sr_session_source_add_pollfd(session, &serial->pollfds[i], timeout, cb, cb_data) != SR_OK) return SR_ERR; } return SR_OK; }
int navilink_open_sp_port(struct sp_port* port, NavilinkDevice* device) { enum sp_return result = sp_open(port, SP_MODE_READ_WRITE); if (result != SP_OK) { CATCH_LIBSERIAL_ERROR(device); goto error_cleanup_port; } struct sp_port_config* config = NULL; result = sp_new_config(&config); if (result != SP_OK) { CATCH_LIBSERIAL_ERROR(device); goto error_clean_config; } // Set the config sp_set_baudrate(port, 115200); sp_set_bits(port, 8); sp_set_parity(port, SP_PARITY_NONE); sp_set_stopbits(port, 1); sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE); sp_set_config(port, config); // Allocate events buffer struct sp_event_set* event_set = NULL; sp_new_event_set(&event_set); sp_add_port_events(event_set, port, SP_EVENT_TX_READY); //Wait for the port to be ready result = sp_wait(event_set, 5000); if (result != SP_OK) { CATCH_LIBSERIAL_ERROR(device); goto error_clean_event_set; } device->serial_port = port; device->event_set = event_set; //Check that this is a Navilink device int res = navilink_check_protocol(device); if (res < 0) { goto error_clean_event_set; } // Retrieve the informations about the device res = navilink_query_information(device, &device->informations); if (res < 0) { goto error_clean_event_set; } // Retrieve the firmware version res = navilink_query_firmware_version(device, &device->firmware_version); if (res < 0) { goto error_clean_event_set; } return 0; error_clean_event_set: sp_free_event_set(event_set); error_clean_config: sp_free_config(config); error_cleanup_port: sp_free_port(port); return -1; }