dslogic: Fixed buffer size calculation

This commit is contained in:
Joel Holdsworth 2017-06-15 16:21:44 -06:00 committed by Uwe Hermann
parent 6dfa2c39bf
commit 03a0002ed4
1 changed files with 35 additions and 40 deletions

View File

@ -67,7 +67,8 @@
#define DS_MODE_EXT_TEST (1 << 14) #define DS_MODE_EXT_TEST (1 << 14)
#define DS_MODE_INT_TEST (1 << 15) #define DS_MODE_INT_TEST (1 << 15)
#define DSLOGIC_ATOMIC_SAMPLES (1 << 6) #define DSLOGIC_ATOMIC_SAMPLES (sizeof(uint64_t) * 8)
#define DSLOGIC_ATOMIC_BYTES sizeof(uint64_t)
/* /*
* The FPGA is configured with TLV tuples. Length is specified as the * The FPGA is configured with TLV tuples. Length is specified as the
@ -873,54 +874,60 @@ static int receive_data(int fd, int revents, void *cb_data)
return TRUE; return TRUE;
} }
static unsigned int to_bytes_per_ms(unsigned int samplerate) static size_t to_bytes_per_ms(const struct sr_dev_inst *sdi)
{ {
if (samplerate > SR_MHZ(100)) const struct dev_context *const devc = sdi->priv;
return SR_MHZ(100) / 1000 * 2; const size_t ch_count = enabled_channel_count(sdi);
return samplerate / 1000 * 2;
if (devc->continuous_mode)
return (devc->cur_samplerate * ch_count) / (1000 * 8);
/* If we're in buffered mode, the transfer rate is not so important,
* but we expect to get at least 10% of the high-speed USB bandwidth.
*/
return 35000000 / (1000 * 10);
} }
static size_t get_buffer_size(struct dev_context *devc) static size_t get_buffer_size(const struct sr_dev_inst *sdi)
{ {
/* /*
* The buffer should be large enough to hold 10ms of data and * The buffer should be large enough to hold 10ms of data and
* a multiple of 512. * a multiple of the size of a data atom.
*/ */
const size_t s = 10 * to_bytes_per_ms(devc->cur_samplerate); const size_t block_size = enabled_channel_count(sdi) * 512;
return (s + 511) & ~511; const size_t s = 10 * to_bytes_per_ms(sdi);
return ((s + block_size - 1) / block_size) * block_size;
} }
static int get_number_of_transfers(struct dev_context *devc) static unsigned int get_number_of_transfers(const struct sr_dev_inst *sdi)
{ {
/* Total buffer size should be able to hold about 100ms of data. */ /* Total buffer size should be able to hold about 100ms of data. */
const unsigned int n = (100 * to_bytes_per_ms(devc->cur_samplerate)) / const unsigned int s = get_buffer_size(sdi);
get_buffer_size(devc); const unsigned int n = (100 * to_bytes_per_ms(sdi) + s - 1) / s;
sr_info("New calculation: %d", n); return (n > NUM_SIMUL_TRANSFERS) ? NUM_SIMUL_TRANSFERS : n;
if (n > NUM_SIMUL_TRANSFERS)
return NUM_SIMUL_TRANSFERS;
return n;
} }
static unsigned int get_timeout(struct dev_context *devc) static unsigned int get_timeout(const struct sr_dev_inst *sdi)
{ {
const size_t total_size = get_buffer_size(devc) * const size_t total_size = get_buffer_size(sdi) *
get_number_of_transfers(devc); get_number_of_transfers(sdi);
const unsigned int timeout = const unsigned int timeout = total_size / to_bytes_per_ms(sdi);
total_size / to_bytes_per_ms(devc->cur_samplerate);
return timeout + timeout / 4; /* Leave a headroom of 25% percent. */ return timeout + timeout / 4; /* Leave a headroom of 25% percent. */
} }
static int start_transfers(const struct sr_dev_inst *sdi) static int start_transfers(const struct sr_dev_inst *sdi)
{ {
const size_t size = get_buffer_size(sdi);
const unsigned int num_transfers = get_number_of_transfers(sdi);
const unsigned int timeout = get_timeout(sdi);
struct dev_context *devc; struct dev_context *devc;
struct sr_usb_dev_inst *usb; struct sr_usb_dev_inst *usb;
struct libusb_transfer *transfer; struct libusb_transfer *transfer;
unsigned int i, num_transfers; unsigned int i;
int timeout, ret; int ret;
unsigned char *buf; unsigned char *buf;
size_t size;
devc = sdi->priv; devc = sdi->priv;
usb = sdi->conn; usb = sdi->conn;
@ -928,17 +935,6 @@ static int start_transfers(const struct sr_dev_inst *sdi)
devc->sent_samples = 0; devc->sent_samples = 0;
devc->acq_aborted = FALSE; devc->acq_aborted = FALSE;
devc->empty_transfer_count = 0; devc->empty_transfer_count = 0;
num_transfers = get_number_of_transfers(devc);
if (devc->cur_samplerate == SR_MHZ(100))
num_transfers = 16;
else if (devc->cur_samplerate == SR_MHZ(200))
num_transfers = 8;
else if (devc->cur_samplerate == SR_MHZ(400))
num_transfers = 4;
size = get_buffer_size(devc);
devc->submitted_transfers = 0; devc->submitted_transfers = 0;
g_free(devc->transfers); g_free(devc->transfers);
@ -948,7 +944,6 @@ static int start_transfers(const struct sr_dev_inst *sdi)
return SR_ERR_MALLOC; return SR_ERR_MALLOC;
} }
timeout = get_timeout(devc);
devc->num_transfers = num_transfers; devc->num_transfers = num_transfers;
for (i = 0; i < num_transfers; i++) { for (i = 0; i < num_transfers; i++) {
if (!(buf = g_try_malloc(size))) { if (!(buf = g_try_malloc(size))) {
@ -1006,13 +1001,14 @@ static void LIBUSB_CALL trigger_receive(struct libusb_transfer *transfer)
SR_PRIV int dslogic_acquisition_start(const struct sr_dev_inst *sdi) SR_PRIV int dslogic_acquisition_start(const struct sr_dev_inst *sdi)
{ {
const unsigned int timeout = get_timeout(sdi);
struct sr_dev_driver *di; struct sr_dev_driver *di;
struct drv_context *drvc; struct drv_context *drvc;
struct dev_context *devc; struct dev_context *devc;
struct sr_usb_dev_inst *usb; struct sr_usb_dev_inst *usb;
struct dslogic_trigger_pos *tpos; struct dslogic_trigger_pos *tpos;
struct libusb_transfer *transfer; struct libusb_transfer *transfer;
int timeout;
int ret; int ret;
if (sdi->status != SR_ST_ACTIVE) if (sdi->status != SR_ST_ACTIVE)
@ -1028,7 +1024,6 @@ SR_PRIV int dslogic_acquisition_start(const struct sr_dev_inst *sdi)
devc->empty_transfer_count = 0; devc->empty_transfer_count = 0;
devc->acq_aborted = FALSE; devc->acq_aborted = FALSE;
timeout = get_timeout(devc);
usb_source_add(sdi->session, devc->ctx, timeout, receive_data, drvc); usb_source_add(sdi->session, devc->ctx, timeout, receive_data, drvc);
if ((ret = command_stop_acquisition(sdi)) != SR_OK) if ((ret = command_stop_acquisition(sdi)) != SR_OK)