Add srd_inst_initial_pins_set_all() and support code.
authorUwe Hermann <uwe@hermann-uwe.de>
Thu, 11 May 2017 21:20:58 +0000 (23:20 +0200)
committerUwe Hermann <uwe@hermann-uwe.de>
Mon, 5 Jun 2017 17:09:48 +0000 (19:09 +0200)
This allows frontends to set the assumed initial pins (i.e., the assumed
state of the pins before the first sample of a capture) to user-specified
values.

The assumed initial pins can be either low, or high, or "use same value
as the first sample of the capture".

The special self.initial_pins decoder attribute is now removed.

decoders/am230x/pd.py
decoders/dcf77/pd.py
decoders/guess_bitrate/pd.py
decoders/i2c/pd.py
decoders/ir_nec/pd.py
decoders/mdio/pd.py
decoders/parallel/pd.py
decoders/spdif/pd.py
decoders/timing/pd.py
instance.c
libsigrokdecode.h

index f76cab20b9f7329556280e0b9fe46e9dbc50afaf..3c5003d129693dd0bb3f42dd968532c9cdbb307f 100644 (file)
@@ -128,9 +128,6 @@ class Decoder(srd.Decoder):
     def start(self):
         self.out_ann = self.register(srd.OUTPUT_ANN)
 
-        # Assume that the initial pin state is high (logic 1).
-        self.initial_pins = [1]
-
     def metadata(self, key, value):
         if key != srd.SRD_CONF_SAMPLERATE:
             return
index b643631081b7e1babed940146b8f87f5aa0136bb..a4e87f64a114b7a94bb98d8f3082a8396d1d523a 100644 (file)
@@ -75,9 +75,6 @@ class Decoder(srd.Decoder):
     def start(self):
         self.out_ann = self.register(srd.OUTPUT_ANN)
 
-        # Assume that the initial pin state is logic 1.
-        self.initial_pins = [1]
-
     def metadata(self, key, value):
         if key == srd.SRD_CONF_SAMPLERATE:
             self.samplerate = value
index 45d68b055c0c39a5ac18e18731fba1b81bd571f0..1bccc5435dd88c7536a1eb6f8b60a0070855ccc5 100644 (file)
@@ -49,8 +49,6 @@ class Decoder(srd.Decoder):
     def start(self):
         self.out_ann = self.register(srd.OUTPUT_ANN)
 
-        self.initial_pins = [1] # TODO: Not generally correct.
-
     def metadata(self, key, value):
         if key == srd.SRD_CONF_SAMPLERATE:
             self.samplerate = value
index d2f8bc454fed3c00341fb986de57c7defdee2e3d..0e7f769e16f16eda276de9809f01fe43106b3983 100644 (file)
@@ -130,10 +130,6 @@ class Decoder(srd.Decoder):
         self.out_bitrate = self.register(srd.OUTPUT_META,
                 meta=(int, 'Bitrate', 'Bitrate from Start bit to Stop bit'))
 
-        # Assume that the initial SCL/SDA pin state is high (logic 1).
-        # This is a good default, since both pins have pullups as per spec.
-        self.initial_pins = [1, 1]
-
     def putx(self, data):
         self.put(self.ss, self.es, self.out_ann, data)
 
index 93b398b59ccfc1dfb481e314aa40d6379b476482..03a5469c2e27d92ee9397a11a2ae10458cb92453 100644 (file)
@@ -108,9 +108,6 @@ class Decoder(srd.Decoder):
         self.out_ann = self.register(srd.OUTPUT_ANN)
         self.active = 0 if self.options['polarity'] == 'active-low' else 1
 
-        # Set the initial (assumed) value of the pin as per user-config.
-        self.initial_pins = [1 if self.active == 0 else 0]
-
     def metadata(self, key, value):
         if key == srd.SRD_CONF_SAMPLERATE:
             self.samplerate = value
index ed6cfef68f6081a226dd4fdf02c798297a7210e4..7c2fc5f3039b465bbe65fb5055c8eb21848d1c85 100644 (file)
@@ -62,7 +62,6 @@ class Decoder(srd.Decoder):
     )
 
     def __init__(self):
-        self.initial_pins = [1, 1]
         self.illegal_bus = 0
         self.samplenum = -1
         self.clause45_addr = -1 # Clause 45 is context sensitive.
index db9b371f3687ed5e570a4e2a83b5dcde1adb5adc..c8ac2b0f74d2211b86f9a3b88c8f031a23e91223 100644 (file)
@@ -99,9 +99,6 @@ class Decoder(srd.Decoder):
         self.out_python = self.register(srd.OUTPUT_PYTHON)
         self.out_ann = self.register(srd.OUTPUT_ANN)
 
