summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
inline | side by side (from parent 1:
1ed9311)
The dev_open() routine postprocesses USB renumeration after a previous
FX2 MCU firmware upload. Concentrate all tunables in the driver's header
file, and discuss their meaning in relation to each other. Rephrase the
logic to start checking earlier, and keep checking for longer, adjust
diagnostics in the process. Void the "firmware uploaded" flag when the
upload took effect. Consistently use u64 for timestamps. Rename a few
variables to improve readabilty.
unsigned int i, j;
const char *conn;
char connection_id[64];
unsigned int i, j;
const char *conn;
char connection_id[64];
unsigned int dev_addr;
drvc = di->context;
unsigned int dev_addr;
drvc = di->context;
sdi->status = SR_ST_INITIALIZING;
sdi->connection_id = g_strdup(connection_id);
sdi->status = SR_ST_INITIALIZING;
sdi->connection_id = g_strdup(connection_id);
dev_addr = libusb_get_device_address(devlist[i]);
if (des.iProduct != 2) {
sr_info("Device at '%s' has no firmware loaded.", connection_id);
dev_addr = libusb_get_device_address(devlist[i]);
if (des.iProduct != 2) {
sr_info("Device at '%s' has no firmware loaded.", connection_id);
- fw_updated = g_get_monotonic_time();
+ fw_uploaded = g_get_monotonic_time();
/* Will re-enumerate. Mark as "unknown address yet". */
dev_addr = 0xff;
}
/* Will re-enumerate. Mark as "unknown address yet". */
dev_addr = 0xff;
}
devc = g_malloc0(sizeof(struct dev_context));
sdi->priv = devc;
devc = g_malloc0(sizeof(struct dev_context));
sdi->priv = devc;
- devc->fw_updated = fw_updated;
+ devc->fw_uploaded = fw_uploaded;
devc->threshold_voltage_idx = 0;
devc->threshold_voltage = logic_threshold_value[devc->threshold_voltage_idx];
devc->threshold_voltage_idx = 0;
devc->threshold_voltage = logic_threshold_value[devc->threshold_voltage_idx];
static int dev_open(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
static int dev_open(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
- int64_t timediff_us, timediff_ms;
- uint64_t reset_done;
- uint64_t now;
+ uint64_t reset_done, now, elapsed_ms;
int ret;
devc = sdi->priv;
/*
int ret;
devc = sdi->priv;
/*
- * When the sigrok driver recently uploaded firmware, wait for
- * the FX2 to re-enumerate. Deal with the condition that the
- * MCU can take some 2000ms to be gone from the bus before it
- * re-appears executing the recently uploaded firmware.
+ * When the sigrok driver recently has uploaded MCU firmware,
+ * then wait for the FX2 to re-enumerate. Allow the USB device
+ * to vanish before it reappears. Timeouts are rough estimates
+ * after all, the imprecise time of the last check (potentially
+ * executes after the total check period) simplifies code paths
+ * with optional diagnostics. And increases the probability of
+ * successfully detecting "late/slow" devices.
- ret = SR_ERR;
- if (devc->fw_updated > 0) {
+ if (devc->fw_uploaded) {
sr_info("Waiting for device to reset after firmware upload.");
sr_info("Waiting for device to reset after firmware upload.");
- reset_done = devc->fw_updated;
- reset_done += 1800 * 1000; /* 1.8 seconds */
now = g_get_monotonic_time();
now = g_get_monotonic_time();
+ reset_done = devc->fw_uploaded + RENUM_GONE_DELAY_MS * 1000;
+ if (now < reset_done)
g_usleep(reset_done - now);
g_usleep(reset_done - now);
- timediff_ms = 0;
- while (timediff_ms < MAX_RENUM_DELAY_MS) {
- g_usleep(200 * 1000);
-
- timediff_us = g_get_monotonic_time() - devc->fw_updated;
- timediff_ms = timediff_us / 1000;
-
- if ((ret = la2016_dev_open(sdi)) == SR_OK)
+ do {
+ now = g_get_monotonic_time();
+ elapsed_ms = (now - devc->fw_uploaded) / 1000;
+ sr_spew("Waited %" PRIu64 "ms.", elapsed_ms);
+ ret = la2016_dev_open(sdi);
+ if (ret == SR_OK) {
+ devc->fw_uploaded = 0;
- sr_spew("Waited %" PRIi64 "ms.", timediff_ms);
- }
+ }
+ g_usleep(RENUM_POLL_INTERVAL_MS * 1000);
+ } while (elapsed_ms < RENUM_CHECK_PERIOD_MS);
if (ret != SR_OK) {
sr_err("Device failed to re-enumerate.");
return SR_ERR;
}
if (ret != SR_OK) {
sr_err("Device failed to re-enumerate.");
return SR_ERR;
}
- sr_info("Device came back after %" PRIi64 "ms.", timediff_ms);
+ sr_info("Device came back after %" PRIi64 "ms.", elapsed_ms);
} else {
ret = la2016_dev_open(sdi);
}
} else {
ret = la2016_dev_open(sdi);
}
#define LA2016_EP6_PKTSZ 512 /* Max packet size of USB endpoint 6. */
#define LA2016_USB_BUFSZ (256 * 2 * LA2016_EP6_PKTSZ) /* 256KiB buffer. */
#define LA2016_EP6_PKTSZ 512 /* Max packet size of USB endpoint 6. */
#define LA2016_USB_BUFSZ (256 * 2 * LA2016_EP6_PKTSZ) /* 256KiB buffer. */
-#define MAX_RENUM_DELAY_MS 3000
+/* USB communication timeout during regular operation. */
#define DEFAULT_TIMEOUT_MS 200
#define DEFAULT_TIMEOUT_MS 200
+/*
+ * Check for MCU firmware to take effect after upload. Check the device
+ * presence for a maximum period of time, delay between checks in that
+ * phase. Allow for the device to vanish after upload and before checks,
+ * to not mistake its earlier incarnation for the successful operation
+ * of the most recently loaded firmware.
+ */
+#define RENUM_CHECK_PERIOD_MS 3000
+#define RENUM_GONE_DELAY_MS 1800
+#define RENUM_POLL_INTERVAL_MS 200
+
#define LA2016_THR_VOLTAGE_MIN 0.40
#define LA2016_THR_VOLTAGE_MAX 4.00
#define LA2016_THR_VOLTAGE_MIN 0.40
#define LA2016_THR_VOLTAGE_MAX 4.00
struct dev_context {
struct sr_context *ctx;
struct dev_context {
struct sr_context *ctx;
/* User specified parameters. */
pwm_setting_t pwm_setting[2];
/* User specified parameters. */
pwm_setting_t pwm_setting[2];