X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fopenbench-logic-sniffer%2Fols.c;h=ad5e7f29ed86f9220202d471b5e7a0cfb509d97a;hb=5d9ed643e9dddbdb43e8917cff197346bdc930e7;hp=4e38f56b5ab9d169bde6a7d0a2a5f6f4449edc6e;hpb=ea9cfed7a55260ab97f57150b57c42a28c3a85a7;p=libsigrok.git diff --git a/hardware/openbench-logic-sniffer/ols.c b/hardware/openbench-logic-sniffer/ols.c index 4e38f56b..ad5e7f29 100644 --- a/hardware/openbench-logic-sniffer/ols.c +++ b/hardware/openbench-logic-sniffer/ols.c @@ -38,15 +38,15 @@ #include #endif #include -#include "sigrok.h" -#include "sigrok-internal.h" +#include "libsigrok.h" +#include "libsigrok-internal.h" #include "ols.h" #ifdef _WIN32 #define O_NONBLOCK FIONBIO #endif -static int hwcaps[] = { +static const int hwcaps[] = { SR_HWCAP_LOGIC_ANALYZER, SR_HWCAP_SAMPLERATE, SR_HWCAP_CAPTURE_RATIO, @@ -55,6 +55,7 @@ static int hwcaps[] = { 0, }; +/* Probes are numbered 0-31 (on the PCB silkscreen). */ static const char *probe_names[NUM_PROBES + 1] = { "0", "1", @@ -92,15 +93,15 @@ static const char *probe_names[NUM_PROBES + 1] = { }; /* default supported samplerates, can be overridden by device metadata */ -static struct sr_samplerates samplerates = { +static const struct sr_samplerates samplerates = { SR_HZ(10), SR_MHZ(200), SR_HZ(1), NULL, }; -/* List of struct sr_serial_dev_inst */ -static GSList *dev_insts = NULL; +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) { @@ -130,10 +131,10 @@ static int send_longcommand(int fd, uint8_t command, uint32_t data) return SR_OK; } -static int configure_probes(struct context *ctx, GSList *probes) +static int configure_probes(struct context *ctx, const GSList *probes) { - struct sr_probe *probe; - GSList *l; + const struct sr_probe *probe; + const GSList *l; int probe_bit, stage, i; char *tc; @@ -145,7 +146,7 @@ static int configure_probes(struct context *ctx, GSList *probes) ctx->num_stages = 0; for (l = probes; l; l = l->next) { - probe = (struct sr_probe *)l->data; + probe = (const struct sr_probe *)l->data; if (!probe->enabled) continue; @@ -226,12 +227,14 @@ static struct sr_dev_inst *get_metadata(int fd) { struct sr_dev_inst *sdi; struct context *ctx; - uint32_t tmp_int; + struct sr_probe *probe; + uint32_t tmp_int, ui; uint8_t key, type, token; GString *tmp_str, *devname, *version; - gchar tmp_c; + guchar tmp_c; sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, NULL, NULL, NULL); + sdi->driver = odi; ctx = ols_dev_new(); sdi->priv = ctx; @@ -288,7 +291,12 @@ static struct sr_dev_inst *get_metadata(int fd) switch (token) { case 0x00: /* Number of usable probes */ - ctx->num_probes = tmp_int; + for (ui = 0; ui < tmp_int; ui++) { + if (!(probe = sr_probe_new(ui, SR_PROBE_LOGIC, TRUE, + probe_names[ui]))) + return 0; + sdi->probes = g_slist_append(sdi->probes, probe); + } break; case 0x01: /* Amount of sample memory available (bytes) */ @@ -321,7 +329,12 @@ static struct sr_dev_inst *get_metadata(int fd) switch (token) { case 0x00: /* Number of usable probes */ - ctx->num_probes = tmp_c; + for (ui = 0; ui < tmp_c; ui++) { + if (!(probe = sr_probe_new(ui, SR_PROBE_LOGIC, TRUE, + probe_names[ui]))) + return 0; + sdi->probes = g_slist_append(sdi->probes, probe); + } break; case 0x01: /* protocol version */ @@ -347,23 +360,30 @@ static struct sr_dev_inst *get_metadata(int fd) return sdi; } -static int hw_init(const char *devinfo) +static int hw_init(void) +{ + + /* Nothing to do. */ + + return SR_OK; +} + +static GSList *hw_scan(GSList *options) { struct sr_dev_inst *sdi; struct context *ctx; - GSList *ports, *l; + struct sr_probe *probe; + GSList *devices, *ports, *l; GPollFD *fds, probefd; - int devcnt, final_devcnt, num_ports, fd, ret, i; + int devcnt, final_devcnt, num_ports, fd, ret, i, j; char buf[8], **dev_names, **serial_params; + (void)options; final_devcnt = 0; + devices = NULL; - if (devinfo) - ports = g_slist_append(NULL, g_strdup(devinfo)); - else - /* No specific device given, so scan all serial ports. */ - ports = list_serial_ports(); - + /* Scan all serial ports. */ + ports = list_serial_ports(); num_ports = g_slist_length(ports); if (!(fds = g_try_malloc0(num_ports * sizeof(GPollFD)))) { @@ -397,7 +417,7 @@ static int hw_init(const char *devinfo) 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, 0, 1, 2); + 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, @@ -444,16 +464,25 @@ static int hw_init(const char *devinfo) /* got metadata */ sdi = get_metadata(fds[i].fd); sdi->index = final_devcnt; + ctx = 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; ctx = ols_dev_new(); - ctx->num_probes = 32; + 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 = ctx; } ctx->serial = sr_serial_dev_inst_new(dev_names[i], -1); - dev_insts = g_slist_append(dev_insts, sdi); + odi->instances = g_slist_append(odi->instances, sdi); + devices = g_slist_append(devices, sdi); + final_devcnt++; serial_close(fds[i].fd); fds[i].fd = 0; @@ -477,17 +506,13 @@ hw_init_free_fds: hw_init_free_ports: g_slist_free(ports); - return final_devcnt; + return devices; } -static int hw_dev_open(int dev_index) +static int hw_dev_open(struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; struct context *ctx; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR; - ctx = sdi->priv; ctx->serial->fd = serial_open(ctx->serial->port, O_RDWR); @@ -499,19 +524,12 @@ static int hw_dev_open(int dev_index) return SR_OK; } -static int hw_dev_close(int dev_index) +static int hw_dev_close(struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; struct context *ctx; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) { - sr_err("ols: %s: sdi was NULL", __func__); - return SR_ERR; /* TODO: SR_ERR_ARG? */ - } - ctx = sdi->priv; - /* TODO */ if (ctx->serial->fd != -1) { serial_close(ctx->serial->fd); ctx->serial->fd = -1; @@ -529,7 +547,7 @@ static int hw_cleanup(void) int ret = SR_OK; /* Properly close and free all devices. */ - for (l = dev_insts; l; l = l->next) { + for (l = odi->instances; l; l = l->next) { if (!(sdi = l->data)) { /* Log error, but continue cleaning up the rest. */ sr_err("ols: %s: sdi was NULL, continuing", __func__); @@ -549,63 +567,61 @@ static int hw_cleanup(void) sr_serial_dev_inst_free(ctx->serial); sr_dev_inst_free(sdi); } - g_slist_free(dev_insts); - dev_insts = NULL; + g_slist_free(odi->instances); + odi->instances = NULL; return ret; } -static void *hw_dev_info_get(int dev_index, int dev_info_id) +static int hw_info_get(int info_id, const void **data, + const struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; struct context *ctx; - void *info; - - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return NULL; - ctx = sdi->priv; - info = NULL; - switch (dev_info_id) { + switch (info_id) { case SR_DI_INST: - info = sdi; + *data = sdi; + break; + case SR_DI_HWCAPS: + *data = hwcaps; break; case SR_DI_NUM_PROBES: - info = GINT_TO_POINTER(NUM_PROBES); + *data = GINT_TO_POINTER(1); break; case SR_DI_PROBE_NAMES: - info = probe_names; + *data = probe_names; break; case SR_DI_SAMPLERATES: - info = &samplerates; + *data = &samplerates; break; case SR_DI_TRIGGER_TYPES: - info = (char *)TRIGGER_TYPES; + *data = (char *)TRIGGER_TYPES; break; case SR_DI_CUR_SAMPLERATE: - info = &ctx->cur_samplerate; + if (sdi) { + ctx = sdi->priv; + *data = &ctx->cur_samplerate; + } else + return SR_ERR; break; + default: + return SR_ERR_ARG; } - return info; + return SR_OK; } static int hw_dev_status_get(int dev_index) { struct sr_dev_inst *sdi; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + if (!(sdi = sr_dev_inst_get(odi->instances, dev_index))) return SR_ST_NOT_FOUND; return sdi->status; } -static int *hw_hwcap_get_all(void) -{ - return hwcaps; -} - -static int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate) +static int set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate) { struct context *ctx; @@ -637,15 +653,13 @@ static int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate) return SR_OK; } -static int hw_dev_config_set(int dev_index, int hwcap, void *value) +static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap, + const void *value) { - struct sr_dev_inst *sdi; struct context *ctx; int ret; - uint64_t *tmp_u64; + const uint64_t *tmp_u64; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR; ctx = sdi->priv; if (sdi->status != SR_ST_ACTIVE) @@ -653,10 +667,10 @@ static int hw_dev_config_set(int dev_index, int hwcap, void *value) switch (hwcap) { case SR_HWCAP_SAMPLERATE: - ret = set_samplerate(sdi, *(uint64_t *)value); + ret = set_samplerate(sdi, *(const uint64_t *)value); break; case SR_HWCAP_PROBECONFIG: - ret = configure_probes(ctx, (GSList *)value); + ret = configure_probes(ctx, (const GSList *)value); break; case SR_HWCAP_LIMIT_SAMPLES: tmp_u64 = value; @@ -669,7 +683,7 @@ static int hw_dev_config_set(int dev_index, int hwcap, void *value) ret = SR_OK; break; case SR_HWCAP_CAPTURE_RATIO: - ctx->capture_ratio = *(uint64_t *)value; + ctx->capture_ratio = *(const uint64_t *)value; if (ctx->capture_ratio < 0 || ctx->capture_ratio > 100) { ctx->capture_ratio = 0; ret = SR_ERR; @@ -690,7 +704,7 @@ static int hw_dev_config_set(int dev_index, int hwcap, void *value) return ret; } -static int receive_data(int fd, int revents, void *session_data) +static int receive_data(int fd, int revents, void *cb_data) { struct sr_datafeed_packet packet; struct sr_datafeed_logic logic; @@ -702,12 +716,13 @@ static int receive_data(int fd, int revents, void *session_data) /* Find this device's ctx struct by its fd. */ ctx = NULL; - for (l = dev_insts; l; l = l->next) { + for (l = odi->instances; l; l = l->next) { sdi = l->data; + ctx = sdi->priv; if (ctx->serial->fd == fd) { - ctx = sdi->priv; break; } + ctx = NULL; } if (!ctx) /* Shouldn't happen. */ @@ -721,7 +736,7 @@ static int receive_data(int fd, int revents, void *session_data) * finished. We'll double that to 30ms to be sure... */ sr_source_remove(fd); - sr_source_add(fd, G_IO_IN, 30, receive_data, session_data); + sr_source_add(fd, G_IO_IN, 30, receive_data, cb_data); ctx->raw_sample_buf = g_try_malloc(ctx->limit_samples * 4); if (!ctx->raw_sample_buf) { sr_err("ols: %s: ctx->raw_sample_buf malloc failed", @@ -833,12 +848,12 @@ static int receive_data(int fd, int revents, void *session_data) logic.unitsize = 4; logic.data = ctx->raw_sample_buf + (ctx->limit_samples - ctx->num_samples) * 4; - sr_session_bus(session_data, &packet); + sr_session_send(cb_data, &packet); } /* send the trigger */ packet.type = SR_DF_TRIGGER; - sr_session_bus(session_data, &packet); + sr_session_send(cb_data, &packet); /* send post-trigger samples */ packet.type = SR_DF_LOGIC; @@ -847,7 +862,7 @@ static int receive_data(int fd, int revents, void *session_data) logic.unitsize = 4; logic.data = ctx->raw_sample_buf + ctx->trigger_at * 4 + (ctx->limit_samples - ctx->num_samples) * 4; - sr_session_bus(session_data, &packet); + sr_session_send(cb_data, &packet); } else { /* no trigger was used */ packet.type = SR_DF_LOGIC; @@ -856,24 +871,25 @@ static int receive_data(int fd, int revents, void *session_data) logic.unitsize = 4; logic.data = ctx->raw_sample_buf + (ctx->limit_samples - ctx->num_samples) * 4; - sr_session_bus(session_data, &packet); + sr_session_send(cb_data, &packet); } g_free(ctx->raw_sample_buf); serial_flush(fd); serial_close(fd); packet.type = SR_DF_END; - sr_session_bus(session_data, &packet); + sr_session_send(cb_data, &packet); } return TRUE; } -static int hw_dev_acquisition_start(int dev_index, gpointer session_data) +static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, + void *cb_data) { struct sr_datafeed_packet *packet; struct sr_datafeed_header *header; - struct sr_dev_inst *sdi; + struct sr_datafeed_meta_logic meta; struct context *ctx; uint32_t trigger_config[4]; uint32_t data; @@ -882,9 +898,6 @@ static int hw_dev_acquisition_start(int dev_index, gpointer session_data) int num_channels; int i; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR; - ctx = sdi->priv; if (sdi->status != SR_ST_ACTIVE) @@ -994,7 +1007,7 @@ static int hw_dev_acquisition_start(int dev_index, gpointer session_data) return SR_ERR; sr_source_add(ctx->serial->fd, G_IO_IN, -1, receive_data, - session_data); + cb_data); if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) { sr_err("ols: %s: packet malloc failed", __func__); @@ -1012,9 +1025,14 @@ static int hw_dev_acquisition_start(int dev_index, gpointer session_data) packet->payload = (unsigned char *)header; header->feed_version = 1; gettimeofday(&header->starttime, NULL); - header->samplerate = ctx->cur_samplerate; - header->num_logic_probes = NUM_PROBES; - sr_session_bus(session_data, packet); + sr_session_send(cb_data, packet); + + /* Send metadata about the SR_DF_LOGIC packets to come. */ + packet->type = SR_DF_META_LOGIC; + packet->payload = &meta; + meta.samplerate = ctx->cur_samplerate; + meta.num_probes = NUM_PROBES; + sr_session_send(cb_data, packet); g_free(header); g_free(packet); @@ -1022,31 +1040,34 @@ static int hw_dev_acquisition_start(int dev_index, gpointer session_data) return SR_OK; } -static int hw_dev_acquisition_stop(int dev_index, gpointer session_dev_id) +/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */ +static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, + void *cb_data) { struct sr_datafeed_packet packet; /* Avoid compiler warnings. */ - (void)dev_index; + (void)sdi; packet.type = SR_DF_END; - sr_session_bus(session_dev_id, &packet); + sr_session_send(cb_data, &packet); return SR_OK; } -SR_PRIV struct sr_dev_plugin ols_plugin_info = { +SR_PRIV struct sr_dev_driver ols_driver_info = { .name = "ols", .longname = "Openbench Logic Sniffer", .api_version = 1, .init = hw_init, .cleanup = hw_cleanup, + .scan = hw_scan, .dev_open = hw_dev_open, .dev_close = hw_dev_close, - .dev_info_get = hw_dev_info_get, + .info_get = hw_info_get, .dev_status_get = hw_dev_status_get, - .hwcap_get_all = hw_hwcap_get_all, .dev_config_set = hw_dev_config_set, .dev_acquisition_start = hw_dev_acquisition_start, .dev_acquisition_stop = hw_dev_acquisition_stop, + .instances = NULL, };