]> sigrok.org Git - libsigrokdecode.git/commitdiff
new srd_logic type implementation for PDs to iterate over.
authorBert Vermeulen <redacted>
Thu, 5 Jan 2012 02:31:36 +0000 (03:31 +0100)
committerBert Vermeulen <redacted>
Thu, 5 Jan 2012 02:39:02 +0000 (03:39 +0100)
Makefile.am
controller.c
decoders/i2c.py
log.c
module_sigrokdecode.c [new file with mode: 0644]
sigrokdecode.h
type_logic.c [new file with mode: 0644]

index 36471214f1cf04edfd4a65d2738861b79cf7f60f..82f59cdb4ac7516cb3435fc022b74666c7ab910c 100644 (file)
@@ -24,7 +24,8 @@ SUBDIRS = decoders
 
 lib_LTLIBRARIES = libsigrokdecode.la
 
-libsigrokdecode_la_SOURCES = controller.c decoder.c log.c util.c
+libsigrokdecode_la_SOURCES = controller.c decoder.c log.c util.c \
+       module_sigrokdecode.c type_logic.c
 
 libsigrokdecode_la_CPPFLAGS = $(CPPFLAGS_PYTHON) \
                              -DDECODERS_DIR='"$(DECODERS_DIR)"'
index 84a22b5b9520d81a1a8e89729080761f2829c0d3..de9b00aa30a570f0c614b21e87760b2bc03fb371 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the sigrok project.
  *
  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
- * Copyright (C) 2011 Bert Vermeulen <bert@biot.com>
+ * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 /* TODO
 static GSList *pipelines = NULL;
-*/
-
-/* lives in decoder.c */
-extern GSList *pd_list;
-extern GSList *di_list;
-
 struct srd_pipeline {
        int id;
        GSList *decoders;
 };
+*/
 
+/* lives in decoder.c */
+extern GSList *pd_list;
+extern GSList *di_list;
 
+/* lives in module_sigrokdecode.c */
+extern PyMODINIT_FUNC PyInit_sigrokdecode(void);
 
