Private
Public Access
2
0

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 <brendan.le.foll@intel.com>
This commit is contained in:
Brendan Le Foll
2015-01-14 11:41:43 +00:00
parent 17ee0c9669
commit b7a0856f51
6 changed files with 160 additions and 11 deletions

View 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
/**

View 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++) {

View File

@@ -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'))

43
examples/python/spi.py Normal file
View File

@@ -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)

View File

@@ -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;

View File

@@ -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