X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fopenbench-logic-sniffer%2Fols.c;h=a8d9dbea908d11996c341c9183412e90c5cf1902;hb=44fc870c9cc5c0e53b47b9d7fa3dffe81731ee3c;hp=6f914a8c8991851dac884897d025fb3de3b773fe;hpb=69b07d14db24055d23bbb4c4cc718ec073ece0b7;p=libsigrok.git diff --git a/hardware/openbench-logic-sniffer/ols.c b/hardware/openbench-logic-sniffer/ols.c index 6f914a8c..a8d9dbea 100644 --- a/hardware/openbench-logic-sniffer/ols.c +++ b/hardware/openbench-logic-sniffer/ols.c @@ -42,9 +42,7 @@ #include "libsigrok-internal.h" #include "ols.h" -#ifdef _WIN32 -#define O_NONBLOCK FIONBIO -#endif +#define SERIALCOMM "115200/8n1" static const int hwcaps[] = { SR_HWCAP_LOGIC_ANALYZER, @@ -103,19 +101,21 @@ static const struct sr_samplerates samplerates = { SR_PRIV struct sr_dev_driver ols_driver_info; static struct sr_dev_driver *odi = &ols_driver_info; -static int send_shortcommand(int fd, uint8_t command) +static int send_shortcommand(struct sr_serial_dev_inst *serial, + uint8_t command) { char buf[1]; sr_dbg("ols: sending cmd 0x%.2x", command); buf[0] = command; - if (serial_write(fd, buf, 1) != 1) + if (serial_write(serial, buf, 1) != 1) return SR_ERR; return SR_OK; } -static int send_longcommand(int fd, uint8_t command, uint32_t data) +static int send_longcommand(struct sr_serial_dev_inst *serial, + uint8_t command, uint32_t data) { char buf[5]; @@ -125,7 +125,7 @@ static int send_longcommand(int fd, uint8_t command, uint32_t data) buf[2] = (data & 0xff0000) >> 16; buf[3] = (data & 0xff00) >> 8; buf[4] = data & 0xff; - if (serial_write(fd, buf, 5) != 5) + if (serial_write(serial, buf, 5) != 5) return SR_ERR; return SR_OK; @@ -212,7 +212,6 @@ static struct dev_context *ols_dev_new(void) { struct dev_context *devc; - /* TODO: Is 'devc' ever g_free()'d? */ if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("ols: %s: devc malloc failed", __func__); return NULL; @@ -226,7 +225,7 @@ static struct dev_context *ols_dev_new(void) return devc; } -static struct sr_dev_inst *get_metadata(int fd) +static struct sr_dev_inst *get_metadata(struct sr_serial_dev_inst *serial) { struct sr_dev_inst *sdi; struct dev_context *devc; @@ -246,7 +245,7 @@ static struct sr_dev_inst *get_metadata(int fd) key = 0xff; while (key) { - if (serial_read(fd, &key, 1) != 1 || key == 0x00) + if (serial_read(serial, &key, 1) != 1 || key == 0x00) break; type = key >> 5; token = key & 0x1f; @@ -254,7 +253,7 @@ static struct sr_dev_inst *get_metadata(int fd) case 0: /* NULL-terminated string */ tmp_str = g_string_new(""); - while (serial_read(fd, &tmp_c, 1) == 1 && tmp_c != '\0') + while (serial_read(serial, &tmp_c, 1) == 1 && tmp_c != '\0') g_string_append_c(tmp_str, tmp_c); sr_dbg("ols: got metadata key 0x%.2x value '%s'", key, tmp_str->str); @@ -286,7 +285,7 @@ static struct sr_dev_inst *get_metadata(int fd) break; case 1: /* 32-bit unsigned integer */ - if (serial_read(fd, &tmp_int, 4) != 4) + if (serial_read(serial, &tmp_int, 4) != 4) break; tmp_int = reverse32(tmp_int); sr_dbg("ols: got metadata key 0x%.2x value 0x%.8x", @@ -325,7 +324,7 @@ static struct sr_dev_inst *get_metadata(int fd) break; case 2: /* 8-bit unsigned integer */ - if (serial_read(fd, &tmp_c, 1) != 1) + if (serial_read(serial, &tmp_c, 1) != 1) break; sr_dbg("ols: got metadata key 0x%.2x value 0x%.2x", key, tmp_c); @@ -378,143 +377,109 @@ static int hw_init(void) static GSList *hw_scan(GSList *options) { + struct sr_hwopt *opt; struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_probe *probe; - GSList *devices, *ports, *l; - GPollFD *fds, probefd; - int devcnt, final_devcnt, num_ports, fd, ret, i, j; - char buf[8], **dev_names, **serial_params; + struct sr_serial_dev_inst *serial; + GPollFD probefd; + GSList *l, *devices; + int ret, i; + const char *conn, *serialcomm; + char buf[8]; (void)options; drvc = odi->priv; - final_devcnt = 0; devices = NULL; - /* Scan all serial ports. */ - ports = list_serial_ports(); - num_ports = g_slist_length(ports); - - if (!(fds = g_try_malloc0(num_ports * sizeof(GPollFD)))) { - sr_err("ols: %s: fds malloc failed", __func__); - goto hw_init_free_ports; /* TODO: SR_ERR_MALLOC. */ + conn = serialcomm = NULL; + for (l = options; l; l = l->next) { + opt = l->data; + switch (opt->hwopt) { + case SR_HWOPT_CONN: + conn = opt->value; + break; + case SR_HWOPT_SERIALCOMM: + serialcomm = opt->value; + break; + } } + if (!conn) + return NULL; - if (!(dev_names = g_try_malloc(num_ports * sizeof(char *)))) { - sr_err("ols: %s: dev_names malloc failed", __func__); - goto hw_init_free_fds; /* TODO: SR_ERR_MALLOC. */ - } + if (serialcomm == NULL) + serialcomm = SERIALCOMM; - if (!(serial_params = g_try_malloc(num_ports * sizeof(char *)))) { - sr_err("ols: %s: serial_params malloc failed", __func__); - goto hw_init_free_dev_names; /* TODO: SR_ERR_MALLOC. */ - } + if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) + return NULL; - devcnt = 0; - for (l = ports; l; l = l->next) { - /* The discovery procedure is like this: first send the Reset - * command (0x00) 5 times, since the device could be anywhere - * in a 5-byte command. Then send the ID command (0x02). - * If the device responds with 4 bytes ("OLS1" or "SLA1"), we - * have a match. - * - * Since it may take the device a while to respond at 115Kb/s, - * we do all the sending first, then wait for all of them to - * respond with g_poll(). - */ - sr_info("ols: probing %s...", (char *)l->data); - fd = serial_open(l->data, O_RDWR | O_NONBLOCK); - if (fd != -1) { - serial_params[devcnt] = serial_backup_params(fd); - serial_set_params(fd, 115200, 8, SERIAL_PARITY_NONE, 1, 2); - ret = SR_OK; - for (i = 0; i < 5; i++) { - if ((ret = send_shortcommand(fd, - CMD_RESET)) != SR_OK) { - /* Serial port is not writable. */ - break; - } - } - if (ret != SR_OK) { - serial_restore_params(fd, - serial_params[devcnt]); - serial_close(fd); - continue; - } - send_shortcommand(fd, CMD_ID); - fds[devcnt].fd = fd; - fds[devcnt].events = G_IO_IN; - dev_names[devcnt] = g_strdup(l->data); - devcnt++; + /* The discovery procedure is like this: first send the Reset + * command (0x00) 5 times, since the device could be anywhere + * in a 5-byte command. Then send the ID command (0x02). + * If the device responds with 4 bytes ("OLS1" or "SLA1"), we + * have a match. + */ + sr_info("ols: probing %s .", conn); + if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK) + return NULL; + + ret = SR_OK; + for (i = 0; i < 5; i++) { + if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) { + sr_err("ols: port %s is not writable.", conn); + break; } - g_free(l->data); } + if (ret != SR_OK) { + serial_close(serial); + sr_err("ols: Could not use port %s. Quitting.", conn); + return NULL; + } + send_shortcommand(serial, CMD_ID); - /* 2ms isn't enough for reliable transfer with pl2303, let's try 10 */ + /* Wait 10ms for a response. */ usleep(10000); - g_poll(fds, devcnt, 1); - - for (i = 0; i < devcnt; i++) { - if (fds[i].revents != G_IO_IN) - continue; - if (serial_read(fds[i].fd, buf, 4) != 4) - continue; - if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4)) - continue; - - /* definitely using the OLS protocol, check if it supports - * the metadata command - */ - send_shortcommand(fds[i].fd, CMD_METADATA); - probefd.fd = fds[i].fd; - probefd.events = G_IO_IN; - if (g_poll(&probefd, 1, 10) > 0) { - /* got metadata */ - sdi = get_metadata(fds[i].fd); - sdi->index = final_devcnt; - devc = sdi->priv; - } else { - /* not an OLS -- some other board that uses the sump protocol */ - sdi = sr_dev_inst_new(final_devcnt, SR_ST_INACTIVE, - "Sump", "Logic Analyzer", "v1.0"); - sdi->driver = odi; - devc = ols_dev_new(); - for (j = 0; j < 32; j++) { - if (!(probe = sr_probe_new(j, SR_PROBE_LOGIC, TRUE, - probe_names[j]))) - return 0; - sdi->probes = g_slist_append(sdi->probes, probe); - } - sdi->priv = devc; - } - devc->serial = sr_serial_dev_inst_new(dev_names[i], -1); - drvc->instances = g_slist_append(drvc->instances, sdi); - devices = g_slist_append(devices, sdi); + probefd.fd = serial->fd; + probefd.events = G_IO_IN; + g_poll(&probefd, 1, 1); - final_devcnt++; - serial_close(fds[i].fd); - fds[i].fd = 0; - } + if (probefd.revents != G_IO_IN) + return NULL; + if (serial_read(serial, buf, 4) != 4) + return NULL; + if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4)) + return NULL; - /* clean up after all the probing */ - for (i = 0; i < devcnt; i++) { - if (fds[i].fd != 0) { - serial_restore_params(fds[i].fd, serial_params[i]); - serial_close(fds[i].fd); + /* Definitely using the OLS protocol, check if it supports + * the metadata command. + */ + send_shortcommand(serial, CMD_METADATA); + if (g_poll(&probefd, 1, 10) > 0) { + /* Got metadata. */ + sdi = get_metadata(serial); + sdi->index = 0; + devc = sdi->priv; + } else { + /* Not an OLS -- some other board that uses the sump protocol. */ + sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, + "Sump", "Logic Analyzer", "v1.0"); + sdi->driver = odi; + devc = ols_dev_new(); + for (i = 0; i < 32; i++) { + if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, + probe_names[i]))) + return 0; + sdi->probes = g_slist_append(sdi->probes, probe); } - g_free(serial_params[i]); - g_free(dev_names[i]); + sdi->priv = devc; } + devc->serial = serial; + drvc->instances = g_slist_append(drvc->instances, sdi); + devices = g_slist_append(devices, sdi); - g_free(serial_params); -hw_init_free_dev_names: - g_free(dev_names); -hw_init_free_fds: - g_free(fds); -hw_init_free_ports: - g_slist_free(ports); + serial_close(serial); return devices; } @@ -534,8 +499,7 @@ static int hw_dev_open(struct sr_dev_inst *sdi) devc = sdi->priv; - devc->serial->fd = serial_open(devc->serial->port, O_RDWR); - if (devc->serial->fd == -1) + if (serial_open(devc->serial, SERIAL_RDWR) != SR_OK) return SR_ERR; sdi->status = SR_ST_ACTIVE; @@ -549,9 +513,8 @@ static int hw_dev_close(struct sr_dev_inst *sdi) devc = sdi->priv; - if (devc->serial->fd != -1) { - serial_close(devc->serial->fd); - devc->serial->fd = -1; + if (devc->serial && devc->serial->fd != -1) { + serial_close(devc->serial); sdi->status = SR_ST_INACTIVE; } @@ -584,9 +547,7 @@ static int hw_cleanup(void) ret = SR_ERR_BUG; continue; } - /* TODO: Check for serial != NULL. */ - if (devc->serial->fd != -1) - serial_close(devc->serial->fd); + hw_dev_close(sdi); sr_serial_dev_inst_free(devc->serial); sr_dev_inst_free(sdi); } @@ -745,9 +706,8 @@ static int receive_data(int fd, int revents, void *cb_data) for (l = drvc->instances; l; l = l->next) { sdi = l->data; devc = sdi->priv; - if (devc->serial->fd == fd) { + if (devc->serial->fd == fd) break; - } devc = NULL; } if (!devc) @@ -781,7 +741,7 @@ static int receive_data(int fd, int revents, void *cb_data) } if (revents == G_IO_IN) { - if (serial_read(fd, &byte, 1) != 1) + if (serial_read(devc->serial, &byte, 1) != 1) return FALSE; /* Ignore it if we've read enough. */ @@ -902,10 +862,9 @@ static int receive_data(int fd, int revents, void *cb_data) } g_free(devc->raw_sample_buf); - serial_flush(fd); - serial_close(fd); - + serial_flush(devc->serial); abort_acquisition(sdi); + serial_close(devc->serial); } return TRUE; @@ -961,53 +920,53 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, delaycount = readcount * (1 - devc->capture_ratio / 100.0); devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_MASK_0, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0, reverse32(devc->trigger_mask[0])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_VALUE_0, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0, reverse32(devc->trigger_value[0])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_CONFIG_0, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0, trigger_config[0]) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_MASK_1, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_1, reverse32(devc->trigger_mask[1])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_VALUE_1, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_1, reverse32(devc->trigger_value[1])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_CONFIG_1, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_1, trigger_config[1]) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_MASK_2, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_2, reverse32(devc->trigger_mask[2])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_VALUE_2, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_2, reverse32(devc->trigger_value[2])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_CONFIG_2, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_2, trigger_config[2]) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_MASK_3, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_3, reverse32(devc->trigger_mask[3])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_VALUE_3, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_3, reverse32(devc->trigger_value[3])) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_CONFIG_3, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_3, trigger_config[3]) != SR_OK) return SR_ERR; } else { - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_MASK_0, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0, devc->trigger_mask[0]) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_VALUE_0, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0, devc->trigger_value[0]) != SR_OK) return SR_ERR; - if (send_longcommand(devc->serial->fd, CMD_SET_TRIGGER_CONFIG_0, + if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0, 0x00000008) != SR_OK) return SR_ERR; delaycount = readcount; @@ -1016,14 +975,14 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, sr_info("ols: setting samplerate to %" PRIu64 " Hz (divider %u, " "demux %s)", devc->cur_samplerate, devc->cur_samplerate_divider, devc->flag_reg & FLAG_DEMUX ? "on" : "off"); - if (send_longcommand(devc->serial->fd, CMD_SET_DIVIDER, + if (send_longcommand(devc->serial, CMD_SET_DIVIDER, reverse32(devc->cur_samplerate_divider)) != SR_OK) return SR_ERR; /* Send sample limit and pre/post-trigger capture ratio. */ data = ((readcount - 1) & 0xffff) << 16; data |= (delaycount - 1) & 0xffff; - if (send_longcommand(devc->serial->fd, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK) + if (send_longcommand(devc->serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK) return SR_ERR; /* The flag register wants them here, and 1 means "disable channel". */ @@ -1031,11 +990,11 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, devc->flag_reg |= FLAG_FILTER; devc->rle_count = 0; data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000); - if (send_longcommand(devc->serial->fd, CMD_SET_FLAGS, data) != SR_OK) + if (send_longcommand(devc->serial, CMD_SET_FLAGS, data) != SR_OK) return SR_ERR; /* Start acquisition on the device. */ - if (send_shortcommand(devc->serial->fd, CMD_RUN) != SR_OK) + if (send_shortcommand(devc->serial, CMD_RUN) != SR_OK) return SR_ERR; sr_source_add(devc->serial->fd, G_IO_IN, -1, receive_data,