X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fopenbench-logic-sniffer%2Fols.c;h=60131805169b86e9bd71df394f5aa9f2a584f228;hb=10e5cbede89976eeed3237d985da065238962dfe;hp=c1deb759e93a5d2bdecebe997187d57ff4ee1339;hpb=d261dbbfcc7317f2fd9aa9c08473dc4a7b6b2b30;p=libsigrok.git diff --git a/hardware/openbench-logic-sniffer/ols.c b/hardware/openbench-logic-sniffer/ols.c index c1deb759..60131805 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, @@ -93,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) { @@ -131,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; @@ -146,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; @@ -227,10 +227,11 @@ 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); ctx = ols_dev_new(); @@ -289,7 +290,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) */ @@ -322,7 +328,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 */ @@ -348,23 +359,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)))) { @@ -398,7 +416,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, @@ -445,16 +463,24 @@ 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"); 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; @@ -478,7 +504,7 @@ 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) @@ -486,7 +512,7 @@ static int hw_dev_open(int dev_index) struct sr_dev_inst *sdi; struct context *ctx; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + if (!(sdi = sr_dev_inst_get(odi->instances, dev_index))) return SR_ERR; ctx = sdi->priv; @@ -505,9 +531,9 @@ static int hw_dev_close(int dev_index) struct sr_dev_inst *sdi; struct context *ctx; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) { + if (!(sdi = sr_dev_inst_get(odi->instances, dev_index))) { sr_err("ols: %s: sdi was NULL", __func__); - return SR_ERR; /* TODO: SR_ERR_ARG? */ + return SR_ERR_BUG; } ctx = sdi->priv; @@ -530,7 +556,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__); @@ -550,17 +576,17 @@ 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 const void *hw_dev_info_get(int dev_index, int dev_info_id) { struct sr_dev_inst *sdi; struct context *ctx; - void *info; + const void *info; if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) return NULL; @@ -595,13 +621,13 @@ 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) +static const int *hw_hwcap_get_all(void) { return hwcaps; } @@ -638,14 +664,14 @@ 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(int dev_index, 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))) + if (!(sdi = sr_dev_inst_get(odi->instances, dev_index))) return SR_ERR; ctx = sdi->priv; @@ -654,10 +680,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; @@ -670,7 +696,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; @@ -691,7 +717,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; @@ -703,12 +729,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. */ @@ -722,7 +749,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", @@ -834,12 +861,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; @@ -848,7 +875,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; @@ -857,23 +884,24 @@ 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(int dev_index, void *cb_data) { struct sr_datafeed_packet *packet; struct sr_datafeed_header *header; + struct sr_datafeed_meta_logic meta; struct sr_dev_inst *sdi; struct context *ctx; uint32_t trigger_config[4]; @@ -883,7 +911,7 @@ 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))) + if (!(sdi = sr_dev_inst_get(odi->instances, dev_index))) return SR_ERR; ctx = sdi->priv; @@ -995,7 +1023,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__); @@ -1013,9 +1041,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); @@ -1023,7 +1056,8 @@ 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(int dev_index, void *cb_data) { struct sr_datafeed_packet packet; @@ -1031,17 +1065,18 @@ static int hw_dev_acquisition_stop(int dev_index, gpointer session_dev_id) (void)dev_index; 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, @@ -1050,4 +1085,5 @@ SR_PRIV struct sr_dev_plugin ols_plugin_info = { .dev_config_set = hw_dev_config_set, .dev_acquisition_start = hw_dev_acquisition_start, .dev_acquisition_stop = hw_dev_acquisition_stop, + .instances = NULL, };