-        # Assume that the initial pin state of all pins is logic 1.
-        self.initial_pins = [1] * (NUM_CHANNELS + 1)
-
     def putpb(self, data):
         self.put(self.ss_item, self.es_item, self.out_python, data)
 
index 1f1ed705b0dff5c95606a367a21d8ef51db48060..0c535e4a6d86e56530e6837390d01bac714b2c73 100644 (file)
@@ -79,9 +79,6 @@ class Decoder(srd.Decoder):
     def start(self):
         self.out_ann = self.register(srd.OUTPUT_ANN)
 
-        # Assume that the initial pin state is logic 0.
-        self.initial_pins = [0]
-
     def metadata(self, key, value):
         if key == srd.SRD_CONF_SAMPLERATE:
             self.samplerate = value
index be600e906b0beffd3abc89cba882404fb35d9161..ab963bb11d33341ff564073f07c62c865f66c574 100644 (file)
@@ -88,7 +88,6 @@ class Decoder(srd.Decoder):
     def start(self):
         self.out_ann = self.register(srd.OUTPUT_ANN)
         self.edge = self.options['edge']
-        self.initial_pins = [0]
 
     def decode(self):
         if not self.samplerate:
index 6d38738b70d12bce88cf0c04c830103caad523f4..61e0ea895360df67b76375fe1e7bbac868cc0cf6 100644 (file)
@@ -353,6 +353,13 @@ SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess,
                di->channel_samples = g_malloc(di->dec_num_channels);
        }
 