-static PyObject *Decoder_init(PyObject *self, PyObject *args)
-{
-       (void)self;
-       (void)args;
-//     printf("init object %x\n", self);
-
-       Py_RETURN_NONE;
-}
-
-struct srd_decoder_instance *get_di_by_decobject(void *decobject);
-
-static PyObject *Decoder_put(PyObject *self, PyObject *args)
-{
-       GSList *l;
-       PyObject *data;
-       struct srd_decoder_instance *di;
-       struct srd_pd_output *pdo;
-       uint64_t timeoffset, duration;
-       int output_id;
-
-       if (!(di = get_di_by_decobject(self)))
-               return NULL;
-
-       if (!PyArg_ParseTuple(args, "KKiO", &timeoffset, &duration, &output_id, &data))
-               return NULL;
-
-       printf("put: %s instance %p time %" PRIu64 " duration %" PRIu64 " ",
-                       di->decoder->name, di, timeoffset, duration);
-
-       if (!(l = g_slist_nth(di->pd_output, output_id)))
-               /* PD supplied invalid output id */
-               /* TODO: better error message */
-               return NULL;
-       pdo = l->data;
-
-       printf("stream %d: ", pdo->output_type);
-       PyObject_Print(data, stdout, Py_PRINT_RAW);
-       puts("");
-
-       Py_RETURN_NONE;
-}
-
-
-static PyObject *Decoder_output_new(PyObject *self, PyObject *py_output_type)
-{
-       PyObject *ret;
-       struct srd_decoder_instance *di;
-       char *protocol_id, *description;
-       int output_type, pdo_id;
-
-       if (!(di = get_di_by_decobject(self)))
-               return NULL;
-
-       printf("output_new di %s\n", di->decoder->name);
-
-//     if (!PyArg_ParseTuple(args, "i:output_type,s:protocol_id,s:description",
-//                     &output_type, &protocol_id, &description))
-       if (!PyArg_ParseTuple(py_output_type, "i:output_type", &output_type))
-               return NULL;
-
-       protocol_id = "i2c";
-       description = "blah";
-       pdo_id = pd_output_new(di, output_type, protocol_id, description);
-       if (pdo_id < 0)
-               Py_RETURN_NONE;
-       else
-               ret = Py_BuildValue("i", pdo_id);
-
-       return ret;
-}
-
-static PyMethodDef no_methods[] = { {NULL, NULL, 0, NULL} };
-static PyMethodDef Decoder_methods[] = {
-       {"__init__", Decoder_init, METH_VARARGS, ""},
-       {"put", Decoder_put, METH_VARARGS,
-        "Accepts a dictionary with the following keys: time, duration, data"},
-       {"output_new", Decoder_output_new, METH_VARARGS,
-        "Create a new output stream"},
-       {NULL, NULL, 0, NULL}
-};
-
-
-typedef struct {
-       PyObject_HEAD
-} sigrok_Decoder_object;
-
-static PyTypeObject sigrok_Decoder_type = {
-       PyVarObject_HEAD_INIT(NULL, 0)
-       .tp_name = "sigrok.Decoder",
-       .tp_basicsize = sizeof(sigrok_Decoder_object),
-       .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-       .tp_doc = "Sigrok Decoder object",
-       .tp_methods = Decoder_methods,
-};
-
-static struct PyModuleDef sigrok_Decoder_module = {
-       PyModuleDef_HEAD_INIT,
-       .m_name = "sigrok",
-       .m_doc = "sigrok base classes",
-       .m_size = -1,
-       .m_methods = no_methods,
-};
-
-PyMODINIT_FUNC PyInit_sigrok(void)
-{
-       PyObject *mod;
-
-       /* assign this here, for compiler portability */
-       sigrok_Decoder_type.tp_new = PyType_GenericNew;
-       if (PyType_Ready(&sigrok_Decoder_type) < 0)
-               return NULL;
-
-//     mod = Py_InitModule3("sigrok", no_methods, "sigrok base classes");
-       mod = PyModule_Create(&sigrok_Decoder_module);
-       Py_INCREF(&sigrok_Decoder_type);
-       if (PyModule_AddObject(mod, "Decoder", (PyObject *)&sigrok_Decoder_type) == -1)
-               return NULL;
-
-       return mod;
-}
-
+/* lives in type_logic.c */
+extern PyTypeObject srd_logic_type;
 
-struct srd_decoder_instance *get_di_by_decobject(void *decobject)
-{
-       GSList *l;
-       struct srd_decoder_instance *di;
-
-       for (l = di_list; l; l = l->next) {
-               di = l->data;
-               if (decobject == di->py_instance)
-                       return di;
-       }
-
-       return NULL;
-}
 
 /**
  * Initialize libsigrokdecode.
@@ -201,14 +69,11 @@ int srd_init(void)
 {
        int ret;
 
-       PyImport_AppendInittab("sigrok", PyInit_sigrok);
+       PyImport_AppendInittab("sigrokdecode", PyInit_sigrokdecode);
 
        /* Py_Initialize() returns void and usually cannot fail. */
        Py_Initialize();
 
