Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

node-spi: added getters / setters and some examples #2

Merged
merged 16 commits into from

4 participants

@anders94

Hi,

Thanks for all your work on node-spi. I've fleshed a little bit more out and have this working on a Raspberry Pi. Importantly, I removed this._spi.open() from the constructor giving people the option to run the setters but therefore requiring use of .open(). Some minimal checking on the setters is also included.

-Anders

vicary and others added some commits
@vicary vicary Tinkerings.
1. Correctly expose constants as documented.
2. Adding "delay" as a property in the C wrapper.
3. Changed internal function full_duplex_transfer to actually accept
speed, delay and size as arguments.
4. Passing aforementioned values into spi_ioc_transfer, which is
ignored currently.
36f024c
@vicary vicary Document fix on options. a886151
Anders Brownworth formatting 735ab79
Anders Brownworth formatting / uncommented device open / prep rx buffer so it is the sa…
…me size as the tx buffer
775ac67
Anders Brownworth minor re-wording 206e31f
Anders Brownworth getters and setters for options / more examples in README
added:
  mode()
  chipSelect()
  bitsPerWord()
  bitOrder()
    ORDER_MSB
    ORDER_LSB
  maxSpeed()
  halfDuplex()
  loopback()

Not all options work on all platforms.
bf1f72d
Anders Brownworth wording fixes 9d3f2de
Anders Brownworth wording fixes b73b790
Anders Brownworth wording fixes 7d3a70b
Anders Brownworth return this._spi to enable option chaining a933594
Anders Brownworth wording fixes 923b6bc
Anders Brownworth wording fixes 925efa9
Anders Brownworth wording fixes 84b198b
Anders Brownworth wording fixes 6d06c98
Anders Brownworth wording fixes 0ab0955
Anders Brownworth wording fixes 6f745be
@RussTheAerialist RussTheAerialist merged commit 2c643ab into RussTheAerialist:master
@RussTheAerialist

Thanks so much for doing this! I haven't had much time to work on it lately, so I appreciate all of the work you did for it!

@anders94
@RussTheAerialist
@anders94
@arpanchal

Hi, Russell
I am using Beaglebone. I am trying to communicate between beaglebone and CC1101 (a transceiver).
I am using nodejs platform for this.
I tried using your node-spi, but When I transfer a tx_buf = new Buffer([0x41,0x42]), Its working fine. But when I try to send
tx_bud = new Buffer([0x41]) (only one value) , Then It shows error!!!

Can you suggest me How can I do this and what changes I have to do in src files.
I have been doing this for the last 3-4 days, but still no success.. :(

Code:
var spi = require('node-spi');
require('buffer');

var mydev = new spi.Spi("/dev/spidev2.0", {
"mode": 0,
"chipSelect":spi.NO_CS,
"maxSpeed":1000000,
"size":8,
});

var out_buffer = new Buffer([0x41]);

mydev.transfer(out_buffer, out_buffer.length, function(device, recv_buffer){
console.log(recv_buffer);
});

error:

/home/ubuntu/node_modules/node-spi/spi.js:85
this._spi.transfer(txbuf, rxbuf);
^
Error: Unable to send SPI message
at Spi.transfer (/home/ubuntu/node_modules/node-spi/spi.js:85:13)
at Object. (/home/ubuntu/code/spi1.js:19:7)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)

@anders94
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 22, 2012
  1. @vicary

    Tinkerings.

    vicary authored
    1. Correctly expose constants as documented.
    2. Adding "delay" as a property in the C wrapper.
    3. Changed internal function full_duplex_transfer to actually accept
    speed, delay and size as arguments.
    4. Passing aforementioned values into spi_ioc_transfer, which is
    ignored currently.
  2. @vicary

    Document fix on options.

    vicary authored
Commits on Dec 20, 2012
  1. formatting

    Anders Brownworth authored
  2. formatting / uncommented device open / prep rx buffer so it is the sa…

    Anders Brownworth authored
    …me size as the tx buffer
Commits on Dec 21, 2012
  1. minor re-wording

    Anders Brownworth authored
