]> sigrok.org Git - libsigrok.git/commitdiff
korad-kaxxxxp: add quirk for long processing times of commands
authorGerhard Sittig <redacted>
Sat, 25 Feb 2023 16:45:57 +0000 (17:45 +0100)
committerGerhard Sittig <redacted>
Sun, 26 Feb 2023 06:47:46 +0000 (07:47 +0100)
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 <redacted>.

src/hardware/korad-kaxxxxp/api.c
src/hardware/korad-kaxxxxp/protocol.c
src/hardware/korad-kaxxxxp/protocol.h

index 8cbd1cce69728eb42689aa53a31c8c8caf0e779b..82e43797484ab29a8f247a2b3e17a4b932ea9638 100644 (file)
@@ -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,
index 2b980352f38f5e4f411f5278d107a757c6cca96b..bac8c8ef705fe06b8d5428fd66436431109e27be 100644 (file)
@@ -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);
index 0c7ba535406961cb9461febe0d723187fa8c3d10..005d94ab15f7757ade08b9fecf05f12079ae549a 100644 (file)
@@ -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. */