--- /dev/null
+/* Copyright (c) 2006-2007 by Sporian Microsystems, Inc.
+ * All Rights Reserved.
+ *
+ * This document is the proprietary and confidential property of Sporian
+ * Microsystems, Inc. All use, distribution, reproduction or re-distribution
+ * is disallowed without the prior express written consent of Sporian
+ * Microsystems, Inc.
+ */
+
+#include <Python.h>
+#include <windows.h>
+#include <io.h>
+#include <dlfcn.h>
+#include "CP210xRuntimeDLL.h"
+
+typedef CP210xRUNTIMEDLL_API CP210x_STATUS WINAPI (*fn_t)(HANDLE, BYTE, BYTE);
+
+void* dll;
+fn_t writeLatch;
+PyObject* exception;
+
+
+static PyObject* cp210xrt_writeLatch(PyObject* self, PyObject* args)
+{
+ int fd;
+ BYTE bMask;
+ BYTE bData;
+ HANDLE hDevice;
+ CP210x_STATUS ret;
+
+ if (!PyArg_ParseTuple(args, "iBB", &fd, &bMask, &bData))
+ return NULL;
+ if (!writeLatch) {
+ PyErr_SetString(exception, "No access to CP210xRuntime.dll");
+ return NULL;
+ }
+
+ hDevice = (HANDLE)get_osfhandle(fd);
+ if (hDevice == INVALID_HANDLE_VALUE)
+ {
+ PyErr_SetString(exception, "No access to device");
+ return NULL;
+ }
+
+ /* If we don't call writeLatch, then we don't core dump when we return to
+ * the python caller. If we do call writeLatch, the latches are set, but
+ * when we return return into python, perhaps the stack has been corrupted
+ * somehow. We get a stackdump from cygwin.
+ *
+ * Note: when we opened the handle here, via CreateFile(), then closed it
+ * before returning, we had no problems.
+ */
+ ret = writeLatch(hDevice, bMask, bData);
+ if (ret != CP210x_SUCCESS) {
+ PyErr_SetString(exception, "IO Error with device");
+ return NULL;
+ }
+
+#if 1
+ Py_INCREF(Py_None);
+ return Py_None;
+#else
+ return Py_BuildValue("i", ret);
+#endif
+}
+
+
+static PyMethodDef cp210xrtMethods[] = {
+ { "writeLatch", cp210xrt_writeLatch, METH_VARARGS, "Set GPIO bits" },
+ { NULL, NULL, 0, NULL }
+};
+
+
+PyMODINIT_FUNC initcp210xrt(void)
+{
+ PyObject* m = Py_InitModule("cp210xrt", cp210xrtMethods);
+ exception = PyErr_NewException("cp210xrt.error", NULL, NULL);
+ Py_INCREF(exception);
+ PyModule_AddObject(m, "error", exception);
+
+ if (!dll) {
+ dll = dlopen("CP210xRuntime.dll", RTLD_NOW);
+ if (dll) {
+ dlerror();
+ writeLatch = (fn_t)dlsym(dll, "CP210xRT_WriteLatch");
+ if (dlerror())
+ writeLatch = NULL;
+ }
+ }
+}
+