/** * Close the ChronoVu LA8 USB port and reset the LA8 sequencer logic. * * @param devc The struct containing private per-device-instance data. * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments. */ SR_PRIV int la8_close_usb_reset_sequencer(struct dev_context *devc) { /* Magic sequence of bytes for resetting the LA8 sequencer logic. */ uint8_t buf[8] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; int ret; if (!devc) { sr_err("%s: devc was NULL.", __func__); return SR_ERR_ARG; } if (!devc->ftdic) { sr_err("%s: devc->ftdic was NULL.", __func__); return SR_ERR_ARG; } if (devc->ftdic->usb_dev) { /* Reset the LA8 sequencer logic, then wait 100ms. */ sr_dbg("Resetting sequencer logic."); (void) la8_write(devc, buf, 8); /* Ignore errors. */ g_usleep(100 * 1000); /* Purge FTDI buffers, then reset and close the FTDI device. */ sr_dbg("Purging buffers, resetting+closing FTDI device."); /* Log errors, but ignore them (i.e., don't abort). */ if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) sr_err("%s: ftdi_usb_purge_buffers: (%d) %s.", __func__, ret, ftdi_get_error_string(devc->ftdic)); if ((ret = ftdi_usb_reset(devc->ftdic)) < 0) sr_err("%s: ftdi_usb_reset: (%d) %s.", __func__, ret, ftdi_get_error_string(devc->ftdic)); if ((ret = ftdi_usb_close(devc->ftdic)) < 0) sr_err("%s: ftdi_usb_close: (%d) %s.", __func__, ret, ftdi_get_error_string(devc->ftdic)); } /* Close USB device, deinitialize and free the FTDI context. */ ftdi_free(devc->ftdic); /* Returns void. */ devc->ftdic = NULL; return SR_OK; }
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) { struct dev_context *devc; uint8_t buf[4]; int bytes_written; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; if (!(devc = sdi->priv)) { sr_err("%s: sdi->priv was NULL.", __func__); return SR_ERR_BUG; } if (!devc->ftdic) { sr_err("%s: devc->ftdic was NULL.", __func__); return SR_ERR_BUG; } devc->divcount = samplerate_to_divcount(devc->cur_samplerate); if (devc->divcount == 0xff) { sr_err("%s: Invalid divcount/samplerate.", __func__); return SR_ERR; } if (configure_probes(sdi) != SR_OK) { sr_err("Failed to configure probes."); return SR_ERR; } /* Fill acquisition parameters into buf[]. */ buf[0] = devc->divcount; buf[1] = 0xff; /* This byte must always be 0xff. */ buf[2] = devc->trigger_pattern; buf[3] = devc->trigger_mask; /* Start acquisition. */ bytes_written = la8_write(devc, buf, 4); if (bytes_written < 0) { sr_err("Acquisition failed to start: %d.", bytes_written); return SR_ERR; } else if (bytes_written != 4) { sr_err("Acquisition failed to start: %d.", bytes_written); return SR_ERR; } sr_dbg("Hardware acquisition started successfully."); devc->cb_data = cb_data; /* Send header packet to the session bus. */ std_session_send_df_header(cb_data, LOG_PREFIX); /* Time when we should be done (for detecting trigger timeouts). */ devc->done = (devc->divcount + 1) * 0.08388608 + time(NULL) + devc->trigger_timeout; devc->block_counter = 0; devc->trigger_found = 0; /* Hook up a dummy handler to receive data from the LA8. */ sr_source_add(-1, G_IO_IN, 0, receive_data, (void *)sdi); return SR_OK; }