-       PyInit_sigrok();
-
-       PyRun_SimpleString("import sys;");
        if ((ret = set_modulepath()) != SRD_OK) {
                Py_Finalize();
                return ret;
@@ -258,6 +123,7 @@ int set_modulepath(void)
 {
        int ret;
 
+       PyRun_SimpleString("import sys");
        ret = PyRun_SimpleString("sys.path.append(r'" DECODERS_DIR "');");
 
        return ret;
@@ -279,6 +145,7 @@ struct srd_decoder_instance *srd_instance_new(const char *id)
        di = g_malloc(sizeof(*di));
        di->decoder = dec;
        di->pd_output = NULL;
+       di->unitsize = 0;
 
        /* Create an empty Python tuple. */
        if (!(py_args = PyTuple_New(0))) { /* NEWREF */
@@ -327,22 +194,21 @@ int srd_instance_set_probe(struct srd_decoder_instance *di,
 }
 
 
-int srd_session_start(const char *driver, int unitsize, uint64_t starttime,
-               uint64_t samplerate)
+int srd_session_start(int num_probes, int unitsize, uint64_t samplerate)
 {
        PyObject *py_res;
        GSList *d;
        struct srd_decoder_instance *di;
 
-       fprintf(stdout, "%s: %s\n", __func__, driver);
+       fprintf(stdout, "%s\n", __func__);
 
        for (d = di_list; d; d = d->next) {
                di = d->data;
+               di->num_probes = num_probes;
+               di->unitsize = unitsize;
+               di->samplerate = samplerate;
                if (!(py_res = PyObject_CallMethod(di->py_instance, "start",
-                                       "{s:s,s:l,s:l,s:l}",
-                                       "driver", driver,
-                                       "unitsize", (long)unitsize,
-                                       "starttime", (long)starttime,
+                                   "{s:l}",
                                        "samplerate", (long)samplerate))) {
                        if (PyErr_Occurred())
                                PyErr_Print(); /* Returns void. */
@@ -366,15 +232,13 @@ int srd_session_start(const char *driver, int unitsize, uint64_t starttime,
  * @return SRD_OK upon success, a (negative) error code otherwise.
  */
 int srd_run_decoder(uint64_t timeoffset, uint64_t duration,
-               struct srd_decoder_instance *dec, uint8_t *inbuf, uint64_t inbuflen)
+               struct srd_decoder_instance *di, uint8_t *inbuf, uint64_t inbuflen)
 {
        PyObject *py_instance, *py_res;
-
-//     fprintf(stdout, "%s: %s\n", __func__, dec->decoder->name);
-//     printf("to %u du %u len %d\n", timeoffset, duration, inbuflen);
+       srd_logic *logic;
 
        /* Return an error upon unusable input. */
-       if (dec == NULL)
+       if (di == NULL)
                return SRD_ERR_ARG; /* TODO: More specific error? */
        if (inbuf == NULL)
                return SRD_ERR_ARG; /* TODO: More specific error? */
@@ -382,11 +246,20 @@ int srd_run_decoder(uint64_t timeoffset, uint64_t duration,
                return SRD_ERR_ARG; /* TODO: More specific error? */
 
        /* TODO: Error handling. */
-       py_instance = dec->py_instance;
+       py_instance = di->py_instance;
        Py_XINCREF(py_instance);
 
+       logic = PyObject_New(srd_logic, &srd_logic_type);
+       Py_INCREF(logic);
+       logic->di = di;
+       logic->itercnt = 0;
+       logic->inbuf = inbuf;
+       logic->inbuflen = inbuflen;
+       logic->sample = PyList_New(2);
+       Py_INCREF(logic->sample);
+
        if (!(py_res = PyObject_CallMethod(py_instance, "decode",
-                       "KKy#", timeoffset, duration, inbuf, inbuflen))) {
+                       "KKO", timeoffset, duration, logic))) {
                if (PyErr_Occurred())
                        PyErr_Print(); /* Returns void. */
 
@@ -394,6 +267,7 @@ int srd_run_decoder(uint64_t timeoffset, uint64_t duration,
        }
 
        Py_XDECREF(py_res);
+
        return SRD_OK;
 }
 
@@ -447,6 +321,20 @@ int pd_output_new(struct srd_decoder_instance *di, int output_type,
        return pdo_id;
 }
 
+struct srd_decoder_instance *get_di_by_decobject(void *decobject)
+{
+       GSList *l;
+       struct srd_decoder_instance *di;
+
+       for (l = di_list; l; l = l->next) {
+               di = l->data;
+               if (decobject == di->py_instance)
+                       return di;
+       }
+
+       return NULL;
+}
+
 
 //int srd_pipeline_new(int plid)
 //{
index cf16d3a28dc0ab86937a170bedba6a22e404e583..1c4903b0dfe24c33b6d3d8d83b2cb272aeed1c1b 100644 (file)
 #  'signals': [{'SCL': }]}
 #
 
-import sigrok
+import sigrokdecode
 
 # symbols for i2c decoders up the stack
 START           = 1
@@ -144,18 +144,8 @@ FIND_START = 0
 FIND_ADDRESS = 1
 FIND_DATA = 2
 
-class Sample():
-    def __init__(self, data):
-        self.data = data
-    def probe(self, probe):
-        s = self.data[probe / 8] & (1 << (probe % 8))
-        return True if s else False
 
-def sampleiter(data, unitsize):
-    for i in range(0, len(data), unitsize):
-        yield(Sample(data[i:i+unitsize]))
-
-class Decoder(sigrok.Decoder):
+class Decoder(sigrokdecode.Decoder):
     id = 'i2c'
     name = 'I2C'
     longname = 'Inter-Integrated Circuit (I2C) bus'
@@ -166,40 +156,28 @@ class Decoder(sigrok.Decoder):
     license = 'gplv2+'
     inputs = ['logic']
     outputs = ['i2c']
-    probes = {
-        'scl': {'ch': 0, 'name': 'SCL', 'desc': 'Serial clock line'},
-        'sda': {'ch': 1, 'name': 'SDA', 'desc': 'Serial data line'},
-    }
+    probes = [
+        {'id': 'scl', 'name': 'SCL', 'desc': 'Serial clock line'},
+        {'id': 'sda', 'name': 'SDA', 'desc': 'Serial data line'},
+    ]
     options = {
         'address-space': ['Address space (in bits)', 7],
     }
 
     def __init__(self, **kwargs):
-        self.probes = Decoder.probes.copy()
         self.output_protocol = None
         self.output_annotation = None
-
-        # TODO: Don't hardcode the number of channels.
-        self.channels = 8
-
-        self.samplenum = 0
+        self.samplecnt = 0
         self.bitcount = 0
         self.databyte = 0
         self.wr = -1
         self.startsample = -1
         self.is_repeat_start = 0
-
         self.state = FIND_START
-
-        # Get the channel/probe number of the SCL/SDA signals.
-        self.scl_bit = self.probes['scl']['ch']
-        self.sda_bit = self.probes['sda']['ch']
-
         self.oldscl = None
         self.oldsda = None
 
     def start(self, metadata):
-        self.unitsize = metadata["unitsize"]
         self.output_protocol = self.output_new(2)
         self.output_annotation = self.output_new(1)
 
@@ -243,7 +221,8 @@ class Decoder(sigrok.Decoder):
         """Gather 8 bits of data plus the ACK/NACK bit."""
 
         if self.startsample == -1:
-            self.startsample = self.samplenum
+            # TODO: should be samplenum, as received from the feed
+            self.startsample = self.samplecnt
         self.bitcount += 1
 
         # Address and data are transmitted MSB-first.
@@ -314,41 +293,19 @@ class Decoder(sigrok.Decoder):
         self.wr = -1
 
     def put(self, output_id, data):
-        timeoffset = self.timeoffset + ((self.samplenum - self.bitcount) * self.period)
-        if self.bitcount > 0:
-            duration = self.bitcount * self.period
-        else:
-            duration = self.period
-        print("**", timeoffset, duration)
-        super(Decoder, self).put(timeoffset, duration, output_id, data)
+        # inject sample range into the call up to sigrok
+        super(Decoder, self).put(0, 0, output_id, data)
 
     def decode(self, timeoffset, duration, data):
-        self.timeoffset = timeoffset
-        self.duration = duration
-        print("++", timeoffset, duration, len(data))
-        # duration of one bit in ps, only valid for this call to decode()
-        self.period = int(duration / len(data))
-
-        # We should accept a list of samples and iterate...
-        for sample in sampleiter(data, self.unitsize):
-
-            # TODO: Eliminate the need for ord().
-            s = ord(sample.data)
-
-            # TODO: Start counting at 0 or 1?
-            self.samplenum += 1
+        for samplenum, (scl, sda) in data:
+            self.samplecnt += 1
 
             # First sample: Save SCL/SDA value.
             if self.oldscl == None:
-                # Get SCL/SDA bit values (0/1 for low/high) of the first sample.
-                self.oldscl = (s & (1 << self.scl_bit)) >> self.scl_bit
-                self.oldsda = (s & (1 << self.sda_bit)) >> self.sda_bit
+                self.oldscl = scl
+                self.oldsda = sda
                 continue
 
-            # Get SCL/SDA bit values (0/1 for low/high).
-            scl = (s & (1 << self.scl_bit)) >> self.scl_bit
-            sda = (s & (1 << self.sda_bit)) >> self.sda_bit
-
             # TODO: Wait until the bus is idle (SDA = SCL = 1) first?
 
             # State machine.
@@ -373,4 +330,3 @@ class Decoder(sigrok.Decoder):
             self.oldscl = scl
             self.oldsda = sda
 
-
diff --git a/log.c b/log.c
index 6add4470c39ede8d963a8ca69ccc2b603d40b1f4..af4196c5dbe2898ca0282df9f6bc797795e22641 100644 (file)
--- a/log.c
+++ b/log.c
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
-#include <stdarg.h>
-#include <stdio.h>
 #include "sigrokdecode.h"
 #include "sigrokdecode-internal.h"
+#include <stdarg.h>
+#include <stdio.h>
 
 static int srd_loglevel = SRD_LOG_WARN; /* Show errors+warnings per default. */
 
diff --git a/module_sigrokdecode.c b/module_sigrokdecode.c
new file mode 100644 (file)
index 0000000..b547e9d
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * This file is part of the sigrok project.
+ *
+ * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
+#include "config.h"
+
+/* lives in type_logic.c */
+extern PyTypeObject srd_logic_type;
+
+
+/* TODO: not used, doesn't work actually */
+static PyObject *Decoder_init(PyObject *self, PyObject *args)
+{
+       (void)self;
+       (void)args;
+       printf("init Decoder object %p\n", self);
+
+       Py_RETURN_NONE;
+}
+
+static PyObject *Decoder_put(PyObject *self, PyObject *args)
+{
+       GSList *l;
+       PyObject *data;
+       struct srd_decoder_instance *di;
+       struct srd_pd_output *pdo;
+       uint64_t timeoffset, duration;
+       int output_id;
+
+       if (!(di = get_di_by_decobject(self)))
+               return NULL;
+
+       if (!PyArg_ParseTuple(args, "KKiO", &timeoffset, &duration, &output_id, &data))
+               return NULL;
+
+       if (!(l = g_slist_nth(di->pd_output, output_id))) {
+               /* PD supplied invalid output id */
+               /* TODO: better error message */
+               return NULL;
+       }
+       pdo = l->data;
+
+       /* TODO: SRD_OUTPUT_ANNOTATION should go back up to the caller,
+        * and SRD_OUTPUT_PROTOCOL should go up the PD stack.
+        */
+       printf("stream %d: ", pdo->output_type);
+       PyObject_Print(data, stdout, Py_PRINT_RAW);
+       puts("");
+
+       Py_RETURN_NONE;
+}
+
+
+static PyObject *Decoder_output_new(PyObject *self, PyObject *py_output_type)
+{
+       PyObject *ret;
+       struct srd_decoder_instance *di;
+       char *protocol_id, *description;
+       int output_type, pdo_id;
+
+       if (!(di = get_di_by_decobject(self)))
+               return NULL;
+
+       printf("output_new di %s\n", di->decoder->name);
+
+       if (!PyArg_ParseTuple(py_output_type, "i:output_type", &output_type))
+               return NULL;
+
+       protocol_id = "i2c";
+       description = "blah";
+       pdo_id = pd_output_new(di, output_type, protocol_id, description);
+       if (pdo_id < 0)
+               Py_RETURN_NONE;
+       else
+               ret = Py_BuildValue("i", pdo_id);
+
+       return ret;
+}
+
+static PyMethodDef no_methods[] = { {NULL, NULL, 0, NULL} };
+static PyMethodDef Decoder_methods[] = {
+       {"put", Decoder_put, METH_VARARGS,
+        "Accepts a dictionary with the following keys: time, duration, data"},
+       {"output_new", Decoder_output_new, METH_VARARGS,
+        "Create a new output stream"},
+       {NULL, NULL, 0, NULL}
+};
+
+
+typedef struct {
+       PyObject_HEAD
+} sigrok_Decoder_object;
+
+static PyTypeObject srd_Decoder_type = {
+       PyVarObject_HEAD_INIT(NULL, 0)
+       .tp_name = "sigrokdecode.Decoder",
+       .tp_basicsize = sizeof(sigrok_Decoder_object),
+       .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+       .tp_doc = "Sigrok Decoder object",
+       .tp_methods = Decoder_methods,
+       .tp_init = (initproc) Decoder_init,
+};
+
+static struct PyModuleDef sigrokdecode_module = {
+       PyModuleDef_HEAD_INIT,
+       .m_name = "sigrokdecode",
+       .m_doc = "sigrokdecode base class",
+       .m_size = -1,
+       .m_methods = no_methods,
+};
+
+PyMODINIT_FUNC PyInit_sigrokdecode(void)
+{
+       PyObject *mod;
+
+       /* tp_new needs to be assigned here for compiler portability */
+       srd_Decoder_type.tp_new = PyType_GenericNew;
+       if (PyType_Ready(&srd_Decoder_type) < 0)
+               return NULL;
+
+       srd_logic_type.tp_new = PyType_GenericNew;
+       if (PyType_Ready(&srd_logic_type) < 0)
+               return NULL;
+
+       mod = PyModule_Create(&sigrokdecode_module);
+       Py_INCREF(&srd_Decoder_type);
+       if (PyModule_AddObject(mod, "Decoder", (PyObject *)&srd_Decoder_type) == -1)
+               return NULL;
+       Py_INCREF(&srd_logic_type);
+       if (PyModule_AddObject(mod, "srd_logic", (PyObject *)&srd_logic_type) == -1)
+               return NULL;
+
+       return mod;
+}
+
index 8266fb50d20ea57ded0dd276022f3ed682797dcb..8c2ccd2271323bc587c7fa36cd93d67a3ac16910 100644 (file)
@@ -2,6 +2,7 @@
  * This file is part of the sigrok project.
  *
  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,20 +47,20 @@ extern "C" {
  * or reused for different #defines later. You can only add new #defines and
  * return codes, but never remove or redefine existing ones.
  */
-#define SRD_OK                  0 /**< No error */
-#define SRD_ERR                        -1 /**< Generic/unspecified error */
-#define SRD_ERR_MALLOC         -2 /**< Malloc/calloc/realloc error */
-#define SRD_ERR_ARG            -3 /**< Function argument error */
-#define SRD_ERR_PYTHON         -4 /**< Python C API error */
-#define SRD_ERR_DECODERS_DIR   -5 /**< Protocol decoder path invalid */
+#define SRD_OK                 0 /**< No error */
+#define SRD_ERR               -1 /**< Generic/unspecified error */
+#define SRD_ERR_MALLOC        -2 /**< Malloc/calloc/realloc error */
+#define SRD_ERR_ARG               -3 /**< Function argument error */
+#define SRD_ERR_PYTHON        -4 /**< Python C API error */
+#define SRD_ERR_DECODERS_DIR  -5 /**< Protocol decoder path invalid */
 
 /* libsigrokdecode loglevels. */
-#define SRD_LOG_NONE   0 /**< Output no messages at all. */
-#define SRD_LOG_ERR    1 /**< Output error messages. */
-#define SRD_LOG_WARN   2 /**< Output warnings. */
-#define SRD_LOG_INFO   3 /**< Output informational messages. */
-#define SRD_LOG_DBG    4 /**< Output debug messages. */
-#define SRD_LOG_SPEW   5 /**< Output very noisy debug messages. */
+#define SRD_LOG_NONE   0 /**< Output no messages at all. */
+#define SRD_LOG_ERR    1 /**< Output error messages. */
+#define SRD_LOG_WARN   2 /**< Output warnings. */
+#define SRD_LOG_INFO   3 /**< Output informational messages. */
+#define SRD_LOG_DBG    4 /**< Output debug messages. */
+#define SRD_LOG_SPEW   5 /**< Output very noisy debug messages. */
 
 enum {
        SRD_OUTPUT_LOGIC = 1,
@@ -67,6 +68,8 @@ enum {
        SRD_OUTPUT_PROTOCOL,
 };
 
+#define SRD_MAX_NUM_PROBES   64
+
 /* TODO: Documentation. */
 struct srd_decoder {
        /** The decoder ID. Must be non-NULL and unique for all decoders. */
@@ -113,6 +116,9 @@ struct srd_decoder_instance {
        struct srd_decoder *decoder;
        PyObject *py_instance;
        GSList *pd_output;
+       int num_probes;
+       int unitsize;
+       uint64_t samplerate;
 };
 
 struct srd_pd_output {
@@ -122,6 +128,17 @@ struct srd_pd_output {
        char *description;
 };
 
+typedef struct {
+       PyObject_HEAD
+       struct srd_decoder_instance *di;
+       unsigned int itercnt;
+       uint8_t *inbuf;
+       uint64_t inbuflen;
+       PyObject *sample;
+} srd_logic;
+
+
+
 /*--- controller.c ----------------------------------------------------------*/
 
 int srd_init(void);
@@ -130,16 +147,14 @@ int set_modulepath(void);
 struct srd_decoder_instance *srd_instance_new(const char *id);
 int srd_instance_set_probe(struct srd_decoder_instance *di,
                                const char *probename, int num);
-int srd_instance_start(struct srd_decoder_instance *di,
-                       const char *driver, int unitsize, uint64_t starttime);
-int srd_session_start(const char *driver, int unitsize, uint64_t starttime,
-               uint64_t samplerate);
+int srd_session_start(int num_probes, int unitsize, uint64_t samplerate);
 int srd_run_decoder(uint64_t timeoffset, uint64_t duration,
                struct srd_decoder_instance *dec, uint8_t *inbuf, uint64_t inbuflen);
 int srd_session_feed(uint64_t timeoffset, uint64_t duration, uint8_t *inbuf,
                uint64_t inbuflen);
 int pd_output_new(struct srd_decoder_instance *di, int output_type,
                char *output_id, char *description);
+struct srd_decoder_instance *get_di_by_decobject(void *decobject);
 
 /*--- decoder.c -------------------------------------------------------------*/
 
diff --git a/type_logic.c b/type_logic.c
new file mode 100644 (file)
index 0000000..2f79234
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * This file is part of the sigrok project.
+ *
+ * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
+#include "config.h"
+#include <inttypes.h>
+#include <string.h>
+
+
+PyObject *srd_logic_iter(PyObject *self)
+{
+
+       return self;
+}
+
+PyObject *srd_logic_iternext(PyObject *self)
+{
+       PyObject *py_samplenum, *py_samples;
+       srd_logic *logic;
+       uint64_t sample;
+       int i;
+       unsigned char probe_samples[SRD_MAX_NUM_PROBES];
+
+       logic = (srd_logic *) self;
+       if (logic->itercnt >= logic->inbuflen / logic->di->unitsize) {
+               /* End iteration loop. */
+               return NULL;
+       }
+
+       /* TODO: use number of probes defined in the PD, in the order the PD
+        * defined them -- not whatever came in from the driver.
+        */
+       /* Convert the bit-packed sample to an array of bytes, with only 0x01
+        * and 0x00 values, so the PD doesn't need to do any bitshifting.
+        */
+       memcpy(&sample, logic->inbuf + logic->itercnt * logic->di->unitsize,
+                       logic->di->unitsize);
+       for (i = 0; i < logic->di->num_probes; i++) {
+               probe_samples[i] = sample & 0x01;
+               sample >>= 1;
+       }
+
+       /* TODO: samplenum should be in the inbuf feed, instead of time/duration.
+        * fake it for now...
+        */
+       /* Prepare the next samplenum/sample list in this iteration. */
+       py_samplenum = PyLong_FromUnsignedLongLong(logic->itercnt++);
+       PyList_SetItem(logic->sample, 0, py_samplenum);
+       py_samples = PyBytes_FromStringAndSize((const char *)probe_samples,
+                       logic->di->num_probes);
+       PyList_SetItem(logic->sample, 1, py_samples);
+       Py_INCREF(logic->sample);
+
+       return logic->sample;
+}
+
+PyTypeObject srd_logic_type = {
+       PyVarObject_HEAD_INIT(NULL, 0)
+       .tp_name = "srd_logic",
+       .tp_basicsize = sizeof(srd_logic),
+       .tp_flags = Py_TPFLAGS_DEFAULT,
+       .tp_doc = "Sigrokdecode logic sample object",
+       .tp_iter = srd_logic_iter,
+       .tp_iternext = srd_logic_iternext,
+};
+