- if(!(sdi = get_sigrok_device_instance(device_instances, device_index)))
- return SIGROK_NOK;
-
- if(sdi->status != ST_ACTIVE)
- return SIGROK_NOK;
-
- /* reset again */
- if(send_longcommand(sdi->serial->fd, CMD_RESET, 0) != SIGROK_OK)
- return SIGROK_NOK;
-
- /* send flag register */
- data = flag_reg << 24;
- if(send_longcommand(sdi->serial->fd, CMD_SET_FLAGS, data) != SIGROK_OK)
- return SIGROK_NOK;
-
- /* send sample limit and pre/post-trigger capture ratio */
- data = limit_samples / 4 << 16;
- if(capture_ratio)
- data |= (limit_samples - (limit_samples / 100 * capture_ratio)) / 4;
- data = 0x00190019;
- if(send_longcommand(sdi->serial->fd, CMD_CAPTURE_SIZE, data) != SIGROK_OK)
- return SIGROK_NOK;
-
- /* trigger masks */
- if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_MASK_0, trigger_mask[0]) != SIGROK_OK)
- return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_MASK_1, trigger_mask[1]) != SIGROK_OK)
-// return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_MASK_2, trigger_mask[2]) != SIGROK_OK)
-// return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_MASK_3, trigger_mask[3]) != SIGROK_OK)
-// return SIGROK_NOK;
-
- if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_VALUE_0, trigger_value[0]) != SIGROK_OK)
- return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_VALUE_1, trigger_value[1]) != SIGROK_OK)
-// return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_VALUE_2, trigger_value[2]) != SIGROK_OK)
-// return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_VALUE_3, trigger_value[3]) != SIGROK_OK)
-// return SIGROK_NOK;
-
- /* trigger configuration */
- /* TODO: the start flag should only be on the last used stage I think... */
- if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_CONFIG_0, 0x00000008) != SIGROK_OK)
- return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_CONFIG_1, 0x00000000) != SIGROK_OK)
-// return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_CONFIG_2, 0x00000000) != SIGROK_OK)
-// return SIGROK_NOK;
-// if(send_longcommand(sdi->serial->fd, CMD_SET_TRIGGER_CONFIG_3, 0x00000000) != SIGROK_OK)
-// return SIGROK_NOK;
-
- set_configuration_samplerate(sdi, cur_samplerate);
-
- /* start acquisition on the device */
- if(send_shortcommand(sdi->serial->fd, CMD_RUN) != SIGROK_OK)
- return SIGROK_NOK;
-
- source_add(sdi->serial->fd, G_IO_IN, -1, receive_data, session_device_id);
-
- /* send header packet to the session bus */
- packet = g_malloc(sizeof(struct datafeed_packet));
- header = g_malloc(sizeof(struct datafeed_header));
- if(!packet || !header)
- return SIGROK_NOK;
- packet->type = DF_HEADER;
- packet->length = sizeof(struct datafeed_header);
- packet->payload = (unsigned char *) header;
+ ols = sdi->priv;
+
+ if (sdi->status != SR_ST_ACTIVE)
+ return SR_ERR;
+
+ /*
+ * Enable/disable channel groups in the flag register according to the
+ * probe mask. Calculate this here, because num_channels is needed
+ * to limit readcount.
+ */
+ changrp_mask = 0;
+ num_channels = 0;
+ for (i = 0; i < 4; i++) {
+ if (ols->probe_mask & (0xff << (i * 8))) {
+ changrp_mask |= (1 << i);
+ num_channels++;
+ }
+ }
+
+ /*
+ * Limit readcount to prevent reading past the end of the hardware
+ * buffer.
+ */
+ readcount = MIN(ols->max_samples / num_channels, ols->limit_samples) / 4;
+
+ memset(trigger_config, 0, 16);
+ trigger_config[ols->num_stages - 1] |= 0x08;
+ if (ols->trigger_mask[0]) {
+ delaycount = readcount * (1 - ols->capture_ratio / 100.0);
+ ols->trigger_at = (readcount - delaycount) * 4 - ols->num_stages;
+
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_0,
+ reverse32(ols->trigger_mask[0])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_0,
+ reverse32(ols->trigger_value[0])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
+ trigger_config[0]) != SR_OK)
+ return SR_ERR;
+
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_1,
+ reverse32(ols->trigger_mask[1])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_1,
+ reverse32(ols->trigger_value[1])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_1,
+ trigger_config[1]) != SR_OK)
+ return SR_ERR;
+
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_2,
+ reverse32(ols->trigger_mask[2])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_2,
+ reverse32(ols->trigger_value[2])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_2,
+ trigger_config[2]) != SR_OK)
+ return SR_ERR;
+
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_3,
+ reverse32(ols->trigger_mask[3])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_3,
+ reverse32(ols->trigger_value[3])) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_3,
+ trigger_config[3]) != SR_OK)
+ return SR_ERR;
+ } else {
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_0,
+ ols->trigger_mask[0]) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_0,
+ ols->trigger_value[0]) != SR_OK)
+ return SR_ERR;
+ if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
+ 0x00000008) != SR_OK)
+ return SR_ERR;
+ delaycount = readcount;
+ }
+
+ sr_info("ols: setting samplerate to %" PRIu64 " Hz (divider %u, "
+ "demux %s)", ols->cur_samplerate, ols->cur_samplerate_divider,
+ ols->flag_reg & FLAG_DEMUX ? "on" : "off");
+ if (send_longcommand(ols->serial->fd, CMD_SET_DIVIDER,
+ reverse32(ols->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(ols->serial->fd, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
+ return SR_ERR;
+
+ /* The flag register wants them here, and 1 means "disable channel". */
+ ols->flag_reg |= ~(changrp_mask << 2) & 0x3c;
+ ols->flag_reg |= FLAG_FILTER;
+ ols->rle_count = 0;
+ data = (ols->flag_reg << 24) | ((ols->flag_reg << 8) & 0xff0000);
+ if (send_longcommand(ols->serial->fd, CMD_SET_FLAGS, data) != SR_OK)
+ return SR_ERR;
+
+ /* Start acquisition on the device. */
+ if (send_shortcommand(ols->serial->fd, CMD_RUN) != SR_OK)
+ return SR_ERR;
+
+ sr_source_add(ols->serial->fd, G_IO_IN, -1, receive_data,
+ session_data);
+
+ if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
+ sr_err("ols: %s: packet malloc failed", __func__);
+ return SR_ERR_MALLOC;
+ }
+
+ if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
+ sr_err("ols: %s: header malloc failed", __func__);
+ g_free(packet);
+ return SR_ERR_MALLOC;
+ }
+
+ /* Send header packet to the session bus. */
+ packet->type = SR_DF_HEADER;
+ packet->payload = (unsigned char *)header;