- memset(&triggerinout_conf, 0, sizeof(struct triggerinout));
- triggerinout_conf.trgout_bytrigger = 1;
- triggerinout_conf.trgout_enable = 1;
-
- sigma_write_register(WRITE_TRIGGER_OPTION,
- (uint8_t *) &triggerinout_conf,
- sizeof(struct triggerinout), devc);
-
- /* Go back to normal mode. */
- sigma_set_register(WRITE_TRIGGER_SELECT1, triggerselect, devc);
-
- /* Set clock select register. */
- if (devc->cur_samplerate == SR_MHZ(200))
- /* Enable 4 channels. */
- sigma_set_register(WRITE_CLOCK_SELECT, 0xf0, devc);
- else if (devc->cur_samplerate == SR_MHZ(100))
- /* Enable 8 channels. */
- sigma_set_register(WRITE_CLOCK_SELECT, 0x00, devc);
- else {
- /*
- * 50 MHz mode (or fraction thereof). Any fraction down to
- * 50 MHz / 256 can be used, but is not supported by sigrok API.
- */
- frac = SR_MHZ(50) / devc->cur_samplerate - 1;
-
- clockselect.async = 0;
- clockselect.fraction = frac;
- clockselect.disabled_channels = 0;
-
- sigma_write_register(WRITE_CLOCK_SELECT,
- (uint8_t *) &clockselect,
- sizeof(clockselect), devc);
+ memset(&triggerinout_conf, 0, sizeof(triggerinout_conf));
+ triggerinout_conf.trgout_bytrigger = TRUE;
+ triggerinout_conf.trgout_enable = TRUE;
+ /* TODO
+ * Verify the correctness of this implementation. The previous
+ * version used to assign to a C language struct with bit fields
+ * which is highly non-portable and hard to guess the resulting
+ * raw memory layout or wire transfer content. The C struct's
+ * field names did not match the vendor documentation's names.
+ * Which means that I could not verify "on paper" either. Let's
+ * re-visit this code later during research for trigger support.
+ */
+ wrptr = cmd_bytes;
+ regval = 0;
+ if (triggerinout_conf.trgout_bytrigger)
+ regval |= TRGOPT_TRGOOUTEN;
+ write_u8_inc(&wrptr, regval);
+ regval &= ~TRGOPT_CLEAR_MASK;
+ if (triggerinout_conf.trgout_enable)
+ regval |= TRGOPT_TRGOEN;
+ write_u8_inc(&wrptr, regval);
+ ret = sigma_write_register(devc, WRITE_TRIGGER_OPTION,
+ cmd_bytes, wrptr - cmd_bytes);
+ if (ret != SR_OK)
+ return ret;
+
+ /* Leave trigger programming mode. */
+ ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, trigsel2);
+ if (ret != SR_OK)
+ return ret;
+
+ /*
+ * Samplerate dependent clock and channels configuration. Some
+ * channels by design are not available at higher clock rates.
+ * Register layout differs between firmware variants (depth 1
+ * with LSB channel mask above 50MHz, depth 4 with more details
+ * up to 50MHz).
+ *
+ * Derive a mask where bits are set for unavailable channels.
+ * Either send the single byte, or the full byte sequence.
+ */
+ pindis_mask = ~BITS_MASK(devc->interp.num_channels);
+ if (devc->clock.samplerate > SR_MHZ(50)) {
+ ret = sigma_set_register(devc, WRITE_CLOCK_SELECT,
+ pindis_mask & 0xff);
+ } else {
+ wrptr = cmd_bytes;
+ /* Select 50MHz base clock, and divider. */
+ async = 0;
+ div = SR_MHZ(50) / devc->clock.samplerate - 1;
+ if (devc->clock.use_ext_clock) {
+ async = CLKSEL_CLKSEL8;
+ div = devc->clock.clock_pin + 1;
+ switch (devc->clock.clock_edge) {
+ case SIGMA_CLOCK_EDGE_RISING:
+ div |= CLKSEL_RISING;
+ break;
+ case SIGMA_CLOCK_EDGE_FALLING:
+ div |= CLKSEL_FALLING;
+ break;
+ case SIGMA_CLOCK_EDGE_EITHER:
+ div |= CLKSEL_RISING;
+ div |= CLKSEL_FALLING;
+ break;
+ }
+ }
+ write_u8_inc(&wrptr, async);
+ write_u8_inc(&wrptr, div);
+ write_u16be_inc(&wrptr, pindis_mask);
+ ret = sigma_write_register(devc, WRITE_CLOCK_SELECT,
+ cmd_bytes, wrptr - cmd_bytes);