Commits on Feb 1, 2013
  1. getters and setters for options / more examples in README

    Anders Brownworth authored
    added:
      mode()
      chipSelect()
      bitsPerWord()
      bitOrder()
        ORDER_MSB
        ORDER_LSB
      maxSpeed()
      halfDuplex()
      loopback()
    
    Not all options work on all platforms.
  2. wording fixes

    Anders Brownworth authored
  3. wording fixes

    Anders Brownworth authored
  4. wording fixes

    Anders Brownworth authored
  5. return this._spi to enable option chaining

    Anders Brownworth authored
  6. wording fixes

    Anders Brownworth authored
  7. wording fixes

    Anders Brownworth authored
  8. wording fixes

    Anders Brownworth authored
  9. wording fixes

    Anders Brownworth authored
  10. wording fixes

    Anders Brownworth authored
  11. wording fixes

    Anders Brownworth authored
This page is out of date. Refresh to see the latest.
Showing with 367 additions and 113 deletions.
  1. +107 −42 README.md
  2. +144 −38 spi.js
  3. +105 −27 src/spi_binding.cc
  4. +11 −6 src/spi_binding.h
View
149 README.md
@@ -1,37 +1,37 @@
node-spi
========
-A NodeJS interface to the SPI bus on embedded linux machines.
+A NodeJS interface to the SPI bus typically found on embedded linux machines
+such as the Raspberry Pi.
There is a native interface and a wrapped JS interface with a slightly
better API.
-**THIS CODE IS NOT FINISHED YET, NOTHING IS FUNCTIONING YET!**
-
-*Note: The first version will be blocking. I know this is antithetics to
-the nodejs philosophy, but I think it's important, when dealing with blocking
-interfaces, to get the code working in a blocking manner, and then introduce
-the async calls using eio.*
+*Note: The first version will be blocking. I know this is antithetical to
+the node.js philosophy, but I think its important to get the code working in a
+blocking manner first, and then introduce the async calls using eio.*
Basic Usage
===========
```javascript
-var spi = require("spi");
-
-var MyDevice = new spi.Spi("/dev/spidev1.1", {
- "mode": 0, // Always do mode first if you need something other than Mode 0
- "chip_select": spi.NO_CS
- "max_speed": 1000000, // In Hz
- "size": 8, // How many bits per word
-});
-
-var out_buffer = new Buffer([ 0x23, 0x48, 0xAF, 0x19, 0x19, 0x19 ]);
-
-MyDevice.transfer(out_buffer, outbuffer.Length(),
- function(device, recv_buffer) {
- // Do Something with the data in the recv buffer, if anything exists
-});
+var SPI = require('spi');
+
+var spi = new SPI.Spi('/dev/spidev0.0', {
+ 'mode': SPI.MODE['MODE_0'], // always set mode as the first option
+ 'chipSelect': SPI.CS['none'] // 'none', 'high' - defaults to low
+ }, function(s){s.open();});
+
+var txbuf = new Buffer([ 0x23, 0x48, 0xAF, 0x19, 0x19, 0x19 ]);
+var rxbuf = new Buffer([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]);
+
+spi.transfer(txbuf, rxbuf, function(device, buf) {
+ // rxbuf and buf should be the same here
+ var s = "";
+ for (var i=0; i < buf.length; i++)
+ s = s + buf[i] + " ";
+ console.log(s + "- " + new Date().getTime());
+ });
```
How you should **really** use the library
@@ -42,17 +42,15 @@ Ideally, for each SPI device that is being controlled should have it's own
object that implements the protocol necessary to talk to your device so that
the device protocol is defined in one place.
-An example project is
-[node-adafruit-pixel](https://github.com/RussTheAerialist/node-adafruit-pixel)
-which is a node module to control the
-[AdaFruit RGB Pixels](http://www.adafruit.com/products/738). The interface is
-defined in terms of color and pixels, and not in messages being sent via the
-SPI bus, but it uses node-spi to do it's work.
+An example project is [node-adafruit-pixel](https://github.com/RussTheAerialist/node-adafruit-pixel)
+which is a node module to control the [AdaFruit RGB Pixels](http://www.adafruit.com/products/738).
+The interface is defined in terms of color and pixels, and not in messages
+being sent via the SPI bus, but it uses node-spi to do it's work.
Native Api Reference
====================
-This section documents the native api which is defined in module \_spi.node.
+This section documents the native api which is defined in module _spi.node.
This is the interface that the normal Spi interface uses, but having a good
understanding of this part is important, as some people may want to use the
native interface directly.
@@ -60,13 +58,50 @@ native interface directly.
Creating, Opening, and Closing the device
-----------------------------------------
-**\_spi.Spi constructor** - The constructor takes a single argument, the path
-to the spi dev file in /dev. We do not check that the file exists until you
-call open.
+**\_spi.Spi constructor** - The constructor only requires the path to the spi
+dev file in /dev. Options and a callback are not required but can be specified.
+
+Example:
+```javascript
+var spi = new SPI.Spi('/dev/spidev0.1');
+```
+
+Options can include:
+* mode
+* chipSelect
+* bitsPerWord
+* bitOrder
+* maxSpeed
+* halfDuplex
+* loopback
+
+Example:
+```javascript
+var spi = new SPI.Spi('/dev/spidev0.0', {'mode': SPI.MODE['MODE_0']});
+```
+
+The callback returns a handle to the newly created SPI object. It might be
+handy to .open() it if you set all of your options in one shot.
-**open()** - This function takes no arguments and will open the device, setting
+Example:
+```javascript
+var spi = new SPI.Spi('/dev/spidev0.0', {}, function(s){s.open();});
+```
+
+**open()** - This function takes no arguments and will open the device using
all of the options that were previously set. Once the device is open, we do not
-allow you to change the settings to the device.
+allow you to change the settings on the device.
+
+Example:
+```javascript
+var spi = new SPI.Spi('/dev/spidev0.0', {'mode': SPI.MODE['MODE_0']});
+
+// get/set aditional options
+spi.maxSpeed(20000); // in Hz
+console.log('max speed: ' + spi.maxSpeed());
+
+spi.open(); // once opened, you can't change the options
+```
**close()** - This function should always be called before ending. Right now
the destructor for the underlying C++ class does not call close(), but that
@@ -115,21 +150,51 @@ if you'd like.
Getting and Sending Data
------------------------
+**transfer(txbuf, rxbuf, callback)** - This takes two buffers, a write and a
+read buffer, and optionally a callback. SPI only reads when a byte is written
+so communicaton is usually full duplex.
+
+Exmple:
+```javascript
+var txbuf = new Buffer([ 0x23, 0x48, 0xAF, 0x19, 0x19, 0x19 ]);
+var rxbuf = new Buffer([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]);
+
+spi.transfer(txbuf, rxbuf, function(device, buf) {
+ var s = "";
+ for (var i=0; i < buf.length; i++)
+ s = s + buf[i] + " ";
+ console.log(s);
+ });
+```
+
+As a convenience feature, read and write functions pad zeros in the opposite
+direction to make simple read and writes work.
-**transfer()** - This takes two buffers, a write buffer and a read buffer.
-If you only want to do one way transfer, then pass null to that argument. For
-example, writes would look like this:
+**read(buffer, callback)** - Reads as much data as the given buffer is big.
+The results of the read are available in the callback.
+Example:
```javascript
-var buff = new Buffer([0x12, 0x12, 0x12]);
-spi.transfer(buff, null);
+var buf1 = new Buffer(8);
+spi.read(buf1, function(device, buf2) {
+ var s = "";
+ for (var i=0; i < buf.length; i++)
+ s = s + buf[i] + " ";
+ console.log(s);
+ });
```
-Reads would look like this:
+**write(buffer, callback)** - Writes out the given buffer.
+Example:
```javascript
-var buff = new Buffer(8);
-spi.transfer(null, buff);
+var buf = new Buffer([0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0]);
+spi.write(buf, function(device, buf2) {
+ var s = "";
+ for (var i=0; i < buf.length; i++)
+ s = s + buf[i] + " ";
+ console.log(s);
+ });
```
Remember that these native apis are currently blocking. I will update, once I
View
182 spi.js
@@ -18,69 +18,175 @@
var _spi = require('bindings')('_spi.node');
-var MODE = [
- _spi.SPI_MODE_0,
- _spi.SPI_MODE_1,
- _spi.SPI_MODE_2,
- _spi.SPI_MODE_3
-];
+// Consistance with docs
+var MODE = {
+ MODE_0: _spi.MODE_0,
+ MODE_1: _spi.MODE_1,
+ MODE_2: _spi.MODE_2,
+ MODE_3: _spi.MODE_3
+};
var CS = {
- 'high': _spi.SPI_CS_HIGH,
- 'low': 0,
- 'none': _spi.SPI_NO_CS
+ none: _spi.NO_CS,
+ high: _spi.CS_HIGH,
+ low: _spi.CS_LOW
+};
+
+var ORDER = {
+ msb: _spi.ORDER_MSB,
+ lsb: _spi.ORDER_LSB
};
function isFunction(object) {
- return object && getClass.call(object) == '[object Function]';
+ return object && typeof object == 'function';
}
var Spi = function(device, options, callback) {
- this._spi = new _spi._spi();
+ this._spi = new _spi._spi();
- if (callback == undefined) {
- callback = options;
- options = {};
- }
+ options = options || {}; // Default to an empty object
- options = options || { }; // Default to an empty object
-
- for(var attrname in options) {
- var value = options[attrname];
- if (attrname in this._spi) {
- console.trace("Setting " + attrname + "=" + value);
- this._spi[attrname](value);
+ for(var attrname in options) {
+ var value = options[attrname];
+ if (attrname in this._spi) {
+ this._spi[attrname](value);
+ }
+ else
+ console.log("Unknown option: " + attrname + "=" + value);
}
- }
- this._spi.open(device);
+ this.device = device;
+
+ isFunction(callback) && callback(this); // TODO: Update once open is async;
+}
+
+Spi.prototype.open = function() {
+ return this._spi.open(this.device);
+}
- callback(this); // TODO: Update once open is async;
+Spi.prototype.close = function() {
+ return this._spi.close();
}
Spi.prototype.write = function(buf, callback) {
- this._spi.transfer(buf, null);
+ this._spi.transfer(buf, new Buffer(buf.length));
- if (callback !== undefined) {
- callback(this, buf); // TODO: Update once transfer is async;
- }
+ isFunction(callback) && callback(this, buf); // TODO: Update once open is async;
}
Spi.prototype.read = function(buf, callback) {
- this._spi.transfer(null, buf);
+ this._spi.transfer(new Buffer(buf.length), buf);
+
+ isFunction(callback) && callback(this, buf); // TODO: Update once open is async;
+}
+
+Spi.prototype.transfer = function(txbuf, rxbuf, callback) {
+ // tx and rx buffers need to be the same size
+ this._spi.transfer(txbuf, rxbuf);
+
+ isFunction(callback) && callback(this, rxbuf); // TODO: Update once open is async;
+}
+
+Spi.prototype.mode = function(mode) {
+ if (typeof(mode) != 'undefined')
+ if (mode == MODE['MODE_0'] || mode == MODE['MODE_1'] ||
+ mode == MODE['MODE_2'] || mode == MODE['MODE_3']) {
+ this._spi['mode'](mode);
+ return this._spi;
+ }
+ else {
+ console.log('Illegal mode');
+ return -1;
+ }
+ else
+ return this._spi['mode']();
+}
+
+Spi.prototype.chipSelect = function(cs) {
+ if (typeof(cs) != 'undefined')
+ if (cs == CS['none'] || cs == CS['high'] || cs == MODE['low']) {
+ this._spi['chipSelect'](cs);
+ return this._spi;
+ }
+ else {
+ console.log('Illegal chip selection');
+ return -1;
+ }
+ else
+ return this._spi['chipSelect']();
+}
+
+Spi.prototype.bitsPerWord = function(bpw) {
+ if (typeof(bpw) != 'undefined')
+ if (bpw > 1) {
+ this._spi['bitsPerWord'](bpw);
+ return this._spi;
+ }
+ else {
+ console.log('Illegal bits per word');
+ return -1;
+ }
+ else
+ return this._spi['bitsPerWord']();
+}
+
+Spi.prototype.bitOrder = function(bo) {
+ if (typeof(bo) != 'undefined')
+ if (bo == ORDER['msb'] || bo == ORDER['lsb']) {
+ this._spi['bitOrder'](bo);
+ return this._spi;
+ }
+ else {
+ console.log('Illegal bit order');
+ return -1;
+ }
+ else
+ return this._spi['bitOrder']();
+}
+
+Spi.prototype.maxSpeed = function(speed) {
+ if (typeof(speed) != 'undefined')
+ if (speed > 0) {
+ this._spi['maxSpeed'](speed);
+ return this._spi;
+ }
+ else {
+ console.log('Speed must be positive');
+ return -1;
+ }
+ else
+ return this._spi['maxSpeed']();
+}
- if (callback !== undefined) {
- callback(this, buf); // TODO: Update once transfer is async;
- }
+Spi.prototype.halfDuplex = function(duplex) {
+ if (typeof(duplex) != 'undefined')
+ if (duplex) {
+ this._spi['halfDuplex'](true);
+ return this._spi;
+ }
+ else {
+ this._spi['halfDuplex'](false);
+ return this._spi;
+ }
+ else
+ return this._spi['halfDuplex']();
}
-Spi.prototype.transfer = function(wrbuf, rdbuf, callback) {
- this._spi.transfer(wrbuf, rdbuf);
- if (callback !== undefined) {
- callback(this, rdbuf); // TODO: Update once transfer is async;
- }
+Spi.prototype.loopback = function(loop) {
+ if (typeof(loop) != 'undefined')
+ if (loop) {
+ this._spi['loopback'](true);
+ return this._spi;
+ }
+ else {
+ this._spi['loopback'](false);
+ return this._spi;
+ }
+ else
+ return this._spi['loopback']();
}
module.exports.MODE = MODE;
module.exports.CS = CS;
+module.exports.ORDER = ORDER;
module.exports.Spi = Spi;
View
132 src/spi_binding.cc
@@ -43,54 +43,117 @@ Persistent<Function> Spi::constructor;
void Spi::Initialize(Handle<Object> target) {
HandleScope scope;
+ // var t = function() {};
Local<FunctionTemplate> t = FunctionTemplate::New(New);
+ // t = function _spi() {};
t->SetClassName(String::NewSymbol("_spi"));
t->InstanceTemplate()->SetInternalFieldCount(1);
+ // t.prototype.open = open;
t->PrototypeTemplate()->Set(String::NewSymbol("open"),
FunctionTemplate::New(Open)->GetFunction());
+ // t.prototype.close = close;
t->PrototypeTemplate()->Set(String::NewSymbol("close"),
FunctionTemplate::New(Close)->GetFunction());
+
+ // t.prototype.transfer = transfer;
t->PrototypeTemplate()->Set(String::NewSymbol("transfer"),
FunctionTemplate::New(Transfer)->GetFunction());
+
+ // t.prototype.mode = GetSetMode;
t->PrototypeTemplate()->Set(String::NewSymbol("mode"),
FunctionTemplate::New(GetSetMode)->GetFunction());
+
+ // t.prototype.chipSelect = GetSetChipSelect;
t->PrototypeTemplate()->Set(String::NewSymbol("chipSelect"),
FunctionTemplate::New(GetSetChipSelect)->GetFunction());
- t->PrototypeTemplate()->Set(String::NewSymbol("bitsPerWord"),
+
+ // t.prototype.bitsPerWord = GetSetBitsPerWord;
+ t->PrototypeTemplate()->Set(String::NewSymbol("size"),
FunctionTemplate::New(GetSetBitsPerWord)->GetFunction());
+
+ // t.prototype.bitOrder = GetSetBitOrder;
t->PrototypeTemplate()->Set(String::NewSymbol("bitOrder"),
FunctionTemplate::New(GetSetBitOrder)->GetFunction());
+
+ // t.prototype.maxSpeed = GetSetMaxSpeed;
t->PrototypeTemplate()->Set(String::NewSymbol("maxSpeed"),
FunctionTemplate::New(GetSetMaxSpeed)->GetFunction());
+
+ // t.prototype.halfDuplex = GetSet3Wire;
t->PrototypeTemplate()->Set(String::NewSymbol("halfDuplex"),
FunctionTemplate::New(GetSet3Wire)->GetFunction());
+
+ // t.prototype.delay = GetSetDelay;
+ t->PrototypeTemplate()->Set(String::NewSymbol("delay"),
+ FunctionTemplate::New(GetSetDelay)->GetFunction());
+
+ // t.prototype.loopback = GetSetLoop;
t->PrototypeTemplate()->Set(String::NewSymbol("loopback"),
FunctionTemplate::New(GetSetLoop)->GetFunction());
+ // var constructor = t; // in context of new.
constructor = Persistent<Function>::New(t->GetFunction());
- target->Set(String::NewSymbol("_spi"), constructor);
-
- // SPI modes
- NODE_DEFINE_CONSTANT(target, SPI_MODE_0);
- NODE_DEFINE_CONSTANT(target, SPI_MODE_1);
- NODE_DEFINE_CONSTANT(target, SPI_MODE_2);
- NODE_DEFINE_CONSTANT(target, SPI_MODE_3);
-
- // Logic Level High for Chip Select
- NODE_DEFINE_CONSTANT(target, SPI_CS_HIGH);
- // No Chip Select
- NODE_DEFINE_CONSTANT(target, SPI_NO_CS);
+ // exports._spi = constructor;
+ target->Set(String::NewSymbol("_spi"), constructor);
+ /* Should be change here.
+
+ // SPI modes
+ NODE_DEFINE_CONSTANT(target, SPI_MODE_0);
+ NODE_DEFINE_CONSTANT(target, SPI_MODE_1);
+ NODE_DEFINE_CONSTANT(target, SPI_MODE_2);
+ NODE_DEFINE_CONSTANT(target, SPI_MODE_3);
+
+ // Logic Level High for Chip Select
+ NODE_DEFINE_CONSTANT(target, SPI_CS_HIGH);
+
+ // No Chip Select
+ NODE_DEFINE_CONSTANT(target, SPI_NO_CS);
+ */
+ /* From:
+ _spi = {
+ SPI_MODE_0: 0
+ , SPI_MODE_1: 1
+ , SPI_MODE_2: 2
+ , SPI_MODE_3: 3
+
+ , SPI_NO_CS: 64
+ , SPI_CS_HIGH: 4
+ };
+ */
+ /* To:
+ var spi = require('spi');
+
+ spi.MODE_0 == 0;
+ spi.MODE_1 == 1;
+ spi.MODE_2 == 2;
+ spi.MODE_3 == 3;
+
+ spi.CS_LOW == 0;
+ spi.CS_HIGH == 4;
+ spi.NO_CS == 64;
+ */
+
+ // Expose constants
+ target->Set(v8::String::NewSymbol("MODE_0"), v8::Integer::New(SPI_MODE_0));
+ target->Set(v8::String::NewSymbol("MODE_1"), v8::Integer::New(SPI_MODE_1));
+ target->Set(v8::String::NewSymbol("MODE_2"), v8::Integer::New(SPI_MODE_2));
+ target->Set(v8::String::NewSymbol("MODE_3"), v8::Integer::New(SPI_MODE_3));
+
+ target->Set(v8::String::NewSymbol("NO_CS"), v8::Integer::New(SPI_NO_CS));
+ target->Set(v8::String::NewSymbol("CS_LOW"), v8::Integer::New(0));
+ target->Set(v8::String::NewSymbol("CS_HIGH"), v8::Integer::New(SPI_CS_HIGH));
+
+ target->Set(v8::String::NewSymbol("ORDER_MSB"), v8::Boolean::New(false));
+ target->Set(v8::String::NewSymbol("ORDER_LSB"), v8::Boolean::New(true));
}
// new Spi(string device)
//Handle<Value> Spi::New(const Arguments& args) {
SPI_FUNC_IMPL(New) {
-
-
Spi* spi = new Spi();
spi->Wrap(args.This());
@@ -165,7 +228,9 @@ Handle<Value> Spi::Transfer(const Arguments &args) {
}
Handle<Value> retval = self->full_duplex_transfer(write_buffer, read_buffer,
- MAX(write_length, read_length));
+ MAX(write_length, read_length),
+ self->m_max_speed, self->m_delay, self->m_bits_per_word);
+
if (!retval->IsUndefined()) {
return retval;
}
@@ -173,23 +238,23 @@ Handle<Value> Spi::Transfer(const Arguments &args) {
FUNCTION_CHAIN;
}
-Handle<Value> Spi::full_duplex_transfer(char *write, char *read, size_t length) {
- struct spi_ioc_transfer data = { 0 };
-
- // .tx_buf = (unsigned long)write,
- // .rx_buf = (unsigned long)read,
- // .len = length,
- // .delay_usecs = 0, // Unsure exactly what delay is for..
- // .speed_hz = 0, // Use the max speed set when opened
- // .bits_per_word = 0, // Use the bits per word set when opened
- //};
+Handle<Value> Spi::full_duplex_transfer(char *write, char *read, size_t length, uint32_t speed, uint16_t delay, uint8_t bits) {
+ struct spi_ioc_transfer data = {
+ (unsigned long)write,
+ (unsigned long)read,
+ length,
+ speed,
+ delay, // Still unsure ... just expose to options.
+ bits,
+ };
int ret = ioctl(this->m_fd, SPI_IOC_MESSAGE(1), &data);
+
if (ret == 1) {
return ERROR("Unable to send SPI message");
}
- return Undefined();
+ return v8::Integer::New(ret);
}
// This overrides any of the OTHER set functions since modes are predefined
@@ -256,6 +321,7 @@ SPI_FUNC_IMPL(GetSetMaxSpeed) {
FUNCTION_CHAIN;
}
+
SPI_FUNC_IMPL(GetSet3Wire) {
FUNCTION_PREAMBLE;
GETTER(1, Boolean::New((self->m_mode&SPI_3WIRE) > 0));
@@ -269,5 +335,17 @@ SPI_FUNC_IMPL(GetSet3Wire) {
FUNCTION_CHAIN;
}
+// Expose m_delay as "delay"
+SPI_FUNC_IMPL(GetSetDelay) {
+ FUNCTION_PREAMBLE;
+ GETTER(1, Number::New(self->m_delay));
+ REQ_INT_ARG_GT(0, Delay, in_value, 0);
+ ASSERT_NOT_OPEN;
+
+ self->m_delay = in_value;
+
+ FUNCTION_CHAIN;
+}
+
SPI_FUNC_BOOLEAN_TOGGLE_IMPL(GetSetLoop, SPI_LOOP);
SPI_FUNC_BOOLEAN_TOGGLE_IMPL(GetSetBitOrder, SPI_LSB_FIRST);
View
17 src/spi_binding.h
@@ -35,9 +35,12 @@ class Spi : ObjectWrap {
static void Initialize(Handle<Object> target);
private:
- Spi() : m_fd(-1), m_mode(0), m_bits_per_word(8),
- m_max_speed(1000000) { }
- ~Spi() { } // Probably close fd if it's open
+ Spi() : m_fd(-1),
+ m_mode(0),
+ m_max_speed(1000000), // default speed in Hz () 1MHz
+ m_delay(0), // expose delay to options
+ m_bits_per_word(8) { } // default bits per word
+ ~Spi() { } // Probably close fd if it's open
SPI_FUNC(New);
SPI_FUNC(Open);
@@ -47,16 +50,18 @@ class Spi : ObjectWrap {
SPI_FUNC(GetSetChipSelect);
SPI_FUNC(GetSetMaxSpeed);
SPI_FUNC(GetSet3Wire);
+ SPI_FUNC(GetSetDelay);
SPI_FUNC(GetSetLoop);
SPI_FUNC(GetSetBitOrder);
SPI_FUNC(GetSetBitsPerWord);
- Handle<Value> full_duplex_transfer(char *write, char *read, size_t length);
+ Handle<Value> full_duplex_transfer(char *write, char *read, size_t length, uint32_t speed, uint16_t delay, uint8_t bits);
int m_fd;
int m_mode;
- int m_bits_per_word;
- int m_max_speed;
+ uint32_t m_max_speed;
+ uint16_t m_delay;
+ uint8_t m_bits_per_word;
};
#define ERROR(STR) ThrowException(Exception::Error(String::New(STR)))
Something went wrong with that request. Please try again.