From b7a0856f51ee53b61802e97b6c6801bff807785d Mon Sep 17 00:00:00 2001 From: Brendan Le Foll Date: Wed, 14 Jan 2015 11:41:43 +0000 Subject: [PATCH] spi: Make Spi write() work from SWIG with typemaps 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 --- api/mraa/spi.hpp | 16 ++++++------- examples/c++/Spi-pot.cpp | 6 ++--- examples/javascript/spi.js | 41 +++++++++++++++++++++++++++++++ examples/python/spi.py | 43 +++++++++++++++++++++++++++++++++ src/javascript/mraajs.i | 16 +++++++++++++ src/python/python-mraa.i | 49 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 160 insertions(+), 11 deletions(-) create mode 100644 examples/javascript/spi.js create mode 100644 examples/python/spi.py diff --git a/api/mraa/spi.hpp b/api/mraa/spi.hpp index f77480c..b2e028a 100644 --- a/api/mraa/spi.hpp +++ b/api/mraa/spi.hpp @@ -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 /** diff --git a/examples/c++/Spi-pot.cpp b/examples/c++/Spi-pot.cpp index b622996..b1bff43 100644 --- a/examples/c++/Spi-pot.cpp +++ b/examples/c++/Spi-pot.cpp @@ -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 index 0000000..5c85136 --- /dev/null +++ b/examples/javascript/spi.js @@ -0,0 +1,41 @@ +#!/usr/bin/env node + +/* + * Author: Brendan Le Foll + * 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 index 0000000..f8ee7ff --- /dev/null +++ b/examples/python/spi.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +# Author: Brendan Le Foll +# 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) + diff --git a/src/javascript/mraajs.i b/src/javascript/mraajs.i index 85a8d60..3e04eb7 100644 --- a/src/javascript/mraajs.i +++ b/src/javascript/mraajs.i @@ -14,7 +14,23 @@ $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; diff --git a/src/python/python-mraa.i b/src/python/python-mraa.i index 682d156..56ee3eb 100644 --- a/src/python/python-mraa.i +++ b/src/python/python-mraa.i @@ -16,13 +16,36 @@ } } +// 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)) { @@ -49,5 +72,31 @@ 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