SR_PRIV const size_t samplerates_count = ARRAY_SIZE(samplerates);
-static const char sigma_firmware_files[][24] = {
+static const char firmware_files[][24] = {
/* 50 MHz, supports 8 bit fractions */
"asix-sigma-50.fw",
/* 100 MHz */
int ret;
ret = ftdi_write_data(&devc->ftdic, (unsigned char *)buf, size);
- if (ret < 0) {
+ if (ret < 0)
sr_err("ftdi_write_data failed: %s",
ftdi_get_error_string(&devc->ftdic));
- } else if ((size_t) ret != size) {
+ else if ((size_t) ret != size)
sr_err("ftdi_write_data did not complete write.");
- }
return ret;
}
{
size_t i;
uint8_t buf[4096];
- int idx = 0;
+ int idx;
/* Send the startchunk. Index start with 1. */
- buf[0] = startchunk >> 8;
- buf[1] = startchunk & 0xff;
- sigma_write_register(WRITE_MEMROW, buf, 2, devc);
+ idx = 0;
+ buf[idx++] = startchunk >> 8;
+ buf[idx++] = startchunk & 0xff;
+ sigma_write_register(WRITE_MEMROW, buf, idx, devc);
/* Read the DRAM. */
+ idx = 0;
buf[idx++] = REG_DRAM_BLOCK;
buf[idx++] = REG_DRAM_WAIT_ACK;
return SR_OK;
}
-SR_PRIV void sigma_clear_helper(void *priv)
-{
- struct dev_context *devc;
-
- devc = priv;
-
- ftdi_deinit(&devc->ftdic);
-}
-
/*
* Configure the FPGA for bitbang mode.
* This sequence is documented in section 2. of the ASIX Sigma programming
static int sigma_fpga_init_la(struct dev_context *devc)
{
/* Initialize the logic analyzer mode. */
+ uint8_t mode_regval = WMR_SDRAMINIT;
uint8_t logic_mode_start[] = {
REG_ADDR_LOW | (READ_ID & 0xf),
REG_ADDR_HIGH | (READ_ID >> 4),
REG_READ_ADDR, /* Read scratch register. */
REG_ADDR_LOW | (WRITE_MODE & 0xf),
- REG_DATA_LOW | 0x0,
- REG_DATA_HIGH_WRITE | 0x8,
+ REG_DATA_LOW | (mode_regval & 0xf),
+ REG_DATA_HIGH_WRITE | (mode_regval >> 4),
};
uint8_t result[3];
unsigned char pins;
size_t buf_size;
const char *firmware;
- struct ftdi_context *ftdic;
/* Avoid downloading the same firmware multiple times. */
- firmware = sigma_firmware_files[firmware_idx];
+ firmware = firmware_files[firmware_idx];
if (devc->cur_firmware == firmware_idx) {
sr_info("Not uploading firmware file '%s' again.", firmware);
return SR_OK;
}
- /* Make sure it's an ASIX SIGMA. */
- ftdic = &devc->ftdic;
- ret = ftdi_usb_open_desc(ftdic, USB_VENDOR, USB_PRODUCT,
- USB_DESCRIPTION, NULL);
- if (ret < 0) {
- sr_err("ftdi_usb_open failed: %s",
- ftdi_get_error_string(ftdic));
- return 0;
- }
-
- ret = ftdi_set_bitmode(ftdic, 0xdf, BITMODE_BITBANG);
+ ret = ftdi_set_bitmode(&devc->ftdic, 0xdf, BITMODE_BITBANG);
if (ret < 0) {
sr_err("ftdi_set_bitmode failed: %s",
- ftdi_get_error_string(ftdic));
- return 0;
+ ftdi_get_error_string(&devc->ftdic));
+ return SR_ERR;
}
/* Four times the speed of sigmalogan - Works well. */
- ret = ftdi_set_baudrate(ftdic, 750 * 1000);
+ ret = ftdi_set_baudrate(&devc->ftdic, 750 * 1000);
if (ret < 0) {
sr_err("ftdi_set_baudrate failed: %s",
- ftdi_get_error_string(ftdic));
- return 0;
+ ftdi_get_error_string(&devc->ftdic));
+ return SR_ERR;
}
/* Initialize the FPGA for firmware upload. */
g_free(buf);
- ret = ftdi_set_bitmode(ftdic, 0x00, BITMODE_RESET);
+ ret = ftdi_set_bitmode(&devc->ftdic, 0x00, BITMODE_RESET);
if (ret < 0) {
sr_err("ftdi_set_bitmode failed: %s",
- ftdi_get_error_string(ftdic));
+ ftdi_get_error_string(&devc->ftdic));
return SR_ERR;
}
- ftdi_usb_purge_buffers(ftdic);
+ ftdi_usb_purge_buffers(&devc->ftdic);
/* Discard garbage. */
while (sigma_read(&pins, 1, devc) == 1)
struct drv_context *drvc;
size_t i;
int ret;
+ int num_channels;
devc = sdi->priv;
drvc = sdi->driver->context;
* firmware is required and higher rates might limit the set
* of available channels.
*/
+ num_channels = devc->num_channels;
if (samplerate <= SR_MHZ(50)) {
ret = upload_firmware(drvc->sr_ctx, 0, devc);
- devc->num_channels = 16;
+ num_channels = 16;
} else if (samplerate == SR_MHZ(100)) {
ret = upload_firmware(drvc->sr_ctx, 1, devc);
- devc->num_channels = 8;
+ num_channels = 8;
} else if (samplerate == SR_MHZ(200)) {
ret = upload_firmware(drvc->sr_ctx, 2, devc);
- devc->num_channels = 4;
+ num_channels = 4;
}
/*
* an "event" (memory organization internal to the device).
*/
if (ret == SR_OK) {
+ devc->num_channels = num_channels;
devc->cur_samplerate = samplerate;
- devc->period_ps = 1000000000000ULL / samplerate;
devc->samples_per_event = 16 / devc->num_channels;
devc->state.state = SIGMA_IDLE;
}
if (match->match == SR_TRIGGER_ONE) {
devc->trigger.simplevalue |= channelbit;
devc->trigger.simplemask |= channelbit;
- }
- else if (match->match == SR_TRIGGER_ZERO) {
+ } else if (match->match == SR_TRIGGER_ZERO) {
devc->trigger.simplevalue &= ~channelbit;
devc->trigger.simplemask |= channelbit;
- }
- else if (match->match == SR_TRIGGER_FALLING) {
+ } else if (match->match == SR_TRIGGER_FALLING) {
devc->trigger.fallingmask |= channelbit;
trigger_set++;
- }
- else if (match->match == SR_TRIGGER_RISING) {
+ } else if (match->match == SR_TRIGGER_RISING) {
devc->trigger.risingmask |= channelbit;
trigger_set++;
}
return SR_OK;
}
-
/* Software trigger to determine exact trigger position. */
static int get_trigger_offset(uint8_t *samples, uint16_t last_sample,
struct sigma_trigger *t)
samples[2 * idx + 1] = (data >> 8) & 0xff;
}
+/*
+ * Local wrapper around sr_session_send() calls. Make sure to not send
+ * more samples to the session's datafeed than what was requested by a
+ * previously configured (optional) sample count.
+ */
+static void sigma_session_send(struct sr_dev_inst *sdi,
+ struct sr_datafeed_packet *packet)
+{
+ struct dev_context *devc;
+ struct sr_datafeed_logic *logic;
+ uint64_t send_now;
+
+ devc = sdi->priv;
+ if (devc->limit_samples) {
+ logic = (void *)packet->payload;
+ send_now = logic->length / logic->unitsize;
+ if (devc->sent_samples + send_now > devc->limit_samples) {
+ send_now = devc->limit_samples - devc->sent_samples;
+ logic->length = send_now * logic->unitsize;
+ }
+ if (!send_now)
+ return;
+ devc->sent_samples += send_now;
+ }
+
+ sr_session_send(sdi, packet);
+}
+
/*
* This size translates to: event count (1K events per cluster), times
* the sample width (unitsize, 16bits per event), times the maximum
logic.data = samples;
/*
- * First of all, send Sigrok a copy of the last sample from
- * previous cluster as many times as needed to make up for
- * the differential characteristics of data we get from the
- * Sigma. Sigrok needs one sample of data per period.
- *
- * One DRAM cluster contains a timestamp and seven samples,
- * the units of timestamp are "devc->period_ps" , the first
- * sample in the cluster happens at the time of the timestamp
- * and the remaining samples happen at timestamp +1...+6 .
+ * If this cluster is not adjacent to the previously received
+ * cluster, then send the appropriate number of samples with the
+ * previous values to the sigrok session. This "decodes RLE".
*/
for (ts = 0; ts < tsdiff; ts++) {
i = ts % 1024;
if ((i == 1023) || (ts == tsdiff - 1)) {
logic.length = (i + 1) * logic.unitsize;
for (j = 0; j < devc->samples_per_event; j++)
- sr_session_send(sdi, &packet);
+ sigma_session_send(sdi, &packet);
}
}
trig_count = trigger_offset * devc->samples_per_event;
packet.type = SR_DF_LOGIC;
logic.length = trig_count * logic.unitsize;
- sr_session_send(sdi, &packet);
+ sigma_session_send(sdi, &packet);
send_ptr += trig_count * logic.unitsize;
send_count -= trig_count;
}
packet.type = SR_DF_LOGIC;
logic.length = send_count * logic.unitsize;
logic.data = send_ptr;
- sr_session_send(sdi, &packet);
+ sigma_session_send(sdi, &packet);
}
ss->lastsample = sample;
struct sr_dev_inst *sdi)
{
struct sigma_dram_cluster *dram_cluster;
- struct dev_context *devc = sdi->priv;
- unsigned int clusters_in_line =
- (events_in_line + (EVENTS_PER_CLUSTER - 1)) / EVENTS_PER_CLUSTER;
+ struct dev_context *devc;
+ unsigned int clusters_in_line;
unsigned int events_in_cluster;
unsigned int i;
- uint32_t trigger_cluster = ~0, triggered = 0;
+ uint32_t trigger_cluster, triggered;
+
+ devc = sdi->priv;
+ clusters_in_line = events_in_line;
+ clusters_in_line += EVENTS_PER_CLUSTER - 1;
+ clusters_in_line /= EVENTS_PER_CLUSTER;
+ trigger_cluster = ~0;
+ triggered = 0;
/* Check if trigger is in this chunk. */
if (trigger_event < (64 * 7)) {
static int download_capture(struct sr_dev_inst *sdi)
{
- struct dev_context *devc = sdi->priv;
const uint32_t chunks_per_read = 32;
+
+ struct dev_context *devc;
struct sigma_dram_line *dram_line;
int bufsz;
uint32_t stoppos, triggerpos;
uint8_t modestatus;
-
uint32_t i;
uint32_t dl_lines_total, dl_lines_curr, dl_lines_done;
- uint32_t dl_events_in_line = 64 * 7;
- uint32_t trg_line = ~0, trg_event = ~0;
+ uint32_t dl_first_line, dl_line;
+ uint32_t dl_events_in_line;
+ uint32_t trg_line, trg_event;
+
+ devc = sdi->priv;
+ dl_events_in_line = 64 * 7;
+ trg_line = ~0;
+ trg_event = ~0;
dram_line = g_try_malloc0(chunks_per_read * sizeof(*dram_line));
if (!dram_line)
return FALSE;
sr_info("Downloading sample data.");
+ devc->state.state = SIGMA_DOWNLOAD;
- /* Stop acquisition. */
- sigma_set_register(WRITE_MODE, 0x11, devc);
+ /*
+ * Ask the hardware to stop data acquisition. Reception of the
+ * FORCESTOP request makes the hardware "disable RLE" (store
+ * clusters to DRAM regardless of whether pin state changes) and
+ * raise the POSTTRIGGERED flag.
+ */
+ sigma_set_register(WRITE_MODE, WMR_FORCESTOP | WMR_SDRAMWRITEEN, devc);
+ do {
+ modestatus = sigma_get_register(READ_MODE, devc);
+ } while (!(modestatus & RMR_POSTTRIGGERED));
/* Set SDRAM Read Enable. */
- sigma_set_register(WRITE_MODE, 0x02, devc);
+ sigma_set_register(WRITE_MODE, WMR_SDRAMREADEN, devc);
/* Get the current position. */
sigma_read_pos(&stoppos, &triggerpos, devc);
/* Check if trigger has fired. */
modestatus = sigma_get_register(READ_MODE, devc);
- if (modestatus & 0x20) {
+ if (modestatus & RMR_TRIGGERED) {
trg_line = triggerpos >> 9;
trg_event = triggerpos & 0x1ff;
}
+ devc->sent_samples = 0;
+
/*
- * Determine how many 1024b "DRAM lines" do we need to read from the
- * Sigma so we have a complete set of samples. Note that the last
- * line can be only partial, containing less than 64 clusters.
+ * Determine how many "DRAM lines" of 1024 bytes each we need to
+ * retrieve from the Sigma hardware, so that we have a complete
+ * set of samples. Note that the last line need not contain 64
+ * clusters, it might be partially filled only.
+ *
+ * When RMR_ROUND is set, the circular buffer in DRAM has wrapped
+ * around. Since the status of the very next line is uncertain in
+ * that case, we skip it and start reading from the next line. The
+ * circular buffer has 32K lines (0x8000).
*/
dl_lines_total = (stoppos >> 9) + 1;
-
+ if (modestatus & RMR_ROUND) {
+ dl_first_line = dl_lines_total + 1;
+ dl_lines_total = 0x8000 - 2;
+ } else {
+ dl_first_line = 0;
+ }
dl_lines_done = 0;
-
while (dl_lines_total > dl_lines_done) {
/* We can download only up-to 32 DRAM lines in one go! */
- dl_lines_curr = MIN(chunks_per_read, dl_lines_total);
+ dl_lines_curr = MIN(chunks_per_read, dl_lines_total - dl_lines_done);
- bufsz = sigma_read_dram(dl_lines_done, dl_lines_curr,
+ dl_line = dl_first_line + dl_lines_done;
+ dl_line %= 0x8000;
+ bufsz = sigma_read_dram(dl_line, dl_lines_curr,
(uint8_t *)dram_line, devc);
/* TODO: Check bufsz. For now, just avoid compiler warnings. */
(void)bufsz;
dl_lines_done += dl_lines_curr;
}
+ g_free(dram_line);
std_session_send_df_end(sdi);
- sdi->driver->dev_acquisition_stop(sdi);
-
- g_free(dram_line);
+ devc->state.state = SIGMA_IDLE;
+ sr_dev_acquisition_stop(sdi);
return TRUE;
}
/*
- * Handle the Sigma when in CAPTURE mode. This function checks:
- * - Sampling time ended
- * - DRAM capacity overflow
- * This function triggers download of the samples from Sigma
- * in case either of the above conditions is true.
+ * Periodically check the Sigma status when in CAPTURE mode. This routine
+ * checks whether the configured sample count or sample time have passed,
+ * and will stop acquisition and download the acquired samples.
*/
static int sigma_capture_mode(struct sr_dev_inst *sdi)
{
- struct dev_context *devc = sdi->priv;
-
+ struct dev_context *devc;
uint64_t running_msec;
- struct timeval tv;
+ uint64_t current_time;
- uint32_t stoppos, triggerpos;
+ devc = sdi->priv;
- /* Check if the selected sampling duration passed. */
- gettimeofday(&tv, 0);
- running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 +
- (tv.tv_usec - devc->start_tv.tv_usec) / 1000;
+ /*
+ * Check if the selected sampling duration passed. Sample count
+ * limits are covered by this enforced timeout as well.
+ */
+ current_time = g_get_monotonic_time();
+ running_msec = (current_time - devc->start_time) / 1000;
if (running_msec >= devc->limit_msec)
return download_capture(sdi);
- /* Get the position in DRAM to which the FPGA is writing now. */
- sigma_read_pos(&stoppos, &triggerpos, devc);
- /* Test if DRAM is full and if so, download the data. */
- if ((stoppos >> 9) == 32767)
- return download_capture(sdi);
-
return TRUE;
}
if (devc->state.state == SIGMA_IDLE)
return TRUE;
+ /*
+ * When the application has requested to stop the acquisition,
+ * then immediately start downloading sample data. Otherwise
+ * keep checking configured limits which will terminate the
+ * acquisition and initiate download.
+ */
+ if (devc->state.state == SIGMA_STOPPING)
+ return download_capture(sdi);
if (devc->state.state == SIGMA_CAPTURE)
return sigma_capture_mode(sdi);