static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct dev_context *devc; gboolean bval; gdouble dval; (void)cg; devc = sdi->priv; 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_VOLTAGE_TARGET: dval = g_variant_get_double(data); if (dval < devc->model->voltage[0] || dval > devc->voltage_max_device) return SR_ERR_ARG; if ((hcs_send_cmd(sdi->conn, "VOLT%03.0f\r", (dval / devc->model->voltage[2])) < 0) || (hcs_read_reply(sdi->conn, 1, devc->buf, sizeof(devc->buf)) < 0)) return SR_ERR; devc->voltage_max = dval; break; case SR_CONF_CURRENT_LIMIT: dval = g_variant_get_double(data); if (dval < devc->model->current[0] || dval > devc->current_max_device) return SR_ERR_ARG; if ((hcs_send_cmd(sdi->conn, "CURR%03.0f\r", (dval / devc->model->current[2])) < 0) || (hcs_read_reply(sdi->conn, 1, devc->buf, sizeof(devc->buf)) < 0)) return SR_ERR; devc->current_max = dval; break; case SR_CONF_ENABLED: bval = g_variant_get_boolean(data); if (hcs_send_cmd(sdi->conn, "SOUT%1d\r", !bval) < 0) { sr_err("Could not send SR_CONF_ENABLED command."); return SR_ERR; } if (hcs_read_reply(sdi->conn, 1, devc->buf, sizeof(devc->buf)) < 0) { sr_err("Could not read SR_CONF_ENABLED reply."); return SR_ERR; } devc->output_enabled = bval; break; default: return SR_ERR_NA; } return SR_OK; }
/** Driver/serial data reception function. */ SR_PRIV int hcs_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; uint64_t elapsed_us; (void)fd; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; serial = sdi->conn; if (revents == G_IO_IN) { /* New data arrived. */ handle_new_data(sdi); } else { /* Timeout. */ } if (sr_sw_limits_check(&devc->limits)) { sdi->driver->dev_acquisition_stop(sdi); return TRUE; } /* Request next packet, if required. */ if (sdi->status == SR_ST_ACTIVE) { if (devc->reply_pending) { elapsed_us = g_get_monotonic_time() - devc->req_sent_at; if (elapsed_us > (REQ_TIMEOUT_MS * 1000)) devc->reply_pending = FALSE; return TRUE; } /* Send command to get voltage, current, and mode (CC or CV). */ if (hcs_send_cmd(serial, "GETD\r") < 0) return TRUE; devc->req_sent_at = g_get_monotonic_time(); devc->reply_pending = TRUE; } return TRUE; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { int i, model_id; struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_config *src; GSList *devices, *l; const char *conn, *serialcomm; struct sr_serial_dev_inst *serial; char reply[50], **tokens, *dummy; drvc = di->context; drvc->instances = NULL; devices = NULL; conn = NULL; serialcomm = NULL; devc = NULL; 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; default: sr_err("Unknown option %d, skipping.", src->key); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = "9600/8n1"; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; serial_flush(serial); sr_info("Probing serial port %s.", conn); /* Get the device model. */ memset(&reply, 0, sizeof(reply)); if ((hcs_send_cmd(serial, "GMOD\r") < 0) || (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0)) return NULL; tokens = g_strsplit((const gchar *)&reply, "\r", 2); model_id = -1; for (i = 0; models[i].id != NULL; i++) { if (!strcmp(models[i].id, tokens[0])) model_id = i; } if (model_id < 0) { sr_err("Unknown model ID '%s' detected, aborting.", tokens[0]); g_strfreev(tokens); return NULL; } g_strfreev(tokens); /* Init device instance, etc. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Manson"); sdi->model = g_strdup(models[model_id].name); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->driver = di; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1"); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); devc->model = &models[model_id]; sdi->priv = devc; /* Get current voltage, current, status. */ if ((hcs_send_cmd(serial, "GETD\r") < 0) || (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0)) goto exit_err; tokens = g_strsplit((const gchar *)&reply, "\r", 2); if (hcs_parse_volt_curr_mode(sdi, tokens) < 0) { g_strfreev(tokens); goto exit_err; } g_strfreev(tokens); /* Get max. voltage and current. */ if ((hcs_send_cmd(serial, "GMAX\r") < 0) || (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0)) goto exit_err; tokens = g_strsplit((const gchar *)&reply, "\r", 2); devc->current_max_device = g_strtod(&tokens[0][3], &dummy) * devc->model->current[2]; tokens[0][3] = '\0'; devc->voltage_max_device = g_strtod(tokens[0], &dummy) * devc->model->voltage[2]; g_strfreev(tokens); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); serial_close(serial); if (!devices) sr_serial_dev_inst_free(serial); return devices; exit_err: sr_dev_inst_free(sdi); g_free(devc); return NULL; }