asix-sigma: download sample memory in multiple receive calls
The previous implementation ran the complete sample memory retrieval in a single call to the receive callback. Which in combination with slow USB communication and deep memory could block application logic for rather long periods of time. Rephrase the download_capture() routine such that it can spread its workload across multiple invocations. Run the acquisition stop and resource allocation for the download, the interpretation of a set of DRAM lines, and the resource cleanup, as needed. And keep calling the download routine until completion of the interpretation of the sample memory region of interest. The workload size per invocation may need more adjustment. The previous implementation could stall UI progress for some 20-30s. This change lets users perceive UI progress while sample memory gets retrieved and interpreted. This resolves bug #1005.
This commit is contained in:
parent
914f8160e7
commit
debe1ff66d
|
@ -1494,6 +1494,7 @@ static void free_sample_buffer(struct dev_context *devc)
|
||||||
{
|
{
|
||||||
g_free(devc->interp.fetch.rcvd_lines);
|
g_free(devc->interp.fetch.rcvd_lines);
|
||||||
devc->interp.fetch.rcvd_lines = NULL;
|
devc->interp.fetch.rcvd_lines = NULL;
|
||||||
|
devc->interp.fetch.lines_per_read = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1870,66 +1871,93 @@ static int download_capture(struct sr_dev_inst *sdi)
|
||||||
uint32_t stoppos, triggerpos;
|
uint32_t stoppos, triggerpos;
|
||||||
uint8_t modestatus;
|
uint8_t modestatus;
|
||||||
int ret;
|
int ret;
|
||||||
|
size_t chunks_per_receive_call;
|
||||||
|
|
||||||
devc = sdi->priv;
|
devc = sdi->priv;
|
||||||
interp = &devc->interp;
|
interp = &devc->interp;
|
||||||
|
|
||||||
sr_info("Downloading sample data.");
|
|
||||||
devc->state = SIGMA_DOWNLOAD;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Check the mode register. Force stop the current acquisition
|
||||||
|
* if it has not yet terminated before. Will block until the
|
||||||
|
* acquisition stops, assuming that this won't take long. Should
|
||||||
|
* execute exactly once, then keep finding its condition met.
|
||||||
|
*
|
||||||
* Ask the hardware to stop data acquisition. Reception of the
|
* Ask the hardware to stop data acquisition. Reception of the
|
||||||
* FORCESTOP request makes the hardware "disable RLE" (store
|
* FORCESTOP request makes the hardware "disable RLE" (store
|
||||||
* clusters to DRAM regardless of whether pin state changes) and
|
* clusters to DRAM regardless of whether pin state changes) and
|
||||||
* raise the POSTTRIGGERED flag.
|
* raise the POSTTRIGGERED flag.
|
||||||
*
|
|
||||||
* Then switch the hardware from DRAM write (data acquisition)
|
|
||||||
* to DRAM read (sample memory download).
|
|
||||||
*/
|
*/
|
||||||
modestatus = WMR_FORCESTOP | WMR_SDRAMWRITEEN;
|
ret = sigma_get_register(devc, READ_MODE, &modestatus);
|
||||||
ret = sigma_set_register(devc, WRITE_MODE, modestatus);
|
if (ret != SR_OK) {
|
||||||
if (ret != SR_OK)
|
sr_err("Could not determine current device state.");
|
||||||
return ret;
|
return FALSE;
|
||||||
do {
|
}
|
||||||
ret = sigma_get_register(devc, READ_MODE, &modestatus);
|
if (!(modestatus & RMR_POSTTRIGGERED)) {
|
||||||
if (ret != SR_OK) {
|
sr_info("Downloading sample data.");
|
||||||
sr_err("Could not poll for post-trigger state.");
|
devc->state = SIGMA_DOWNLOAD;
|
||||||
|
|
||||||
|
modestatus = WMR_FORCESTOP | WMR_SDRAMWRITEEN;
|
||||||
|
ret = sigma_set_register(devc, WRITE_MODE, modestatus);
|
||||||
|
if (ret != SR_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
do {
|
||||||
} while (!(modestatus & RMR_POSTTRIGGERED));
|
ret = sigma_get_register(devc, READ_MODE, &modestatus);
|
||||||
ret = sigma_set_register(devc, WRITE_MODE, WMR_SDRAMREADEN);
|
if (ret != SR_OK) {
|
||||||
if (ret != SR_OK)
|
sr_err("Could not poll for post-trigger state.");
|
||||||
return ret;
|
return FALSE;
|
||||||
|
}
|
||||||
|
} while (!(modestatus & RMR_POSTTRIGGERED));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Switch the hardware from DRAM write (data acquisition) to
|
||||||
|
* DRAM read (sample memory download). Prepare resources for
|
||||||
|
* sample memory content retrieval. Should execute exactly once,
|
||||||
|
* then keep finding its condition met.
|
||||||
|
*
|
||||||
* Get the current positions (acquisition write pointer, and
|
* Get the current positions (acquisition write pointer, and
|
||||||
* trigger match location). With disabled triggers, use a value
|
* trigger match location). With disabled triggers, use a value
|
||||||
* for the location that will never match during interpretation.
|
* for the location that will never match during interpretation.
|
||||||
*/
|
|
||||||
ret = sigma_read_pos(devc, &stoppos, &triggerpos, &modestatus);
|
|
||||||
if (ret != SR_OK) {
|
|
||||||
sr_err("Could not query capture positions/state.");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!devc->use_triggers)
|
|
||||||
triggerpos = ~0;
|
|
||||||
if (!(modestatus & RMR_TRIGGERED))
|
|
||||||
triggerpos = ~0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine which area of the sample memory to retrieve,
|
* Determine which area of the sample memory to retrieve,
|
||||||
* allocate a receive buffer, and setup counters/pointers.
|
* allocate a receive buffer, and setup counters/pointers.
|
||||||
*/
|
*/
|
||||||
ret = alloc_sample_buffer(devc, stoppos, triggerpos, modestatus);
|
if (!interp->fetch.lines_per_read) {
|
||||||
if (ret != SR_OK)
|
ret = sigma_set_register(devc, WRITE_MODE, WMR_SDRAMREADEN);
|
||||||
return FALSE;
|
if (ret != SR_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
ret = alloc_submit_buffer(sdi);
|
ret = sigma_read_pos(devc, &stoppos, &triggerpos, &modestatus);
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK) {
|
||||||
return FALSE;
|
sr_err("Could not query capture positions/state.");
|
||||||
ret = setup_submit_limit(devc);
|
return FALSE;
|
||||||
if (ret != SR_OK)
|
}
|
||||||
return FALSE;
|
if (!devc->use_triggers)
|
||||||
|
triggerpos = ~0;
|
||||||
|
if (!(modestatus & RMR_TRIGGERED))
|
||||||
|
triggerpos = ~0;
|
||||||
|
|
||||||
|
ret = alloc_sample_buffer(devc, stoppos, triggerpos, modestatus);
|
||||||
|
if (ret != SR_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ret = alloc_submit_buffer(sdi);
|
||||||
|
if (ret != SR_OK)
|
||||||
|
return FALSE;
|
||||||
|
ret = setup_submit_limit(devc);
|
||||||
|
if (ret != SR_OK)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get another set of sample memory rows, and interpret its
|
||||||
|
* content. Will execute as many times as it takes to complete
|
||||||
|
* the memory region that the recent acquisition spans.
|
||||||
|
*
|
||||||
|
* The size of a receive call's workload and the main loop's
|
||||||
|
* receive call poll period determine the UI responsiveness and
|
||||||
|
* the overall transfer time for the sample memory content.
|
||||||
|
*/
|
||||||
|
chunks_per_receive_call = 50;
|
||||||
while (interp->fetch.lines_done < interp->fetch.lines_total) {
|
while (interp->fetch.lines_done < interp->fetch.lines_total) {
|
||||||
size_t dl_events_in_line;
|
size_t dl_events_in_line;
|
||||||
|
|
||||||
|
@ -1949,15 +1977,35 @@ static int download_capture(struct sr_dev_inst *sdi)
|
||||||
interp->fetch.curr_line++;
|
interp->fetch.curr_line++;
|
||||||
interp->fetch.lines_done++;
|
interp->fetch.lines_done++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Keep returning to application code for large data sets. */
|
||||||
|
if (!--chunks_per_receive_call) {
|
||||||
|
ret = flush_submit_buffer(devc);
|
||||||
|
if (ret != SR_OK)
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
flush_submit_buffer(devc);
|
|
||||||
free_submit_buffer(devc);
|
|
||||||
free_sample_buffer(devc);
|
|
||||||
|
|
||||||
std_session_send_df_end(sdi);
|
/*
|
||||||
|
* Release previously allocated resources, and adjust state when
|
||||||
|
* all of the sample memory was retrieved, and interpretation has
|
||||||
|
* completed. Should execute exactly once.
|
||||||
|
*/
|
||||||
|
if (interp->fetch.lines_done >= interp->fetch.lines_total) {
|
||||||
|
ret = flush_submit_buffer(devc);
|
||||||
|
if (ret != SR_OK)
|
||||||
|
return FALSE;
|
||||||
|
free_submit_buffer(devc);
|
||||||
|
free_sample_buffer(devc);
|
||||||
|
|
||||||
devc->state = SIGMA_IDLE;
|
ret = std_session_send_df_end(sdi);
|
||||||
sr_dev_acquisition_stop(sdi);
|
if (ret != SR_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
devc->state = SIGMA_IDLE;
|
||||||
|
sr_dev_acquisition_stop(sdi);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1994,12 +2042,15 @@ SR_PRIV int sigma_receive_data(int fd, int revents, void *cb_data)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the application has requested to stop the acquisition,
|
* When the application has requested to stop the acquisition,
|
||||||
* then immediately start downloading sample data. Otherwise
|
* then immediately start downloading sample data. Continue a
|
||||||
|
* previously initiated download until completion. Otherwise
|
||||||
* keep checking configured limits which will terminate the
|
* keep checking configured limits which will terminate the
|
||||||
* acquisition and initiate download.
|
* acquisition and initiate download.
|
||||||
*/
|
*/
|
||||||
if (devc->state == SIGMA_STOPPING)
|
if (devc->state == SIGMA_STOPPING)
|
||||||
return download_capture(sdi);
|
return download_capture(sdi);
|
||||||
|
if (devc->state == SIGMA_DOWNLOAD)
|
||||||
|
return download_capture(sdi);
|
||||||
if (devc->state == SIGMA_CAPTURE)
|
if (devc->state == SIGMA_CAPTURE)
|
||||||
return sigma_capture_mode(sdi);
|
return sigma_capture_mode(sdi);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue