Difference between revisions of "Probe Groups"

From sigrok
Jump to navigation Jump to search
m (Fix headings)
m
 
(10 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<div style="background-color:lime">
'''Status''': The proposal below has been implemented in [[libsigrok]] as of 11/2013 ("probe groups" are now called "channel groups", though).
</div>


== Problem ==
== Problem ==
Line 12: Line 15:
== Use Cases ==
== Use Cases ==


1. Settings that apply for each available individual probe.
=== Settings that apply for each available individual probe ===


The Rigol DS1052E has two analog probes, CH1 and CH2. Volts per division
* The [[Rigol DS1052E]] has two analog probes, CH1 and CH2. Volts per division can be set individually for each.
can be set individually for each.


2. Settings that apply only for probes of a given type.
=== Settings that apply only for probes of a given type ===


The Rigol DS1102D has two analog probes, and 16 digital probes. Volts per
* The Rigol DS1102D has two analog probes, and 16 digital probes. Volts per division can be set only for the analog probes. Threshold voltage can be set only for the digital probes.
division can be set only for the analog probes. Threshold voltage can be
set only for the digital probes.


3. Settings that apply only for groups of probes of the same type.
=== Settings that apply only for groups of probes of the same type ===


The PicoScope 2205 has 16 digital probes in two groups of 8. Threshold
* The [[Pico Technology PicoScope 2205]] has 16 digital probes in two groups of 8. Threshold voltage can be set only for each group of 8.
voltage can be set only for each group of 8.
* The [[IKALOGIC ScanaPLUS]] logic analyzer has 9 probes.
** The voltage threshold can be set for two groups of probes individually (first group: probes 1-4, second group: probes 5-9).
** Additional special cases on this device are that probes 5 and 6 can either be used "normally" as digital logic analyzer inputs, or they can be combined together (by LA user config at runtime, when configuring the LA) to form one differential probe. The same applies to probes 7 and 8, they can be used individually as normal LA probes, or combined together to form a differential probe (e.g. for differential RS485/CAN/other probing). It is possible to only combine probes 5+6, or probes 7+8, or both, or none.


== Previous Ideas ==
== Previous Ideas ==


1. Use the existing API, but where settings are per-probe, use a GVariant
# Use the existing API, but where settings are per-probe, use a GVariant array of the values for each probe, rather than a single GVariant value.
array of the values for each probe, rather than a single GVariant value.
#* This does not address use case 3.
# Use the existing API, but where settings are per-probe, use a GVariant array of (probes, value) tuples, rather than a single GVariant value.
#* This is possible, but creates a lot of work. Probes could not be specified by pointer in the GVariant, so would have to be passed by name. In a sr_config_set call, the driver would then have to match the names to some internal data structure.
#* It also loads a lot of structure into a GVariant value that was originally conceived as being merely a simple value whose type would vary between configuration settings according to the nature of each setting.
#* Every frontend, driver and binding would have to implement the code required to pack and unpack these GVariant structures.


This does not address use case 3.
== Proposal ==


2. Use the existing API, but where settings are per-probe, use a GVariant
=== Concept ===
array of (probes, value) tuples, rather than a single GVariant value.


This is possible, but creates a lot of work. Probes could not be specified by
* Modify the API to include an explicit "probe group" data type, which can be passed to sr_config_{get,set,list} to address a specific group of probes.
pointer in the GVariant, so would have to be passed by name. In a sr_config_set
* Provide a way for frontends to get the available probe groups for a device.
call, the driver would then have to match the names to some internal data
structure.


It also loads a lot of structure into a GVariant value that was originally
=== API ===
conceived as being merely a simple value whose type would vary between
configuration settings according to the nature of each setting.


Every frontend, driver and binding would have to implement the code required
Define the following structure for a probe group:
to pack and unpack these GVariant structures.


== Proposed Concept ==
struct sr_probe_group {
    /** Name of the probe group. */
    char *name;
    /** List of sr_probe structs of the probes belonging to this group. */
    GSList *probes;
    /** Private data for driver use. */
    void *priv;
};


- Modify the API to include an explicit "probe group" data type, which can
Modify the signatures for sr_config_{get,set,list} as follows:
be passed to sr_config_{get,set,list} to address a specific group of probes.


- Provide a way for frontends to get the available probe groups for a device.
SR_API int sr_config_get(const struct sr_dev_driver *driver,
      const struct sr_dev_inst *sdi,
      const struct sr_probe_group *probe_group,
      int key, GVariant **data);


== Proposed API ==
SR_API int sr_config_set(const struct sr_dev_inst *sdi,
      const struct sr_probe_group *probe_group,
      int key, GVariant *data);


Define the following structure for a probe group:
SR_API int sr_config_list(const struct sr_dev_driver *driver,
      const struct sr_dev_inst *sdi,
      const struct sr_probe_group *probe_group,
      int key, GVariant **data);


struct sr_probe_group {
Modify the signatures in struct sr_dev_driver as follows:
      /* List of sr_probe structs. */
      GSList *probes;
      /* Private data for driver use. */
      void *data;
};


Modify the signatures for sr_config_{get,set,list} as follows:
int (*config_get) (int key, GVariant **data,
      const struct sr_dev_inst *sdi,
      const struct sr_probe_group *probe_group);


SR_API int sr_config_get(const struct sr_dev_driver *driver,
int (*config_set) (int key, GVariant *data,
        const struct sr_dev_inst *sdi,
      const struct sr_dev_inst *sdi,
        const struct sr_probe_group *probe_group,
      const struct sr_probe_group *probe_group);
        int key, GVariant **data);
SR_API int sr_config_set(const struct sr_dev_inst *sdi,
        const struct sr_probe_group *probe_group,
        int key, GVariant *data);
SR_API int sr_config_list(const struct sr_dev_driver *driver,
        const struct sr_dev_inst *sdi,
        const struct sr_probe_group *probe_group,
        int key, GVariant **data);


Modify the signatures in struct sr_dev_driver as follows:
int (*config_list) (int key, GVariant **data,
 
      const struct sr_dev_inst *sdi,
int (*config_get) (int id, GVariant **data,
      const struct sr_probe_group *probe_group);
        const struct sr_dev_inst *sdi,
        const struct sr_probe_group *probe_group);
int (*config_set) (int id, GVariant *data,
        const struct sr_dev_inst *sdi,
        const struct sr_probe_group *probe_group);
int (*config_list) (int info_id, GVariant **data,
        const struct sr_dev_inst *sdi,
        const struct sr_probe_group *probe_group);


In all the above functions, passing NULL for probe_group would have the same
In all the above functions, passing NULL for probe_group would have the same
Line 107: Line 102:
ways that change dynamically. In this case, we will need to replace this field
ways that change dynamically. In this case, we will need to replace this field
with a new API call that retrieves the currently applicable groups.
with a new API call that retrieves the currently applicable groups.
== Proposed Implementation ==
Steps 1-7 are to be done in a probe_groups branch on each project repository.
1. Implement the above API change for libsigrok.
See commit at:
https://github.com/martinling/libsigrok/commit/fc59c9a9433857600eccb02b54ebbbf34a7449ed
After this change, all drivers can be considered to implement device-wide
settings only and all devices have an empty list of probe groups.
2. Patch clients to work with new API.
Initially, this can be done by simply adding a NULL probe_group parameter to
all sr_config_{get,set,list} calls.
3. Implement probe groups in drivers.
4. Implement probe group support in clients.
5. Testing and evaluation.
6. Decide whether to move forward, or revise the concept/implementation.
7. Update documentation.
8. Merge into master.

Latest revision as of 18:08, 3 January 2015

Status: The proposal below has been implemented in libsigrok as of 11/2013 ("probe groups" are now called "channel groups", though).

Problem

Some settings supported by a device may apply to specific probes, rather than a device instance as a whole. The current sr_config_{get,set,list} API does not define a way to represent this.

A representation of this information is needed in the API so that frontends can provide an appropriate UI to the user, and so that configuration requests can be made unambiguously to devices with probe-specific settings.

Use Cases

Settings that apply for each available individual probe

  • The Rigol DS1052E has two analog probes, CH1 and CH2. Volts per division can be set individually for each.

Settings that apply only for probes of a given type

  • The Rigol DS1102D has two analog probes, and 16 digital probes. Volts per division can be set only for the analog probes. Threshold voltage can be set only for the digital probes.

Settings that apply only for groups of probes of the same type

  • The Pico Technology PicoScope 2205 has 16 digital probes in two groups of 8. Threshold voltage can be set only for each group of 8.
  • The IKALOGIC ScanaPLUS logic analyzer has 9 probes.
    • The voltage threshold can be set for two groups of probes individually (first group: probes 1-4, second group: probes 5-9).
    • Additional special cases on this device are that probes 5 and 6 can either be used "normally" as digital logic analyzer inputs, or they can be combined together (by LA user config at runtime, when configuring the LA) to form one differential probe. The same applies to probes 7 and 8, they can be used individually as normal LA probes, or combined together to form a differential probe (e.g. for differential RS485/CAN/other probing). It is possible to only combine probes 5+6, or probes 7+8, or both, or none.

Previous Ideas

  1. Use the existing API, but where settings are per-probe, use a GVariant array of the values for each probe, rather than a single GVariant value.
    • This does not address use case 3.
  2. Use the existing API, but where settings are per-probe, use a GVariant array of (probes, value) tuples, rather than a single GVariant value.
    • This is possible, but creates a lot of work. Probes could not be specified by pointer in the GVariant, so would have to be passed by name. In a sr_config_set call, the driver would then have to match the names to some internal data structure.
    • It also loads a lot of structure into a GVariant value that was originally conceived as being merely a simple value whose type would vary between configuration settings according to the nature of each setting.
    • Every frontend, driver and binding would have to implement the code required to pack and unpack these GVariant structures.

Proposal

Concept

  • Modify the API to include an explicit "probe group" data type, which can be passed to sr_config_{get,set,list} to address a specific group of probes.
  • Provide a way for frontends to get the available probe groups for a device.

API

Define the following structure for a probe group:

struct sr_probe_group {
    /** Name of the probe group. */
    char *name;
    /** List of sr_probe structs of the probes belonging to this group. */
    GSList *probes;
    /** Private data for driver use. */
    void *priv;
};

Modify the signatures for sr_config_{get,set,list} as follows:

SR_API int sr_config_get(const struct sr_dev_driver *driver,
     const struct sr_dev_inst *sdi,
     const struct sr_probe_group *probe_group,
     int key, GVariant **data);
SR_API int sr_config_set(const struct sr_dev_inst *sdi,
     const struct sr_probe_group *probe_group,
     int key, GVariant *data);
SR_API int sr_config_list(const struct sr_dev_driver *driver,
     const struct sr_dev_inst *sdi,
     const struct sr_probe_group *probe_group,
     int key, GVariant **data);

Modify the signatures in struct sr_dev_driver as follows:

int (*config_get) (int key, GVariant **data,
     const struct sr_dev_inst *sdi,
     const struct sr_probe_group *probe_group);
int (*config_set) (int key, GVariant *data,
     const struct sr_dev_inst *sdi,
     const struct sr_probe_group *probe_group);
int (*config_list) (int key, GVariant **data,
     const struct sr_dev_inst *sdi,
     const struct sr_probe_group *probe_group);

In all the above functions, passing NULL for probe_group would have the same meaning as the current function without the probe_group parameter. Passing a probe group would implement the function for that specific group of probes.

The available probe groups are defined by the driver.

Initially, it is proposed to add a GSList *probe_groups field to struct sr_dev_inst to list the probe groups for a device. In all current use cases, these groups are static.

In future we may encounter devices in which certain settings are grouped in ways that change dynamically. In this case, we will need to replace this field with a new API call that retrieves the currently applicable groups.