+ struct sr_dev_driver *di = sdi->driver;
+ struct drv_context *drvc = di->context;
+ struct dev_context *devc = sdi->priv;
+ struct sr_trigger *trigger = sr_session_trigger_get(sdi->session);
+ struct h4032l_cmd_pkt *cmd_pkt = &devc->cmd_pkt;
+
+ /* Calculate packet ratio. */
+ cmd_pkt->pre_trigger_size = (cmd_pkt->sample_size * devc->capture_ratio) / 100;
+
+ cmd_pkt->trig_flags.enable_trigger1 = 0;
+ cmd_pkt->trig_flags.enable_trigger2 = 0;
+ cmd_pkt->trig_flags.trigger_and_logic = 0;
+
+ if (trigger && trigger->stages) {
+ GSList *stages = trigger->stages;
+ struct sr_trigger_stage *stage1 = stages->data;
+ if (stages->next) {
+ sr_err("only one trigger stage supported for now");
+ return SR_ERR;
+ }
+ cmd_pkt->trig_flags.enable_trigger1 = 1;
+ cmd_pkt->trigger[0].flags.edge_type = H4032L_TRIGGER_EDGE_TYPE_DISABLED;
+ cmd_pkt->trigger[0].flags.data_range_enabled = 0;
+ cmd_pkt->trigger[0].flags.time_range_enabled = 0;
+ cmd_pkt->trigger[0].flags.combined_enabled = 0;
+ cmd_pkt->trigger[0].flags.data_range_type = H4032L_TRIGGER_DATA_RANGE_TYPE_MAX;
+ cmd_pkt->trigger[0].data_range_mask = 0;
+ cmd_pkt->trigger[0].data_range_max = 0;
+
+ /* Initialize range mask values. */
+ uint32_t range_mask = 0;
+ uint32_t range_value = 0;
+
+ GSList *channel = stage1->matches;
+ while (channel) {
+ struct sr_trigger_match *match = channel->data;
+
+ switch (match->match) {
+ case SR_TRIGGER_ZERO:
+ range_mask |= (1 << match->channel->index);
+ break;
+ case SR_TRIGGER_ONE:
+ range_mask |= (1 << match->channel->index);
+ range_value |= (1 << match->channel->index);
+ break;
+ case SR_TRIGGER_RISING:
+ if (cmd_pkt->trigger[0].flags.edge_type != H4032L_TRIGGER_EDGE_TYPE_DISABLED) {
+ sr_err("only one trigger signal with fall/rising/edge allowed");
+ return SR_ERR;
+ }
+ cmd_pkt->trigger[0].flags.edge_type = H4032L_TRIGGER_EDGE_TYPE_RISE;
+ cmd_pkt->trigger[0].flags.edge_signal = match->channel->index;
+ break;
+ case SR_TRIGGER_FALLING:
+ if (cmd_pkt->trigger[0].flags.edge_type != H4032L_TRIGGER_EDGE_TYPE_DISABLED) {
+ sr_err("only one trigger signal with fall/rising/edge allowed");
+ return SR_ERR;
+ }
+ cmd_pkt->trigger[0].flags.edge_type = H4032L_TRIGGER_EDGE_TYPE_FALL;
+ cmd_pkt->trigger[0].flags.edge_signal = match->channel->index;
+ break;
+ case SR_TRIGGER_EDGE:
+ if (cmd_pkt->trigger[0].flags.edge_type != H4032L_TRIGGER_EDGE_TYPE_DISABLED) {
+ sr_err("only one trigger signal with fall/rising/edge allowed");
+ return SR_ERR;
+ }
+ cmd_pkt->trigger[0].flags.edge_type = H4032L_TRIGGER_EDGE_TYPE_TOGGLE;
+ cmd_pkt->trigger[0].flags.edge_signal = match->channel->index;
+ break;
+ default:
+ sr_err("unknown trigger value");
+ return SR_ERR;
+ }
+
+ channel = channel->next;
+ }
+
+ /* Compress range mask value and apply range settings. */
+ if (range_mask) {
+ cmd_pkt->trigger[0].flags.data_range_enabled = 1;
+ cmd_pkt->trigger[0].data_range_mask |= (range_mask);
+
+ uint32_t new_range_value = 0;
+ uint32_t bit_mask = 1;
+ while (range_mask) {
+ if ((range_mask & 1) != 0) {
+ new_range_value <<= 1;
+ if ((range_value & 1) != 0)
+ new_range_value |= bit_mask;
+ bit_mask <<= 1;
+ }
+ range_mask >>= 1;
+ range_value >>= 1;
+ }
+ cmd_pkt->trigger[0].data_range_max |= range_value;
+ }
+ }