]> sigrok.org Git - libsigrokdecode.git/commitdiff
new dynamic output stream registration code, not finished.
authorBert Vermeulen <redacted>
Wed, 7 Dec 2011 08:56:49 +0000 (09:56 +0100)
committerUwe Hermann <redacted>
Wed, 28 Dec 2011 11:17:13 +0000 (12:17 +0100)
controller.c
decoder.c
decoders/i2c.py
decoders/spi.py
sigrokdecode.h

index 882cafbe272f25e0bee3fce5d2eb6693407b3a8c..efeef2808e70c56fe074f9309a8f389acf160d20 100644 (file)
 #endif
 
 
+/* TODO
 static GSList *pipelines = NULL;
+*/
 
 /* lives in decoder.c */
-extern GSList *list_pds;
-extern GSList *decoders;
+extern GSList *pd_list;
+extern GSList *di_list;
 
 struct srd_pipeline {
        int id;
@@ -53,33 +55,77 @@ static PyObject *Decoder_init(PyObject *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
+struct srd_decoder_instance *get_di_by_decobject(void *decobject);
 
 static PyObject *Decoder_put(PyObject *self, PyObject *args)
 {
-       PyObject *arg;
+       GSList *l;
+       PyObject *data;
+       struct srd_decoder_instance *di;
+       struct srd_pd_output *pdo;
+       int output_id;
+
+       if (!(di = get_di_by_decobject(self)))
+               return NULL;
 
-//     printf("put object %x\n", self);
+       printf("put: %s instance %x: ", di->decoder->name, (unsigned int) di);
+
+       if (!PyArg_ParseTuple(args, "iO", &output_id, &data))
+               return NULL;
 
-       if (!PyArg_ParseTuple(args, "O:put", &arg))
+       if (!(l = g_slist_nth(di->pd_output, output_id)))
+               /* PD supplied invalid output id */
+               /* TODO: better error message */
                return NULL;
+       pdo = l->data;
 
-       // fprintf(stdout, "sigrok.put() called by decoder:\n");
-       PyObject_Print(arg, stdout, Py_PRINT_RAW);
+       printf("output type %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}
 };
 
 
-// class Decoder(sigrok.Decoder):
 typedef struct {
        PyObject_HEAD
 } sigrok_Decoder_object;
@@ -97,6 +143,7 @@ PyMODINIT_FUNC init_sigrok_Decoder(void)
 {
        PyObject *mod;
 
+       /* assign this here, for compiler portability */
        sigrok_Decoder_type.tp_new = PyType_GenericNew;
        if (PyType_Ready(&sigrok_Decoder_type) < 0)
                return;
@@ -108,6 +155,20 @@ PyMODINIT_FUNC init_sigrok_Decoder(void)
 }
 
 
+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.
  *
@@ -171,7 +232,7 @@ int srd_exit(void)
        /* Unload/free all decoders, and then the list of decoders itself. */
        /* TODO: Error handling. */
        srd_unload_all_decoders();
-       g_slist_free(list_pds);
+       g_slist_free(pd_list);
 
        /* Py_Finalize() returns void, any finalization errors are ignored. */
        Py_Finalize();
@@ -227,7 +288,7 @@ struct srd_decoder_instance *srd_instance_new(const char *id)
                Py_XDECREF(py_args);
                return NULL; /* TODO: More specific error? */
        }
-       decoders = g_slist_append(decoders, di);
+       di_list = g_slist_append(di_list, di);
 
        Py_XDECREF(py_args);
 
@@ -267,7 +328,7 @@ int srd_session_start(const char *driver, int unitsize, uint64_t starttime,
 
        fprintf(stdout, "%s: %s\n", __func__, driver);
 
-       for (d = decoders; d; d = d->next) {
+       for (d = di_list; d; d = d->next) {
                di = d->data;
                if (!(py_res = PyObject_CallMethod(di->py_instance, "start",
                                        "{s:s,s:l,s:l,s:l}",
@@ -293,8 +354,6 @@ int srd_session_start(const char *driver, int unitsize, uint64_t starttime,
  * @param dec TODO
  * @param inbuf TODO
  * @param inbuflen TODO
- * @param outbuf TODO
- * @param outbuflen TODO
  *
  * @return SRD_OK upon success, a (negative) error code otherwise.
  */
@@ -345,7 +404,7 @@ int srd_session_feed(uint8_t *inbuf, uint64_t inbuflen)
 
 //     fprintf(stdout, "%s: %d bytes\n", __func__, inbuflen);
 
-       for (d = decoders; d; d = d->next) {
+       for (d = di_list; d; d = d->next) {
                if ((ret = srd_run_decoder(d->data, inbuf, inbuflen)) != SRD_OK)
                        return ret;
        }
@@ -354,18 +413,42 @@ int srd_session_feed(uint8_t *inbuf, uint64_t inbuflen)
 }
 
 
+int pd_output_new(struct srd_decoder_instance *di, int output_type,
+               char *protocol_id, char *description)
+{
+       GSList *l;
+       struct srd_pd_output *pdo;
+       int pdo_id;
+
+       fprintf(stdout, "%s: output type %d, protocol_id %s, description %s\n",
+                       __func__, output_type, protocol_id, description);
+
+       pdo_id = -1;
+       for (l = di->pd_output; l; l = l->next) {
+               pdo = l->data;
+               if (pdo->pdo_id > pdo_id)
+                       pdo_id = pdo->pdo_id;
+       }
+       pdo_id++;
+
+       if (!(pdo = g_try_malloc(sizeof(struct srd_pd_output))))
+               return -1;
+
+       pdo->pdo_id = pdo_id;
+       pdo->output_type = output_type;
+       pdo->protocol_id = g_strdup(protocol_id);
+       pdo->description = g_strdup(description);
+       di->pd_output = g_slist_append(di->pd_output, pdo);
+
+       return pdo_id;
+}
+
+
 //int srd_pipeline_new(int plid)
 //{
 //
 //
 //}
-//
-//
-//int pd_output_new(int output_type, char *output_id, char *description)
-//{
-//
-//
-//}
 
 
 
index e69eae8da694ff77ef2e2dec7fecbdd70866c818..5d719d3d75ffc7f8690422d44751aa09a3b09441 100644 (file)
--- a/decoder.c
+++ b/decoder.c
@@ -23,8 +23,8 @@
 #include <dirent.h>
 
 /* The list of protocol decoders. */
-GSList *list_pds = NULL;
-GSList *decoders = NULL;
+GSList *pd_list = NULL;
+GSList *di_list = NULL;
 
 
 /**
@@ -37,7 +37,7 @@ GSList *decoders = NULL;
 GSList *srd_list_decoders(void)
 {
 
-       return list_pds;
+       return pd_list;
 }
 
 
@@ -194,7 +194,7 @@ int srd_load_all_decoders(void)
                /* TODO: Warning if loading fails for a decoder. */
                if ((ret = srd_load_decoder(decodername, &dec)) == SRD_OK) {
                        /* Append it to the list of supported/loaded decoders. */
-                       list_pds = g_slist_append(list_pds, dec);
+                       pd_list = g_slist_append(pd_list, dec);
                }
        }
        closedir(dir);
index 659ea553b6c77949684c849ab1337749d303e45c..9ff89c9755993c797fc54ee9e34f475c92a525e0 100644 (file)
 
 import sigrok
 
+# symbols for i2c decoders up the stack
+START           = 1
+START_REPEAT    = 2
+STOP            = 3
+ACK             = 4
+NACK            = 5
+ADDRESS_READ    = 6
+ADDRESS_WRITE   = 7
+DATA_READ       = 8
+DATA_WRITE      = 9
+
 # States
 FIND_START = 0
 FIND_ADDRESS = 1
@@ -165,6 +176,8 @@ class Decoder(sigrok.Decoder):
 
     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
@@ -187,6 +200,8 @@ class Decoder(sigrok.Decoder):
 
     def start(self, metadata):
         self.unitsize = metadata["unitsize"]
+        self.output_protocol = self.output_new(2)
+        self.output_annotation = self.output_new(1)
 
     def report(self):
         pass
@@ -209,21 +224,23 @@ class Decoder(sigrok.Decoder):
             return True
         return False
 
-    def find_start(self, scl, sda):
-        out = []
-        # o = {'type': 'S', 'range': (self.samplenum, self.samplenum),
-        #      'data': None, 'ann': None},
-        o = (self.is_repeat_start == 1) and 'Sr' or 'S'
-        out.append(o)
+    def found_start(self, scl, sda):
+        if self.is_repeat_start == 1:
+            out_proto = [ START_REPEAT ]
+            out_ann = [ "START REPEAT" ]
+        else:
+            out_proto = [ START ]
+            out_ann = [ "START" ]
+        self.put(self.output_protocol, out_proto)
+        self.put(self.output_annotation, out_ann)
+
         self.state = FIND_ADDRESS
         self.bitcount = self.databyte = 0
         self.is_repeat_start = 1
         self.wr = -1
-        return out
 
-    def find_address_or_data(self, scl, sda):
+    def found_address_or_data(self, scl, sda):
         """Gather 8 bits of data plus the ACK/NACK bit."""
-        out = o = []
 
         if self.startsample == -1:
             self.startsample = self.samplenum
@@ -240,8 +257,6 @@ class Decoder(sigrok.Decoder):
         # We received 8 address/data bits and the ACK/NACK bit.
         self.databyte >>= 1 # Shift out unwanted ACK/NACK bit here.
 
-        ack = 'N' if (sda == 1) else 'A'
-
         if self.state == FIND_ADDRESS:
             d = self.databyte & 0xfe
             # The READ/WRITE bit is only in address bytes, not data bytes.
@@ -252,28 +267,34 @@ class Decoder(sigrok.Decoder):
             # TODO: Error?
             pass
 
-        # o = {'type': self.state,
-        #      'range': (self.startsample, self.samplenum - 1),
-        #      'data': d, 'ann': None}
-
-        o = {'data': '0x%02x' % d}
-
+        out_proto = []
+        out_ann = []
         # TODO: Simplify.
         if self.state == FIND_ADDRESS and self.wr == 1:
-            o['type'] = 'AW'
+            cmd = ADDRESS_WRITE
+            ann = 'ADDRESS WRITE'
         elif self.state == FIND_ADDRESS and self.wr == 0:
-            o['type'] = 'AR'
+            cmd = ADDRESS_READ
+            ann = 'ADDRESS READ'
         elif self.state == FIND_DATA and self.wr == 1:
-            o['type'] = 'DW'
+            cmd = DATA_WRITE
+            ann = 'DATA WRITE'
         elif self.state == FIND_DATA and self.wr == 0:
-            o['type'] = 'DR'
+            cmd = DATA_READ
+            ann = 'DATA READ'
+        out_proto.append( [cmd, d] )
+        out_ann.append( ["%s" % ann, "0x%02x" % d] )
+
+        if sda == 1:
+            out_proto.append( [NACK] )
+            out_ann.append( ["NACK"] )
+        else:
+            out_proto.append( [ACK] )
+            out_ann.append( ["ACK"] )
 
-        out.append(o)
+        self.put(self.output_protocol, out_proto)
+        self.put(self.output_annotation, out_ann)
 
-        # o = {'type': ack, 'range': (self.samplenum, self.samplenum),
-        #      'data': None, 'ann': None}
-        o = ack
-        out.append(o)
         self.bitcount = self.databyte = 0
         self.startsample = -1
 
@@ -284,27 +305,17 @@ class Decoder(sigrok.Decoder):
             # So, either find a STOP condition or another data byte next.
             pass
 
-        return out
-
-    def find_stop(self, scl, sda):
-        out = o = []
+    def found_stop(self, scl, sda):
+        self.put(self.output_protocol, [ STOP ])
+        self.put(self.output_annotation, [ "STOP" ])
 
-        # o = {'type': 'P', 'range': (self.samplenum, self.samplenum),
-        #      'data': None, 'ann': None},
-        o = 'P'
-        out.append(o)
         self.state = FIND_START
         self.is_repeat_start = 0
         self.wr = -1
 
-        return out
-
     def decode(self, data):
         """I2C protocol decoder"""
 
-        out = []
-        o = ack = d = ''
-
         # We should accept a list of samples and iterate...
         for sample in sampleiter(data['data'], self.unitsize):
 
@@ -330,17 +341,17 @@ class Decoder(sigrok.Decoder):
             # State machine.
             if self.state == FIND_START:
                 if self.is_start_condition(scl, sda):
-                    out += self.find_start(scl, sda)
+                    self.found_start(scl, sda)
             elif self.state == FIND_ADDRESS:
                 if self.is_data_bit(scl, sda):
-                    out += self.find_address_or_data(scl, sda)
+                    self.found_address_or_data(scl, sda)
             elif self.state == FIND_DATA:
                 if self.is_data_bit(scl, sda):
-                    out += self.find_address_or_data(scl, sda)
+                    self.found_address_or_data(scl, sda)
                 elif self.is_start_condition(scl, sda):
-                    out += self.find_start(scl, sda)
+                    self.found_start(scl, sda)
                 elif self.is_stop_condition(scl, sda):
-                    out += self.find_stop(scl, sda)
+                    self.found_stop(scl, sda)
             else:
                 # TODO: Error?
                 pass
@@ -349,6 +360,4 @@ class Decoder(sigrok.Decoder):
             self.oldscl = scl
             self.oldsda = sda
 
-        if out != []:
-            self.put(out)
 
index a363b5afba3c0f53838229435876d83c0450d2e2..ba626734c68d616263d9654d088351be28fc90e1 100644 (file)
@@ -52,9 +52,13 @@ class Decoder(sigrok.Decoder):
         self.rxcount = 0
         self.rxdata = 0
         self.bytesreceived = 0
+        self.output_protocol = None
+        self.output_annotation = None
 
     def start(self, metadata):
         self.unitsize = metadata['unitsize']
+        self.output_protocol = self.output_new(2)
+        self.output_annotation = self.output_new(1)
 
     def report(self):
         return 'SPI: %d bytes received' % self.bytesreceived
index 4d7567f9ff0b2ca625cd54056da421b713da3993..053a7a1ae5362f0c259d59b081a66824c9f33239 100644 (file)
@@ -61,6 +61,12 @@ extern "C" {
 #define SRD_LOG_DBG    4 /**< Output debug messages. */
 #define SRD_LOG_SPEW   5 /**< Output very noisy debug messages. */
 
+enum {
+       SRD_OUTPUT_LOGIC = 1,
+       SRD_OUTPUT_ANNOTATION,
+       SRD_OUTPUT_PROTOCOL,
+};
+
 /* TODO: Documentation. */
 struct srd_decoder {
        /** The decoder ID. Must be non-NULL and unique for all decoders. */
@@ -109,6 +115,13 @@ struct srd_decoder_instance {
        GSList *pd_output;
 };
 
+struct srd_pd_output {
+       int pdo_id;
+       int output_type;
+       char *protocol_id;
+       char *description;
+};
+
 /*--- controller.c ----------------------------------------------------------*/
 
 int srd_init(void);
@@ -122,6 +135,8 @@ int srd_instance_start(struct srd_decoder_instance *di,
 int srd_session_start(const char *driver, int unitsize, uint64_t starttime,
                uint64_t samplerate);
 int srd_session_feed(uint8_t *inbuf, uint64_t inbuflen);
+int pd_output_new(struct srd_decoder_instance *di, int output_type,
+               char *output_id, char *description);
 
 /*--- decoder.c -------------------------------------------------------------*/