X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fhameg-hmo%2Fapi.c;h=bd97af8865e75cf17b4a76ba7d607e4217c6b78e;hb=eff1ee0321166b7017765f91f5833fdf69e30d1b;hp=4868410a00655d179260062a016815bb17a1e588;hpb=082972e8c5deb48eba5c2b558e451dea1005e23f;p=libsigrok.git diff --git a/hardware/hameg-hmo/api.c b/hardware/hameg-hmo/api.c index 4868410a..bd97af88 100644 --- a/hardware/hameg-hmo/api.c +++ b/hardware/hameg-hmo/api.c @@ -23,6 +23,13 @@ #define SERIALCOMM "115200/8n1/flow=1" +SR_PRIV struct sr_dev_driver hameg_hmo_driver_info; +static struct sr_dev_driver *di = &hameg_hmo_driver_info; + +static const char *manufacturers[] = { + "HAMEG", +}; + static const int32_t hwopts[] = { SR_CONF_CONN, SR_CONF_SERIALCOMM, @@ -186,6 +193,83 @@ skip_device: #endif } +static int check_manufacturer(const char *manufacturer) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(manufacturers); ++i) + if (!strcmp(manufacturer, manufacturers[i])) + return SR_OK; + + return SR_ERR; +} + +static struct sr_dev_inst *hmo_probe_serial_device(const char *serial_device, + const char *serial_options) +{ + struct sr_dev_inst *sdi; + struct dev_context *devc; + struct sr_scpi_hw_info *hw_info; + struct sr_scpi_dev_inst *scpi; + + sdi = NULL; + devc = NULL; + scpi = NULL; + hw_info = NULL; + + if (!(scpi = scpi_dev_inst_new(serial_device, serial_options))) + goto fail; + + sr_info("Probing %s.", serial_device); + if (sr_scpi_open(scpi) != SR_OK) + goto fail; + + if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) { + sr_info("Couldn't get IDN response."); + goto fail; + } + + if (check_manufacturer(hw_info->manufacturer) != SR_OK) + goto fail; + + if (!(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, + hw_info->manufacturer, hw_info->model, + hw_info->firmware_version))) { + goto fail; + } + sr_scpi_hw_info_free(hw_info); + hw_info = NULL; + + if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) + goto fail; + + sdi->driver = di; + sdi->priv = devc; + sdi->inst_type = SR_INST_SCPI; + sdi->conn = scpi; + + if (hmo_init_device(sdi) != SR_OK) + goto fail; + + sr_scpi_close(sdi->conn); + + sdi->status = SR_ST_INACTIVE; + + return sdi; + +fail: + if (hw_info) + sr_scpi_hw_info_free(hw_info); + if (scpi) + sr_scpi_free(scpi); + if (sdi) + sr_dev_inst_free(sdi); + if (devc) + g_free(devc); + + return NULL; +} + static GSList *scan(GSList *options) { GSList *devices; @@ -270,8 +354,7 @@ static int dev_clear(void) static int dev_open(struct sr_dev_inst *sdi) { - if (sdi->status != SR_ST_ACTIVE && - serial_open(sdi->conn, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK) + if (sdi->status != SR_ST_ACTIVE && sr_scpi_open(sdi->conn) != SR_OK) return SR_ERR; if (hmo_scope_state_get(sdi) != SR_OK) @@ -287,7 +370,7 @@ static int dev_close(struct sr_dev_inst *sdi) if (sdi->status == SR_ST_INACTIVE) return SR_OK; - serial_close(sdi->conn); + sr_scpi_close(sdi->conn); sdi->status = SR_ST_INACTIVE; @@ -332,6 +415,7 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, unsigned int i; struct dev_context *devc; struct scope_config *model; + struct scope_state *state; if (!sdi || !(devc = sdi->priv)) return SR_ERR_ARG; @@ -341,6 +425,7 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, ret = SR_ERR_NA; model = devc->model_config; + state = devc->model_state; switch (key) { case SR_CONF_NUM_TIMEBASE: @@ -364,6 +449,10 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, ret = SR_ERR_NA; } break; + case SR_CONF_SAMPLERATE: + *data = g_variant_new_uint64(state->sample_rate); + ret = SR_OK; + break; default: ret = SR_ERR_NA; } @@ -395,13 +484,14 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, { int ret, pg_type; unsigned int i, j; - char command[MAX_COMMAND_SIZE]; + char command[MAX_COMMAND_SIZE], float_str[30]; struct dev_context *devc; struct scope_config *model; struct scope_state *state; const char *tmp; uint64_t p, q, tmp_u64; double tmp_d; + gboolean update_sample_rate; if (!sdi || !(devc = sdi->priv)) return SR_ERR_ARG; @@ -411,6 +501,7 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, model = devc->model_config; state = devc->model_state; + update_sample_rate = FALSE; ret = SR_ERR_NA; @@ -448,10 +539,11 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, for (j = 1; j <= model->analog_channels; ++j) { if (probe_group != &devc->analog_groups[j - 1]) continue; - state->analog_channels[j - 1].vdiv = (float) p / q; + state->analog_channels[j - 1].vdiv = i; + g_ascii_formatd(float_str, sizeof(float_str), "%E", (float) p / q); g_snprintf(command, sizeof(command), (*model->scpi_dialect)[SCPI_CMD_SET_VERTICAL_DIV], - j, state->analog_channels[j-1].vdiv); + j, float_str); if (sr_scpi_send(sdi->conn, command) != SR_OK || sr_scpi_get_opc(sdi->conn) != SR_OK) @@ -471,12 +563,14 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, if (p != (*model->timebases)[i][0] || q != (*model->timebases)[i][1]) continue; - state->timebase = (float) p / q; + state->timebase = i; + g_ascii_formatd(float_str, sizeof(float_str), "%E", (float) p / q); g_snprintf(command, sizeof(command), (*model->scpi_dialect)[SCPI_CMD_SET_TIMEBASE], - state->timebase); + float_str); ret = sr_scpi_send(sdi->conn, command); + update_sample_rate = TRUE; break; } break; @@ -545,6 +639,9 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, if (ret == SR_OK) ret = sr_scpi_get_opc(sdi->conn); + if (ret == SR_OK && update_sample_rate) + ret = hmo_update_sample_rate(sdi); + return ret; } @@ -673,18 +770,19 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi) { GSList *l; unsigned int i; - gboolean *pod_enabled; + gboolean *pod_enabled, setup_changed; char command[MAX_COMMAND_SIZE]; struct scope_state *state; struct scope_config *model; struct sr_probe *probe; struct dev_context *devc; - struct sr_serial_dev_inst *serial; + struct sr_scpi_dev_inst *scpi; devc = sdi->priv; - serial = sdi->conn; + scpi = sdi->conn; state = devc->model_state; model = devc->model_config; + setup_changed = FALSE; pod_enabled = g_try_malloc0(sizeof(gboolean) * model->digital_pods); @@ -698,9 +796,10 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi) (*model->scpi_dialect)[SCPI_CMD_SET_ANALOG_CHAN_STATE], probe->index + 1, probe->enabled); - if (sr_scpi_send(serial, command) != SR_OK) + if (sr_scpi_send(scpi, command) != SR_OK) return SR_ERR; state->analog_channels[probe->index].state = probe->enabled; + setup_changed = TRUE; break; case SR_PROBE_LOGIC: /* @@ -716,10 +815,11 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi) (*model->scpi_dialect)[SCPI_CMD_SET_DIG_CHAN_STATE], probe->index, probe->enabled); - if (sr_scpi_send(serial, command) != SR_OK) + if (sr_scpi_send(scpi, command) != SR_OK) return SR_ERR; state->digital_channels[probe->index] = probe->enabled; + setup_changed = TRUE; break; default: return SR_ERR; @@ -732,13 +832,17 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi) g_snprintf(command, sizeof(command), (*model->scpi_dialect)[SCPI_CMD_SET_DIG_POD_STATE], i, pod_enabled[i - 1]); - if (sr_scpi_send(serial, command) != SR_OK) + if (sr_scpi_send(scpi, command) != SR_OK) return SR_ERR; state->digital_pods[i - 1] = pod_enabled[i - 1]; + setup_changed = TRUE; } g_free(pod_enabled); + if (setup_changed && hmo_update_sample_rate(sdi) != SR_OK) + return SR_ERR; + return SR_OK; } @@ -748,12 +852,12 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) gboolean digital_added; struct sr_probe *probe; struct dev_context *devc; - struct sr_serial_dev_inst *serial; + struct sr_scpi_dev_inst *scpi; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; - serial = sdi->conn; + scpi = sdi->conn; devc = sdi->priv; digital_added = FALSE; @@ -783,7 +887,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) return SR_ERR; } - sr_source_add(serial->fd, G_IO_IN, 50, hmo_receive_data, (void *)sdi); + sr_scpi_source_add(scpi, G_IO_IN, 50, hmo_receive_data, (void *)sdi); /* Send header packet to the session bus. */ std_session_send_df_header(cb_data, LOG_PREFIX); @@ -796,10 +900,15 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) { struct dev_context *devc; - struct sr_serial_dev_inst *serial; + struct sr_scpi_dev_inst *scpi; + struct sr_datafeed_packet packet; (void)cb_data; + packet.type = SR_DF_END; + packet.payload = NULL; + sr_session_send(sdi, &packet); + if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; @@ -807,8 +916,8 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) g_slist_free(devc->enabled_probes); devc->enabled_probes = NULL; - serial = sdi->conn; - sr_source_remove(serial->fd); + scpi = sdi->conn; + sr_scpi_source_remove(scpi); return SR_OK; }