summaryrefslogtreecommitdiffstats
path: root/oncology/dpfhack_display/python/py_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'oncology/dpfhack_display/python/py_device.c')
-rw-r--r--oncology/dpfhack_display/python/py_device.c492
1 files changed, 492 insertions, 0 deletions
diff --git a/oncology/dpfhack_display/python/py_device.c b/oncology/dpfhack_display/python/py_device.c
new file mode 100644
index 00000000..98b4bc03
--- /dev/null
+++ b/oncology/dpfhack_display/python/py_device.c
@@ -0,0 +1,492 @@
+/* Device wrapper for python
+ *
+ * (c) 2003-2010 Martin Strubel <hackfin@section5.ch>
+ *
+ * This file is part of the netpp library
+ *
+ * Additions by BöserFisch for hacked DPF access
+ *
+ */
+
+#include "Python.h"
+#include "dpf.h"
+
+#ifdef DEBUG
+# include <stdio.h>
+#endif
+
+#define CONCAT(x, y) x##y
+#define INITMODULE(x) CONCAT(init, x)
+#define RESOLVE(x) #x
+#define STRINGIFY(x) RESOLVE(x)
+
+////////////////////////////////////////////////////////////////////////////
+// AUX
+
+#define HANDLE_ERROR(err, msg) handleError(err, __LINE__)
+
+PyObject *
+handleError(int err, int line)
+{
+ char s[256];
+ PyObject *exctype = PyExc_SystemError;
+
+ // catch some special errors
+ switch (err) {
+ case DEVERR_OPEN:
+ exctype = PyExc_TypeError;
+ sprintf(s, "%d:%s", line, dev_errstr(err));
+ break;
+ default:
+ sprintf(s, "%d:(%x): %s", line, err, dev_errstr(err));
+ }
+ PyErr_SetString(exctype, s);
+ return NULL;
+}
+
+staticforward PyTypeObject DeviceType;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Device object
+//
+////////////////////////////////////////////////////////////////////////////
+
+#define FLAGS_VALID 0x0001
+
+typedef struct {
+ PyObject_HEAD
+ DPFHANDLE dpf;
+ uint16_t flags;
+} DeviceObject;
+
+staticforward PyTypeObject DeviceType;
+
+#define DeviceObject_Check(v) ((v)->ob_type == &DeviceType)
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Device object method functions
+//
+////////////////////////////////////////////////////////////////////////////
+
+
+static PyObject *
+Device_close(DeviceObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ dpf_close(self->dpf);
+ self->dpf = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject *
+Device_probeflash(DeviceObject *self, PyObject *args)
+{
+ int error;
+ unsigned char id[3];
+
+ error = flash_probe(self->dpf, id);
+ if (error < 0) return HANDLE_ERROR(error, "probeflash");
+
+ return Py_BuildValue("(iii)", id[0], id[1], id[2]);
+}
+
+PyObject *
+Device_readflash(DeviceObject *self, PyObject *args)
+{
+ int error;
+ unsigned int count;
+ ADDR addr;
+ Py_ssize_t sz;
+ PyObject *p;
+ unsigned char *buf;
+
+ if (!PyArg_ParseTuple(args, "II", &addr, &count))
+ return NULL;
+
+ p = PyBuffer_New(count);
+
+ error = PyObject_AsWriteBuffer(p, (void**) &buf, &sz);
+ while (error >= 0 && count > MAX_CHUNKSIZE) {
+ error = flash_read(self->dpf, buf, addr, 0x10000);
+ addr += MAX_CHUNKSIZE;
+ count -= MAX_CHUNKSIZE;
+ buf += MAX_CHUNKSIZE;
+ }
+ if (error >= 0) {
+ error = flash_read(self->dpf, buf, addr, count);
+ }
+ if (error < 0) {
+ Py_DECREF(p);
+ return HANDLE_ERROR(error, "readflash");
+ }
+ return p;
+}
+
+PyObject *
+Device_eraseflash(DeviceObject *self, PyObject *args)
+{
+ int error;
+ ADDR addr;
+
+ if (!PyArg_ParseTuple(args, "I", &addr))
+ return NULL;
+
+ error = flash_erase(self->dpf, addr);
+ if (error < 0) return HANDLE_ERROR(error, "eraseflash");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+PyObject *
+Device_writeflash(DeviceObject *self, PyObject *args)
+{
+ int error;
+ PyObject *p;
+ ADDR addr;
+ const void *buf;
+ ssize_t len;
+
+ if (!PyArg_ParseTuple(args, "IO", &addr, &p))
+ return NULL;
+
+ error = PyObject_AsReadBuffer(p, &buf, &len);
+ if (error < 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "Could not get pointer to buffer object");
+ return NULL;
+ }
+
+ error = flash_write(self->dpf, (const unsigned char *) buf, addr, len);
+ if (error < 0) return HANDLE_ERROR(error, "writeflash");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+PyObject *
+Device_patchsector(DeviceObject *self, PyObject *args)
+{
+ int error;
+ ADDR reloc;
+ const char *hexfile;
+ ADDR addr;
+
+ if (!PyArg_ParseTuple(args, "IIs", &reloc, &addr, &hexfile))
+ return NULL;
+
+ if (addr < 0x10000) {
+ PyErr_SetString(PyExc_ValueError,
+ "Not allowed to write to first sector. It will brick your device.");
+ return NULL;
+ }
+
+ error = patch_sector(self->dpf, reloc, addr, hexfile);
+ if (error < 0) return HANDLE_ERROR(error, "patchsector");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject *
+Device_setProperty(DeviceObject *self, PyObject *args)
+{
+ int error;
+ PyObject *p;
+ int prop;
+ DPFValue v;
+
+ if (!PyArg_ParseTuple(args, "iO", &prop, &p))
+ return NULL;
+
+ if (PyInt_Check(p)) {
+ v.type = TYPE_INTEGER;
+ v.value.integer = PyInt_AsLong(p);
+ }
+
+ error = dpf_setproperty(self->dpf, prop, &v);
+ if (error < 0) return HANDLE_ERROR(error, "set_property");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject *
+Device_writelcd(DeviceObject *self, PyObject *args)
+{
+ int error;
+ PyObject *p;
+ const void *buf;
+ ssize_t len;
+
+ if (!PyArg_ParseTuple(args, "O", &p))
+ return NULL;
+
+ error = PyObject_AsReadBuffer(p, &buf, &len);
+ if (error < 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "Could not get pointer to buffer object");
+ return NULL;
+ }
+
+ error = write_screen(self->dpf, buf, len);
+ if (error < 0) return HANDLE_ERROR(error, "writescreen");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject *
+Device_readmem(DeviceObject *self, PyObject *args)
+{
+ int error;
+ int count;
+ ADDR addr;
+ Py_ssize_t sz;
+ PyObject *p;
+ unsigned char *buf;
+
+ if (!PyArg_ParseTuple(args, "Ii", &addr, &count))
+ return NULL;
+
+ p = PyBuffer_New(count);
+
+ error = PyObject_AsWriteBuffer(p, (void**) &buf, &sz);
+ if (error >= 0) {
+ error = read_mem(self->dpf, buf, addr, count);
+ }
+ if (error < 0) {
+ Py_DECREF(p);
+ return HANDLE_ERROR(error, "readmem");
+ }
+ return p;
+}
+
+PyObject *
+Device_writemem(DeviceObject *self, PyObject *args)
+{
+ int error;
+ char *name;
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ error = write_mem(self->dpf, name);
+ if (error < 0) return HANDLE_ERROR(error, "hexfile");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject *
+Device_exec(DeviceObject *self, PyObject *args)
+{
+ int error;
+ ADDR addr;
+
+ if (!PyArg_ParseTuple(args, "I", &addr))
+ return NULL;
+
+ error = code_go(self->dpf, addr);
+ if (error < 0) return HANDLE_ERROR(error, "exec");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+PyObject *
+Device_runapp(DeviceObject *self, PyObject *args)
+{
+ int error;
+ const void *buf;
+ ADDR addr;
+ ADDR start;
+ PyObject *p;
+ ssize_t len;
+
+ if (!PyArg_ParseTuple(args, "IOI", &addr, &p, &start))
+ return NULL;
+
+ error = PyObject_AsReadBuffer(p, &buf, &len);
+ if (error < 0) return HANDLE_ERROR(error, "read buffer");
+
+ error = dpf_bootstrap(self->dpf, addr, (unsigned char *) buf, len, start);
+ if (error < 0) return HANDLE_ERROR(error, "runapp");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+static PyMethodDef Device_methods[] =
+{
+ // BASIC ACCESS
+ {"close", (PyCFunction) Device_close, METH_VARARGS},
+ {"probeFlash", (PyCFunction) Device_probeflash, METH_VARARGS},
+ {"readFlash", (PyCFunction) Device_readflash, METH_VARARGS},
+ {"eraseFlash", (PyCFunction) Device_eraseflash, METH_VARARGS},
+ {"writeFlash", (PyCFunction) Device_writeflash, METH_VARARGS},
+ {"patchSector", (PyCFunction) Device_patchsector, METH_VARARGS},
+ {"setProperty", (PyCFunction) Device_setProperty, METH_VARARGS},
+ {"writeLCD", (PyCFunction) Device_writelcd, METH_VARARGS},
+ {"readMemory", (PyCFunction) Device_readmem, METH_VARARGS},
+ {"writeMemory", (PyCFunction) Device_writemem, METH_VARARGS},
+ {"run", (PyCFunction) Device_exec, METH_VARARGS},
+ {"runApp", (PyCFunction) Device_runapp, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+////////////////////////////////////////////////////////////////////////////
+// Device type object standard methods
+//
+
+
+static void
+Device_dealloc(DeviceObject *self)
+{
+ if (self->dpf)
+ dpf_close(self->dpf);
+ PyObject_Del(self);
+}
+
+
+static PyObject *
+Device_getattr(DeviceObject *self, char *name)
+{
+ return Py_FindMethod(Device_methods, (PyObject *)self, name);
+}
+
+// finally, the object type definition
+
+statichere PyTypeObject DeviceType = {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "device.Device", /*tp_name*/
+ sizeof(DeviceObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) Device_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc) Device_getattr, /*tp_getattr*/
+ (setattrfunc) 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+
+
+//
+// Create new device Python object and return it
+//
+static DeviceObject *
+newDeviceObject(DPFHANDLE h)
+{
+ DeviceObject *self;
+ self = PyObject_New(DeviceObject, &DeviceType);
+ if (self == NULL)
+ return NULL;
+ self->dpf = h; // device port handle
+ self->flags = 0;
+ return self;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Device module definitions
+//
+////////////////////////////////////////////////////////////////////////////
+
+static PyObject *
+device_open(PyObject *self, PyObject *args)
+{
+ char *portname;
+ DPFHANDLE h;
+ int error;
+ int raw = 0;
+ char errstring[256];
+
+ DeviceObject *d;
+
+ if (!PyArg_ParseTuple(args, "s|i", &portname, &raw)) {
+ return 0;
+ }
+
+ error = dpf_open(portname, &h);
+
+ if (error == 0 || (raw && error > 0)) {
+ d = newDeviceObject(h);
+ // if no error or warning, device is valid
+ if (error == 0) d->flags |= FLAGS_VALID;
+ return (PyObject *) d;
+ } else {
+ // Warnings don't automatically close the device, so
+ // we do it
+ if (error > 0) {
+ dpf_close(h);
+ }
+ sprintf(errstring, "Failed to open port:\n%s\n",
+ dev_errstr(error));
+ PyErr_SetString(PyExc_SystemError, errstring);
+ return 0;
+ }
+}
+
+static PyMethodDef device_methods[] = {
+ {"open", device_open, METH_VARARGS },
+ {NULL, NULL}
+};
+
+
+#ifdef __WIN32__
+ __declspec(dllexport)
+#endif
+
+void
+INITMODULE(MODULENAME)(void)
+{
+ // XXX
+ // this only for windows portability
+ // might be removed when using g++ or any other C++ compiler
+ DeviceType.ob_type = &PyType_Type;
+ //
+ Py_InitModule("dpf", device_methods);
+
+}