summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBert Vermeulen <bert@biot.com>2011-12-07 09:56:49 +0100
committerUwe Hermann <uwe@hermann-uwe.de>2011-12-28 12:17:13 +0100
commite508088229e96423854ba6db63084c9bb18eeb34 (patch)
treeecfa9ca795845c944f390b04fad135ee439c574d
parenta62186e44c606a8d4cb45b3d8c3cc9fa6a5038ea (diff)
downloadlibsigrokdecode-e508088229e96423854ba6db63084c9bb18eeb34.tar.gz
libsigrokdecode-e508088229e96423854ba6db63084c9bb18eeb34.zip
new dynamic output stream registration code, not finished.
-rw-r--r--controller.c125
-rw-r--r--decoder.c8
-rw-r--r--decoders/i2c.py101
-rw-r--r--decoders/spi.py4
-rw-r--r--sigrokdecode.h15
5 files changed, 182 insertions, 71 deletions
diff --git a/controller.c b/controller.c
index 882cafb..efeef28 100644
--- a/controller.c
+++ b/controller.c
@@ -31,11 +31,13 @@
#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)
-//{
-//
-//
-//}
diff --git a/decoder.c b/decoder.c
index e69eae8..5d719d3 100644
--- 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);
diff --git a/decoders/i2c.py b/decoders/i2c.py
index 659ea55..9ff89c9 100644
--- a/decoders/i2c.py
+++ b/decoders/i2c.py
@@ -128,6 +128,17 @@
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)
diff --git a/decoders/spi.py b/decoders/spi.py
index a363b5a..ba62673 100644
--- a/decoders/spi.py
+++ b/decoders/spi.py
@@ -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
diff --git a/sigrokdecode.h b/sigrokdecode.h
index 4d7567f..053a7a1 100644
--- a/sigrokdecode.h
+++ b/sigrokdecode.h
@@ -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 -------------------------------------------------------------*/