From: Gerhard Sittig Date: Sat, 16 May 2020 20:08:08 +0000 (+0200) Subject: asix-sigma: prepare configuration re-use across sigrok sessions X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=53c8a99c41120a5359e407934ae5041a285046e1;p=libsigrok.git asix-sigma: prepare configuration re-use across sigrok sessions Introduce the required infrastructure to store successfully applied configuration data in hardware registers. This lets the probe phase of the next sigrok session pick up where the previous session left. Which improves usability, and increases performance by eliminating delays in the acquisition start, by not repeating unnecessary firmware uploads. The vendor documentation suggests there would be FPGA registers that are available for application use ("plugin configuration"). Unfortunately experiments show that registers beyond address 0x0f don't hold the data which was written to them. As do unused registers in the first page. So the desirable feature is not operational in this implementation. There could be different netlist versions which I'm not aware of, or there could be flaws in this driver implementation. This needs more attention. --- diff --git a/src/hardware/asix-sigma/api.c b/src/hardware/asix-sigma/api.c index 81a5df93..d8f9bf27 100644 --- a/src/hardware/asix-sigma/api.c +++ b/src/hardware/asix-sigma/api.c @@ -252,9 +252,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) devc->capture_ratio = 50; devc->use_triggers = 0; - /* TODO Retrieve some of this state from hardware? */ - devc->firmware_idx = SIGMA_FW_NONE; - devc->clock.samplerate = sigma_get_samplerate(sdi); + /* Get current hardware configuration (or use defaults). */ + (void)sigma_fetch_hw_config(sdi); } libusb_free_device_list(devlist, 1); g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index dd74ec98..b1af2e5a 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -1014,11 +1014,51 @@ SR_PRIV int sigma_normalize_samplerate(uint64_t want_rate, uint64_t *have_rate) return SR_ERR_ARG; } -SR_PRIV uint64_t sigma_get_samplerate(const struct sr_dev_inst *sdi) +/* Gets called at probe time. Can seed software settings from hardware state. */ +SR_PRIV int sigma_fetch_hw_config(const struct sr_dev_inst *sdi) { - /* TODO Retrieve value from hardware. */ + struct dev_context *devc; + int ret; + uint8_t regaddr, regval; + + devc = sdi->priv; + if (!devc) + return SR_ERR_ARG; + + /* Seed configuration values from defaults. */ + devc->firmware_idx = SIGMA_FW_NONE; + devc->clock.samplerate = samplerates[0]; + + /* TODO + * Ideally the device driver could retrieve recently stored + * details from hardware registers, thus re-use user specified + * configuration values across sigrok sessions. Which could + * avoid repeated expensive though unnecessary firmware uploads, + * improve performance and usability. Unfortunately it appears + * that the registers range which is documented as available for + * application use keeps providing 0xff data content. At least + * with the netlist version which ships with sigrok. The same + * was observed with unused registers in the first page. + */ + return SR_ERR_NA; + + /* This is for research, currently does not work yet. */ + ret = sigma_check_open(sdi); + regaddr = 16; + regaddr = 14; + ret = sigma_set_register(devc, regaddr, 'F'); + ret = sigma_get_register(devc, regaddr, ®val); + sr_warn("%s() reg[%u] val[%u] rc[%d]", __func__, regaddr, regval, ret); + ret = sigma_check_close(devc); + return ret; +} + +/* Gets called after successful (volatile) hardware configuration. */ +SR_PRIV int sigma_store_hw_config(const struct sr_dev_inst *sdi) +{ + /* TODO See above, registers seem to not hold written data. */ (void)sdi; - return samplerates[0]; + return SR_ERR_NA; } SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi) @@ -1064,6 +1104,14 @@ SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi) devc->samples_per_event = 16 / devc->num_channels; } + /* + * Store the firmware type and most recently configured samplerate + * in hardware, such that subsequent sessions can start from there. + * This is a "best effort" approach. Failure is non-fatal. + */ + if (ret == SR_OK) + (void)sigma_store_hw_config(sdi); + return ret; } diff --git a/src/hardware/asix-sigma/protocol.h b/src/hardware/asix-sigma/protocol.h index 5b4f669f..a56542a2 100644 --- a/src/hardware/asix-sigma/protocol.h +++ b/src/hardware/asix-sigma/protocol.h @@ -90,6 +90,12 @@ enum asix_device_type { * are available to applications and plugin features. Can libsigrok's * asix-sigma driver store configuration data there, to avoid expensive * operations (think: firmware re-load). + * + * Update: The documentation may be incorrect, or the FPGA netlist may + * be incomplete. Experiments show that registers beyond 0x0f can get + * accessed, USB communication passes, but data bytes are always 0xff. + * Are several firmware versions around, and the documentation does not + * match the one that ships with sigrok? */ enum sigma_write_register { @@ -103,6 +109,9 @@ enum sigma_write_register { WRITE_PIN_VIEW = 7, /* Unassigned register locations. */ WRITE_TEST = 15, + /* Reserved for plugin features. */ + REG_PLUGIN_START = 16, + REG_PLUGIN_STOP = 256, }; enum sigma_read_register { @@ -122,6 +131,7 @@ enum sigma_read_register { READ_PIN_VIEW = 13, /* Unassigned register location. */ READ_TEST = 15, + /* Reserved for plugin features. See above. */ }; #define HI4(b) (((b) >> 4) & 0x0f) @@ -368,6 +378,10 @@ SR_PRIV int sigma_check_close(struct dev_context *devc); SR_PRIV int sigma_force_open(const struct sr_dev_inst *sdi); SR_PRIV int sigma_force_close(struct dev_context *devc); +/* Save configuration across sessions, to reduce cost of continuation. */ +SR_PRIV int sigma_store_hw_config(const struct sr_dev_inst *sdi); +SR_PRIV int sigma_fetch_hw_config(const struct sr_dev_inst *sdi); + /* Send register content (simple and complex) to the hardware. */ SR_PRIV int sigma_write_register(struct dev_context *devc, uint8_t reg, uint8_t *data, size_t len); @@ -378,7 +392,6 @@ SR_PRIV int sigma_write_trigger_lut(struct dev_context *devc, /* Samplerate constraints check, get/set/list helpers. */ SR_PRIV int sigma_normalize_samplerate(uint64_t want_rate, uint64_t *have_rate); -SR_PRIV uint64_t sigma_get_samplerate(const struct sr_dev_inst *sdi); SR_PRIV GVariant *sigma_get_samplerates_list(void); /* Preparation of data acquisition, spec conversion, hardware configuration. */