X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fatten-pps3xxx%2Fapi.c;h=b82b9fb333cf9fd460764d638ce325f3e607caaf;hb=7d0f52f7e5cb16d204490ca4006983237bf3df7d;hp=ce0531c967195cad2487a5bb85f632750fcbf2b2;hpb=700d6b64d578ce10e57f6a2289e37a5564eccf1c;p=libsigrok.git diff --git a/src/hardware/atten-pps3xxx/api.c b/src/hardware/atten-pps3xxx/api.c index ce0531c9..b82b9fb3 100644 --- a/src/hardware/atten-pps3xxx/api.c +++ b/src/hardware/atten-pps3xxx/api.c @@ -41,7 +41,7 @@ static const uint32_t drvopts[] = { }; static const uint32_t devopts[] = { - SR_CONF_CONTINUOUS | SR_CONF_SET, + SR_CONF_CONTINUOUS, SR_CONF_CHANNEL_CONFIG | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET, }; @@ -75,23 +75,15 @@ static const struct pps_model models[] = { }, }; -SR_PRIV struct sr_dev_driver atten_pps3203_driver_info; - -static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx) -{ - return std_init(sr_ctx, di, LOG_PREFIX); -} - static GSList *scan(struct sr_dev_driver *di, GSList *options, int modelid) { struct sr_dev_inst *sdi; - struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_channel *ch; struct sr_channel_group *cg; struct sr_serial_dev_inst *serial; - GSList *l, *devices; + GSList *l; const struct pps_model *model; uint8_t packet[PACKET_SIZE]; unsigned int i; @@ -99,10 +91,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options, int modelid) const char *conn, *serialcomm; char channel[10]; - devices = NULL; - drvc = di->context; - drvc->instances = NULL; - conn = serialcomm = NULL; for (l = options; l; l = l->next) { src = l->data; @@ -166,7 +154,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options, int modelid) sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Atten"); sdi->model = g_strdup(model->name); - sdi->driver = di; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; for (i = 0; i < MAX_CHANNELS; i++) { @@ -184,14 +171,10 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options, int modelid) devc->config = g_malloc0(sizeof(struct per_channel_config) * model->num_channels); devc->delay_ms = delay_ms; sdi->priv = devc; - 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; + return std_scan_complete(di, g_slist_append(NULL, sdi)); } static GSList *scan_3203(struct sr_dev_driver *di, GSList *options) @@ -199,26 +182,19 @@ static GSList *scan_3203(struct sr_dev_driver *di, GSList *options) return scan(di, options, PPS_3203T_3S); } -static GSList *dev_list(const struct sr_dev_driver *di) -{ - return ((struct drv_context *)(di->context))->instances; -} - -static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, - const struct sr_channel_group *cg) +static int config_get(uint32_t key, GVariant **data, + const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct dev_context *devc; struct sr_channel *ch; - int channel, ret; + int channel; if (!sdi) return SR_ERR_ARG; devc = sdi->priv; - ret = SR_OK; if (!cg) { - /* No channel group: global options. */ switch (key) { case SR_CONF_CHANNEL_CONFIG: *data = g_variant_new_string(channel_modes[devc->channel_mode]); @@ -255,64 +231,36 @@ static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *s } } - return ret; -} - -static int find_str(const char *str, const char **strings, int array_size) -{ - int idx, i; - - idx = -1; - for (i = 0; i < array_size; i++) { - if (!strcmp(str, strings[i])) { - idx = i; - break; - } - } - - return idx; + return SR_OK; } -static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi, - const struct sr_channel_group *cg) +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; struct sr_channel *ch; gdouble dval; - int channel, ret, ival; - const char *sval; + int channel, ival; gboolean bval; - if (sdi->status != SR_ST_ACTIVE) - return SR_ERR_DEV_CLOSED; - - ret = SR_OK; devc = sdi->priv; + if (!cg) { - /* No channel group: global options. */ switch (key) { case SR_CONF_CHANNEL_CONFIG: - sval = g_variant_get_string(data, NULL); - if ((ival = find_str(sval, channel_modes, - ARRAY_SIZE(channel_modes))) == -1) { - ret = SR_ERR_ARG; - break; - } - if (devc->model->channel_modes && (1 << ival) == 0) { - /* Not supported on this model. */ - ret = SR_ERR_ARG; - } + if ((ival = std_str_idx(data, ARRAY_AND_SIZE(channel_modes))) < 0) + return SR_ERR_ARG; + if (devc->model->channel_modes && (1 << ival) == 0) + return SR_ERR_ARG; /* Not supported on this model. */ if (ival == devc->channel_mode_set) - /* Nothing to do. */ - break; + break; /* Nothing to do. */ devc->channel_mode_set = ival; devc->config_dirty = TRUE; break; case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED: bval = g_variant_get_boolean(data); if (bval == devc->over_current_protection_set) - /* Nothing to do. */ - break; + break; /* Nothing to do. */ devc->over_current_protection_set = bval; devc->config_dirty = TRUE; break; @@ -320,7 +268,6 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd return SR_ERR_NA; } } else { - /* Channel group specified: per-channel options. */ /* We only ever have one channel per channel group in this driver. */ ch = cg->channels->data; channel = ch->index; @@ -329,116 +276,85 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd case SR_CONF_VOLTAGE_TARGET: dval = g_variant_get_double(data); if (dval < 0 || dval > devc->model->channels[channel].voltage[1]) - ret = SR_ERR_ARG; + return SR_ERR_ARG; devc->config[channel].output_voltage_max = dval; devc->config_dirty = TRUE; break; case SR_CONF_CURRENT_LIMIT: dval = g_variant_get_double(data); if (dval < 0 || dval > devc->model->channels[channel].current[1]) - ret = SR_ERR_ARG; + return SR_ERR_ARG; devc->config[channel].output_current_max = dval; devc->config_dirty = TRUE; break; case SR_CONF_ENABLED: bval = g_variant_get_boolean(data); if (bval == devc->config[channel].output_enabled_set) - /* Nothing to do. */ - break; + break; /* Nothing to do. */ devc->config[channel].output_enabled_set = bval; devc->config_dirty = TRUE; break; default: - ret = SR_ERR_NA; + return SR_ERR_NA; } } - return ret; + return SR_OK; } -static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, - const struct sr_channel_group *cg) +static int config_list(uint32_t key, GVariant **data, + const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct dev_context *devc; struct sr_channel *ch; - GVariant *gvar; - GVariantBuilder gvb; - int channel, ret, i; - - /* Always available. */ - if (key == SR_CONF_SCAN_OPTIONS) { - *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t)); - return SR_OK; - } - - if (key == SR_CONF_DEVICE_OPTIONS && !sdi) { - *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t)); - return SR_OK; - } + int channel; - if (!sdi) - return SR_ERR_ARG; + devc = (sdi) ? sdi->priv : NULL; - devc = sdi->priv; - ret = SR_OK; if (!cg) { - /* No channel group: global options. */ switch (key) { + case SR_CONF_SCAN_OPTIONS: case SR_CONF_DEVICE_OPTIONS: - *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - devopts, ARRAY_SIZE(devopts), sizeof(uint32_t)); - break; + return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts); case SR_CONF_CHANNEL_CONFIG: + if (!devc || !devc->model) + return SR_ERR_ARG; if (devc->model->channel_modes == CHANMODE_INDEPENDENT) { /* The 1-channel models. */ *data = g_variant_new_strv(channel_modes, 1); } else { /* The other models support all modes. */ - *data = g_variant_new_strv(channel_modes, ARRAY_SIZE(channel_modes)); + *data = g_variant_new_strv(ARRAY_AND_SIZE(channel_modes)); } break; default: return SR_ERR_NA; } } else { - /* Channel group specified: per-channel options. */ - if (!sdi) - return SR_ERR_ARG; /* We only ever have one channel per channel group in this driver. */ ch = cg->channels->data; channel = ch->index; switch (key) { case SR_CONF_DEVICE_OPTIONS: - *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - devopts_cg, ARRAY_SIZE(devopts_cg), sizeof(uint32_t)); + *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg)); break; case SR_CONF_VOLTAGE_TARGET: - g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY); - /* Min, max, step. */ - for (i = 0; i < 3; i++) { - gvar = g_variant_new_double(devc->model->channels[channel].voltage[i]); - g_variant_builder_add_value(&gvb, gvar); - } - *data = g_variant_builder_end(&gvb); + if (!devc || !devc->model) + return SR_ERR_ARG; + *data = std_gvar_min_max_step_array(devc->model->channels[channel].voltage); break; case SR_CONF_CURRENT_LIMIT: - g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY); - /* Min, max, step. */ - for (i = 0; i < 3; i++) { - gvar = g_variant_new_double(devc->model->channels[channel].current[i]); - g_variant_builder_add_value(&gvb, gvar); - } - *data = g_variant_builder_end(&gvb); + if (!devc || !devc->model) + return SR_ERR_ARG; + *data = std_gvar_min_max_step_array(devc->model->channels[channel].current); break; default: return SR_ERR_NA; } } - return ret; + return SR_OK; } static int dev_close(struct sr_dev_inst *sdi) @@ -446,6 +362,7 @@ static int dev_close(struct sr_dev_inst *sdi) struct dev_context *devc; devc = sdi->priv; + if (devc->config_dirty) /* Some configuration changes were queued up but didn't * get sent to the device, likely because we were never @@ -461,9 +378,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) struct sr_serial_dev_inst *serial; uint8_t packet[PACKET_SIZE]; - if (sdi->status != SR_ST_ACTIVE) - return SR_ERR_DEV_CLOSED; - devc = sdi->priv; memset(devc->packet, 0x44, PACKET_SIZE); devc->packet_size = 0; @@ -473,7 +387,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) serial = sdi->conn; serial_source_add(sdi->session, serial, G_IO_IN, 50, atten_pps3xxx_receive_data, (void *)sdi); - std_session_send_df_header(sdi, LOG_PREFIX); + std_session_send_df_header(sdi); /* Send a "channel" configuration packet now. */ memset(packet, 0, PACKET_SIZE); @@ -488,24 +402,21 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) { struct dev_context *devc; - if (sdi->status != SR_ST_ACTIVE) - return SR_ERR_DEV_CLOSED; - devc = sdi->priv; devc->acquisition_running = FALSE; return SR_OK; } -SR_PRIV struct sr_dev_driver atten_pps3203_driver_info = { +static struct sr_dev_driver atten_pps3203_driver_info = { .name = "atten-pps3203", .longname = "Atten PPS3203T-3S", .api_version = 1, - .init = init, + .init = std_init, .cleanup = std_cleanup, .scan = scan_3203, - .dev_list = dev_list, - .dev_clear = NULL, + .dev_list = std_dev_list, + .dev_clear = std_dev_clear, .config_get = config_get, .config_set = config_set, .config_list = config_list, @@ -515,3 +426,4 @@ SR_PRIV struct sr_dev_driver atten_pps3203_driver_info = { .dev_acquisition_stop = dev_acquisition_stop, .context = NULL, }; +SR_REGISTER_DEV_DRIVER(atten_pps3203_driver_info);