X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=blobdiff_plain;f=src%2Fhardware%2Fgwinstek-gpd%2Fapi.c;h=6e745ee48c41cd1fb4fa36a6d10ef54c2769e8f8;hp=79688afb6595f7efacfde7df6c8e1c868cea96fd;hb=c329b788d297d68b2442b89c0f33b0d189132336;hpb=eaa8c6597b880d018731c36922ed4013e34813e1 diff --git a/src/hardware/gwinstek-gpd/api.c b/src/hardware/gwinstek-gpd/api.c index 79688afb..6e745ee4 100644 --- a/src/hardware/gwinstek-gpd/api.c +++ b/src/hardware/gwinstek-gpd/api.c @@ -21,6 +21,8 @@ #include #include "protocol.h" +#define IDN_RETRIES 3 /* at least 2 */ + static const uint32_t scanopts[] = { SR_CONF_CONN, SR_CONF_SERIALCOMM, @@ -60,6 +62,16 @@ static const struct gpd_model models[] = { { { 0, 30, 0.001 }, { 0, 3, 0.001 } }, }, }, + { GPD_3303S, "GPD-3303S", + CHANMODE_INDEPENDENT, + 2, + { + /* Channel 1 */ + { { 0, 32, 0.001 }, { 0, 3.2, 0.001 } }, + /* Channel 2 */ + { { 0, 32, 0.001 }, { 0, 3.2, 0.001 } }, + }, + }, }; static GSList *scan(struct sr_dev_driver *di, GSList *options) @@ -72,7 +84,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) GSList *l; struct sr_serial_dev_inst *serial; struct sr_dev_inst *sdi; - char reply[50]; + char reply[100]; unsigned int i; struct dev_context *devc; char channel[10]; @@ -102,18 +114,37 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) return NULL; if (!serialcomm) serialcomm = "115200/8n1"; - sr_info("Probing serial port %s.", conn); + sr_info("Probing serial port %s @ %s", conn, serialcomm); serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; - serial_flush(serial); - gpd_send_cmd(serial, "*IDN?\n"); - if (gpd_receive_reply(serial, reply, sizeof(reply)) != SR_OK) { - sr_err("Device did not reply."); + /* + * Problem: we need to clear the GPD receive buffer before we + * can expect it to process commands correctly. + * + * Do not just send a newline, since that may cause it to + * execute a currently buffered command. + * + * Solution: Send identification request a few times. + * The first should corrupt any previous buffered command if present + * and respond with "Invalid Character." or respond directly with + * an identification string starting with "GW INSTEK" + */ + for (i = 0; ioutput_enabled, &baud1, &baud2) != 8) { - sr_err("Invalid reply to STATUS: '%s'.", reply); - goto error; + /* old firmware (< 2.00?) responds with different format */ + if (sscanf(reply, "%1u %1u %1u %1u %1u X %1u X", &cc_cv_ch1, + &cc_cv_ch2, &track1, &track2, &beep, + &devc->output_enabled) != 6) { + sr_err("Invalid reply to STATUS: '%s'.", reply); + goto error; + } + /* ignore remaining two lines of status message */ + gpd_receive_reply(serial, reply, sizeof(reply)); + gpd_receive_reply(serial, reply, sizeof(reply)); } for (i = 0; i < model->num_channels; ++i) { @@ -220,7 +259,7 @@ error: static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { - int ret, channel; + int channel; const struct dev_context *devc; const struct sr_channel *ch; @@ -231,6 +270,9 @@ static int config_get(uint32_t key, GVariant **data, if (!cg) { switch (key) { + case SR_CONF_LIMIT_SAMPLES: + case SR_CONF_LIMIT_MSEC: + return sr_sw_limits_config_get(&devc->limits, key, data); case SR_CONF_CHANNEL_CONFIG: *data = g_variant_new_string( channel_modes[devc->channel_mode]); @@ -244,7 +286,6 @@ static int config_get(uint32_t key, GVariant **data, } else { ch = cg->channels->data; channel = ch->index; - ret = SR_OK; switch (key) { case SR_CONF_VOLTAGE: *data = g_variant_new_double( @@ -267,7 +308,7 @@ static int config_get(uint32_t key, GVariant **data, } } - return ret; + return SR_OK; } static int config_set(uint32_t key, GVariant *data, @@ -384,7 +425,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) return SR_OK; } -SR_PRIV const struct sr_dev_driver gwinstek_gpd_driver_info = { +static struct sr_dev_driver gwinstek_gpd_driver_info = { .name = "gwinstek-gpd", .longname = "GW Instek GPD", .api_version = 1,