Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/hardware/korad-kaxxxxp/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ static const double amps_5[] = { 0, 5.1, 0.001, };

static const struct korad_kaxxxxp_model models[] = {
/* Vendor, model name, ID reply, channels, voltage, current, quirks. */
{"Korad", "KA3005PS", "", 1, volts_30, amps_5,
KORAD_QUIRK_NEWLINE},
{"Korad", "KA3005P", "", 1, volts_30, amps_5,
KORAD_QUIRK_ID_TRAILING},
{"Korad", "KD3005P", "", 1, volts_30, amps_5, 0},
Expand Down Expand Up @@ -278,11 +280,26 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
len = sizeof(reply) - 1;
sr_dbg("Want max %zu bytes.", len);

ret = korad_kaxxxxp_send_cmd(serial, "*IDN?");
/*
* For the identification we send two messages due to the newline quirk
* The first works on devices that require no newline to be there
* The second adds support for devices that require the newline to be there
* The timeout makes sure the former devices handle the cmd first
*/
ret = korad_kaxxxxp_send_cmd(serial, "*IDN?", false);
if (ret < 0)
return NULL;

ret = korad_kaxxxxp_read_chars(serial, len, reply);
g_usleep(100000);
ret = korad_kaxxxxp_send_cmd(serial, "\n", false);
if (ret < 0)
return NULL;

/*
* Newline stripping enabled by default - doesn't matter for devices that
* don't add one
*/
ret = korad_kaxxxxp_read_chars(serial, len, reply, true);
if (ret < 0)
return NULL;
sr_dbg("Received: %d, %s", ret, reply);
Expand Down
48 changes: 35 additions & 13 deletions src/hardware/korad-kaxxxxp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,26 @@
#define EXTRA_PROCESSING_TIME_MS 450

SR_PRIV int korad_kaxxxxp_send_cmd(struct sr_serial_dev_inst *serial,
const char *cmd)
const char *cmd, bool add_newline)
{
int ret;

sr_dbg("Sending '%s'.", cmd);
if ((ret = serial_write_blocking(serial, cmd, strlen(cmd), 0)) < 0) {
char* addition = "";
if (add_newline)
addition = "\n";

/* 21 was chosen here because 20 is chosen in korad_kaxxxxp_set_value */
char newcmd[21];
ret = sr_snprintf_ascii(newcmd, 21, "%s%s", cmd, addition);
if (ret < 0 || ret >= 21) {
sr_err("Error creating command: %d.", ret);
if (ret > 0)
ret = -ret; /* make errors always return negative numbers */
return ret;
}

sr_dbg("Sending '%s'.", newcmd);
if ((ret = serial_write_blocking(serial, newcmd, strlen(newcmd), 0)) < 0) {
sr_err("Error sending command: %d.", ret);
return ret;
}
Expand Down Expand Up @@ -71,7 +85,7 @@ SR_PRIV int korad_kaxxxxp_send_cmd(struct sr_serial_dev_inst *serial,
* larger initial timeout period before receive data is seen.
*/
SR_PRIV int korad_kaxxxxp_read_chars(struct sr_serial_dev_inst *serial,
size_t count, char *buf)
size_t count, char *buf, bool strip_newline)
{
int timeout_first, timeout_later, timeout;
size_t retries_first, retries_later, retries;
Expand Down Expand Up @@ -146,6 +160,10 @@ SR_PRIV int korad_kaxxxxp_read_chars(struct sr_serial_dev_inst *serial,
timeout = timeout_later;
retries = retries_later;
}

if (strip_newline && buf[received-1] == '\n')
buf[--received] = 0x00;

/* TODO Escape non-printables? Seen those with status queries. */
sr_dbg("got %zu bytes, received: '%s'.", received, buf);

Expand Down Expand Up @@ -259,7 +277,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);
ret = korad_kaxxxxp_send_cmd(serial, msg, devc->model->quirks & KORAD_QUIRK_NEWLINE);
devc->next_req_time = next_req_time(devc, TRUE, target);
}

Expand All @@ -272,7 +290,7 @@ SR_PRIV int korad_kaxxxxp_get_value(struct sr_serial_dev_inst *serial,
int target, struct dev_context *devc)
{
int ret, count;
char reply[6];
char reply[7];
float *value;
char status_byte;
gboolean needs_ovp_quirk;
Expand All @@ -282,36 +300,40 @@ SR_PRIV int korad_kaxxxxp_get_value(struct sr_serial_dev_inst *serial,
give_device_time_to_process(devc);

value = NULL;
count = 5;
count = 6;

bool newline_quirk = devc->model->quirks & KORAD_QUIRK_NEWLINE;

switch (target) {
case KAXXXXP_CURRENT:
/* Read current from device. */
ret = korad_kaxxxxp_send_cmd(serial, "IOUT1?");
ret = korad_kaxxxxp_send_cmd(serial, "IOUT1?", newline_quirk);
value = &(devc->current);
break;
case KAXXXXP_CURRENT_LIMIT:
/* Read set current from device. */
ret = korad_kaxxxxp_send_cmd(serial, "ISET1?");
ret = korad_kaxxxxp_send_cmd(serial, "ISET1?", newline_quirk);
value = &(devc->current_limit);
break;
case KAXXXXP_VOLTAGE:
/* Read voltage from device. */
ret = korad_kaxxxxp_send_cmd(serial, "VOUT1?");
ret = korad_kaxxxxp_send_cmd(serial, "VOUT1?", newline_quirk);
value = &(devc->voltage);
break;
case KAXXXXP_VOLTAGE_TARGET:
/* Read set voltage from device. */
ret = korad_kaxxxxp_send_cmd(serial, "VSET1?");
ret = korad_kaxxxxp_send_cmd(serial, "VSET1?", newline_quirk);
value = &(devc->voltage_target);
break;
case KAXXXXP_STATUS:
case KAXXXXP_OUTPUT:
case KAXXXXP_OCP:
case KAXXXXP_OVP:
/* Read status from device. */
ret = korad_kaxxxxp_send_cmd(serial, "STATUS?");
ret = korad_kaxxxxp_send_cmd(serial, "STATUS?", newline_quirk);
count = 1;
if (newline_quirk)
count = 2;
break;
default:
sr_err("Don't know how to query %d.", target);
Expand All @@ -324,7 +346,7 @@ SR_PRIV int korad_kaxxxxp_get_value(struct sr_serial_dev_inst *serial,

devc->next_req_time = next_req_time(devc, FALSE, target);

if ((ret = korad_kaxxxxp_read_chars(serial, count, reply)) < 0) {
if ((ret = korad_kaxxxxp_read_chars(serial, count, reply, newline_quirk)) < 0) {
g_mutex_unlock(&devc->rw_mutex);
return ret;
}
Expand Down
8 changes: 5 additions & 3 deletions src/hardware/korad-kaxxxxp/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef LIBSIGROK_HARDWARE_KORAD_KAXXXXP_PROTOCOL_H
#define LIBSIGROK_HARDWARE_KORAD_KAXXXXP_PROTOCOL_H

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <glib.h>
Expand All @@ -38,7 +39,8 @@ enum korad_quirks_flag {
KORAD_QUIRK_ID_TRAILING = 1UL << 2,
KORAD_QUIRK_ID_OPT_VERSION = 1UL << 3,
KORAD_QUIRK_SLOW_PROCESSING = 1UL << 4,
KORAD_QUIRK_ALL = (1UL << 5) - 1,
KORAD_QUIRK_NEWLINE = 1UL << 5,
KORAD_QUIRK_ALL = (1UL << 6) - 1,
};

/* Information on single model */
Expand Down Expand Up @@ -103,9 +105,9 @@ struct dev_context {
};

SR_PRIV int korad_kaxxxxp_send_cmd(struct sr_serial_dev_inst *serial,
const char *cmd);
const char *cmd, bool add_newline);
SR_PRIV int korad_kaxxxxp_read_chars(struct sr_serial_dev_inst *serial,
size_t count, char *buf);
size_t count, char *buf, bool strip_newline);
SR_PRIV int korad_kaxxxxp_set_value(struct sr_serial_dev_inst *serial,
int target, struct dev_context *devc);
SR_PRIV int korad_kaxxxxp_get_value(struct sr_serial_dev_inst *serial,
Expand Down