* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
#include "protocol.h"
-#include <libserialport.h>
#define SERIALCOMM "115200/8n1"
-static const uint32_t drvopts[] = {
- SR_CONF_LOGIC_ANALYZER,
-};
-
static const uint32_t scanopts[] = {
SR_CONF_CONN,
SR_CONF_SERIALCOMM,
+ SR_CONF_PROBE_NAMES,
+};
+
+static const uint32_t drvopts[] = {
+ SR_CONF_LOGIC_ANALYZER,
};
static const uint32_t devopts[] = {
+ SR_CONF_CONN | SR_CONF_GET,
SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
- SR_CONF_EXTERNAL_CLOCK | SR_CONF_SET,
+ SR_CONF_EXTERNAL_CLOCK | SR_CONF_GET | SR_CONF_SET,
+ SR_CONF_CLOCK_EDGE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_SWAP | SR_CONF_SET,
SR_CONF_RLE | SR_CONF_GET | SR_CONF_SET,
SR_TRIGGER_ONE,
};
+static const char *external_clock_edges[] = {
+ "rising", /* positive edge */
+ "falling" /* negative edge */
+};
+
#define STR_PATTERN_NONE "None"
#define STR_PATTERN_EXTERNAL "External"
#define STR_PATTERN_INTERNAL "Internal"
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
"13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
"24", "25", "26", "27", "28", "29", "30", "31",
- NULL,
};
/* Default supported samplerates, can be overridden by device metadata. */
SR_HZ(1),
};
-SR_PRIV struct sr_dev_driver ols_driver_info;
-
-static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
-{
- return std_init(sr_ctx, di, LOG_PREFIX);
-}
+#define RESPONSE_DELAY_US (20 * 1000)
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
struct sr_config *src;
struct sr_dev_inst *sdi;
- struct drv_context *drvc;
- struct dev_context *devc;
struct sr_serial_dev_inst *serial;
- GSList *l, *devices;
- int ret, i;
- const char *conn, *serialcomm;
- char buf[8];
-
- drvc = di->priv;
-
- devices = NULL;
+ GSList *l;
+ int num_read;
+ unsigned int i;
+ const char *conn, *serialcomm, *probe_names;
+ char buf[4] = { 0, 0, 0, 0 };
+ struct dev_context *devc;
+ size_t ch_max;
conn = serialcomm = NULL;
+ probe_names = NULL;
for (l = options; l; l = l->next) {
src = l->data;
switch (src->key) {
case SR_CONF_SERIALCOMM:
serialcomm = g_variant_get_string(src->data, NULL);
break;
+ case SR_CONF_PROBE_NAMES:
+ probe_names = g_variant_get_string(src->data, NULL);
+ break;
}
}
if (!conn)
return NULL;
- if (serialcomm == NULL)
+ if (!serialcomm)
serialcomm = SERIALCOMM;
serial = sr_serial_dev_inst_new(conn, serialcomm);
if (serial_open(serial, SERIAL_RDWR) != SR_OK)
return NULL;
- ret = SR_OK;
- for (i = 0; i < 5; i++) {
- if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
- sr_err("Port %s is not writable.", conn);
- break;
- }
- }
- if (ret != SR_OK) {
+ if (ols_send_reset(serial) != SR_OK) {
serial_close(serial);
sr_err("Could not use port %s. Quitting.", conn);
return NULL;
}
send_shortcommand(serial, CMD_ID);
- /* Wait 10ms for a response. */
- g_usleep(10000);
+ g_usleep(RESPONSE_DELAY_US);
- if (sp_input_waiting(serial->data) == 0) {
- sr_dbg("Didn't get any reply.");
+ if (serial_has_receive_data(serial) == 0) {
+ sr_dbg("Didn't get any ID reply.");
return NULL;
}
- ret = serial_read_blocking(serial, buf, 4, serial_timeout(serial, 4));
- if (ret != 4) {
- sr_err("Invalid reply (expected 4 bytes, got %d).", ret);
+ num_read =
+ serial_read_blocking(serial, buf, 4, serial_timeout(serial, 4));
+ if (num_read < 0) {
+ sr_err("Getting ID reply failed (%d).", num_read);
return NULL;
}
if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4)) {
- sr_err("Invalid reply (expected '1SLO' or '1ALS', got "
- "'%c%c%c%c').", buf[0], buf[1], buf[2], buf[3]);
+ GString *id = sr_hexdump_new((uint8_t *)buf, num_read);
+
+ sr_err("Invalid ID reply (got %s).", id->str);
+
+ sr_hexdump_free(id);
return NULL;
+ } else {
+ sr_dbg("Successful detection, got '%c%c%c%c' (0x%02x 0x%02x 0x%02x 0x%02x).",
+ buf[0], buf[1], buf[2], buf[3],
+ buf[0], buf[1], buf[2], buf[3]);
}
- /* Definitely using the OLS protocol, check if it supports
- * the metadata command.
+ /*
+ * Create common data structures (sdi, devc) here in the common
+ * code path. These further get filled in either from metadata
+ * which is gathered from the device, or from open coded generic
+ * fallback data which is kept in the driver source code.
*/
- send_shortcommand(serial, CMD_METADATA);
-
- /* Wait 10ms for a response. */
- g_usleep(10000);
+ sdi = g_malloc0(sizeof(*sdi));
+ sdi->status = SR_ST_INACTIVE;
+ sdi->inst_type = SR_INST_SERIAL;
+ sdi->conn = serial;
+ sdi->connection_id = g_strdup(serial->port);
+ devc = g_malloc0(sizeof(*devc));
+ sdi->priv = devc;
+ devc->trigger_at_smpl = OLS_NO_TRIGGER;
+ devc->channel_names = sr_parse_probe_names(probe_names,
+ ols_channel_names, ARRAY_SIZE(ols_channel_names),
+ ARRAY_SIZE(ols_channel_names), &ch_max);
- if (sp_input_waiting(serial->data) != 0) {
+ /*
+ * Definitely using the OLS protocol, check if it supports
+ * the metadata command. Otherwise assign generic values.
+ * Create as many sigrok channels as was determined when
+ * the device was probed.
+ */
+ send_shortcommand(serial, CMD_METADATA);
+ g_usleep(RESPONSE_DELAY_US);
+ if (serial_has_receive_data(serial) != 0) {
/* Got metadata. */
- sdi = get_metadata(serial);
- devc = sdi->priv;
+ (void)ols_get_metadata(sdi);
} else {
- /* Not an OLS -- some other board that uses the sump protocol. */
+ /* Not an OLS -- some other board using the SUMP protocol. */
sr_info("Device does not support metadata.");
- sdi = g_malloc0(sizeof(struct sr_dev_inst));
- sdi->status = SR_ST_INACTIVE;
sdi->vendor = g_strdup("Sump");
sdi->model = g_strdup("Logic Analyzer");
sdi->version = g_strdup("v1.0");
- sdi->driver = di;
- for (i = 0; i < 32; i++)
- sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
- ols_channel_names[i]);
- devc = ols_dev_new();
- sdi->priv = devc;
+ devc->max_channels = ch_max;
+ }
+ if (devc->max_channels && ch_max > devc->max_channels)
+ ch_max = devc->max_channels;
+ for (i = 0; i < ch_max; i++) {
+ sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
+ devc->channel_names[i]);
}
/* Configure samplerate and divider. */
if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
- sr_dbg("Failed to set default samplerate (%"PRIu64").",
- DEFAULT_SAMPLERATE);
- sdi->inst_type = SR_INST_SERIAL;
- sdi->conn = serial;
-
- drvc->instances = g_slist_append(drvc->instances, sdi);
- devices = g_slist_append(devices, sdi);
+ sr_dbg("Failed to set default samplerate (%" PRIu64 ").",
+ DEFAULT_SAMPLERATE);
serial_close(serial);
- return devices;
-}
-
-static GSList *dev_list(const struct sr_dev_driver *di)
-{
- return ((struct drv_context *)(di->priv))->instances;
-}
-
-static int cleanup(const struct sr_dev_driver *di)
-{
- return std_dev_clear(di, NULL);
+ return std_scan_complete(di, g_slist_append(NULL, sdi));
}
-static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
- const struct sr_channel_group *cg)
+static int config_get(uint32_t key, GVariant **data,
+ const struct sr_dev_inst *sdi,
+ const struct sr_channel_group *cg)
{
struct dev_context *devc;
return SR_ERR_ARG;
devc = sdi->priv;
+
switch (key) {
+ case SR_CONF_CONN:
+ if (!sdi->conn || !sdi->connection_id)
+ return SR_ERR_NA;
+ *data = g_variant_new_string(sdi->connection_id);
+ break;
case SR_CONF_SAMPLERATE:
*data = g_variant_new_uint64(devc->cur_samplerate);
break;
*data = g_variant_new_uint64(devc->limit_samples);
break;
case SR_CONF_PATTERN_MODE:
- if (devc->flag_reg & FLAG_EXTERNAL_TEST_MODE)
+ if (devc->capture_flags & CAPTURE_FLAG_EXTERNAL_TEST_MODE)
*data = g_variant_new_string(STR_PATTERN_EXTERNAL);
- else if (devc->flag_reg & FLAG_INTERNAL_TEST_MODE)
+ else if (devc->capture_flags & CAPTURE_FLAG_INTERNAL_TEST_MODE)
*data = g_variant_new_string(STR_PATTERN_INTERNAL);
else
*data = g_variant_new_string(STR_PATTERN_NONE);
break;
case SR_CONF_RLE:
- *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
+ *data = g_variant_new_boolean(
+ devc->capture_flags & CAPTURE_FLAG_RLE ? TRUE : FALSE);
+ break;
+ case SR_CONF_EXTERNAL_CLOCK:
+ *data = g_variant_new_boolean(
+ devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL
+ ? TRUE : FALSE);
+ break;
+ case SR_CONF_CLOCK_EDGE:
+ *data = g_variant_new_string(external_clock_edges[
+ devc->capture_flags & CAPTURE_FLAG_INVERT_EXT_CLOCK
+ ? 1 : 0]);
break;
default:
return SR_ERR_NA;
return SR_OK;
}
-static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
- const struct sr_channel_group *cg)
+static int config_set(uint32_t key, GVariant *data,
+ const struct sr_dev_inst *sdi,
+ const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint16_t flag;
uint64_t tmp_u64;
- int ret;
const char *stropt;
(void)cg;
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR_DEV_CLOSED;
-
devc = sdi->priv;
switch (key) {
tmp_u64 = g_variant_get_uint64(data);
if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
return SR_ERR_SAMPLERATE;
- ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
- break;
+ return ols_set_samplerate(sdi, g_variant_get_uint64(data));
case SR_CONF_LIMIT_SAMPLES:
tmp_u64 = g_variant_get_uint64(data);
if (tmp_u64 < MIN_NUM_SAMPLES)
return SR_ERR;
devc->limit_samples = tmp_u64;
- ret = SR_OK;
break;
case SR_CONF_CAPTURE_RATIO:
devc->capture_ratio = g_variant_get_uint64(data);
- if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
- devc->capture_ratio = 0;
- ret = SR_ERR;
- } else
- ret = SR_OK;
break;
case SR_CONF_EXTERNAL_CLOCK:
if (g_variant_get_boolean(data)) {
sr_info("Enabling external clock.");
- devc->flag_reg |= FLAG_CLOCK_EXTERNAL;
+ devc->capture_flags |= CAPTURE_FLAG_CLOCK_EXTERNAL;
} else {
sr_info("Disabled external clock.");
- devc->flag_reg &= ~FLAG_CLOCK_EXTERNAL;
+ devc->capture_flags &= ~CAPTURE_FLAG_CLOCK_EXTERNAL;
+ }
+ break;
+ case SR_CONF_CLOCK_EDGE:
+ stropt = g_variant_get_string(data, NULL);
+ if (!strcmp(stropt, external_clock_edges[1])) {
+ sr_info("Triggering on falling edge of external clock.");
+ devc->capture_flags |= CAPTURE_FLAG_INVERT_EXT_CLOCK;
+ } else {
+ sr_info("Triggering on rising edge of external clock.");
+ devc->capture_flags &= ~CAPTURE_FLAG_INVERT_EXT_CLOCK;
}
- ret = SR_OK;
break;
case SR_CONF_PATTERN_MODE:
stropt = g_variant_get_string(data, NULL);
- ret = SR_OK;
- flag = 0xffff;
if (!strcmp(stropt, STR_PATTERN_NONE)) {
sr_info("Disabling test modes.");
flag = 0x0000;
- }else if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
+ } else if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
sr_info("Enabling internal test mode.");
- flag = FLAG_INTERNAL_TEST_MODE;
+ flag = CAPTURE_FLAG_INTERNAL_TEST_MODE;
} else if (!strcmp(stropt, STR_PATTERN_EXTERNAL)) {
sr_info("Enabling external test mode.");
- flag = FLAG_EXTERNAL_TEST_MODE;
+ flag = CAPTURE_FLAG_EXTERNAL_TEST_MODE;
} else {
- ret = SR_ERR;
- }
- if (flag != 0xffff) {
- devc->flag_reg &= ~(FLAG_INTERNAL_TEST_MODE | FLAG_EXTERNAL_TEST_MODE);
- devc->flag_reg |= flag;
+ return SR_ERR;
}
+ devc->capture_flags &= ~CAPTURE_FLAG_INTERNAL_TEST_MODE;
+ devc->capture_flags &= ~CAPTURE_FLAG_EXTERNAL_TEST_MODE;
+ devc->capture_flags |= flag;
break;
case SR_CONF_SWAP:
if (g_variant_get_boolean(data)) {
sr_info("Enabling channel swapping.");
- devc->flag_reg |= FLAG_SWAP_CHANNELS;
+ devc->capture_flags |= CAPTURE_FLAG_SWAP_CHANNELS;
} else {
sr_info("Disabling channel swapping.");
- devc->flag_reg &= ~FLAG_SWAP_CHANNELS;
+ devc->capture_flags &= ~CAPTURE_FLAG_SWAP_CHANNELS;
}
- ret = SR_OK;
break;
-
case SR_CONF_RLE:
if (g_variant_get_boolean(data)) {
sr_info("Enabling RLE.");
- devc->flag_reg |= FLAG_RLE;
+ devc->capture_flags |= CAPTURE_FLAG_RLE;
} else {
sr_info("Disabling RLE.");
- devc->flag_reg &= ~FLAG_RLE;
+ devc->capture_flags &= ~CAPTURE_FLAG_RLE;
}
- ret = SR_OK;
break;
default:
- ret = SR_ERR_NA;
+ return SR_ERR_NA;
}
- return ret;
+ return SR_OK;
}
-static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
- const struct sr_channel_group *cg)
+static int config_list(uint32_t key, GVariant **data,
+ const struct sr_dev_inst *sdi,
+ const struct sr_channel_group *cg)
{
struct dev_context *devc;
- GVariant *gvar, *grange[2];
- GVariantBuilder gvb;
int num_ols_changrp, i;
- (void)cg;
-
switch (key) {
case SR_CONF_SCAN_OPTIONS:
- *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
- scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
- break;
case SR_CONF_DEVICE_OPTIONS:
- if (!sdi)
- *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
- drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
- else
- *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
- devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
- break;
+ return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts,
+ devopts);
case SR_CONF_SAMPLERATE:
- g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
- gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
- ARRAY_SIZE(samplerates), sizeof(uint64_t));
- g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
- *data = g_variant_builder_end(&gvb);
+ *data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
break;
case SR_CONF_TRIGGER_MATCH:
- *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
- trigger_matches, ARRAY_SIZE(trigger_matches),
- sizeof(int32_t));
+ *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
+ break;
+ case SR_CONF_CLOCK_EDGE:
+ *data = std_gvar_array_str(ARRAY_AND_SIZE(external_clock_edges));
break;
case SR_CONF_PATTERN_MODE:
- *data = g_variant_new_strv(patterns, ARRAY_SIZE(patterns));
+ *data = g_variant_new_strv(ARRAY_AND_SIZE(patterns));
break;
case SR_CONF_LIMIT_SAMPLES:
if (!sdi)
return SR_ERR_ARG;
devc = sdi->priv;
- if (devc->flag_reg & FLAG_RLE)
- return SR_ERR_NA;
if (devc->max_samples == 0)
/* Device didn't specify sample memory size in metadata. */
return SR_ERR_NA;
* Channel groups are turned off if no channels in that group are
* enabled, making more room for samples for the enabled group.
*/
- ols_channel_mask(sdi);
+ uint32_t channel_mask = ols_channel_mask(sdi);
num_ols_changrp = 0;
for (i = 0; i < 4; i++) {
- if (devc->channel_mask & (0xff << (i * 8)))
+ if (channel_mask & (0xff << (i * 8)))
num_ols_changrp++;
}
- grange[0] = g_variant_new_uint64(MIN_NUM_SAMPLES);
- if (num_ols_changrp)
- grange[1] = g_variant_new_uint64(devc->max_samples / num_ols_changrp);
- else
- grange[1] = g_variant_new_uint64(MIN_NUM_SAMPLES);
- *data = g_variant_new_tuple(grange, 2);
+
+ *data = std_gvar_tuple_u64(MIN_NUM_SAMPLES, (num_ols_changrp)
+ ? devc->max_samples / num_ols_changrp : MIN_NUM_SAMPLES);
break;
default:
return SR_ERR_NA;
return SR_OK;
}
-static int set_trigger(const struct sr_dev_inst *sdi, int stage)
-{
- struct dev_context *devc;
- struct sr_serial_dev_inst *serial;
- uint8_t cmd, arg[4];
-
- devc = sdi->priv;
- serial = sdi->conn;
-
- cmd = CMD_SET_TRIGGER_MASK + stage * 4;
- arg[0] = devc->trigger_mask[stage] & 0xff;
- arg[1] = (devc->trigger_mask[stage] >> 8) & 0xff;
- arg[2] = (devc->trigger_mask[stage] >> 16) & 0xff;
- arg[3] = (devc->trigger_mask[stage] >> 24) & 0xff;
- if (send_longcommand(serial, cmd, arg) != SR_OK)
- return SR_ERR;
-
- cmd = CMD_SET_TRIGGER_VALUE + stage * 4;
- arg[0] = devc->trigger_value[stage] & 0xff;
- arg[1] = (devc->trigger_value[stage] >> 8) & 0xff;
- arg[2] = (devc->trigger_value[stage] >> 16) & 0xff;
- arg[3] = (devc->trigger_value[stage] >> 24) & 0xff;
- if (send_longcommand(serial, cmd, arg) != SR_OK)
- return SR_ERR;
-
- cmd = CMD_SET_TRIGGER_CONFIG + stage * 4;
- arg[0] = arg[1] = arg[3] = 0x00;
- arg[2] = stage;
- if (stage == devc->num_stages)
- /* Last stage, fire when this one matches. */
- arg[3] |= TRIGGER_START;
- if (send_longcommand(serial, cmd, arg) != SR_OK)
- return SR_ERR;
-
- return SR_OK;
-}
-
-static int dev_acquisition_start(const struct sr_dev_inst *sdi,
- void *cb_data)
+static int dev_acquisition_start(const struct sr_dev_inst *sdi)
{
+ int ret;
struct dev_context *devc;
struct sr_serial_dev_inst *serial;
- uint16_t samplecount, readcount, delaycount;
- uint8_t ols_changrp_mask, arg[4];
- int num_ols_changrp;
- int ret, i;
-
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR_DEV_CLOSED;
devc = sdi->priv;
serial = sdi->conn;
- ols_channel_mask(sdi);
-
- num_ols_changrp = 0;
- ols_changrp_mask = 0;
- for (i = 0; i < 4; i++) {
- if (devc->channel_mask & (0xff << (i * 8))) {
- ols_changrp_mask |= (1 << i);
- num_ols_changrp++;
- }
- }
-
- /*
- * Limit readcount to prevent reading past the end of the hardware
- * buffer.
- */
- samplecount = MIN(devc->max_samples / num_ols_changrp, devc->limit_samples);
- readcount = samplecount / 4;
-
- /* Rather read too many samples than too few. */
- if (samplecount % 4 != 0)
- readcount++;
-
- /* Basic triggers. */
- if (ols_convert_trigger(sdi) != SR_OK) {
- sr_err("Failed to configure channels.");
- return SR_ERR;
- }
- if (devc->num_stages > 0) {
- delaycount = readcount * (1 - devc->capture_ratio / 100.0);
- devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
- for (i = 0; i <= devc->num_stages; i++) {
- sr_dbg("Setting OLS stage %d trigger.", i);
- if ((ret = set_trigger(sdi, i)) != SR_OK)
- return ret;
- }
- } else {
- /* No triggers configured, force trigger on first stage. */
- sr_dbg("Forcing trigger at stage 0.");
- if ((ret = set_trigger(sdi, 0)) != SR_OK)
- return ret;
- delaycount = readcount;
- }
-
- /* Samplerate. */
- sr_dbg("Setting samplerate to %" PRIu64 "Hz (divider %u)",
- devc->cur_samplerate, devc->cur_samplerate_divider);
- arg[0] = devc->cur_samplerate_divider & 0xff;
- arg[1] = (devc->cur_samplerate_divider & 0xff00) >> 8;
- arg[2] = (devc->cur_samplerate_divider & 0xff0000) >> 16;
- arg[3] = 0x00;
- if (send_longcommand(serial, CMD_SET_DIVIDER, arg) != SR_OK)
- return SR_ERR;
-
- /* Send sample limit and pre/post-trigger capture ratio. */
- sr_dbg("Setting sample limit %d, trigger point at %d",
- (readcount - 1) * 4, (delaycount - 1) * 4);
- arg[0] = ((readcount - 1) & 0xff);
- arg[1] = ((readcount - 1) & 0xff00) >> 8;
- arg[2] = ((delaycount - 1) & 0xff);
- arg[3] = ((delaycount - 1) & 0xff00) >> 8;
- if (send_longcommand(serial, CMD_CAPTURE_SIZE, arg) != SR_OK)
- return SR_ERR;
-
- /* Flag register. */
- sr_dbg("Setting intpat %s, extpat %s, RLE %s, noise_filter %s, demux %s",
- devc->flag_reg & FLAG_INTERNAL_TEST_MODE ? "on": "off",
- devc->flag_reg & FLAG_EXTERNAL_TEST_MODE ? "on": "off",
- devc->flag_reg & FLAG_RLE ? "on" : "off",
- devc->flag_reg & FLAG_FILTER ? "on": "off",
- devc->flag_reg & FLAG_DEMUX ? "on" : "off");
- /*
- * Enable/disable OLS channel groups in the flag register according
- * to the channel mask. 1 means "disable channel".
- */
- devc->flag_reg |= ~(ols_changrp_mask << 2) & 0x3c;
- arg[0] = devc->flag_reg & 0xff;
- arg[1] = devc->flag_reg >> 8;
- arg[2] = arg[3] = 0x00;
- if (send_longcommand(serial, CMD_SET_FLAGS, arg) != SR_OK)
- return SR_ERR;
+ ret = ols_prepare_acquisition(sdi);
+ if (ret != SR_OK)
+ return ret;
/* Start acquisition on the device. */
- if (send_shortcommand(serial, CMD_RUN) != SR_OK)
+ if (send_shortcommand(serial, CMD_ARM_BASIC_TRIGGER) != SR_OK)
return SR_ERR;
/* Reset all operational states. */
devc->cnt_bytes = devc->cnt_samples = devc->cnt_samples_rle = 0;
memset(devc->sample, 0, 4);
- /* Send header packet to the session bus. */
- std_session_send_df_header(cb_data, LOG_PREFIX);
-
- serial_source_add(sdi->session, serial, G_IO_IN, -1,
- ols_receive_data, cb_data);
+ std_session_send_df_header(sdi);
- return SR_OK;
+ /* If the device stops sending for longer than it takes to send a byte,
+ * that means it's finished. But wait at least 100 ms to be safe.
+ */
+ return serial_source_add(sdi->session, serial, G_IO_IN, 100,
+ ols_receive_data, (struct sr_dev_inst *)sdi);
}
-static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
+static int dev_acquisition_stop(struct sr_dev_inst *sdi)
{
- (void)cb_data;
-
abort_acquisition(sdi);
return SR_OK;
}
-SR_PRIV struct sr_dev_driver ols_driver_info = {
+static struct sr_dev_driver ols_driver_info = {
.name = "ols",
- .longname = "Openbench Logic Sniffer",
+ .longname = "Openbench Logic Sniffer & SUMP compatibles",
.api_version = 1,
- .init = init,
- .cleanup = cleanup,
+ .init = std_init,
+ .cleanup = std_cleanup,
.scan = scan,
- .dev_list = dev_list,
- .dev_clear = NULL,
+ .dev_list = std_dev_list,
+ .dev_clear = std_dev_clear,
.config_get = config_get,
.config_set = config_set,
.config_list = config_list,
.dev_close = std_serial_dev_close,
.dev_acquisition_start = dev_acquisition_start,
.dev_acquisition_stop = dev_acquisition_stop,
- .priv = NULL,
+ .context = NULL,
};
+SR_REGISTER_DEV_DRIVER(ols_driver_info);