zketech-ebd-usb: First version of the driver.
This commit is contained in:
parent
c527132aec
commit
9890fb1f08
|
@ -20,115 +20,198 @@
|
|||
#include <config.h>
|
||||
#include "protocol.h"
|
||||
|
||||
static const uint32_t scanopts[] = {
|
||||
SR_CONF_CONN,
|
||||
SR_CONF_SERIALCOMM,
|
||||
};
|
||||
|
||||
static const uint32_t drvopts[] = {
|
||||
SR_CONF_ELECTRONIC_LOAD,
|
||||
};
|
||||
|
||||
static const uint32_t devopts[] = {
|
||||
SR_CONF_CONTINUOUS,
|
||||
SR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
|
||||
SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
|
||||
};
|
||||
|
||||
static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
||||
{
|
||||
struct drv_context *drvc;
|
||||
GSList *devices;
|
||||
struct dev_context *devc;
|
||||
GSList *l;
|
||||
struct sr_dev_inst *sdi;
|
||||
const char *conn, *serialcomm;
|
||||
struct sr_config *src;
|
||||
struct sr_serial_dev_inst *serial;
|
||||
uint8_t reply[MSGLEN];
|
||||
|
||||
(void)options;
|
||||
conn = NULL;
|
||||
serialcomm = NULL;
|
||||
|
||||
devices = NULL;
|
||||
drvc = di->context;
|
||||
drvc->instances = NULL;
|
||||
|
||||
/* TODO: scan for devices, either based on a SR_CONF_CONN option
|
||||
* or on a USB scan. */
|
||||
|
||||
return devices;
|
||||
for (l = options; l; l = l->next) {
|
||||
src = l->data;
|
||||
switch (src->key) {
|
||||
case SR_CONF_CONN:
|
||||
conn = g_variant_get_string(src->data, NULL);
|
||||
break;
|
||||
case SR_CONF_SERIALCOMM:
|
||||
serialcomm = g_variant_get_string(src->data, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int dev_open(struct sr_dev_inst *sdi)
|
||||
{
|
||||
(void)sdi;
|
||||
if (!conn)
|
||||
return NULL;
|
||||
if (!serialcomm)
|
||||
serialcomm = "9600/8e1";
|
||||
|
||||
/* TODO: get handle from sdi->conn and open it. */
|
||||
serial = sr_serial_dev_inst_new(conn, serialcomm);
|
||||
if (serial_open(serial, SERIAL_RDWR) != SR_OK)
|
||||
return NULL;
|
||||
|
||||
return SR_OK;
|
||||
sdi = g_malloc0(sizeof(struct sr_dev_inst));
|
||||
sdi->status = SR_ST_INACTIVE;
|
||||
sdi->vendor = g_strdup("ZKETECH");
|
||||
sdi->model = g_strdup("EBD-USB");
|
||||
sdi->inst_type = SR_INST_SERIAL;
|
||||
sdi->conn = serial;
|
||||
|
||||
sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "V");
|
||||
sr_channel_new(sdi, 1, SR_CHANNEL_ANALOG, TRUE, "I");
|
||||
|
||||
devc = g_malloc0(sizeof(struct dev_context));
|
||||
g_mutex_init(&devc->rw_mutex);
|
||||
devc->current_limit = 0;
|
||||
devc->running = FALSE;
|
||||
devc->load_activated = FALSE;
|
||||
sr_sw_limits_init(&devc->limits);
|
||||
sdi->priv = devc;
|
||||
|
||||
/* Starting device. */
|
||||
zketech_ebd_usb_init(serial, devc);
|
||||
int ret = zketech_ebd_usb_read_chars(serial, MSGLEN, reply);
|
||||
if (ret != MSGLEN || reply[MSGFRAMEBEGINPOS] != MSGFRAMEBEGIN \
|
||||
|| reply[MSGFRAMEENDPOS] != MSGFRAMEEND) {
|
||||
sr_warn("Invalid message received!");
|
||||
ret = SR_ERR;
|
||||
}
|
||||
zketech_ebd_usb_stop(serial, devc);
|
||||
|
||||
serial_close(serial);
|
||||
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
return std_scan_complete(di, g_slist_append(NULL, sdi));
|
||||
}
|
||||
|
||||
static int dev_close(struct sr_dev_inst *sdi)
|
||||
{
|
||||
(void)sdi;
|
||||
struct dev_context *devc;
|
||||
|
||||
/* TODO: get handle from sdi->conn and close it. */
|
||||
devc = (sdi) ? sdi->priv : NULL;
|
||||
if (devc)
|
||||
g_mutex_clear(&devc->rw_mutex);
|
||||
|
||||
return SR_OK;
|
||||
return std_serial_dev_close(sdi);
|
||||
}
|
||||
|
||||
static int config_get(uint32_t key, GVariant **data,
|
||||
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
|
||||
{
|
||||
int ret;
|
||||
struct dev_context *devc;
|
||||
float fvalue;
|
||||
|
||||
(void)sdi;
|
||||
(void)data;
|
||||
(void)cg;
|
||||
|
||||
ret = SR_OK;
|
||||
if (!sdi || !data)
|
||||
return SR_ERR_ARG;
|
||||
|
||||
devc = sdi->priv;
|
||||
|
||||
switch (key) {
|
||||
/* TODO */
|
||||
case SR_CONF_LIMIT_SAMPLES:
|
||||
case SR_CONF_LIMIT_MSEC:
|
||||
return sr_sw_limits_config_get(&devc->limits, key, data);
|
||||
case SR_CONF_CURRENT_LIMIT:
|
||||
ret = zketech_ebd_usb_get_current_limit(sdi, &fvalue);
|
||||
if (ret == SR_OK)
|
||||
*data = g_variant_new_double(fvalue);
|
||||
return ret;
|
||||
default:
|
||||
return SR_ERR_NA;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int config_set(uint32_t key, GVariant *data,
|
||||
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
|
||||
{
|
||||
int ret;
|
||||
double value;
|
||||
struct dev_context *devc;
|
||||
|
||||
(void)sdi;
|
||||
(void)data;
|
||||
(void)cg;
|
||||
|
||||
ret = SR_OK;
|
||||
switch (key) {
|
||||
/* TODO */
|
||||
default:
|
||||
ret = SR_ERR_NA;
|
||||
}
|
||||
devc = sdi->priv;
|
||||
|
||||
return ret;
|
||||
switch (key) {
|
||||
case SR_CONF_LIMIT_MSEC:
|
||||
case SR_CONF_LIMIT_SAMPLES:
|
||||
return sr_sw_limits_config_set(&devc->limits, key, data);
|
||||
case SR_CONF_CURRENT_LIMIT:
|
||||
value = g_variant_get_double(data);
|
||||
if (value < 0.0 || value > 4.0)
|
||||
return SR_ERR_ARG;
|
||||
return zketech_ebd_usb_set_current_limit(sdi, value);
|
||||
default:
|
||||
return SR_ERR_NA;
|
||||
}
|
||||
}
|
||||
|
||||
static int config_list(uint32_t key, GVariant **data,
|
||||
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)sdi;
|
||||
(void)data;
|
||||
(void)cg;
|
||||
|
||||
ret = SR_OK;
|
||||
switch (key) {
|
||||
/* TODO */
|
||||
case SR_CONF_SCAN_OPTIONS:
|
||||
case SR_CONF_DEVICE_OPTIONS:
|
||||
return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
|
||||
case SR_CONF_CURRENT_LIMIT:
|
||||
*data = std_gvar_min_max_step(0.0, 4.0, 0.01);
|
||||
break;
|
||||
default:
|
||||
return SR_ERR_NA;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
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 *devc;
|
||||
struct sr_serial_dev_inst *serial;
|
||||
|
||||
(void)sdi;
|
||||
devc = sdi->priv;
|
||||
serial = sdi->conn;
|
||||
|
||||
sr_sw_limits_acquisition_start(&devc->limits);
|
||||
std_session_send_df_header(sdi);
|
||||
|
||||
zketech_ebd_usb_init(serial, devc);
|
||||
if (!zketech_ebd_usb_current_is0(devc))
|
||||
zketech_ebd_usb_loadstart(serial, devc);
|
||||
|
||||
serial_source_add(sdi->session, serial, G_IO_IN, 100,
|
||||
zketech_ebd_usb_receive_data, (void *)sdi);
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
static int dev_acquisition_stop(struct sr_dev_inst *sdi)
|
||||
{
|
||||
/* TODO: stop acquisition. */
|
||||
zketech_ebd_usb_loadstop(sdi->conn, sdi->priv);
|
||||
|
||||
(void)sdi;
|
||||
|
||||
return SR_OK;
|
||||
return std_serial_dev_acquisition_stop(sdi);
|
||||
}
|
||||
|
||||
SR_PRIV struct sr_dev_driver zketech_ebd_usb_driver_info = {
|
||||
|
@ -143,11 +226,10 @@ SR_PRIV struct sr_dev_driver zketech_ebd_usb_driver_info = {
|
|||
.config_get = config_get,
|
||||
.config_set = config_set,
|
||||
.config_list = config_list,
|
||||
.dev_open = dev_open,
|
||||
.dev_open = std_serial_dev_open,
|
||||
.dev_close = dev_close,
|
||||
.dev_acquisition_start = dev_acquisition_start,
|
||||
.dev_acquisition_stop = dev_acquisition_stop,
|
||||
.context = NULL,
|
||||
};
|
||||
|
||||
SR_REGISTER_DEV_DRIVER(zketech_ebd_usb_driver_info);
|
||||
|
|
|
@ -20,22 +20,324 @@
|
|||
#include <config.h>
|
||||
#include "protocol.h"
|
||||
|
||||
/* Send a command to the device. */
|
||||
SR_PRIV int zketech_ebd_usb_send(struct sr_serial_dev_inst *serial,
|
||||
uint8_t buf[], size_t count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
zketech_ebd_usb_buffer_debug("Sending", buf, count);
|
||||
ret = serial_write_blocking(serial, buf, count, 0);
|
||||
if (ret < 0) {
|
||||
sr_err("Error sending command: %d.", ret);
|
||||
return ret;
|
||||
}
|
||||
sr_dbg("Sent %d bytes.", ret);
|
||||
|
||||
return (ret == (int)count) ? SR_OK : SR_ERR;
|
||||
}
|
||||
|
||||
/* Send the init/connect sequence; drive starts sending voltage and current. */
|
||||
SR_PRIV int zketech_ebd_usb_init(struct sr_serial_dev_inst *serial,
|
||||
struct dev_context *devc)
|
||||
{
|
||||
uint8_t init[] = { 0xfa, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf8 };
|
||||
|
||||
(void)devc;
|
||||
|
||||
int ret = zketech_ebd_usb_send(serial, init, 10);
|
||||
if (ret == SR_OK)
|
||||
devc->running = TRUE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start the load functionality. */
|
||||
SR_PRIV int zketech_ebd_usb_loadstart(struct sr_serial_dev_inst *serial,
|
||||
struct dev_context *devc)
|
||||
{
|
||||
uint8_t start[] = { 0xfa, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8 };
|
||||
int ret;
|
||||
|
||||
ret = zketech_ebd_usb_send(serial, start, 10);
|
||||
sr_dbg("Current limit: %f.", devc->current_limit);
|
||||
if (zketech_ebd_usb_current_is0(devc))
|
||||
return SR_OK;
|
||||
|
||||
ret = zketech_ebd_usb_sendcfg(serial, devc);
|
||||
if (ret == SR_OK) {
|
||||
sr_dbg("Load activated.");
|
||||
devc->load_activated = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Stop the load functionality. */
|
||||
SR_PRIV int zketech_ebd_usb_loadstop(struct sr_serial_dev_inst *serial,
|
||||
struct dev_context *devc)
|
||||
{
|
||||
int ret;
|
||||
uint8_t stop[] = { 0xfa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xF8 };
|
||||
|
||||
ret = zketech_ebd_usb_send(serial, stop, 10);
|
||||
if (ret == SR_OK)
|
||||
devc->load_activated = FALSE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Stop the drive. */
|
||||
SR_PRIV int zketech_ebd_usb_stop(struct sr_serial_dev_inst *serial,
|
||||
struct dev_context *devc)
|
||||
{
|
||||
uint8_t stop[] = { 0xfa, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xF8 };
|
||||
int ret;
|
||||
|
||||
(void) devc;
|
||||
|
||||
ret = zketech_ebd_usb_send(serial, stop, 10);
|
||||
if (ret == SR_OK) {
|
||||
devc->load_activated = FALSE;
|
||||
devc->running= FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Send updated configuration values to the load. */
|
||||
SR_PRIV int zketech_ebd_usb_sendcfg(struct sr_serial_dev_inst *serial,
|
||||
struct dev_context *devc)
|
||||
{
|
||||
uint8_t send[] = { 0xfa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8 };
|
||||
|
||||
zketech_ebd_usb_value_encode(devc->current_limit, &send[2],
|
||||
&send[3], 1000.0);
|
||||
|
||||
send[8] = send[1] ^ send[2] ^ send[3] ^ send[4] ^ send[5] ^ \
|
||||
send[6] ^ send[7];
|
||||
|
||||
return zketech_ebd_usb_send(serial, send, 10);
|
||||
}
|
||||
|
||||
/** Read count bytes from the serial connection. */
|
||||
SR_PRIV int zketech_ebd_usb_read_chars(struct sr_serial_dev_inst *serial,
|
||||
int count, uint8_t *buf)
|
||||
{
|
||||
int ret, received, turns;
|
||||
|
||||
received = 0;
|
||||
turns = 0;
|
||||
|
||||
do {
|
||||
ret = serial_read_blocking(serial, buf + received,
|
||||
count - received, serial_timeout(serial, count));
|
||||
if (ret < 0) {
|
||||
sr_err("Error %d reading %d bytes.", ret, count);
|
||||
return ret;
|
||||
}
|
||||
received += ret;
|
||||
turns++;
|
||||
} while ((received < count) && (turns < 100));
|
||||
|
||||
zketech_ebd_usb_buffer_debug("Received", buf, received);
|
||||
|
||||
return received;
|
||||
}
|
||||
|
||||
/* Decode high byte and low byte into a float. */
|
||||
SR_PRIV float zketech_ebd_usb_value_decode(uint8_t hi, uint8_t lo, float divisor)
|
||||
{
|
||||
return ((float)hi * 240.0 + (float)lo) / divisor;
|
||||
}
|
||||
|
||||
/* Encode a float into high byte and low byte. */
|
||||
SR_PRIV void zketech_ebd_usb_value_encode(float current, uint8_t *hi,
|
||||
uint8_t *lo, float divisor)
|
||||
{
|
||||
int value;
|
||||
|
||||
value = (int)(current * divisor);
|
||||
sr_dbg("Value %d %d %d", value, value / 240, value % 240);
|
||||
*hi = value / 240;
|
||||
*lo = value % 240;
|
||||
}
|
||||
|
||||
SR_PRIV int zketech_ebd_usb_receive_data(int fd, int revents, void *cb_data)
|
||||
{
|
||||
const struct sr_dev_inst *sdi;
|
||||
struct sr_dev_inst *sdi;
|
||||
struct dev_context *devc;
|
||||
struct sr_serial_dev_inst *serial;
|
||||
struct sr_datafeed_packet packet;
|
||||
struct sr_datafeed_analog analog;
|
||||
struct sr_analog_encoding encoding;
|
||||
struct sr_analog_meaning meaning;
|
||||
struct sr_analog_spec spec;
|
||||
float voltage, current, current_limit;
|
||||
GSList *l;
|
||||
|
||||
(void)revents;
|
||||
(void)fd;
|
||||
|
||||
if (!(sdi = cb_data))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
|
||||
if (!(devc = sdi->priv))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
|
||||
if (revents == G_IO_IN) {
|
||||
/* TODO */
|
||||
serial = sdi->conn;
|
||||
|
||||
uint8_t reply[MSGLEN];
|
||||
int ret = zketech_ebd_usb_read_chars(serial, MSGLEN, reply);
|
||||
|
||||
/* Tests for correct message. */
|
||||
if (ret != MSGLEN) {
|
||||
sr_err("Message invalid [Len].");
|
||||
return (ret < 0) ? ret : SR_ERR;
|
||||
}
|
||||
|
||||
uint8_t xor = reply[1] ^ reply[2] ^ reply[3] ^ reply[4] ^ \
|
||||
reply[5] ^ reply[6] ^ reply[7] ^ reply[8] ^ \
|
||||
reply[9] ^ reply[10] ^ reply[11] ^ reply[12] ^ \
|
||||
reply[13] ^ reply[14] ^ reply[15] ^ reply[16];
|
||||
|
||||
if (reply[MSGFRAMEBEGINPOS] != MSGFRAMEBEGIN || \
|
||||
reply[MSGFRAMEENDPOS] != MSGFRAMEEND || \
|
||||
xor != reply[MSGCHECKSUMPOS]) {
|
||||
sr_err("Message invalid [XOR, BEGIN/END].");
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
/* Calculate values. */
|
||||
sr_dbg("V: %02X %02X A: %02X %02X -- Limit %02X %02X", reply[4],
|
||||
reply[5], reply[2], reply[3], reply[10], reply[11]);
|
||||
|
||||
voltage = zketech_ebd_usb_value_decode(reply[4], reply[5], 1000.0);
|
||||
current = zketech_ebd_usb_value_decode(reply[2], reply[3], 10000.0);
|
||||
current_limit = zketech_ebd_usb_value_decode(reply[10], reply[11], 1000.0);
|
||||
|
||||
sr_dbg("Voltage %f", voltage);
|
||||
sr_dbg("Current %f", current);
|
||||
sr_dbg("Current limit %f", current_limit);
|
||||
|
||||
/* Begin frame. */
|
||||
packet.type = SR_DF_FRAME_BEGIN;
|
||||
packet.payload = NULL;
|
||||
sr_session_send(sdi, &packet);
|
||||
|
||||
sr_analog_init(&analog, &encoding, &meaning, &spec, 4);
|
||||
|
||||
packet.type = SR_DF_ANALOG;
|
||||
packet.payload = &analog;
|
||||
analog.num_samples = 1;
|
||||
|
||||
/* Voltage */
|
||||
l = g_slist_copy(sdi->channels);
|
||||
l = g_slist_remove_link(l, g_slist_nth(l, 1));
|
||||
meaning.channels = l;
|
||||
meaning.mq = SR_MQ_VOLTAGE;
|
||||
meaning.mqflags = SR_MQFLAG_DC;
|
||||
meaning.unit = SR_UNIT_VOLT;
|
||||
analog.data = &voltage;
|
||||
sr_session_send(sdi, &packet);
|
||||
g_slist_free(l);
|
||||
|
||||
/* Current */
|
||||
l = g_slist_copy(sdi->channels);
|
||||
l = g_slist_remove_link(l, g_slist_nth(l, 0));
|
||||
meaning.channels = l;
|
||||
meaning.mq = SR_MQ_CURRENT;
|
||||
meaning.mqflags = SR_MQFLAG_DC;
|
||||
meaning.unit = SR_UNIT_AMPERE;
|
||||
analog.data = ¤t;
|
||||
sr_session_send(sdi, &packet);
|
||||
g_slist_free(l);
|
||||
|
||||
/* End frame. */
|
||||
packet.type = SR_DF_FRAME_END;
|
||||
packet.payload = NULL;
|
||||
sr_session_send(sdi, &packet);
|
||||
|
||||
sr_sw_limits_update_samples_read(&devc->limits, 1);
|
||||
if (sr_sw_limits_check(&devc->limits))
|
||||
sr_dev_acquisition_stop(sdi);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SR_PRIV int zketech_ebd_usb_get_current_limit(const struct sr_dev_inst *sdi,
|
||||
float *current)
|
||||
{
|
||||
struct dev_context *devc;
|
||||
|
||||
if (!(devc = sdi->priv))
|
||||
return SR_ERR;
|
||||
|
||||
g_mutex_lock(&devc->rw_mutex);
|
||||
*current = devc->current_limit;
|
||||
g_mutex_unlock(&devc->rw_mutex);
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int zketech_ebd_usb_set_current_limit(const struct sr_dev_inst *sdi,
|
||||
float current)
|
||||
{
|
||||
struct dev_context *devc;
|
||||
int ret;
|
||||
|
||||
if (!(devc = sdi->priv))
|
||||
return SR_ERR;
|
||||
|
||||
g_mutex_lock(&devc->rw_mutex);
|
||||
devc->current_limit = current;
|
||||
|
||||
if (!devc->running) {
|
||||
sr_dbg("Setting current limit later.");
|
||||
g_mutex_unlock(&devc->rw_mutex);
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
sr_dbg("Setting current limit to %fV.", current);
|
||||
|
||||
if (devc->load_activated) {
|
||||
if (zketech_ebd_usb_current_is0(devc)) {
|
||||
/* Stop load. */
|
||||
ret = zketech_ebd_usb_loadstop(sdi->conn, devc);
|
||||
} else {
|
||||
/* Send new current. */
|
||||
ret = zketech_ebd_usb_sendcfg(sdi->conn, devc);
|
||||
}
|
||||
} else {
|
||||
if (zketech_ebd_usb_current_is0(devc)) {
|
||||
/* Nothing to do. */
|
||||
ret = SR_OK;
|
||||
} else {
|
||||
/* Start load. */
|
||||
ret = zketech_ebd_usb_loadstart(sdi->conn, devc);
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock(&devc->rw_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SR_PRIV gboolean zketech_ebd_usb_current_is0(struct dev_context *devc)
|
||||
{
|
||||
return devc->current_limit < 0.001;
|
||||
}
|
||||
|
||||
/* Log a byte-array as hex values. */
|
||||
SR_PRIV void zketech_ebd_usb_buffer_debug(const char *message, uint8_t buf[],
|
||||
size_t count)
|
||||
{
|
||||
char buffer[count * 2 + 1];
|
||||
|
||||
for (size_t j = 0; j < count; j++)
|
||||
sprintf(&buffer[2 * j], "%02X", buf[j]);
|
||||
|
||||
buffer[count * 2] = 0;
|
||||
|
||||
sr_dbg("%s: %s [%lu bytes]", message, buffer, count);
|
||||
}
|
||||
|
|
|
@ -27,9 +27,44 @@
|
|||
|
||||
#define LOG_PREFIX "zketech-ebd-usb"
|
||||
|
||||
#define MSGLEN 19
|
||||
#define MSGCHECKSUMPOS 17
|
||||
#define MSGFRAMEBEGIN 0xfa
|
||||
#define MSGFRAMEBEGINPOS 0
|
||||
#define MSGFRAMEEND 0xf8
|
||||
#define MSGFRAMEENDPOS 18
|
||||
|
||||
struct dev_context {
|
||||
struct sr_sw_limits limits;
|
||||
GMutex rw_mutex;
|
||||
float current_limit;
|
||||
gboolean running;
|
||||
gboolean load_activated;
|
||||
};
|
||||
|
||||
SR_PRIV float zketech_ebd_usb_value_decode(uint8_t b1, uint8_t b2, float divisor);
|
||||
SR_PRIV void zketech_ebd_usb_value_encode(float voltage, uint8_t *b1, uint8_t *b2, float divisor);
|
||||
|
||||
/* Communication via serial. */
|
||||
SR_PRIV int zketech_ebd_usb_send(struct sr_serial_dev_inst *serial, uint8_t buf[], size_t count);
|
||||
SR_PRIV int zketech_ebd_usb_sendcfg(struct sr_serial_dev_inst *serial, struct dev_context *devc);
|
||||
SR_PRIV int zketech_ebd_usb_read_chars(struct sr_serial_dev_inst *serial,
|
||||
int count, uint8_t *buf);
|
||||
|
||||
/* Commands. */
|
||||
SR_PRIV int zketech_ebd_usb_init(struct sr_serial_dev_inst *serial, struct dev_context *devc);
|
||||
SR_PRIV int zketech_ebd_usb_loadstart(struct sr_serial_dev_inst *serial, struct dev_context *devc);
|
||||
SR_PRIV int zketech_ebd_usb_receive_data(int fd, int revents, void *cb_data);
|
||||
SR_PRIV int zketech_ebd_usb_stop(struct sr_serial_dev_inst *serial, struct dev_context *devc);
|
||||
SR_PRIV int zketech_ebd_usb_loadstop(struct sr_serial_dev_inst *serial, struct dev_context *devc);
|
||||
|
||||
/* Configuration. */
|
||||
SR_PRIV int zketech_ebd_usb_get_current_limit(const struct sr_dev_inst *sdi,
|
||||
float *current);
|
||||
SR_PRIV int zketech_ebd_usb_set_current_limit(const struct sr_dev_inst *sdi,
|
||||
float current);
|
||||
SR_PRIV gboolean zketech_ebd_usb_current_is0(struct dev_context *devc);
|
||||
|
||||
SR_PRIV void zketech_ebd_usb_buffer_debug(const char *message, uint8_t buf[], size_t count);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue