From: Gerhard Sittig Date: Sat, 25 Feb 2023 16:45:57 +0000 (+0100) Subject: korad-kaxxxxp: add quirk for long processing times of commands X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=0f63fbea33ab923395efd6d5215165938b6a843d;p=libsigrok.git korad-kaxxxxp: add quirk for long processing times of commands Some Korad compatibles are said to take rather long a time between reception of adjacent commands. It's not just that the response is delayed, or that execution takes a long time. It's worse in that the next request isn't received, and later responses don't correspond to the requests which host software associates them with. A driver implementation detail then "reads" 0.000 current values when the PSU failed to respond to the "IOUT?" request. Add a quirk flag. Allow for extra processing time after SET commands and the GET command for STATUS. Add the Velleman PS3005D V1.3 model with this quirk. Behaviour does not change for other devices. This implementation is based on a submission that was provided by Pilatomic . --- diff --git a/src/hardware/korad-kaxxxxp/api.c b/src/hardware/korad-kaxxxxp/api.c index 8cbd1cce..82e43797 100644 --- a/src/hardware/korad-kaxxxxp/api.c +++ b/src/hardware/korad-kaxxxxp/api.c @@ -74,6 +74,8 @@ static const struct korad_kaxxxxp_model models[] = { {"Tenma", "72-2710", "", 1, volts_30, amps_5, 0}, {"Velleman", "LABPS3005D", "", 1, volts_30, amps_5, KORAD_QUIRK_LABPS_OVP_EN}, + {"Velleman", "PS3005D V1.3", "VELLEMANPS3005DV1.3" , 1, volts_30, amps_5, + KORAD_QUIRK_ID_TRAILING | KORAD_QUIRK_SLOW_PROCESSING}, {"Velleman", "PS3005D", "", 1, volts_30, amps_5, 0}, ALL_ZERO }; @@ -327,7 +329,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) sr_sw_limits_init(&devc->limits); g_mutex_init(&devc->rw_mutex); devc->model = model; - devc->req_sent_at = 0; + devc->next_req_time = 0; devc->cc_mode_1_changed = FALSE; devc->cc_mode_2_changed = FALSE; devc->output_enabled_changed = FALSE; @@ -516,7 +518,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) sr_sw_limits_acquisition_start(&devc->limits); std_session_send_df_header(sdi); - devc->req_sent_at = 0; + devc->next_req_time = 0; serial = sdi->conn; serial_source_add(sdi->session, serial, G_IO_IN, KAXXXXP_POLL_INTERVAL_MS, diff --git a/src/hardware/korad-kaxxxxp/protocol.c b/src/hardware/korad-kaxxxxp/protocol.c index 2b980352..bac8c8ef 100644 --- a/src/hardware/korad-kaxxxxp/protocol.c +++ b/src/hardware/korad-kaxxxxp/protocol.c @@ -22,6 +22,7 @@ #include "protocol.h" #define DEVICE_PROCESSING_TIME_MS 80 +#define EXTRA_PROCESSING_TIME_MS 450 SR_PRIV int korad_kaxxxxp_send_cmd(struct sr_serial_dev_inst *serial, const char *cmd) @@ -155,18 +156,34 @@ static void give_device_time_to_process(struct dev_context *devc) { int64_t sleeping_time; - if (!devc->req_sent_at) + if (!devc->next_req_time) return; - sleeping_time = devc->req_sent_at + (DEVICE_PROCESSING_TIME_MS * 1000); - sleeping_time -= g_get_monotonic_time(); - + sleeping_time = devc->next_req_time - g_get_monotonic_time(); if (sleeping_time > 0) { g_usleep(sleeping_time); sr_spew("Sleeping for processing %" PRIi64 " usec", sleeping_time); } } +static int64_t next_req_time(struct dev_context *devc, + gboolean is_set, int target) +{ + gboolean is_slow_device, is_long_command; + int64_t processing_time_us; + + is_slow_device = devc->model->quirks & KORAD_QUIRK_SLOW_PROCESSING; + is_long_command = is_set; + is_long_command |= target == KAXXXXP_STATUS; + + processing_time_us = DEVICE_PROCESSING_TIME_MS; + if (is_slow_device && is_long_command) + processing_time_us += EXTRA_PROCESSING_TIME_MS; + processing_time_us *= 1000; + + return g_get_monotonic_time() + processing_time_us; +} + SR_PRIV int korad_kaxxxxp_set_value(struct sr_serial_dev_inst *serial, int target, struct dev_context *devc) { @@ -243,7 +260,7 @@ SR_PRIV int korad_kaxxxxp_set_value(struct sr_serial_dev_inst *serial, if (ret == SR_OK && msg[0]) { ret = korad_kaxxxxp_send_cmd(serial, msg); - devc->req_sent_at = g_get_monotonic_time(); + devc->next_req_time = next_req_time(devc, TRUE, target); } g_mutex_unlock(&devc->rw_mutex); @@ -305,7 +322,7 @@ SR_PRIV int korad_kaxxxxp_get_value(struct sr_serial_dev_inst *serial, return ret; } - devc->req_sent_at = g_get_monotonic_time(); + devc->next_req_time = next_req_time(devc, FALSE, target); if ((ret = korad_kaxxxxp_read_chars(serial, count, reply)) < 0) { g_mutex_unlock(&devc->rw_mutex); diff --git a/src/hardware/korad-kaxxxxp/protocol.h b/src/hardware/korad-kaxxxxp/protocol.h index 0c7ba535..005d94ab 100644 --- a/src/hardware/korad-kaxxxxp/protocol.h +++ b/src/hardware/korad-kaxxxxp/protocol.h @@ -37,7 +37,8 @@ enum korad_quirks_flag { KORAD_QUIRK_ID_NO_VENDOR = 1UL << 1, KORAD_QUIRK_ID_TRAILING = 1UL << 2, KORAD_QUIRK_ID_OPT_VERSION = 1UL << 3, - KORAD_QUIRK_ALL = (1UL << 4) - 1, + KORAD_QUIRK_SLOW_PROCESSING = 1UL << 4, + KORAD_QUIRK_ALL = (1UL << 5) - 1, }; /* Information on single model */ @@ -70,7 +71,7 @@ struct dev_context { const struct korad_kaxxxxp_model *model; /**< Model information. */ struct sr_sw_limits limits; - int64_t req_sent_at; + int64_t next_req_time; GMutex rw_mutex; float current; /**< Last current value [A] read from device. */