]> sigrok.org Git - libsigrok.git/blame - src/hardware/zketech-ebd-usb/api.c
scpi-pps: Add a missing "break" in config_get().
[libsigrok.git] / src / hardware / zketech-ebd-usb / api.c
CommitLineData
c527132a
SBO
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2018 Sven Bursch-Osewold <sb_git@bursch.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <config.h>
21#include "protocol.h"
22
9890fb1f
SBO
23static const uint32_t scanopts[] = {
24 SR_CONF_CONN,
25 SR_CONF_SERIALCOMM,
26};
c527132a 27
9890fb1f
SBO
28static const uint32_t drvopts[] = {
29 SR_CONF_ELECTRONIC_LOAD,
30};
c527132a 31
9890fb1f
SBO
32static const uint32_t devopts[] = {
33 SR_CONF_CONTINUOUS,
34 SR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
35 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
36};
c527132a 37
9890fb1f
SBO
38static GSList *scan(struct sr_dev_driver *di, GSList *options)
39{
40 struct dev_context *devc;
41 GSList *l;
42 struct sr_dev_inst *sdi;
43 const char *conn, *serialcomm;
44 struct sr_config *src;
45 struct sr_serial_dev_inst *serial;
ec4806dc 46 uint8_t reply[MSG_LEN];
9890fb1f
SBO
47
48 conn = NULL;
49 serialcomm = NULL;
50
51 for (l = options; l; l = l->next) {
52 src = l->data;
53 switch (src->key) {
54 case SR_CONF_CONN:
55 conn = g_variant_get_string(src->data, NULL);
56 break;
57 case SR_CONF_SERIALCOMM:
58 serialcomm = g_variant_get_string(src->data, NULL);
59 break;
60 }
61 }
c527132a 62
9890fb1f
SBO
63 if (!conn)
64 return NULL;
65 if (!serialcomm)
66 serialcomm = "9600/8e1";
67
68 serial = sr_serial_dev_inst_new(conn, serialcomm);
69 if (serial_open(serial, SERIAL_RDWR) != SR_OK)
70 return NULL;
71
72 sdi = g_malloc0(sizeof(struct sr_dev_inst));
73 sdi->status = SR_ST_INACTIVE;
74 sdi->vendor = g_strdup("ZKETECH");
75 sdi->model = g_strdup("EBD-USB");
76 sdi->inst_type = SR_INST_SERIAL;
77 sdi->conn = serial;
78
79 sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "V");
80 sr_channel_new(sdi, 1, SR_CHANNEL_ANALOG, TRUE, "I");
81
82 devc = g_malloc0(sizeof(struct dev_context));
83 g_mutex_init(&devc->rw_mutex);
84 devc->current_limit = 0;
85 devc->running = FALSE;
86 devc->load_activated = FALSE;
87 sr_sw_limits_init(&devc->limits);
88 sdi->priv = devc;
89
90 /* Starting device. */
330a32b2
UH
91 ebd_init(serial, devc);
92 int ret = ebd_read_chars(serial, MSG_LEN, reply);
ec4806dc
UH
93 if (ret != MSG_LEN || reply[MSG_FRAME_BEGIN_POS] != MSG_FRAME_BEGIN \
94 || reply[MSG_FRAME_END_POS] != MSG_FRAME_END) {
9890fb1f
SBO
95 sr_warn("Invalid message received!");
96 ret = SR_ERR;
97 }
330a32b2 98 ebd_stop(serial, devc);
c527132a 99
9890fb1f 100 serial_close(serial);
c527132a 101
9890fb1f
SBO
102 if (ret < 0)
103 return NULL;
c527132a 104
9890fb1f 105 return std_scan_complete(di, g_slist_append(NULL, sdi));
c527132a
SBO
106}
107
108static int dev_close(struct sr_dev_inst *sdi)
109{
9890fb1f 110 struct dev_context *devc;
c527132a 111
9890fb1f
SBO
112 devc = (sdi) ? sdi->priv : NULL;
113 if (devc)
114 g_mutex_clear(&devc->rw_mutex);
c527132a 115
9890fb1f 116 return std_serial_dev_close(sdi);
c527132a
SBO
117}
118
119static int config_get(uint32_t key, GVariant **data,
120 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
121{
122 int ret;
9890fb1f
SBO
123 struct dev_context *devc;
124 float fvalue;
c527132a 125
c527132a
SBO
126 (void)cg;
127
9890fb1f
SBO
128 if (!sdi || !data)
129 return SR_ERR_ARG;
130
131 devc = sdi->priv;
132
c527132a 133 switch (key) {
9890fb1f
SBO
134 case SR_CONF_LIMIT_SAMPLES:
135 case SR_CONF_LIMIT_MSEC:
136 return sr_sw_limits_config_get(&devc->limits, key, data);
137 case SR_CONF_CURRENT_LIMIT:
330a32b2 138 ret = ebd_get_current_limit(sdi, &fvalue);
9890fb1f
SBO
139 if (ret == SR_OK)
140 *data = g_variant_new_double(fvalue);
141 return ret;
c527132a
SBO
142 default:
143 return SR_ERR_NA;
144 }
c527132a
SBO
145}
146
147static int config_set(uint32_t key, GVariant *data,
148 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
149{
9890fb1f
SBO
150 double value;
151 struct dev_context *devc;
c527132a 152
c527132a
SBO
153 (void)data;
154 (void)cg;
155
9890fb1f
SBO
156 devc = sdi->priv;
157
c527132a 158 switch (key) {
9890fb1f
SBO
159 case SR_CONF_LIMIT_MSEC:
160 case SR_CONF_LIMIT_SAMPLES:
161 return sr_sw_limits_config_set(&devc->limits, key, data);
162 case SR_CONF_CURRENT_LIMIT:
163 value = g_variant_get_double(data);
164 if (value < 0.0 || value > 4.0)
165 return SR_ERR_ARG;
330a32b2 166 return ebd_set_current_limit(sdi, value);
c527132a 167 default:
9890fb1f 168 return SR_ERR_NA;
c527132a 169 }
c527132a
SBO
170}
171
172static int config_list(uint32_t key, GVariant **data,
173 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
174{
c527132a 175 switch (key) {
9890fb1f
SBO
176 case SR_CONF_SCAN_OPTIONS:
177 case SR_CONF_DEVICE_OPTIONS:
178 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
179 case SR_CONF_CURRENT_LIMIT:
180 *data = std_gvar_min_max_step(0.0, 4.0, 0.01);
181 break;
c527132a
SBO
182 default:
183 return SR_ERR_NA;
184 }
185
9890fb1f 186 return SR_OK;
c527132a
SBO
187}
188
189static int dev_acquisition_start(const struct sr_dev_inst *sdi)
190{
9890fb1f
SBO
191 struct dev_context *devc;
192 struct sr_serial_dev_inst *serial;
193
194 devc = sdi->priv;
195 serial = sdi->conn;
196
197 sr_sw_limits_acquisition_start(&devc->limits);
198 std_session_send_df_header(sdi);
c527132a 199
330a32b2
UH
200 ebd_init(serial, devc);
201 if (!ebd_current_is0(devc))
202 ebd_loadstart(serial, devc);
9890fb1f
SBO
203
204 serial_source_add(sdi->session, serial, G_IO_IN, 100,
330a32b2 205 ebd_receive_data, (void *)sdi);
c527132a
SBO
206
207 return SR_OK;
208}
209
210static int dev_acquisition_stop(struct sr_dev_inst *sdi)
211{
330a32b2 212 ebd_loadstop(sdi->conn, sdi->priv);
c527132a 213
9890fb1f 214 return std_serial_dev_acquisition_stop(sdi);
c527132a
SBO
215}
216
217SR_PRIV struct sr_dev_driver zketech_ebd_usb_driver_info = {
218 .name = "zketech-ebd-usb",
219 .longname = "ZKETECH EBD-USB",
220 .api_version = 1,
221 .init = std_init,
222 .cleanup = std_cleanup,
223 .scan = scan,
224 .dev_list = std_dev_list,
225 .dev_clear = std_dev_clear,
226 .config_get = config_get,
227 .config_set = config_set,
228 .config_list = config_list,
9890fb1f 229 .dev_open = std_serial_dev_open,
c527132a
SBO
230 .dev_close = dev_close,
231 .dev_acquisition_start = dev_acquisition_start,
232 .dev_acquisition_stop = dev_acquisition_stop,
233 .context = NULL,
234};
c527132a 235SR_REGISTER_DEV_DRIVER(zketech_ebd_usb_driver_info);