From: Uwe Hermann Date: Thu, 11 May 2017 21:20:58 +0000 (+0200) Subject: Add srd_inst_initial_pins_set_all() and support code. X-Git-Tag: libsigrokdecode-0.5.0~13 X-Git-Url: http://sigrok.org/gitweb/?p=libsigrokdecode.git;a=commitdiff_plain;h=97b874bd0b6913ed52df1b8aac5e7491479fac9a Add srd_inst_initial_pins_set_all() and support code. 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. --- diff --git a/decoders/am230x/pd.py b/decoders/am230x/pd.py index f76cab2..3c5003d 100644 --- a/decoders/am230x/pd.py +++ b/decoders/am230x/pd.py @@ -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 diff --git a/decoders/dcf77/pd.py b/decoders/dcf77/pd.py index b643631..a4e87f6 100644 --- a/decoders/dcf77/pd.py +++ b/decoders/dcf77/pd.py @@ -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 diff --git a/decoders/guess_bitrate/pd.py b/decoders/guess_bitrate/pd.py index 45d68b0..1bccc54 100644 --- a/decoders/guess_bitrate/pd.py +++ b/decoders/guess_bitrate/pd.py @@ -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 diff --git a/decoders/i2c/pd.py b/decoders/i2c/pd.py index d2f8bc4..0e7f769 100644 --- a/decoders/i2c/pd.py +++ b/decoders/i2c/pd.py @@ -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) diff --git a/decoders/ir_nec/pd.py b/decoders/ir_nec/pd.py index 93b398b..03a5469 100644 --- a/decoders/ir_nec/pd.py +++ b/decoders/ir_nec/pd.py @@ -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 diff --git a/decoders/mdio/pd.py b/decoders/mdio/pd.py index ed6cfef..7c2fc5f 100644 --- a/decoders/mdio/pd.py +++ b/decoders/mdio/pd.py @@ -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. diff --git a/decoders/parallel/pd.py b/decoders/parallel/pd.py index db9b371..c8ac2b0 100644 --- a/decoders/parallel/pd.py +++ b/decoders/parallel/pd.py @@ -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) diff --git a/decoders/spdif/pd.py b/decoders/spdif/pd.py index 1f1ed70..0c535e4 100644 --- a/decoders/spdif/pd.py +++ b/decoders/spdif/pd.py @@ -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 diff --git a/decoders/timing/pd.py b/decoders/timing/pd.py index be600e9..ab963bb 100644 --- a/decoders/timing/pd.py +++ b/decoders/timing/pd.py @@ -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: diff --git a/instance.c b/instance.c index 6d38738..61e0ea8 100644 --- a/instance.c +++ b/instance.c @@ -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); diff --git a/libsigrokdecode.h b/libsigrokdecode.h index df1cb5c..d37c432 100644 --- a/libsigrokdecode.h +++ b/libsigrokdecode.h @@ -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,