+       /* Default to the initial pins being the same as in sample 0. */
+       di->old_pins_array = g_array_sized_new(FALSE, TRUE, sizeof(uint8_t),
+                                               di->dec_num_channels);
+       g_array_set_size(di->old_pins_array, di->dec_num_channels);
+       memset(di->old_pins_array->data, SRD_INITIAL_PIN_SAME_AS_SAMPLE0,
+               di->dec_num_channels);
+
        /* Create a new instance of this decoder class. */
        if (!(di->py_inst = PyObject_CallObject(dec->py_dec, NULL))) {
                if (PyErr_Occurred())
@@ -376,7 +383,6 @@ SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess,
        di->inbuf = NULL;
        di->inbuflen = 0;
        di->abs_cur_samplenum = 0;
-       di->old_pins_array = NULL;
        di->thread_handle = NULL;
        di->got_new_samples = FALSE;
        di->handled_all_samples = FALSE;
@@ -625,51 +631,49 @@ SRD_PRIV struct srd_decoder_inst *srd_inst_find_by_obj(const GSList *stack,
 /**
  * Set the list of initial (assumed) pin values.
  *
- * If the list already exists, do nothing.
- *
  * @param di Decoder instance to use. Must not be NULL.
+ * @param initial_pins A GArray of uint8_t values. Must not be NULL.
  *
- * @private
+ * @since 0.5.0
  */
-static void set_initial_pin_values(struct srd_decoder_inst *di)
+SRD_API int srd_inst_initial_pins_set_all(struct srd_decoder_inst *di, GArray *initial_pins)
 {
        int i;
        GString *s;
-       PyObject *py_initial_pins;
 
-       if (!di || !di->py_inst) {
+       if (!di) {
                srd_err("Invalid decoder instance.");
-               return;
-       }
-
-       /* Nothing to do if di->old_pins_array is already != NULL. */
-       if (di->old_pins_array) {
-               srd_dbg("Initial pins already set, nothing to do.");
-               return;
+               return SRD_ERR_ARG;
        }
 
-       /* Create an array of old (previous sample) pins, init to 0. */
-       di->old_pins_array = g_array_sized_new(FALSE, TRUE, sizeof(uint8_t), di->dec_num_channels);
-       g_array_set_size(di->old_pins_array, di->dec_num_channels);
+       if (!initial_pins)
+               return SRD_ERR_ARG;
 
-       /* Check if the decoder has set self.initial_pins. */
-       if (!PyObject_HasAttrString(di->py_inst, "initial_pins")) {
-               srd_dbg("Initial pins: all 0 (self.initial_pins not set).");
-               return;
+       if (initial_pins->len != (guint)di->dec_num_channels) {
+               srd_err("Incorrect number of channels (need %d, got %d).",
+                       di->dec_num_channels, initial_pins->len);
+               return SRD_ERR_ARG;
        }
 
-       /* Get self.initial_pins. */
-       py_initial_pins = PyObject_GetAttrString(di->py_inst, "initial_pins");
+       /* Sanity-check initial pin state values. */
+       for (i = 0; i < di->dec_num_channels; i++) {
+               if (initial_pins->data[i] <= 2)
+                       continue;
+               srd_err("Invalid initial channel %d pin state: %d.",
+                       i, initial_pins->data[i]);
+               return SRD_ERR_ARG;
+       }
 
-       /* Fill di->old_pins_array based on self.initial_pins. */
        s = g_string_sized_new(100);
        for (i = 0; i < di->dec_num_channels; i++) {
-               di->old_pins_array->data[i] = PyLong_AsLong(PyList_GetItem(py_initial_pins, i));
+               di->old_pins_array->data[i] = initial_pins->data[i];
                g_string_append_printf(s, "%d, ", di->old_pins_array->data[i]);
        }
        s = g_string_truncate(s, s->len - 2);
        srd_dbg("Initial pins: %s.", s->str);
        g_string_free(s, TRUE);
+
+       return SRD_OK;
 }
 
 SRD_PRIV void oldpins_array_free(struct srd_decoder_inst *di)
@@ -704,9 +708,6 @@ SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di)
        }
        Py_DecRef(py_res);
 
-       /* Set the initial pins based on self.initial_pins. */
-       set_initial_pin_values(di);
-
        /* Set self.samplenum to 0. */
        PyObject_SetAttrString(di->py_inst, "samplenum", PyLong_FromLong(0));
 
@@ -840,6 +841,27 @@ static void update_old_pins_array(struct srd_decoder_inst *di,
        }
 }
 
+static void update_old_pins_array_initial_pins(struct srd_decoder_inst *di)
+{
+       uint8_t sample;
+       int i, byte_offset, bit_offset;
+       const uint8_t *sample_pos;
+
+       if (!di || !di->dec_channelmap)
+               return;
+
+       sample_pos = di->inbuf + ((di->abs_cur_samplenum - di->abs_start_samplenum) * di->data_unitsize);
+
+       for (i = 0; i < di->dec_num_channels; i++) {
+               if (di->old_pins_array->data[i] != SRD_INITIAL_PIN_SAME_AS_SAMPLE0)
+                       continue;
+               byte_offset = di->dec_channelmap[i] / 8;
+               bit_offset = di->dec_channelmap[i] % 8;
+               sample = *(sample_pos + byte_offset) & (1 << bit_offset) ? 1 : 0;
+               di->old_pins_array->data[i] = sample;
+       }
+}
+
 static gboolean term_matches(const struct srd_decoder_inst *di,
                struct srd_term *term, const uint8_t *sample_pos)
 {
@@ -924,6 +946,10 @@ static gboolean find_match(struct srd_decoder_inst *di)
        di->match_array = g_array_sized_new(FALSE, TRUE, sizeof(gboolean), num_conditions);
        g_array_set_size(di->match_array, num_conditions);
 
+       /* Sample 0: Set di->old_pins_array for SRD_INITIAL_PIN_SAME_AS_SAMPLE0 pins. */
+       if (di->abs_cur_samplenum == 0)
+               update_old_pins_array_initial_pins(di);
+
        for (i = 0, s = 0; i < num_samples_to_process; i++, s++, (di->abs_cur_samplenum)++) {
 
                sample_pos = di->inbuf + ((di->abs_cur_samplenum - di->abs_start_samplenum) * di->data_unitsize);
index df1cb5c481192d95fbfe5fb9e491ee3e81965291..d37c432a537c9c5a8cbacbc6b4e27674eec69149 100644 (file)
@@ -194,6 +194,12 @@ struct srd_decoder {
        void *py_dec;
 };
 
+enum srd_initial_pin {
+       SRD_INITIAL_PIN_LOW,
+       SRD_INITIAL_PIN_HIGH,
+       SRD_INITIAL_PIN_SAME_AS_SAMPLE0,
+};
+
 /**
  * Structure which contains information about one protocol decoder channel.
  * For example, I2C has two channels, SDA and SCL.
@@ -347,6 +353,8 @@ SRD_API int srd_inst_stack(struct srd_session *sess,
                struct srd_decoder_inst *di_from, struct srd_decoder_inst *di_to);
 SRD_API struct srd_decoder_inst *srd_inst_find_by_id(struct srd_session *sess,
                const char *inst_id);
+SRD_API int srd_inst_initial_pins_set_all(struct srd_decoder_inst *di,
+               GArray *initial_pins);
 
 /* log.c */
 typedef int (*srd_log_callback)(void *cb_data, int loglevel,