finish up acquisition, also it compiles now
This commit is contained in:
parent
d70c0bc625
commit
33758a51e7
|
@ -8,6 +8,7 @@
|
|||
/configure.lineno
|
||||
/m4/libtool.m4
|
||||
/m4/lt*.m4
|
||||
/build
|
||||
|
||||
# Editor/IDE cruft
|
||||
*.kate-swp
|
||||
|
|
|
@ -69,20 +69,20 @@ static const uint64_t samplerates[] = {
|
|||
SR_KHZ(500), SR_KHZ(250), SR_KHZ(100), SR_KHZ(50), SR_KHZ(10)
|
||||
};
|
||||
|
||||
static uint64_t dc_samples_to_msec(struct device_context *dc, uint64_t samples)
|
||||
static uint64_t dc_samples_to_msec(struct dev_context *dc, uint64_t samples)
|
||||
{
|
||||
float msec_per_sample = 1.0f / ((float)dc->samplerate * 0.001f);
|
||||
|
||||
return (uint64_t)((float)samples * msec_per_sample);
|
||||
}
|
||||
static uint64_t dc_msec_to_samples(struct device_context *dc, uint64_t msec)
|
||||
static uint64_t dc_msec_to_samples(struct dev_context *dc, uint64_t msec)
|
||||
{
|
||||
float samples_per_msec = ((float)dc->samplerate * 0.001f);
|
||||
|
||||
return (uint64_t)((float)msec * samples_per_msec);
|
||||
}
|
||||
|
||||
static int dev_clear(struct sr_dev_driver *di)
|
||||
static int dev_clear(const struct sr_dev_driver *di)
|
||||
{
|
||||
return std_dev_clear_with_callback(di, (std_dev_clear_callback)sq_destroy);
|
||||
}
|
||||
|
@ -90,11 +90,11 @@ static int dev_clear(struct sr_dev_driver *di)
|
|||
static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
||||
{
|
||||
struct sr_dev_inst *sdi;
|
||||
struct drv_context *dc;
|
||||
struct dev_context *dc;
|
||||
struct ftdi_context *ft;
|
||||
char *manuf, *prod, *serial;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
int rv;
|
||||
|
||||
(void)options;
|
||||
|
||||
|
@ -113,7 +113,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
|||
/* open the FTDI device for a second to 1) check it exists, and
|
||||
* 2) check which device it is from the SQ series */
|
||||
|
||||
rv = ftdio_usb_open(ft, USB_VENDOR_ID, USB_PRODUCT_ID);
|
||||
rv = ftdi_usb_open(ft, USB_VENDOR_ID, USB_PRODUCT_ID);
|
||||
if (rv < 0) {
|
||||
if (rv != -3) { /* -3: device not found */
|
||||
sr_err("Failed to open device (%d): %s", rv, ftdi_get_error_string(ft));
|
||||
|
@ -122,15 +122,15 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
|||
}
|
||||
}
|
||||
|
||||
manuf = gmalloc0(256);
|
||||
prod = gmalloc0(256);
|
||||
serial = gmalloc0(256);
|
||||
rv = ftdio_eeprom_get_strings(ft, manuf, 256, prod, 256, serial, 256);
|
||||
manuf = g_malloc0(256);
|
||||
prod = g_malloc0(256);
|
||||
serial = g_malloc0(256);
|
||||
rv = ftdi_eeprom_get_strings(ft, manuf, 256, prod, 256, serial, 256);
|
||||
if (rv < 0) {
|
||||
sr_err("Failed to get device info strings (%d): %s", rv, ftdi_get_error_string(ft));
|
||||
gfree(serial);
|
||||
gfree(prod );
|
||||
gfree(manuf );
|
||||
g_free(serial);
|
||||
g_free(prod );
|
||||
g_free(manuf );
|
||||
sq_destroy(dc);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -143,23 +143,26 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
|||
|
||||
if (!strcmp(prod, USB_IPRODUCT_25)) {
|
||||
dc->devtype = 25;
|
||||
dc->memsize = MAX_MEMSIZE_SQ50 / 2;
|
||||
sr_info(prod);
|
||||
dc->memsize_max = MAX_MEMSIZE_SQ50 / 2;
|
||||
sr_info("%s", prod);
|
||||
} else if (!strcmp(prod, USB_IPRODUCT_50)) {
|
||||
dc->devtype = 50;
|
||||
dc->memsize = MAX_MEMSIZE_SQ50;
|
||||
sr_info(prod);
|
||||
dc->memsize_max = MAX_MEMSIZE_SQ50;
|
||||
sr_info("%s", prod);
|
||||
} else if (!strcmp(prod, USB_IPRODUCT_100)) {
|
||||
dc->devtype = 100;
|
||||
dc->memsize = MAX_MEMSIZE_SQ50 * 2;
|
||||
sr_info(prod);
|
||||
dc->memsize_max = MAX_MEMSIZE_SQ50 * 2;
|
||||
sr_info("%s", prod);
|
||||
} else if (!strcmp(prod, USB_IPRODUCT_200)) {
|
||||
dc->devtype = 200;
|
||||
dc->memsize = MAX_MEMSIZE_SQ50 * 4;
|
||||
sr_info(prod);
|
||||
dc->memsize_max = MAX_MEMSIZE_SQ50 * 4;
|
||||
sr_info("%s", prod);
|
||||
} else {
|
||||
sr_warn("Unexpected product name %s! Assuming SQ50 behavior...", prod);
|
||||
dc->devtype = 50;
|
||||
dc->memsize_max = MAX_MEMSIZE_SQ50;
|
||||
}
|
||||
dc->limit_samples = dc->memsize_max;
|
||||
|
||||
sr_info("ScanaQuad serial number: %s", serial);
|
||||
|
||||
|
@ -169,9 +172,9 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
|||
sdi->model = g_strdup(prod);
|
||||
sdi->priv = dc;
|
||||
|
||||
gfree(serial);
|
||||
gfree(prod );
|
||||
gfree(manuf );
|
||||
g_free(serial);
|
||||
g_free(prod );
|
||||
g_free(manuf );
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(channel_names); ++i)
|
||||
sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE/* enabled */, channel_names[i]);
|
||||
|
@ -187,7 +190,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
|||
} \
|
||||
} while (0) \
|
||||
|
||||
#define CHECK_SQ_RETVAL(msg, ft, rv) \
|
||||
#define CHECK_SQ_RETVAL(rv, msg) \
|
||||
do { \
|
||||
if ((rv) < 0) { \
|
||||
sr_err(msg " (%d).\n", (rv)); \
|
||||
|
@ -202,6 +205,8 @@ static int dev_open(struct sr_dev_inst *sdi)
|
|||
|
||||
dc = sdi->priv;
|
||||
|
||||
if (!dc || !dc->ft) return SR_ERR_BUG;
|
||||
|
||||
rv = ftdi_set_interface(dc->ft, INTERFACE_A);
|
||||
CHECK_FTDI_RETVAL("Failed to set FTDI interface A", dc->ft, rv);
|
||||
|
||||
|
@ -214,8 +219,8 @@ static int dev_open(struct sr_dev_inst *sdi)
|
|||
rv = ftdi_set_latency_timer(dc->ft, 2);
|
||||
CHECK_FTDI_RETVAL("Failed to set FTDI latency timer", dc->ft, rv);
|
||||
|
||||
rv = ftdi_read_data_set_chunksize(dc->ft, 64*1024); /* TODO: is this the right size? */
|
||||
CHECK_FTDI_RETVAL("Failed to set FTDI read data chunk size", dc->ft, rv);
|
||||
/*rv = ftdi_read_data_set_chunksize(dc->ft, 64*1024);
|
||||
CHECK_FTDI_RETVAL("Failed to set FTDI read data chunk size", dc->ft, rv);*/
|
||||
|
||||
return scanaquad_init(dc);
|
||||
}
|
||||
|
@ -227,25 +232,13 @@ static int dev_close(struct sr_dev_inst *sdi)
|
|||
|
||||
dc = sdi->priv;
|
||||
|
||||
rv = sq_get_status(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to get ScanaQuad status", rv);
|
||||
if (rv == sq_status_app) {
|
||||
/* cancel ongoing capture/wait-for-trigger */
|
||||
rv = sq_app_cancel_capture(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing SC/WFT", rv);
|
||||
if (!dc || !dc->ft) return SR_ERR_BUG;
|
||||
|
||||
/* cancel ongoing pattern generation */
|
||||
rv = sq_app_apply_default_settings(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to apply default settings", rv);
|
||||
rv = scanaquad_cancel_all(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing ScanaQuad transfers");
|
||||
|
||||
/* cancel ongoing capture/wait-for-trigger */
|
||||
rv = sq_app_cancel_capture(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing SC/WFT", rv);
|
||||
|
||||
/* cancel ongoing pattern generation */
|
||||
rv = sq_app_apply_default_settings(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to apply default settings", rv);
|
||||
}
|
||||
rv = ftdi_tcioflush(dc->ft);
|
||||
CHECK_FTDI_RETVAL("Failed to purge buffers", dc->ft, rv);
|
||||
|
||||
rv = ftdi_usb_close(dc->ft);
|
||||
CHECK_FTDI_RETVAL("Failed to close FTDI device", dc->ft, rv);
|
||||
|
@ -263,6 +256,8 @@ static int config_get(uint32_t key, GVariant **data,
|
|||
|
||||
(void)cg;
|
||||
|
||||
if (!dc) return SR_ERR_BUG;
|
||||
|
||||
rv = SR_OK;
|
||||
switch (key) {
|
||||
case SR_CONF_SAMPLERATE:
|
||||
|
@ -295,6 +290,8 @@ static int config_set(uint32_t key, GVariant *data,
|
|||
|
||||
(void)cg;
|
||||
|
||||
if (!dc) return SR_ERR_BUG;
|
||||
|
||||
rv = SR_OK;
|
||||
switch (key) {
|
||||
case SR_CONF_SAMPLERATE:
|
||||
|
@ -339,21 +336,24 @@ static int config_list(uint32_t key, GVariant **data,
|
|||
|
||||
static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||
{
|
||||
/* TODO: configure hardware, reset acquisition state, set up
|
||||
* callbacks and send header packet. */
|
||||
struct dev_context *dc;
|
||||
|
||||
(void)sdi;
|
||||
dc = sdi->priv;
|
||||
|
||||
return SR_OK;
|
||||
if (!dc || !dc->ft) return SR_ERR_BUG;
|
||||
|
||||
return scanaquad_acquisition_start(dc);
|
||||
}
|
||||
|
||||
static int dev_acquisition_stop(struct sr_dev_inst *sdi)
|
||||
{
|
||||
/* TODO: stop acquisition. */
|
||||
struct dev_context *dc;
|
||||
|
||||
(void)sdi;
|
||||
dc = sdi->priv;
|
||||
|
||||
return SR_OK;
|
||||
if (!dc || !dc->ft) return SR_ERR_BUG;
|
||||
|
||||
return scanaquad_acquisition_stop(sdi, dc);
|
||||
}
|
||||
|
||||
static struct sr_dev_driver ikalogic_scanaquad_driver_info = {
|
||||
|
@ -364,7 +364,7 @@ static struct sr_dev_driver ikalogic_scanaquad_driver_info = {
|
|||
.cleanup = std_cleanup,
|
||||
.scan = scan,
|
||||
.dev_list = std_dev_list,
|
||||
.dev_clear = std_dev_clear,
|
||||
.dev_clear = dev_clear,
|
||||
.config_get = config_get,
|
||||
.config_set = config_set,
|
||||
.config_list = config_list,
|
||||
|
|
|
@ -24,13 +24,17 @@
|
|||
SR_PRIV struct dev_context *sq_new(struct ftdi_context *ft)
|
||||
{
|
||||
struct dev_context *dc;
|
||||
int rv;
|
||||
|
||||
if (!ft) return NULL;
|
||||
|
||||
dc = (struct dev_context *)gmalloc0(sizeof(struct dev_context));
|
||||
dc = (struct dev_context *)g_malloc0(sizeof(struct dev_context));
|
||||
dc->ft = ft;
|
||||
|
||||
/* some sensible defaults */
|
||||
dc->samplerate = SR_MHZ(25);
|
||||
dc->capture_ratio = 0;
|
||||
dc->voltage = 3.3f;
|
||||
|
||||
return dc;
|
||||
}
|
||||
SR_PRIV void sq_destroy(struct dev_context *dc)
|
||||
|
@ -41,7 +45,7 @@ SR_PRIV void sq_destroy(struct dev_context *dc)
|
|||
ftdi_free(dc->ft);
|
||||
dc->ft = NULL;
|
||||
}
|
||||
gfree(dc);
|
||||
g_free(dc);
|
||||
}
|
||||
|
||||
#define CHECK_FTDI_RETVAL(write, ft, rv, expect, ...) \
|
||||
|
@ -50,7 +54,7 @@ SR_PRIV void sq_destroy(struct dev_context *dc)
|
|||
sr_err("Failed to %s FTDI data (%d): %s.\n", (write)?"write":"read", (rv), \
|
||||
ftdi_get_error_string(ft)); \
|
||||
return SR_ERR; \
|
||||
} else if ((rv) != (expect) __VA_OPT__(&& __VA_ARGS__)) { \
|
||||
} else if ((size_t)(rv) != (expect) __VA_OPT__(&& __VA_ARGS__)) { \
|
||||
sr_err("FTDI %s error, only %d/%zu bytes %s: %s.", (write)?"write":"read",\
|
||||
(rv), expect, (write)?"written":"read", ftdi_get_error_string(ft)); \
|
||||
return SR_ERR; \
|
||||
|
@ -85,7 +89,7 @@ SR_PRIV int sq_get_status(struct dev_context *dc)
|
|||
rv = ftdi_read_data(dc->ft, stat, sizeof stat);
|
||||
CHECK_FTDI_RETVAL(FALSE, dc->ft, rv, sizeof stat);
|
||||
|
||||
if (stat[0] != staŧ[1] || stat[0] != stat[2] || staŧ[0] != stat[3])
|
||||
if (stat[0] != stat[1] || stat[0] != stat[2] || stat[0] != stat[3])
|
||||
sr_warn("status: incoherent: %02x %02x %02x %02x", stat[0], stat[1], stat[2], stat[3]);
|
||||
else
|
||||
sr_spew("status: %02x", stat[0]);
|
||||
|
@ -121,18 +125,19 @@ SR_PRIV int sq_reset_bl(struct dev_context *dc)
|
|||
}
|
||||
SR_PRIV int sq_get_devid_from_eeprom(struct dev_context *dc, uint8_t *devid)
|
||||
{
|
||||
int val1, val2, rv;
|
||||
uint16_t val1, val2;
|
||||
int rv;
|
||||
|
||||
if (!dc) return SR_ERR;
|
||||
|
||||
if ((rv = ftdi_read_eeprom_location(dc->ft, 0x12, &val1)) < 0) {
|
||||
sr_err("Failed to read EEPROM index 0x12 (%d): %s.",
|
||||
ret, ftdi_get_error_string(dc->ft));
|
||||
rv, ftdi_get_error_string(dc->ft));
|
||||
return SR_ERR;
|
||||
}
|
||||
if ((rv = ftdi_read_eeprom_location(dc->ft, 0x13, &val2)) < 0) {
|
||||
sr_err("Failed to read EEPROM index 0x13 (%d): %s.",
|
||||
ret, ftdi_get_error_string(dc->ft));
|
||||
rv, ftdi_get_error_string(dc->ft));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
|
@ -200,7 +205,7 @@ SR_PRIV int sq_bl_spi_xfer(struct dev_context *dc, uint8_t val)
|
|||
CHECK_FTDI_RETVAL(TRUE, dc->ft, rv, sizeof send_spi_xfer_cmd);
|
||||
|
||||
rv = ftdi_read_data(dc->ft, &read, 1);
|
||||
CHECK_FTDI_RETVAL(FALSE, dc->ft, rv, 1);
|
||||
CHECK_FTDI_RETVAL(FALSE, dc->ft, rv, (size_t)1);
|
||||
|
||||
sr_spew("SPI xfer: %02x -> %02x", val, read);
|
||||
|
||||
|
@ -221,34 +226,44 @@ SR_PRIV int sq_app_cancel_capture(struct dev_context *dc)
|
|||
|
||||
return SR_OK;
|
||||
}
|
||||
SR_PRIV int sq_app_start_capture(struct dev_context *dc)
|
||||
SR_PRIV struct ftdi_transfer_control *sq_app_start_capture(struct dev_context *dc, uint32_t *resbuf)
|
||||
{
|
||||
static const uint8_t send_start_capture_cmd[] = {0xf0,0x01};
|
||||
uint8_t result[4];
|
||||
int rv;
|
||||
|
||||
if (!dc) return SR_ERR;
|
||||
if (!dc) return NULL;
|
||||
|
||||
sr_spew("sc/wft");
|
||||
|
||||
rv = ftdi_write_data(dc->ft, send_start_capture_cmd, sizeof send_start_capture_cmd);
|
||||
CHECK_FTDI_RETVAL(TRUE, dc->ft, rv, sizeof send_start_capture_cmd);
|
||||
if (rv < 0) {
|
||||
sr_err("Failed to write FTDI data (%d): %s.\n", rv, ftdi_get_error_string(dc->ft));
|
||||
return NULL;
|
||||
} else if (rv != sizeof send_start_capture_cmd) {
|
||||
sr_err("FTDI write error, only %d/%zu bytes written: %s.", rv,
|
||||
sizeof send_start_capture_cmd, ftdi_get_error_string(dc->ft));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
return ftdi_read_data_submit(dc->ft, (uint8_t *)resbuf, 4);
|
||||
}
|
||||
SR_PRIV int sq_app_get_capture_result(struct dev_context *dc, uint32_t *trig_instant)
|
||||
SR_PRIV int sq_app_get_capture_result(struct dev_context *dc, struct ftdi_transfer_control *tc, uint32_t *trig_instant)
|
||||
{
|
||||
uint8_t result[4];
|
||||
uint32_t ti;
|
||||
int rv;
|
||||
|
||||
if (!dc || !trig_instant) return SR_ERR;
|
||||
if (!dc || !tc) return SR_ERR;
|
||||
|
||||
if (!tc->completed) return SR_ERR_ARG;
|
||||
|
||||
rv = ftdi_read_data(dc->ft, result, sizeof result);
|
||||
CHECK_FTDI_RETVAL(FALSE, dc->ft, rv, sizeof result);
|
||||
|
||||
*trig_instant = (uint32_t)result[0] | ((uint32_t)result[1] << 8) | ((uint32_t)result[2] << 16);
|
||||
ti = (uint32_t)result[0] | ((uint32_t)result[1] << 8) | ((uint32_t)result[2] << 16);
|
||||
if (trig_instant) *trig_instant = ti;
|
||||
|
||||
sr_spew("sc/wft -> %06x %02x", *trig_instant, result[3]);
|
||||
sr_spew("sc/wft -> %06x %02x", ti, result[3]);
|
||||
|
||||
return result[3];
|
||||
}
|
||||
|
@ -259,26 +274,33 @@ SR_PRIV int sq_app_start_generate_inf(struct dev_context *dc)
|
|||
|
||||
if (!dc) return SR_ERR;
|
||||
|
||||
sc_spew("start generate inf");
|
||||
sr_spew("start generate inf");
|
||||
|
||||
rv = ftdi_write_data(dc->ft, send_start_geninf_cmd, sizeof send_start_geninf_cmd);
|
||||
CHECK_FTDI_RETVAL(TRUE, dc->ft, rv, sizeof send_start_geninf_cmd);
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
SR_PRIV int sq_app_start_capgenmix(struct dev_context *dc)
|
||||
SR_PRIV struct ftdi_transfer_control *sq_app_start_capgenmix(struct dev_context *dc, uint32_t *resbuf)
|
||||
{
|
||||
static const uint8_t send_start_capture_cmd[] = {0xf0,0x03};
|
||||
static const uint8_t send_start_capgenmix_cmd[] = {0xf0,0x03};
|
||||
int rv;
|
||||
|
||||
if (!dc) return SR_ERR;
|
||||
if (!dc) return NULL;
|
||||
|
||||
sr_spew("start mixed sc/g/wft");
|
||||
|
||||
rv = ftdi_write_data(dc->ft, send_start_capgenmix_cmd, sizeof send_start_capgenmix_cmd);
|
||||
CHECK_FTDI_RETVAL(TRUE, dc->ft, rv, sizeof send_start_capgenmix_cmd);
|
||||
if (rv < 0) {
|
||||
sr_err("Failed to write FTDI data (%d): %s.\n", rv, ftdi_get_error_string(dc->ft));
|
||||
return NULL;
|
||||
} else if (rv != sizeof send_start_capgenmix_cmd) {
|
||||
sr_err("FTDI write error, only %d/%zu bytes written: %s.", rv,
|
||||
sizeof send_start_capgenmix_cmd, ftdi_get_error_string(dc->ft));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
return ftdi_read_data_submit(dc->ft, (uint8_t *)resbuf, 4);
|
||||
}
|
||||
SR_PRIV int sq_app_upload_genpattern(struct dev_context *dc, const void *data, size_t len)
|
||||
{
|
||||
|
@ -293,6 +315,7 @@ SR_PRIV int sq_app_upload_genpattern(struct dev_context *dc, const void *data, s
|
|||
rv = ftdi_write_data(dc->ft, send_upl_genpat_cmd, sizeof send_upl_genpat_cmd);
|
||||
CHECK_FTDI_RETVAL(TRUE, dc->ft, rv, sizeof send_upl_genpat_cmd);
|
||||
|
||||
/* TODO: use async libftdi api? */
|
||||
do {
|
||||
rv = ftdi_write_data(dc->ft, (const uint8_t *)data + pos, len - pos);
|
||||
CHECK_FTDI_RETVAL(TRUE, dc->ft, rv, len, FALSE);
|
||||
|
@ -324,7 +347,7 @@ SR_PRIV int sq_app_download_capture(struct dev_context *dc, void *data, size_t l
|
|||
|
||||
return SR_OK;
|
||||
}
|
||||
SR_PRIV sq_app_start_generate_once(struct dev_context *dc)
|
||||
SR_PRIV int sq_app_start_generate_once(struct dev_context *dc)
|
||||
{
|
||||
static const uint8_t send_start_genonce_cmd[] = {0xf0,0x07};
|
||||
int rv;
|
||||
|
@ -339,7 +362,7 @@ SR_PRIV sq_app_start_generate_once(struct dev_context *dc)
|
|||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV sq_app_apply_settings(struct dev_context *dc, const struct sq_app_settings *sett)
|
||||
SR_PRIV int sq_app_apply_settings(struct dev_context *dc, const struct sq_app_settings *sett)
|
||||
{
|
||||
uint8_t send_sett_cmd[25] = {0xf1, 0};
|
||||
uint8_t *blob;
|
||||
|
@ -381,7 +404,7 @@ SR_PRIV sq_app_apply_settings(struct dev_context *dc, const struct sq_app_settin
|
|||
|
||||
return SR_OK;
|
||||
}
|
||||
SR_PRIV sq_app_apply_triggers(struct dev_context *dc, const struct sq_app_trigstep *steps, size_t nsteps)
|
||||
SR_PRIV int sq_app_apply_triggers(struct dev_context *dc, const struct sq_app_trigstep *steps, size_t nsteps)
|
||||
{
|
||||
uint8_t *send_trig_cmd;
|
||||
size_t i, blobsize;
|
||||
|
@ -392,7 +415,7 @@ SR_PRIV sq_app_apply_triggers(struct dev_context *dc, const struct sq_app_trigst
|
|||
|
||||
/* nsteps shouldn't exceed 8 or so */
|
||||
blobsize = 1 + nsteps * 4;
|
||||
send_trig_cmd = (uint8_t *)gmalloc0(blobsize);
|
||||
send_trig_cmd = (uint8_t *)g_malloc0(blobsize);
|
||||
send_trig_cmd[0] = 0xf4;
|
||||
|
||||
for (i = 0; i < nsteps; ++i) {
|
||||
|
@ -416,7 +439,7 @@ SR_PRIV sq_app_apply_triggers(struct dev_context *dc, const struct sq_app_trigst
|
|||
sr_spew("apply triggers"); /* TODO: print info about applied triggers */
|
||||
|
||||
rv = ftdi_write_data(dc->ft, send_trig_cmd, blobsize);
|
||||
gfree(send_trig_cmd);
|
||||
g_free(send_trig_cmd);
|
||||
CHECK_FTDI_RETVAL(TRUE, dc->ft, rv, sizeof send_trig_cmd);
|
||||
|
||||
return SR_OK;
|
||||
|
@ -506,23 +529,307 @@ SR_PRIV int scanaquad_init(struct dev_context *dc)
|
|||
|
||||
return sq_app_apply_default_settings(dc);
|
||||
}
|
||||
|
||||
SR_PRIV int ikalogic_scanaquad_receive_data(int fd, int revents, void *cb_data)
|
||||
SR_PRIV int scanaquad_cancel_all(struct dev_context *dc)
|
||||
{
|
||||
const struct sr_dev_inst *sdi;
|
||||
struct dev_context *devc;
|
||||
int rv;
|
||||
|
||||
if (dc->tc) {
|
||||
/* TODO: timeout? */
|
||||
ftdi_transfer_data_cancel(dc->tc, NULL);
|
||||
dc->tc = NULL;
|
||||
}
|
||||
if (dc->tcbuf) {
|
||||
g_free(dc->tcbuf);
|
||||
dc->tcbuf = NULL;
|
||||
}
|
||||
dc->tcsize = 0;
|
||||
|
||||
dc->acq_started = FALSE;
|
||||
|
||||
rv = sq_get_status(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to get ScanaQuad status");
|
||||
|
||||
if (rv == sq_status_app) {
|
||||
/* cancel ongoing capture/wait-for-trigger */
|
||||
rv = sq_app_cancel_capture(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing SC/WFT");
|
||||
|
||||
/* cancel ongoing pattern generation */
|
||||
rv = scanaquad_apply_current_settings(dc, TRUE);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to apply default settings");
|
||||
|
||||
/* cancel ongoing capture/wait-for-trigger */
|
||||
rv = sq_app_cancel_capture(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing SC/WFT");
|
||||
|
||||
/* cancel ongoing pattern generation */
|
||||
rv = scanaquad_apply_current_settings(dc, TRUE);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to apply default settings");
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int scanaquad_apply_current_settings(struct dev_context *dc, gboolean passive)
|
||||
{
|
||||
/* if passive:
|
||||
* * no triggers
|
||||
* * set to capture mode(?) */
|
||||
|
||||
uint32_t ms1, ms2, ms3;
|
||||
struct sq_app_settings sett;
|
||||
|
||||
/* clockfreq == 100000 / samplerate_kHz */
|
||||
sett.clockfreq = (uint16_t)((100000uLL*1000) / dc->samplerate);
|
||||
sett.voltage[0] = /*floorf(dc->voltage * 39.2f);*/0x81;
|
||||
sett.voltage[1] = passive ? 0x4b : 0x46; /* FIXME: 0x46: hardcoded for 3.3V */
|
||||
sett.chanoutmap = 0x0f; /* TODO: hardcoded: all inputs */
|
||||
|
||||
/* TODO: limit_msec, limit_samples, capture_ratio */
|
||||
/* TODO: more than just capture mode */
|
||||
ms1 = dc->memsize_max;
|
||||
ms2 = dc->memsize_max;
|
||||
/* capture_ratio is currently fixed at 10%... */
|
||||
ms3 = (uint32_t)(dc->memsize_max * (1 - 0.10f));
|
||||
|
||||
sett.memsetting1[0] = (ms1>> 0) & 0xff;
|
||||
sett.memsetting1[1] = (ms1>> 8) & 0xff;
|
||||
sett.memsetting1[2] = (ms1>>16) & 0xff;
|
||||
sett.memsetting2[0] = (ms2>> 0) & 0xff;
|
||||
sett.memsetting2[1] = (ms2>> 8) & 0xff;
|
||||
sett.memsetting2[2] = (ms2>>16) & 0xff;
|
||||
sett.memsetting3[0] = (ms3>> 0) & 0xff;
|
||||
sett.memsetting3[1] = (ms3>> 8) & 0xff;
|
||||
sett.memsetting3[2] = (ms3>>16) & 0xff;
|
||||
|
||||
/* TODO */
|
||||
sett.trigscale_us = 0x01;
|
||||
sett.ntrigsteps = 0;
|
||||
sett.trigger_pw_scale = 0;
|
||||
sett.capture = TRUE;
|
||||
sett.generate = FALSE;
|
||||
|
||||
dc->MS_capture = ms1;
|
||||
dc->MS_generate = ms2 - ms1;
|
||||
|
||||
return sq_app_apply_settings(dc, &sett);
|
||||
}
|
||||
SR_PRIV int scanaquad_apply_current_triggers(struct dev_context *dc)
|
||||
{
|
||||
(void)dc;
|
||||
return SR_OK; /* HUGE TODO */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SR_PRIV int scanaquad_acquisition_start(struct dev_context *dc)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (!dc) return SR_ERR;
|
||||
|
||||
if (dc->tc || dc->tcbuf || dc->acq_started) return SR_ERR_BUG;
|
||||
|
||||
rv = scanaquad_cancel_all(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing ScanaQuad transfers");
|
||||
|
||||
rv = sq_get_status(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to get current device state");
|
||||
if (rv != sq_status_app) {
|
||||
sr_err("Device not in application mode.");
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
rv = scanaquad_apply_current_settings(dc, FALSE);
|
||||
if (rv == SR_OK) rv = scanaquad_apply_current_triggers(dc);
|
||||
if (rv < 0) {
|
||||
/* rollback */
|
||||
scanaquad_apply_current_settings(dc, TRUE);
|
||||
sq_app_cancel_capture(dc);
|
||||
}
|
||||
CHECK_SQ_RETVAL(rv, "Failed to apply device settings");
|
||||
|
||||
rv = sq_get_status(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to get current device state");
|
||||
if (rv != sq_status_app) {
|
||||
sr_err("Device not in application mode.");
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
rv = sq_app_cancel_capture(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing ScanaQuad transfers");
|
||||
|
||||
dc->tcbuf = g_malloc0(4);
|
||||
dc->tcsize = 4;
|
||||
dc->tc = sq_app_start_capture(dc, (uint32_t *)dc->tcbuf);
|
||||
|
||||
if (!dc->tc) {
|
||||
sr_err("Couldn't start capture");
|
||||
g_free(dc->tcbuf);
|
||||
dc->tcbuf = NULL;
|
||||
dc->tcsize = 0;
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
dc->acq_started = TRUE;
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
static void scanaquad_unpack_samples(uint8_t *rdata, size_t totalunpackbytes)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = totalunpackbytes / 2; i > 0; --i) {
|
||||
rdata[i*2-1] = (rdata[i-1] & 0xf0) >> 4;
|
||||
rdata[i*2-2] = (rdata[i-1] & 0x0f) >> 0;
|
||||
}
|
||||
}
|
||||
|
||||
SR_PRIV int scanaquad_acquisition_finish(struct sr_dev_inst *sdi, struct dev_context *dc)
|
||||
{
|
||||
struct sr_datafeed_packet packet1, packet2, packet3;
|
||||
struct sr_datafeed_logic logic1, logic3;
|
||||
size_t nbytes;
|
||||
uint8_t *rdata;
|
||||
uint32_t trig_instant;
|
||||
int rv;
|
||||
|
||||
if (!dc || !dc->tc) return SR_ERR_BUG;
|
||||
|
||||
rv = ftdi_transfer_data_done(dc->tc);
|
||||
dc->tc = NULL;
|
||||
if (rv < 0) {
|
||||
sr_err("Coudln't read async FTDI device status (%d): %s",
|
||||
rv, ftdi_get_error_string(dc->ft));
|
||||
|
||||
g_free(dc->tcbuf);
|
||||
dc->tcbuf = 0;
|
||||
dc->tcsize = 0;
|
||||
return SR_ERR;
|
||||
} else if (rv != 4) {
|
||||
sr_err("Unexpected async FTDI transfer size %d: %s",
|
||||
rv, ftdi_get_error_string(dc->ft));
|
||||
|
||||
g_free(dc->tcbuf);
|
||||
dc->tcbuf = 0;
|
||||
dc->tcsize = 0;
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
trig_instant = *(uint32_t *)dc->tcbuf;
|
||||
g_free(dc->tcbuf);
|
||||
dc->tcbuf = 0;
|
||||
dc->tcsize = 0;
|
||||
|
||||
sr_spew("trig_instant = %u", trig_instant);
|
||||
|
||||
nbytes = dc->MS_capture * 2;
|
||||
/* we need 2x the amount of bytes we'll read from the device, as these are
|
||||
* currently packed per nybbles, while sigrok wants the samples in separate
|
||||
* bytes */
|
||||
rdata = g_try_malloc(nbytes * 2);
|
||||
if (!rdata) {
|
||||
sr_err("Out of memory: cannot download captured samples");
|
||||
|
||||
/* rollback */
|
||||
scanaquad_apply_current_settings(dc, TRUE);
|
||||
sq_app_cancel_capture(dc);
|
||||
|
||||
return SR_ERR;
|
||||
}
|
||||
/* convert from trig_instant units (MS1*16) to bytes */
|
||||
trig_instant = (trig_instant * 2) / 8;
|
||||
|
||||
rv = sq_app_download_capture(dc, rdata, nbytes);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to download captured samples");
|
||||
|
||||
rv = sq_app_cancel_capture(dc);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to cancel ongoing ScanaQuad transfers");
|
||||
|
||||
rv = scanaquad_apply_current_settings(dc, TRUE);
|
||||
CHECK_SQ_RETVAL(rv, "Failed to reset ScanaQuad settings");
|
||||
|
||||
scanaquad_unpack_samples(rdata, nbytes * 2);
|
||||
|
||||
logic1.length = trig_instant;
|
||||
logic1.unitsize = 1;
|
||||
logic1.data = rdata;
|
||||
packet1.type = SR_DF_LOGIC;
|
||||
packet1.payload = &logic1;
|
||||
|
||||
packet2.type = SR_DF_TRIGGER;
|
||||
packet2.payload = NULL;
|
||||
|
||||
logic3.length = (nbytes * 2) - trig_instant;
|
||||
logic3.unitsize = 1;
|
||||
logic3.data = rdata + trig_instant;
|
||||
packet3.type = SR_DF_LOGIC;
|
||||
packet3.payload = &logic3;
|
||||
|
||||
sr_session_send(sdi, &packet1);
|
||||
sr_session_send(sdi, &packet2);
|
||||
sr_session_send(sdi, &packet3);
|
||||
|
||||
/* I hope this is fine to do?? */
|
||||
g_free(rdata);
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
SR_PRIV int scanaquad_acquisition_stop(struct sr_dev_inst *sdi, struct dev_context *dc)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = sq_app_get_capture_result(dc, dc->tc, (uint32_t *)dc->tcbuf);
|
||||
if (rv == SR_ERR_ARG) { /* still busy */
|
||||
return scanaquad_acquisition_stop(sdi, dc);
|
||||
} else if (rv < SR_OK) {
|
||||
sr_err("Cannot get device state / capture result");
|
||||
return SR_ERR;
|
||||
} else if (rv == SQ_APP_START_CAPTURE_SUCCESS) {
|
||||
return scanaquad_acquisition_finish(sdi, dc);
|
||||
} else {
|
||||
sr_err("Acquisition failed");
|
||||
return SR_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
SR_PRIV int scanaquad_receive_data(int fd, int revents, void *cb_data)
|
||||
{
|
||||
struct sr_dev_inst *sdi;
|
||||
struct dev_context *dc;
|
||||
int rv;
|
||||
|
||||
(void)fd;
|
||||
|
||||
if (!(sdi = cb_data))
|
||||
return TRUE;
|
||||
if (!(sdi = cb_data)) return TRUE;
|
||||
if (!(dc = sdi->priv)) return TRUE;
|
||||
if (!dc->ft) return TRUE;
|
||||
|
||||
if (!(devc = sdi->priv))
|
||||
return TRUE;
|
||||
if (revents != G_IO_IN) return TRUE;
|
||||
|
||||
if (revents == G_IO_IN) {
|
||||
/* TODO */
|
||||
rv = sq_app_get_capture_result(dc, dc->tc, (uint32_t *)dc->tcbuf);
|
||||
if (rv == SR_ERR_ARG) { /* still busy */
|
||||
sr_spew("Acquisition still busy...");
|
||||
return TRUE;
|
||||
} else if (rv < SR_OK) {
|
||||
sr_err("Cannot get device state / capture result");
|
||||
sr_dev_acquisition_stop(sdi);
|
||||
return FALSE;
|
||||
} else if (rv == SQ_APP_START_CAPTURE_SUCCESS) {
|
||||
rv = scanaquad_acquisition_finish(sdi, dc);
|
||||
if (rv == SR_ERR) {
|
||||
sr_err("acquisition_finish failed");
|
||||
sr_dev_acquisition_stop(sdi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sr_dev_acquisition_stop(sdi);
|
||||
return TRUE;
|
||||
} else {
|
||||
sr_err("Acquisition failed");
|
||||
sr_dev_acquisition_stop(sdi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -35,16 +35,25 @@
|
|||
struct dev_context {
|
||||
struct ftdi_context *ft;
|
||||
|
||||
struct ftdi_transfer_control *tc;
|
||||
uint8_t *tcbuf;
|
||||
size_t tcsize;
|
||||
|
||||
/* settings for next capture */
|
||||
uint64_t samplerate;
|
||||
uint64_t limit_samples;
|
||||
uint64_t capture_ratio;
|
||||
uint64_t limit_samples; /* samples */
|
||||
uint64_t capture_ratio; /* 0..100? MAYBE? */
|
||||
float voltage;
|
||||
|
||||
uint32_t MS_capture;
|
||||
uint32_t MS_generate;
|
||||
|
||||
uint32_t memsize_max;
|
||||
int devtype; /* 25, 50, 100 or 200 for SQ25, SQ50, and so on */
|
||||
uint8_t devid[3];
|
||||
gboolean has_devid;
|
||||
|
||||
gboolean acq_started;
|
||||
};
|
||||
|
||||
enum sq_status {
|
||||
|
@ -100,11 +109,11 @@ SR_PRIV int sq_bl_spi_chipsel(struct dev_context *dc);
|
|||
SR_PRIV int sq_bl_spi_chipdesel(struct dev_context *dc);
|
||||
SR_PRIV int sq_bl_spi_xfer(struct dev_context *dc, uint8_t val);
|
||||
/* two aliases for clarity */
|
||||
static inline SR_PRIV int sq_bl_spi_xfer_write(struct dev_context *dc, uint8_t val)
|
||||
static inline int sq_bl_spi_xfer_write(struct dev_context *dc, uint8_t val)
|
||||
{
|
||||
return sq_bl_spi_xfer(dc, val);
|
||||
}
|
||||
static inline SR_PRIV int sq_bl_spi_xfer_read(struct dev_context *dc)
|
||||
static inline int sq_bl_spi_xfer_read(struct dev_context *dc)
|
||||
{
|
||||
return sq_bl_spi_xfer(dc, 0xff);
|
||||
}
|
||||
|
@ -112,12 +121,12 @@ static inline SR_PRIV int sq_bl_spi_xfer_read(struct dev_context *dc)
|
|||
/* application mode commands */
|
||||
/* 0xf0 0x0X commands */
|
||||
SR_PRIV int sq_app_cancel_capture(struct dev_context *dc);
|
||||
SR_PRIV int sq_app_start_capture(struct dev_context *dc);
|
||||
SR_PRIV int sq_app_get_capture_result(struct dev_context *dc, uint32_t *trig_instant);
|
||||
SR_PRIV struct ftdi_transfer_control *sq_app_start_capture(struct dev_context *dc, uint32_t *resbuf);
|
||||
SR_PRIV int sq_app_get_capture_result(struct dev_context *dc, struct ftdi_transfer_control *tc, uint32_t *trig_instant);
|
||||
SR_PRIV int sq_app_start_generate_inf(struct dev_context *dc);
|
||||
SR_PRIV int sq_app_start_capgenmix(struct dev_context *dc);
|
||||
static inline SR_PRIV int sq_app_get_capgenmix_result(struct dev_context *dc, uint32_t *trig_instant) {
|
||||
return sq_app_get_capture_result(dc, trig_instant);
|
||||
SR_PRIV struct ftdi_transfer_control *sq_app_start_capgenmix(struct dev_context *dc, uint32_t *resbuf);
|
||||
static inline int sq_app_get_capgenmix_result(struct dev_context *dc, struct ftdi_transfer_control *tc, uint32_t *trig_instant) {
|
||||
return sq_app_get_capture_result(dc, tc, trig_instant);
|
||||
}
|
||||
/* NOTE: at this point, no checks are done whether the length of the data is
|
||||
* consistent with the current capture/genpattern memory size in the
|
||||
|
@ -135,7 +144,16 @@ SR_PRIV int sq_app_apply_default_settings(struct dev_context *dc);
|
|||
|
||||
/* higher-level stuff used by api.c */
|
||||
|
||||
SR_PRIV int scanaquad_init(struct dev_context *devc);
|
||||
SR_PRIV int scanaquad_init(struct dev_context *dc);
|
||||
SR_PRIV int scanaquad_cancel_all(struct dev_context *dc);
|
||||
SR_PRIV int scanaquad_apply_current_settings(struct dev_context *dc, gboolean passive);
|
||||
SR_PRIV int scanaquad_apply_current_triggers(struct dev_context *dc);
|
||||
|
||||
SR_PRIV int scanaquad_acquisition_start(struct dev_context *dc);
|
||||
/* stuff to do when an acquisition ended successfully */
|
||||
SR_PRIV int scanaquad_acquisition_finish(struct sr_dev_inst *sdi, struct dev_context *dc);
|
||||
/* either finish when possible right now, or abort */
|
||||
SR_PRIV int scanaquad_acquisition_stop(struct sr_dev_inst *sdi, struct dev_context *dc);
|
||||
SR_PRIV int scanaquad_receive_data(int fd, int revents, void *cb_data);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue