+static void pre_trigger_append(struct soft_trigger_logic *stl,
+ uint8_t *buf, int len)
+{
+ /* Avoid uselessly copying more than the pre-trigger size. */
+ if (len > stl->pre_trigger_size) {
+ buf += len - stl->pre_trigger_size;
+ len = stl->pre_trigger_size;
+ }
+
+ /* Update the filling level of the pre-trigger circular buffer. */
+ stl->pre_trigger_fill = MIN(stl->pre_trigger_fill + len,
+ stl->pre_trigger_size);
+
+ /* Actually copy data to the pre-trigger circular buffer. */
+ while (len > 0) {
+ size_t size = MIN(stl->pre_trigger_buffer + stl->pre_trigger_size
+ - stl->pre_trigger_head, len);
+ memcpy(stl->pre_trigger_head, buf, size);
+ stl->pre_trigger_head += size;
+ if (stl->pre_trigger_head >= stl->pre_trigger_buffer
+ + stl->pre_trigger_size)
+ stl->pre_trigger_head = stl->pre_trigger_buffer;
+ buf += size;
+ len -= size;
+ }
+}
+
+static void pre_trigger_send(struct soft_trigger_logic *stl,
+ int *pre_trigger_samples)
+{
+ struct sr_datafeed_packet packet;
+ struct sr_datafeed_logic logic;
+
+ packet.type = SR_DF_LOGIC;
+ packet.payload = &logic;
+ logic.unitsize = stl->unitsize;
+
+ if (pre_trigger_samples)
+ *pre_trigger_samples = 0;
+
+ /* If pre-trigger buffer not full, rewind head to the first valid sample. */
+ if (stl->pre_trigger_fill < stl->pre_trigger_size)
+ stl->pre_trigger_head = stl->pre_trigger_buffer;
+
+ /* Send logic packets for the pre-trigger circular buffer content. */
+ while (stl->pre_trigger_fill > 0) {
+ size_t size = MIN(stl->pre_trigger_buffer + stl->pre_trigger_size
+ - stl->pre_trigger_head, stl->pre_trigger_fill);
+ logic.length = size;
+ logic.data = stl->pre_trigger_head;
+ sr_session_send(stl->sdi, &packet);
+ stl->pre_trigger_head = stl->pre_trigger_buffer;
+ stl->pre_trigger_fill -= size;
+ if (pre_trigger_samples)
+ *pre_trigger_samples += size / stl->unitsize;
+ }
+}
+