spi: Make Spi write() work from SWIG with typemaps
authorBrendan Le Foll <brendan.le.foll@intel.com>
Wed, 14 Jan 2015 11:41:43 +0000 (11:41 +0000)
committerBrendan Le Foll <brendan.le.foll@intel.com>
Wed, 14 Jan 2015 11:52:12 +0000 (11:52 +0000)
This change also changes the C++ API write(char) call to writeByte(uint8_t) and
the write() call now takes a uint8_t* instead of a char*. This should not alter
any code significantly and does not affect the C API.

Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
api/mraa/spi.hpp
examples/c++/Spi-pot.cpp
examples/javascript/spi.js [new file with mode: 0644]
examples/python/spi.py [new file with mode: 0644]
src/javascript/mraajs.i
src/python/python-mraa.i

index f77480c..b2e028a 100644 (file)
@@ -91,20 +91,20 @@ class Spi {
          * @param data the byte to send
          * @return data received on the miso line
          */
-        char write(char data) {
-            return (char) mraa_spi_write(m_spi, (uint8_t) data);
+        uint8_t writeByte(uint8_t data) {
+            return mraa_spi_write(m_spi, (uint8_t) data);
         }
         /**
          * Write buffer of bytes to SPI device The pointer return has to be
         * free'd by the caller. It will return a NULL pointer in cases of
         * error
          *
-         * @param data buffer to send
+         * @param txBuf buffer to send
          * @param length size of buffer to send
-         * @return char* data received on the miso line. Same length as passed in
+         * @return uint8_t* data received on the miso line. Same length as passed in
          */
-        char* write(char* data, size_t length) {
-            return (char*) mraa_spi_write_buf(m_spi, (uint8_t *) data, (int) length);
+        uint8_t* write(uint8_t* txBuf, int length) {
+            return mraa_spi_write_buf(m_spi, txBuf, length);
         }
 #ifndef SWIG
         /**
@@ -116,8 +116,8 @@ class Spi {
          * @param length size of buffer to send
          * @return Result of operation
          */
-        mraa_result_t transfer(char* data, char* rxBuf, size_t length) {
-            return mraa_spi_transfer_buf(m_spi, (uint8_t *) data, (uint8_t *)rxBuf, (int) length);
+        mraa_result_t transfer(uint8_t* txBuf, uint8_t* rxBuf, int length) {
+            return mraa_spi_transfer_buf(m_spi, txBuf, rxBuf, length);
         }
 #endif
         /**
index b622996..b1bff43 100644 (file)
@@ -48,9 +48,9 @@ int main ()
 
     spi = new mraa::Spi(0);
 
-    char data[] = {0x00, 100};
-    char rxBuf[2];
-    char *recv;
+    uint8_t data[] = {0x00, 100};
+    uint8_t rxBuf[2];
+    uint8_t *recv;
     while (running == 0) {
         int i;
         for (i = 90; i < 130; i++) {
diff --git a/examples/javascript/spi.js b/examples/javascript/spi.js
new file mode 100644 (file)
index 0000000..5c85136
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/env node
+
+/*
+ * Author: Brendan Le Foll <brendan.le.foll@intel.com>
+ * Copyright (c) 2015 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+var m = require('mraa'); //require mraa
+
+// helper function to go from hex val to dec
+function char(x) { return parseInt(x, 16); }
+
+x = new m.Spi(0)
+buf = new Buffer(4)
+buf[0] = char('0xf4')
+buf[1] = char('0x2e')
+buf[2] = char('0x3e')
+buf[3] = char('0x4e')
+buf2 = x.write(buf)
+console.log("Sent: " + buf.toString('hex') + ". Received: " + buf2.toString('hex'))
+
+
diff --git a/examples/python/spi.py b/examples/python/spi.py
new file mode 100644 (file)
index 0000000..f8ee7ff
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+# Author: Brendan Le Foll <brendan.le.foll@intel.com>
+# Copyright (c) 2015 Intel Corporation.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+
+import mraa as m
+import random as rand
+
+# Excuse the super boring example, I was out of fun devices to play with, this
+# will write and read the same data back to itself, a few 100 times, just short
+# MISO & MOSI on your board
+
+dev = m.Spi(0)
+
+for x in range(0,100):
+  txbuf = bytearray(4)
+  for y in range(0,4):
+    txbuf[y] = rand.randrange(0, 256)
+  rxbuf = dev.write(txbuf)
+  if rxbuf != txbuf:
+    print("We have an error captain!")
+    break
+    exit(1)
+
index 85a8d60..3e04eb7 100644 (file)
   $2 = node::Buffer::Length($input);
 }
 
+// Spi write()
+%typemap(in) (uint8_t *txBuf, int length) {
+  $1 = (uint8_t*) node::Buffer::Data($input);
+  $2 = node::Buffer::Length($input);
+}
+
+namespace mraa {
+class Spi;
+%typemap(out) uint8_t*
+{
+  // need to loop over length
+  $result = node::Buffer::New((char*) $1, arg3)->handle_;
+}
+}
+
 %newobject I2c::read(uint8_t *data, int length);
+%newobject Spi::write(uint8_t *data, int length);
 
 %typemap(in) (uint8_t *data, int length) {
    int x;
index 682d156..56ee3eb 100644 (file)
   }
 }
 
+// Spi write()
+%typemap(in) (uint8_t *txBuf, int length) {
+  if (PyByteArray_Check($input)) {
+    // whilst this may seem 'hopeful' it turns out this is safe
+    $1 = (uint8_t*) PyByteArray_AsString($input);
+    $2 = PyByteArray_Size($input);
+  }
+}
+
+namespace mraa {
+class I2c;
 %typemap(out) uint8_t*
 {
   // need to loop over length
   $result = PyByteArray_FromStringAndSize((char*) $1, arg2);
 }
 
+class Spi;
+%typemap(out) uint8_t*
+{
+  // need to loop over length
+  $result = PyByteArray_FromStringAndSize((char*) $1, arg3);
+}
+}
+
 %newobject I2c::read(uint8_t *data, int length);
+%newobject Spi::write(uint8_t *data, int length);
+%newobject Spi::transfer(uint8_t *txBuf, uint8_t *rxBuf, int length);
+
+// I2c::read()
 
 %typemap(in) (uint8_t *data, int length) {
    if (!PyInt_Check($input)) {
    free($1);
 }
 
+// Spi::transfer()
+
+%typemap(in) (uint8_t* txBuf, uint8_t* rxBuf, int length) {
+   if (!PyInt_Check($input)) {
+       PyErr_SetString(PyExc_ValueError, "Expecting an integer");
+       return NULL;
+   }
+   $3 = PyInt_AsLong($input);
+   if ($3 < 0) {
+       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
+       return NULL;
+   }
+   $2 = (uint8_t*) malloc($3 * sizeof(uint8_t));
+}
+
+%typemap(argout) (uint8_t* txBuf, uint8_t* rxBuf, int length) {
+   Py_XDECREF($result);   /* Blow away any previous result */
+   if (result != MRAA_SUCCESS) {      /* Check for I/O error */
+       free($2);
+       PyErr_SetFromErrno(PyExc_IOError);
+       return NULL;
+   }
+   $result = PyByteArray_FromStringAndSize((char*) $2, $3);
+   free($2);
+}
+
 %include ../mraa.i