]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/demo/api.c
ols: add feature to support >256K memory
[libsigrok.git] / src / hardware / demo / api.c
index d0abe4ff92e053f111c6cb44b7cc9e66f9aa0f50..7d3e08872d07c21b38832845a138d5cf2bd3fe80 100644 (file)
@@ -50,6 +50,7 @@ static const char *logic_pattern_str[] = {
 static const uint32_t scanopts[] = {
        SR_CONF_NUM_LOGIC_CHANNELS,
        SR_CONF_NUM_ANALOG_CHANNELS,
+       SR_CONF_LIMIT_FRAMES,
 };
 
 static const uint32_t drvopts[] = {
@@ -62,9 +63,12 @@ static const uint32_t devopts[] = {
        SR_CONF_CONTINUOUS,
        SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
        SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
+       SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
        SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
        SR_CONF_AVERAGING | SR_CONF_GET | SR_CONF_SET,
        SR_CONF_AVG_SAMPLES | SR_CONF_GET | SR_CONF_SET,
+       SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
+       SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
 };
 
 static const uint32_t devopts_cg_logic[] = {
@@ -80,6 +84,14 @@ static const uint32_t devopts_cg_analog_channel[] = {
        SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
 };
 
+static const int32_t trigger_matches[] = {
+       SR_TRIGGER_ZERO,
+       SR_TRIGGER_ONE,
+       SR_TRIGGER_RISING,
+       SR_TRIGGER_FALLING,
+       SR_TRIGGER_EDGE,
+};
+
 static const uint64_t samplerates[] = {
        SR_HZ(1),
        SR_GHZ(1),
@@ -96,10 +108,12 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
        struct analog_gen *ag;
        GSList *l;
        int num_logic_channels, num_analog_channels, pattern, i;
+       uint64_t limit_frames;
        char channel_name[16];
 
        num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
        num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
+       limit_frames = DEFAULT_LIMIT_FRAMES;
        for (l = options; l; l = l->next) {
                src = l->data;
                switch (src->key) {
@@ -109,6 +123,9 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
                case SR_CONF_NUM_ANALOG_CHANNELS:
                        num_analog_channels = g_variant_get_int32(src->data);
                        break;
+               case SR_CONF_LIMIT_FRAMES:
+                       limit_frames = g_variant_get_uint64(src->data);
+                       break;
                }
        }
 
@@ -125,6 +142,9 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
        devc->all_logic_channels_mask--;
        devc->logic_pattern = DEFAULT_LOGIC_PATTERN;
        devc->num_analog_channels = num_analog_channels;
+       devc->limit_frames = limit_frames;
+       devc->capture_ratio = 20;
+       devc->stl = NULL;
 
        if (num_logic_channels > 0) {
                /* Logic channels, all in one channel group. */
@@ -223,6 +243,9 @@ static int config_get(uint32_t key, GVariant **data,
        case SR_CONF_LIMIT_MSEC:
                *data = g_variant_new_uint64(devc->limit_msec);
                break;
+       case SR_CONF_LIMIT_FRAMES:
+               *data = g_variant_new_uint64(devc->limit_frames);
+               break;
        case SR_CONF_AVERAGING:
                *data = g_variant_new_boolean(devc->avg);
                break;
@@ -254,6 +277,9 @@ static int config_get(uint32_t key, GVariant **data,
                ag = g_hash_table_lookup(devc->ch_ag, ch);
                *data = g_variant_new_double(ag->amplitude);
                break;
+       case SR_CONF_CAPTURE_RATIO:
+               *data = g_variant_new_uint64(devc->capture_ratio);
+               break;
        default:
                return SR_ERR_NA;
        }
@@ -284,6 +310,9 @@ static int config_set(uint32_t key, GVariant *data,
                devc->limit_msec = g_variant_get_uint64(data);
                devc->limit_samples = 0;
                break;
+       case SR_CONF_LIMIT_FRAMES:
+               devc->limit_frames = g_variant_get_uint64(data);
+               break;
        case SR_CONF_AVERAGING:
                devc->avg = g_variant_get_boolean(data);
                sr_dbg("%s averaging", devc->avg ? "Enabling" : "Disabling");
@@ -334,6 +363,9 @@ static int config_set(uint32_t key, GVariant *data,
                        ag->amplitude = g_variant_get_double(data);
                }
                break;
+       case SR_CONF_CAPTURE_RATIO:
+               devc->capture_ratio = g_variant_get_uint64(data);
+               break;
        default:
                return SR_ERR_NA;
        }
@@ -354,6 +386,9 @@ static int config_list(uint32_t key, GVariant **data,
                case SR_CONF_SAMPLERATE:
                        *data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
                        break;
+               case SR_CONF_TRIGGER_MATCH:
+                       *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
+                       break;
                default:
                        return SR_ERR_NA;
                }
@@ -401,11 +436,33 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        uint8_t mask;
        GHashTableIter iter;
        void *value;
+       struct sr_trigger *trigger;
 
        devc = sdi->priv;
        devc->sent_samples = 0;
        devc->sent_frame_samples = 0;
 
+       /* Setup triggers */
+       if ((trigger = sr_session_trigger_get(sdi->session))) {
+               int pre_trigger_samples = 0;
+               if (devc->limit_samples > 0)
+                       pre_trigger_samples = (devc->capture_ratio * devc->limit_samples) / 100;
+               devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
+               if (!devc->stl)
+                       return SR_ERR_MALLOC;
+
+               /* Disable all analog channels since using them when there are logic
+                * triggers set up would require having pre-trigger sample buffers
+                * for analog sample data.
+                */
+               for (l = sdi->channels; l; l = l->next) {
+                       ch = l->data;
+                       if (ch->type == SR_CHANNEL_ANALOG)
+                               ch->enabled = FALSE;
+               }
+       }
+       devc->trigger_fired = FALSE;
+
        /*
         * Determine the numbers of logic and analog channels that are
         * involved in the acquisition. Determine an offset and a mask to
@@ -458,7 +515,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
 
        std_session_send_df_header(sdi);
 
-       if (SAMPLES_PER_FRAME > 0)
+       if (devc->limit_frames > 0)
                std_session_send_frame_begin(sdi);
 
        /* We use this timestamp to decide how many more samples to send. */
@@ -471,13 +528,21 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
 
 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
 {
+       struct dev_context *devc;
+
        sr_session_source_remove(sdi->session, -1);
 
-       if (SAMPLES_PER_FRAME > 0)
+       devc = sdi->priv;
+       if (devc->limit_frames > 0)
                std_session_send_frame_end(sdi);
 
        std_session_send_df_end(sdi);
 
+       if (devc->stl) {
+               soft_trigger_logic_free(devc->stl);
+               devc->stl = NULL;
+       }
+
        return SR_OK;
 }