diff --git a/CHANGELOG.md b/CHANGELOG.md index 56bee6c..f91daa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,21 @@ # CHANGELOG -## v2.1.0 *[not released yes]* - * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.21 `nekuz0r` +## v2.1.0 *[not released yet]* + * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.25 `nekuz0r` + * **Update:** wiringPiISR now keeps event loop running `nekuz0r` + * **Update:** piModelNames string array `nekuz0r` + * **Update:** piMakerNames string array `nekuz0r` + * **Update:** install.sh now clone tagged version of the custom libWiringPi + * **Add:** support for node 0.12.0 * **Add:** raspberry pi A+ support `nekuz0r` + * **Add:** raspberry pi 2 support `nekuz0r` + * **Add:** constant PI_MODEL_AP `nekuz0r` + * **Add:** constant PI_MODEL_2 `nekuz0r` + * **Add:** constant PI_MARKER_MBEST `nekuz0r` + * **Add:** wiringPiISRCancel `nekuz0r` + * **Add:** wiringPiSPISetupMode `nekuz0r` + * **Fix:** blink.js example `louterrailloune` + * **Fix:** SPI speed select argument `noddy76` ## v2.0.0 *[Jan 1 2015]* * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.20 `nekuz0r` diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index b1548c6..e4792d1 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -136,13 +136,23 @@ This is an un-documented special to let you set any pin to any mode. `mode` can be one of the following values: -* `WPI_MODE_PINS` - >= 1.0.0 -* `WPI_MODE_PHYS` - >= 1.0.0 -* `WPI_MODE_GPIO` - >= 1.0.0 - +* `FSEL_INPT` + >= 2.1.0 +* `FSEL_OUTP` + >= 2.1.0 +* `FSEL_ALT0` + >= 2.1.0 +* `FSEL_ALT1` + >= 2.1.0 +* `FSEL_ALT2` + >= 2.1.0 +* `FSEL_ALT3` + >= 2.1.0 +* `FSEL_ALT4` + >= 2.1.0 +* `FSEL_ALT5` + >= 2.1.0 + ### pinMode(pin, mode) >= 0.1.0 @@ -176,7 +186,7 @@ If you need to change the pin mode, the you can do it with the gpio program in a >= 1.1.0 * `SOFT_TONE_OUTPUT` >= 1.1.0 - + ### pullUpDnControl(pin, pud) >= 0.2.0 @@ -194,7 +204,7 @@ The internal pull up/down resistors have a value of approximately 50KΩ on the R >= 0.2.0 * `PUD_UP` *pull to 3.3v* >= 0.2.0 - + ### digitalRead(pin) >= 0.1.1 @@ -258,7 +268,7 @@ Gives up and returns 0 if no pulse starts within a specified time out. >= 0.1.2 * `LOW` >= 0.1.2 - + ### delay(milliseconds) >= 1.1.0 @@ -318,6 +328,8 @@ wpi.wiringPiISR(7, wpi.INT_EDGE_FALLING, function(delta) { console.log('Pin 7 changed to LOW (', delta, ')'); }); ``` +### wiringPiISRCancel(pin) + >= 2.1.0 --- @@ -355,12 +367,16 @@ Indexes of each string table have corresponding constants >= 2.0.0 * `PI_MODEL_A` >= 1.1.0 + * `PI_MODEL_AP` + >= 2.1.0 * `PI_MODEL_B` >= 1.1.0 * `PI_MODEL_BP` >= 2.0.0 * `PI_MODEL_CM` >= 1.1.1 + * `PI_MODEL_2` + >= 2.1.0 * `PI_REVISION_NAMES` @@ -380,6 +396,8 @@ Indexes of each string table have corresponding constants >= 2.0.0 * `PI_MAKER_EGOMAN` >= 2.0.0 + * `PI_MAKER_MBEST` + >= 2.1.0 * `PI_MAKER_SONY` >= 2.0.0 * `PI_MAKER_QISDA` @@ -429,7 +447,7 @@ The mark:space mode is traditional, however the default mode in the Pi is “bal * `PWM_MODE_BAL` *balanced* * `PWM_MODE_MS` *mark:space* - + ### pwmSetRange(range) >= 0.1.1 @@ -541,6 +559,9 @@ The returned value is the Linux file-descriptor for the device, or -1 on error. If an error has happened, you may use the standard errno global variable to see why. +### wiringPiSPISetupMode(channel, speed, mode) + >= 2.1.0 + --- ## Serial @@ -556,7 +577,7 @@ The return value is the file descriptor or -1 for any error, in which case errno **NOTE: The file descriptor (fd) returned is a standard Linux file descriptor.** -**You can use the standard read(), write(), etc. system calls on this file descriptor as required.** +**You can use the standard read(), write(), etc. system calls on this file descriptor as required.** **E.g. you may wish to write a larger block of binary data where the serialPutchar() or serialPuts() function may not be the most appropriate function to use, in which case, you can use write() to send the data.** diff --git a/install.sh b/install.sh index 001b72d..33a973f 100644 --- a/install.sh +++ b/install.sh @@ -40,7 +40,7 @@ rm ./install.log 2>/dev/null 1>&2 echo -n "Cloning libWiringPi ... " rm -Rf ./wiringpi 2>/dev/null 1>&2 -git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 +git clone https://github.com/nekuz0r/wiringpi.git -b 2.25 > ./install.log 2>&1 check_git_clone #git submodule init #check_git_clone diff --git a/package.json b/package.json index 88eed48..9979e88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wiring-pi", - "version": "2.0.0", + "version": "2.1.0", "description": "Bindings to wiringPi", "main": "lib/exports.js", "scripts": { diff --git a/patchs/devLib_Makefile.patch b/patchs/devLib_Makefile.patch index 8ae4125..cb9fc41 100644 --- a/patchs/devLib_Makefile.patch +++ b/patchs/devLib_Makefile.patch @@ -14,6 +14,6 @@ CC = gcc -INCLUDE = -I. +INCLUDE = -I. -I$(PWD)/../wiringPi + DEFS = -D_GNU_SOURCE CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC - LIBS = diff --git a/src/addon.cc b/src/addon.cc index ab1dec3..a7a58bc 100644 --- a/src/addon.cc +++ b/src/addon.cc @@ -20,12 +20,20 @@ bool find_int(const int value, const int array[], size_t s) { return false; } +#if NODE_VERSION_AT_LEAST(0, 11, 0) +void throw_error(v8::Isolate* isolate, const char* format, ...) { +#else void throw_error(const char* format, ...) { +#endif char buffer[256]; va_list args; va_start(args, format); vsnprintf(buffer, 156, format, args); va_end(args); - v8::ThrowException(v8::Exception::Error(v8::String::New(buffer))); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, buffer))); + #else + v8::ThrowException(v8::Exception::Error(v8::String::New(buffer))); + #endif } \ No newline at end of file diff --git a/src/addon.h b/src/addon.h index 666f552..091973e 100644 --- a/src/addon.h +++ b/src/addon.h @@ -2,6 +2,7 @@ #define _ADDON_H_ #include + #include using namespace v8; @@ -19,71 +20,157 @@ bool find_string(const char* string, const char* array[], size_t s); bool find_int(const int value, const int array[], size_t s); - void throw_error(const char* fmt, ...); + + #if NODE_VERSION_AT_LEAST(0, 11, 0) + void throw_error(v8::Isolate* isolate, const char* fmt, ...); + #else + void throw_error(const char* fmt, ...); + #endif + + #if NODE_VERSION_AT_LEAST(0, 11, 0) + + #define DECLARE(name) \ + namespace nodemodule { \ + static void name(const v8::FunctionCallbackInfo& args); \ + } + + #define IMPLEMENT(name) \ + void nodemodule::name(const v8::FunctionCallbackInfo& args) - #define DECLARE(name) \ - namespace nodemodule { \ - static v8::Handle name(const v8::Arguments& args); \ - } + #define EXPORT_FUNCTION(name) \ + target->Set(v8::String::NewFromUtf8(isolate, #name, v8::String::kInternalizedString), \ + v8::FunctionTemplate::New(isolate, nodemodule::name)->GetFunction()) + + #define EXPORT_CONSTANT_INT(name) \ + target->ForceSet(v8::String::NewFromUtf8(isolate, #name, v8::String::kInternalizedString), \ + v8::Int32::New(isolate, name), static_cast(v8::ReadOnly | v8::DontDelete)); + + #define EXPORT_CONSTANT_STRING(name) \ + target->ForceSet(v8::String::NewFrontUtf8(isolate, #name, v8::String::kInternalizedString), \ + v8::String::NewFromUtf8(isolate, name), static_cast(v8::ReadOnly | v8::DontDelete)); - #define IMPLEMENT(name) \ - v8::Handle nodemodule::name(const v8::Arguments& args) + #define EXPORT_CONSTANT_INT_ARRAY(name, array, length) \ + { \ + v8::Local arr = v8::Array::New(isolate, length); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, v8::Int32::New(isolate, array[i])); \ + } \ + target->ForceSet(v8::String::NewFromUtf8(isolate, #name, v8::String::kInternalizedString), \ + arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ + } + + #define EXPORT_CONSTANT_STRING_ARRAY(name, array, length) \ + { \ + v8::Local arr = v8::Array::New(isolate, length); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, v8::String::NewFromUtf8(isolate, array[i])); \ + } \ + target->ForceSet(v8::String::NewFromUtf8(isolate, #name, v8::String::kInternalizedString), \ + arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ + } - #define EXPORT_FUNCTION(name) \ - target->Set(v8::String::NewSymbol(#name), \ - v8::FunctionTemplate::New(nodemodule::name)->GetFunction()) + #define NODE_MODULE_INIT() \ + namespace nodemodule { \ + void init(v8::Handle target); \ + } \ + void nodemodule::init(v8::Handle target) - #define EXPORT_CONSTANT_INT(name) \ - target->Set(v8::String::NewSymbol(#name), \ - v8::Int32::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); + #define NODE_MODULE_DECLARE(name) NODE_MODULE(name, nodemodule::init) + #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(v8::Isolate* isolate, v8::Handle target) + #define DECLARE_EXPORT_INIT(name) \ + namespace nodemodule { \ + void init##name(v8::Isolate* isolate, v8::Handle target); \ + } + + #define INIT(name) nodemodule::init##name(isolate, target); + + #define SCOPE_OPEN() \ + v8::Isolate* isolate = args.GetIsolate(); \ + v8::HandleScope scope(isolate) + #define SCOPE_CLOSE(obj) args.GetReturnValue().Set(obj) + + #else - #define EXPORT_CONSTANT_STRING(name) \ - target->Set(v8::String::NewSymbol(#name), \ - v8::String::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); + #define DECLARE(name) \ + namespace nodemodule { \ + static v8::Handle name(const v8::Arguments& args); \ + } + + #define IMPLEMENT(name) \ + v8::Handle nodemodule::name(const v8::Arguments& args) - #define EXPORT_CONSTANT_INT_ARRAY(name, array, length) \ - { \ - v8::Local arr = v8::Array::New(); \ - for (int i = 0; i < length; i++) { \ - arr->Set(i, v8::Int32::New(array[i])); \ - } \ - target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ - } + #define EXPORT_FUNCTION(name) \ + target->Set(v8::String::NewSymbol(#name), \ + v8::FunctionTemplate::New(nodemodule::name)->GetFunction()) + + #define EXPORT_CONSTANT_INT(name) \ + target->Set(v8::String::NewSymbol(#name), \ + v8::Int32::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); - #define EXPORT_CONSTANT_STRING_ARRAY(name, array, length) \ - { \ - v8::Local arr = v8::Array::New(); \ - for (int i = 0; i < length; i++) { \ - arr->Set(i, v8::String::New(array[i])); \ + #define EXPORT_CONSTANT_STRING(name) \ + target->Set(v8::String::NewSymbol(#name), \ + v8::String::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); + + #define EXPORT_CONSTANT_INT_ARRAY(name, array, length) \ + { \ + v8::Local arr = v8::Array::New(length); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, v8::Int32::New(array[i])); \ + } \ + target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ + } + + #define EXPORT_CONSTANT_STRING_ARRAY(name, array, length) \ + { \ + v8::Local arr = v8::Array::New(length); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, v8::String::New(array[i])); \ + } \ + target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ + } + + #define NODE_MODULE_INIT() \ + namespace nodemodule { \ + void init(v8::Handle target); \ } \ - target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ - } - - #define NODE_MODULE_INIT() \ - namespace nodemodule { \ - void init(v8::Handle target); \ - } \ - void nodemodule::init(v8::Handle target) - #define NODE_MODULE_DECLARE(name) NODE_MODULE(name, nodemodule::init) - #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(v8::Handle target) - #define DECLARE_EXPORT_INIT(name) \ - namespace nodemodule { \ - void init##name(v8::Handle target); \ - } + void nodemodule::init(v8::Handle target) + #define NODE_MODULE_DECLARE(name) NODE_MODULE(name, nodemodule::init) + #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(v8::Handle target) + #define DECLARE_EXPORT_INIT(name) \ + namespace nodemodule { \ + void init##name(v8::Handle target); \ + } + + #define INIT(name) nodemodule::init##name(target); + + #define SCOPE_OPEN() v8::HandleScope scope + #define SCOPE_CLOSE(obj) return scope.Close(obj) + + #endif + - #define INIT(name) nodemodule::init##name(target); - #define SCOPE_OPEN() v8::HandleScope scope - #define SCOPE_CLOSE(obj) return scope.Close(obj) + #if NODE_VERSION_AT_LEAST(0, 11, 0) + #define UNDEFINED() v8::Undefined(isolate) + #define INT32(v) v8::Int32::New(isolate, v) + #define UINT32(v) v8::Uint32::NewFromUnsigned(isolate, v) + #define STRING(v) v8::String::NewFromUtf8(isolate, v) + #else + #define UNDEFINED() v8::Undefined() + #define INT32(v) v8::Int32::New(v) + #define UINT32(v) v8::Uint32::NewFromUnsigned(v) + #define STRING(v) v8::String::New(v) + #endif - #define UNDEFINED() v8::Undefined() - #define INT32(v) v8::Int32::New(v) - #define UINT32(v) v8::Uint32::New(v) - #define STRING(v) v8::String::New(v) - - #define THROW_ERROR(fmt, ...) \ - throw_error(fmt, __VA_ARGS__); \ - SCOPE_CLOSE(UNDEFINED()) + #if NODE_VERSION_AT_LEAST(0, 11, 0) + #define THROW_ERROR(fmt, ...) \ + throw_error(isolate, fmt, __VA_ARGS__); \ + SCOPE_CLOSE(UNDEFINED()); + #else + #define THROW_ERROR(fmt, ...) \ + throw_error(fmt, __VA_ARGS__); \ + SCOPE_CLOSE(UNDEFINED()) + #endif #define SET_ARGUMENT_NAME(id, name) static const char* arg##id = #name #define GET_ARGUMENT_NAME(id) arg##id @@ -122,7 +209,10 @@ #define GET_ARGUMENT_AS_NUMBER(id) GET_ARGUMENT_AS_TYPE(id, NumberValue) #define GET_ARGUMENT_AS_STRING(id) GET_ARGUMENT_AS_TYPE(id, ToString) #define GET_ARGUMENT_AS_LOCAL_FUNCTION(id) v8::Local::Cast(args[id]) - #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) v8::Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) + + #if !NODE_VERSION_AT_LEAST(0, 11, 0) + #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) v8::Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) + #endif #define LIST(...) { __VA_ARGS__ } #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ diff --git a/src/devlib/ds1302.cc b/src/devlib/ds1302.cc index fe6e127..15ba05a 100644 --- a/src/devlib/ds1302.cc +++ b/src/devlib/ds1302.cc @@ -94,9 +94,17 @@ IMPLEMENT(ds1302clockRead) { int clockData[8]; ::ds1302clockRead(clockData); - v8::Local res = v8::Array::New(8); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Local res = v8::Array::New(isolate, 8); + #else + v8::Local res = v8::Array::New(8); + #endif for (int i = 0; i < 8; i++) { - res->Set(i, v8::Int32::New(clockData[i])); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + res->Set(i, v8::Int32::New(isolate, clockData[i])); + #else + res->Set(i, v8::Int32::New(clockData[i])); + #endif } SCOPE_CLOSE(res); diff --git a/src/devlib/lcd.cc b/src/devlib/lcd.cc index 6fbd787..32495e8 100644 --- a/src/devlib/lcd.cc +++ b/src/devlib/lcd.cc @@ -203,7 +203,11 @@ IMPLEMENT(lcdPuts) { CHECK_ARGUMENT_TYPE_STRING(1); int fd = GET_ARGUMENT_AS_INT32(0); - v8::String::AsciiValue data(GET_ARGUMENT_AS_STRING(1)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::String::Utf8Value data(GET_ARGUMENT_AS_STRING(1)); + #else + v8::String::AsciiValue data(GET_ARGUMENT_AS_STRING(1)); + #endif ::lcdPuts(fd, *data); diff --git a/src/devlib/lcd128x64.cc b/src/devlib/lcd128x64.cc index 2e4c2bb..1a6ffe1 100644 --- a/src/devlib/lcd128x64.cc +++ b/src/devlib/lcd128x64.cc @@ -60,9 +60,15 @@ IMPLEMENT(lcd128x64orientCoordinates) { int x, y; ::lcd128x64orientCoordinates(&x, &y); - v8::Local res = v8::Array::New(2); - res->Set(0, v8::Int32::New(x)); - res->Set(1, v8::Int32::New(y)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Local res = v8::Array::New(isolate, 2); + res->Set(0, v8::Int32::New(isolate, x)); + res->Set(1, v8::Int32::New(isolate, y)); + #else + v8::Local res = v8::Array::New(2); + res->Set(0, v8::Int32::New(x)); + res->Set(1, v8::Int32::New(y)); + #endif SCOPE_CLOSE(res); } @@ -75,9 +81,15 @@ IMPLEMENT(lcd128x64getScreenSize) { int x, y; ::lcd128x64getScreenSize(&x, &y); - v8::Local res = v8::Array::New(2); - res->Set(0, v8::Int32::New(x)); - res->Set(1, v8::Int32::New(y)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Local res = v8::Array::New(isolate, 2); + res->Set(0, v8::Int32::New(isolate, x)); + res->Set(1, v8::Int32::New(isolate, y)); + #else + v8::Local res = v8::Array::New(2); + res->Set(0, v8::Int32::New(x)); + res->Set(1, v8::Int32::New(y)); + #endif SCOPE_CLOSE(res); } @@ -291,7 +303,11 @@ IMPLEMENT(lcd128x64puts) { int x = GET_ARGUMENT_AS_INT32(0); int y = GET_ARGUMENT_AS_INT32(1); - v8::String::AsciiValue string(GET_ARGUMENT_AS_STRING(2)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::String::Utf8Value string(GET_ARGUMENT_AS_STRING(2)); + #else + v8::String::AsciiValue string(GET_ARGUMENT_AS_STRING(2)); + #endif int bgColor = GET_ARGUMENT_AS_INT32(3); int fgColor = GET_ARGUMENT_AS_INT32(4); diff --git a/src/devlib/maxdetect.cc b/src/devlib/maxdetect.cc index 75b674c..e921d46 100644 --- a/src/devlib/maxdetect.cc +++ b/src/devlib/maxdetect.cc @@ -18,13 +18,26 @@ IMPLEMENT(maxDetectRead) { unsigned char buffer[4]; int res = ::maxDetectRead(pin, buffer); - v8::Local data = v8::Array::New(4); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Local data = v8::Array::New(isolate, 4); + #else + v8::Local data = v8::Array::New(4); + #endif for (int i = 0; i < 4; i++) { - data->Set(i, Int32::New(buffer[i])); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + data->Set(i, Int32::New(isolate, buffer[i])); + #else + data->Set(i, Int32::New(buffer[i])); + #endif } - v8::Local ret = v8::Array::New(2); - ret->Set(0, Int32::New(res)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Local ret = v8::Array::New(isolate, 2); + ret->Set(0, Int32::New(isolate, res)); + #else + v8::Local ret = v8::Array::New(2); + ret->Set(0, Int32::New(res)); + #endif ret->Set(1, data); SCOPE_CLOSE(ret); @@ -44,10 +57,17 @@ IMPLEMENT(readRHT03) { int temp, rh; int res = ::readRHT03(pin, &temp, &rh); - v8::Local ret = v8::Array::New(3); - ret->Set(0, v8::Int32::New(res)); - ret->Set(1, v8::Int32::New(temp)); - ret->Set(2, v8::Int32::New(rh)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Local ret = v8::Array::New(isolate, 3); + ret->Set(0, v8::Int32::New(isolate, res)); + ret->Set(1, v8::Int32::New(isolate, temp)); + ret->Set(2, v8::Int32::New(isolate, rh)); + #else + v8::Local ret = v8::Array::New(3); + ret->Set(0, v8::Int32::New(res)); + ret->Set(1, v8::Int32::New(temp)); + ret->Set(2, v8::Int32::New(rh)); + #endif SCOPE_CLOSE(ret); } diff --git a/src/devlib/tcs34725.cc b/src/devlib/tcs34725.cc index d25026d..b07b27a 100644 --- a/src/devlib/tcs34725.cc +++ b/src/devlib/tcs34725.cc @@ -26,11 +26,19 @@ IMPLEMENT(tcs34725ReadRGBC) { ::tcs34725ReadRGBC(id, &r, &g, &b, &c); - Local obj = Object::New(); - obj->Set(String::NewSymbol("r"), UINT32(r)); - obj->Set(String::NewSymbol("g"), UINT32(g)); - obj->Set(String::NewSymbol("b"), UINT32(b)); - obj->Set(String::NewSymbol("c"), UINT32(c)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "r", v8::String::kInternalizedString), UINT32(r)); + obj->Set(String::NewFromUtf8(isolate, "g", v8::String::kInternalizedString), UINT32(g)); + obj->Set(String::NewFromUtf8(isolate, "b", v8::String::kInternalizedString), UINT32(b)); + obj->Set(String::NewFromUtf8(isolate, "c", v8::String::kInternalizedString), UINT32(c)); + #else + Local obj = Object::New(); + obj->Set(String::NewSymbol("r"), UINT32(r)); + obj->Set(String::NewSymbol("g"), UINT32(g)); + obj->Set(String::NewSymbol("b"), UINT32(b)); + obj->Set(String::NewSymbol("c"), UINT32(c)); + #endif SCOPE_CLOSE(obj); } @@ -50,10 +58,17 @@ IMPLEMENT(tcs34725ReadHSV) { ::tcs34725ReadHSV(id, &h, &s, &v); - Local obj = Object::New(); - obj->Set(String::NewSymbol("h"), UINT32(h)); - obj->Set(String::NewSymbol("s"), UINT32(s)); - obj->Set(String::NewSymbol("v"), UINT32(v)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "h", v8::String::kInternalizedString), UINT32(h)); + obj->Set(String::NewFromUtf8(isolate, "s", v8::String::kInternalizedString), UINT32(s)); + obj->Set(String::NewFromUtf8(isolate, "v", v8::String::kInternalizedString), UINT32(v)); + #else + Local obj = Object::New(); + obj->Set(String::NewSymbol("h"), UINT32(h)); + obj->Set(String::NewSymbol("s"), UINT32(s)); + obj->Set(String::NewSymbol("v"), UINT32(v)); + #endif SCOPE_CLOSE(obj); } diff --git a/src/extensions/drcSerial.cc b/src/extensions/drcSerial.cc index 1a7bf1a..b2729a4 100644 --- a/src/extensions/drcSerial.cc +++ b/src/extensions/drcSerial.cc @@ -24,7 +24,11 @@ IMPLEMENT(drcSetupSerial) { int pinBase = GET_ARGUMENT_AS_INT32(0); int numPins = GET_ARGUMENT_AS_INT32(1); - String::AsciiValue device(GET_ARGUMENT_AS_STRING(2)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + String::Utf8Value device(GET_ARGUMENT_AS_STRING(2)); + #else + String::AsciiValue device(GET_ARGUMENT_AS_STRING(2)); + #endif int baudrate = GET_ARGUMENT_AS_INT32(3); int res = ::drcSetupSerial(pinBase, numPins, *device, baudrate); diff --git a/src/extensions/extensions.cc b/src/extensions/extensions.cc index 2f3002e..e1bf51e 100644 --- a/src/extensions/extensions.cc +++ b/src/extensions/extensions.cc @@ -1,5 +1,6 @@ #include "extensions.h" +#include "dac7678.h" #include "drcSerial.h" #include "max5322.h" #include "max31855.h" @@ -19,6 +20,7 @@ #include "pca9685.h" IMPLEMENT_EXPORT_INIT(extensions) { + INIT(dac7678); INIT(drcSerial); INIT(max5322); INIT(max31855); @@ -35,4 +37,4 @@ IMPLEMENT_EXPORT_INIT(extensions) { INIT(pcf8591); INIT(sr595); INIT(pca9685); -} \ No newline at end of file +} diff --git a/src/wiringPi.cc b/src/wiringPi.cc index 6f862f5..e7f55be 100644 --- a/src/wiringPi.cc +++ b/src/wiringPi.cc @@ -41,17 +41,21 @@ DECLARE(gpioClockSet); IMPLEMENT(setup) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, mode); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_STRING(0); - - String::AsciiValue mode(GET_ARGUMENT_AS_STRING(0)); - + + #if NODE_VERSION_AT_LEAST(0, 11, 0) + String::Utf8Value mode(GET_ARGUMENT_AS_STRING(0)); + #else + String::AsciiValue mode(GET_ARGUMENT_AS_STRING(0)); + #endif + CHECK_ARGUMENT_IN_STRINGS(0, mode, ("wpi", "gpio", "sys", "phys")); - + int res = 0; if (!strcasecmp(*mode, "wpi")) { res = ::wiringPiSetup(); @@ -65,10 +69,10 @@ IMPLEMENT(setup) { else if (!strcasecmp(*mode, "phys")) { res = ::wiringPiSetupPhys(); } - + // libWiringPi v2 setup functions always returns 0, so this check is kind of useless, unless v1 behaviour is restored - // NOTE: If you want to restore the v1 behaviour, then you need to set the - // environment variable: WIRINGPI_CODES (to any value, it just needs to exist) + // NOTE: If you want to restore the v1 behaviour, then you need to set the + // environment variable: WIRINGPI_CODES (to any value, it just needs to exist) SCOPE_CLOSE(INT32(res)); } @@ -76,7 +80,7 @@ IMPLEMENT(setup) { // Returns : error code if v1 mode otherwise always returns 0 // Description : Initialises wiringPi and assumes that the calling program is going // to be using the wiringPi pin numbering scheme. -// This is a simplified numbering scheme which provides a mapping from virtual +// This is a simplified numbering scheme which provides a mapping from virtual // pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. // see the pins page (https://projects.drogon.net/raspberry-pi/wiringpi/pins/) for a table // which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location @@ -85,11 +89,11 @@ IMPLEMENT(setup) { IMPLEMENT(wiringPiSetup) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + int res = ::wiringPiSetup(); - + SCOPE_CLOSE(INT32(res)); } @@ -102,11 +106,11 @@ IMPLEMENT(wiringPiSetup) { IMPLEMENT(wiringPiSetupGpio) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + int res = ::wiringPiSetupGpio(); - + SCOPE_CLOSE(INT32(res)); } @@ -126,27 +130,27 @@ IMPLEMENT(wiringPiSetupGpio) { IMPLEMENT(wiringPiSetupSys) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + int res = ::wiringPiSetupSys(); - + SCOPE_CLOSE(INT32(res)); } // Func : int wiringPiSetupPhys(void) // Returns : error code if v1 mode otherwise always returns 0 -// Description : Identical to above, however it allows the calling programs to use +// Description : Identical to above, however it allows the calling programs to use // the physical pin numbers on the P1 connector only. // As above, this function needs to be called with root priviliges. IMPLEMENT(wiringPiSetupPhys) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + int res = ::wiringPiSetupPhys(); - + SCOPE_CLOSE(INT32(res)); } @@ -156,22 +160,22 @@ IMPLEMENT(wiringPiSetupPhys) { IMPLEMENT(pinModeAlt) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, mode); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int mode = GET_ARGUMENT_AS_INT32(1); - + CHECK_ARGUMENT_IN_INTS(1, mode, (WPI_MODE_PINS, WPI_MODE_PHYS, WPI_MODE_GPIO)); - + ::pinModeAlt(pin, mode); - + SCOPE_CLOSE(UNDEFINED()); } @@ -184,22 +188,22 @@ IMPLEMENT(pinModeAlt) { IMPLEMENT(pinMode) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, mode); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int mode = GET_ARGUMENT_AS_INT32(1); - + CHECK_ARGUMENT_IN_INTS(1, mode, (INPUT, OUTPUT, PWM_OUTPUT, GPIO_CLOCK, SOFT_PWM_OUTPUT, SOFT_TONE_OUTPUT)); - + ::pinMode(pin, mode); - + SCOPE_CLOSE(UNDEFINED()); } @@ -211,22 +215,22 @@ IMPLEMENT(pinMode) { IMPLEMENT(pullUpDnControl) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, pud); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int pud = GET_ARGUMENT_AS_INT32(1); - + CHECK_ARGUMENT_IN_INTS(1, pud, (PUD_OFF, PUD_DOWN, PUD_UP)); - + ::pullUpDnControl(pin, pud); - + SCOPE_CLOSE(UNDEFINED()); } @@ -236,21 +240,21 @@ IMPLEMENT(pullUpDnControl) { IMPLEMENT(digitalRead) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int pin = GET_ARGUMENT_AS_INT32(0); int res = ::digitalRead(pin); - + // Make sure the function returns strictly 1 or 0 // §4.7/4 from the C++ Standard says (Integral Conversion) // If the source type is bool, the value false is converted to zero and the value true is converted to one. res = (res != 0); - + SCOPE_CLOSE(INT32(res)); } @@ -261,22 +265,22 @@ IMPLEMENT(digitalRead) { IMPLEMENT(digitalWrite) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, state); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int state = GET_ARGUMENT_AS_INT32(1); - + CHECK_ARGUMENT_IN_INTS(1, state, (HIGH, LOW)); - + ::digitalWrite(pin, state); - + SCOPE_CLOSE(UNDEFINED()); } @@ -288,35 +292,35 @@ IMPLEMENT(digitalWrite) { IMPLEMENT(pwmWrite) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, value); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int value = GET_ARGUMENT_AS_INT32(1); - + ::pwmWrite(pin, value); - + SCOPE_CLOSE(UNDEFINED()); } IMPLEMENT(analogRead) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int pin = GET_ARGUMENT_AS_INT32(0); int res = ::analogRead(pin); - + SCOPE_CLOSE(INT32(res)); } @@ -326,93 +330,93 @@ IMPLEMENT(analogRead) { IMPLEMENT(analogWrite) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, value); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int value = GET_ARGUMENT_AS_INT32(1); - + ::analogWrite(pin, value); - + SCOPE_CLOSE(UNDEFINED()); } IMPLEMENT(pulseIn) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, state); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int state = GET_ARGUMENT_AS_INT32(1); - + CHECK_ARGUMENT_IN_INTS(1, state, (HIGH, LOW)); - + int us = ::pulseIn(pin, state); - + SCOPE_CLOSE(INT32(us)); } IMPLEMENT(delay) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, ms); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int ms = GET_ARGUMENT_AS_INT32(0); - + ::delay(ms); - + SCOPE_CLOSE(UNDEFINED()); } IMPLEMENT(delayMicroseconds) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, us); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int us = GET_ARGUMENT_AS_INT32(0); - + ::delayMicroseconds(us); - + SCOPE_CLOSE(UNDEFINED()); } IMPLEMENT(millis) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + unsigned int ms = ::millis(); - + SCOPE_CLOSE(UINT32(ms)); } IMPLEMENT(micros) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + unsigned int us = ::micros(); - + SCOPE_CLOSE(UINT32(us)); } @@ -425,33 +429,42 @@ IMPLEMENT(micros) { IMPLEMENT(piBoardRev) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + int res = ::piBoardRev(); - + SCOPE_CLOSE(INT32(res)); } IMPLEMENT(piBoardId) { SCOPE_OPEN(); - + CHECK_ARGUMENTS_LENGTH_EQUAL(0); - + // libWiringPi 2.20 changes: // maker is now a int indexing makerNames string tables // a fifth arguments was added named overvolted int model, rev, mem, marker, overvolted; - + ::piBoardId(&model, &rev, &mem, &marker, &overvolted); - - Local obj = Object::New(); - obj->Set(String::NewSymbol("model"), INT32(model)); - obj->Set(String::NewSymbol("rev"), INT32(rev)); - obj->Set(String::NewSymbol("mem"), INT32(mem)); - obj->Set(String::NewSymbol("marker"), INT32(marker)); - obj->Set(String::NewSymbol("overvolted"), INT32(overvolted)); - + + #if NODE_VERSION_AT_LEAST(0, 11, 0) + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "model", v8::String::kInternalizedString), INT32(model)); + obj->Set(String::NewFromUtf8(isolate, "rev", v8::String::kInternalizedString), INT32(rev)); + obj->Set(String::NewFromUtf8(isolate, "mem", v8::String::kInternalizedString), INT32(mem)); + obj->Set(String::NewFromUtf8(isolate, "marker", v8::String::kInternalizedString), INT32(marker)); + obj->Set(String::NewFromUtf8(isolate, "overvolted", v8::String::kInternalizedString), INT32(overvolted)); + #else + Local obj = Object::New(); + obj->Set(String::NewSymbol("model"), INT32(model)); + obj->Set(String::NewSymbol("rev"), INT32(rev)); + obj->Set(String::NewSymbol("mem"), INT32(mem)); + obj->Set(String::NewSymbol("marker"), INT32(marker)); + obj->Set(String::NewSymbol("overvolted"), INT32(overvolted)); + #endif + SCOPE_CLOSE(obj); } @@ -461,16 +474,16 @@ IMPLEMENT(piBoardId) { IMPLEMENT(wpiPinToGpio) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int pin = GET_ARGUMENT_AS_INT32(0); int res = ::wpiPinToGpio(pin); - + SCOPE_CLOSE(INT32(res)); } @@ -479,16 +492,16 @@ IMPLEMENT(wpiPinToGpio) { IMPLEMENT(physPinToGpio) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int pin = GET_ARGUMENT_AS_INT32(0); int res = ::physPinToGpio(pin); - + SCOPE_CLOSE(INT32(res)); } @@ -499,20 +512,20 @@ IMPLEMENT(physPinToGpio) { IMPLEMENT(setPadDrive) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, group); SET_ARGUMENT_NAME(1, value); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int group = GET_ARGUMENT_AS_INT32(0); int value = GET_ARGUMENT_AS_INT32(1); - + ::setPadDrive(group, value); - + SCOPE_CLOSE(UNDEFINED()); } @@ -522,118 +535,118 @@ IMPLEMENT(setPadDrive) { IMPLEMENT(getAlt) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int pin = GET_ARGUMENT_AS_INT32(0); int res = ::getAlt(pin); - + SCOPE_CLOSE(INT32(res)); } IMPLEMENT(pwmToneWrite) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, frequency); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int frequency = GET_ARGUMENT_AS_INT32(1); - + ::pwmToneWrite(pin, frequency); - + SCOPE_CLOSE(UNDEFINED()); } // Func : void digitalWriteByte(int value) -// Description : This writes the 8-bit byte supplied to the first 8 GPIO pins. -// It’s the fastest way to set all 8 bits at once to a particular value, although it still takes +// Description : This writes the 8-bit byte supplied to the first 8 GPIO pins. +// It’s the fastest way to set all 8 bits at once to a particular value, although it still takes // two write operations to the Pi’s GPIO hardware. IMPLEMENT(digitalWriteByte) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, byte); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int byte = GET_ARGUMENT_AS_INT32(0); ::digitalWriteByte(byte); - + SCOPE_CLOSE(UNDEFINED()); } // Func : void pwmSetMode(int mode) -// Description : The PWM generator can run in 2 modes – “balanced” and “mark:space”. -// The mark:space mode is traditional, however the default mode in the Pi is “balanced”. +// Description : The PWM generator can run in 2 modes – “balanced” and “mark:space”. +// The mark:space mode is traditional, however the default mode in the Pi is “balanced”. // You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS. IMPLEMENT(pwmSetMode) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, mode); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int mode = GET_ARGUMENT_AS_INT32(0); - + CHECK_ARGUMENT_IN_INTS(0, mode, (PWM_MODE_BAL, PWM_MODE_MS)); - + ::pwmSetMode(mode); - + SCOPE_CLOSE(UNDEFINED()); } // Func : void pwmSetRange(unsigned int range) // Description : This sets the range register in the PWM generator. The default is 1024. -// Note: The PWM control functions can not be used when in Sys mode. To understand more about +// Note: The PWM control functions can not be used when in Sys mode. To understand more about // the PWM system, you’ll need to read the Broadcom ARM peripherals manual. IMPLEMENT(pwmSetRange) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, range); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_UINT32(0); - + unsigned int range = GET_ARGUMENT_AS_UINT32(0); ::pwmSetRange(range); - + SCOPE_CLOSE(UNDEFINED()); } // Func : void pwmSetClock(int divisor) // Description : This sets the divisor for the PWM clock. -// Note: The PWM control functions can not be used when in Sys mode. To understand more about +// Note: The PWM control functions can not be used when in Sys mode. To understand more about // the PWM system, you’ll need to read the Broadcom ARM peripherals manual. IMPLEMENT(pwmSetClock) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, divisor); - + CHECK_ARGUMENTS_LENGTH_EQUAL(1); - + CHECK_ARGUMENT_TYPE_INT32(0); - + int divisor = GET_ARGUMENT_AS_INT32(0); ::pwmSetClock(divisor); - + SCOPE_CLOSE(UNDEFINED()); } @@ -642,20 +655,20 @@ IMPLEMENT(pwmSetClock) { IMPLEMENT(gpioClockSet) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, frequency); - + CHECK_ARGUMENTS_LENGTH_EQUAL(2); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); - + int pin = GET_ARGUMENT_AS_INT32(0); int frequency = GET_ARGUMENT_AS_INT32(1); - + ::gpioClockSet(pin, frequency); - + SCOPE_CLOSE(UNDEFINED()); } @@ -666,7 +679,7 @@ IMPLEMENT_EXPORT_INIT(wiringPi) { EXPORT_FUNCTION(wiringPiSetupGpio); EXPORT_FUNCTION(wiringPiSetupSys); EXPORT_FUNCTION(wiringPiSetupPhys); - + // Core functions EXPORT_FUNCTION(pinModeAlt); EXPORT_FUNCTION(pinMode); @@ -677,12 +690,12 @@ IMPLEMENT_EXPORT_INIT(wiringPi) { EXPORT_FUNCTION(analogRead); EXPORT_FUNCTION(analogWrite); EXPORT_FUNCTION(pulseIn); - + EXPORT_FUNCTION(delay); EXPORT_FUNCTION(delayMicroseconds); EXPORT_FUNCTION(millis); EXPORT_FUNCTION(micros); - + // On-Board Rasberry Pi hardware specific stuff EXPORT_FUNCTION(piBoardRev); EXPORT_FUNCTION(piBoardId); @@ -696,12 +709,12 @@ IMPLEMENT_EXPORT_INIT(wiringPi) { EXPORT_FUNCTION(pwmSetRange); EXPORT_FUNCTION(pwmSetClock); EXPORT_FUNCTION(gpioClockSet); - + // pinModeAlt EXPORT_CONSTANT_INT(WPI_MODE_PINS); EXPORT_CONSTANT_INT(WPI_MODE_PHYS); EXPORT_CONSTANT_INT(WPI_MODE_GPIO); - + // pinMode EXPORT_CONSTANT_INT(INPUT); EXPORT_CONSTANT_INT(OUTPUT); @@ -709,39 +722,50 @@ IMPLEMENT_EXPORT_INIT(wiringPi) { EXPORT_CONSTANT_INT(GPIO_CLOCK); EXPORT_CONSTANT_INT(SOFT_PWM_OUTPUT); EXPORT_CONSTANT_INT(SOFT_TONE_OUTPUT); - + // pullUpDnControl EXPORT_CONSTANT_INT(PUD_OFF); EXPORT_CONSTANT_INT(PUD_DOWN); EXPORT_CONSTANT_INT(PUD_UP); - + // digitalRead/Write EXPORT_CONSTANT_INT(HIGH); EXPORT_CONSTANT_INT(LOW); - + // pwmSetMode EXPORT_CONSTANT_INT(PWM_MODE_BAL); EXPORT_CONSTANT_INT(PWM_MODE_MS); - + EXPORT_CONSTANT_INT(PI_MODEL_UNKNOWN); EXPORT_CONSTANT_INT(PI_MODEL_A); EXPORT_CONSTANT_INT(PI_MODEL_B); EXPORT_CONSTANT_INT(PI_MODEL_BP); EXPORT_CONSTANT_INT(PI_MODEL_CM); - + EXPORT_CONSTANT_INT(PI_MODEL_AP); + EXPORT_CONSTANT_INT(PI_MODEL_2); + EXPORT_CONSTANT_INT(PI_VERSION_UNKNOWN); EXPORT_CONSTANT_INT(PI_VERSION_1); EXPORT_CONSTANT_INT(PI_VERSION_1_1); EXPORT_CONSTANT_INT(PI_VERSION_1_2); EXPORT_CONSTANT_INT(PI_VERSION_2); - + EXPORT_CONSTANT_INT(PI_MAKER_UNKNOWN); EXPORT_CONSTANT_INT(PI_MAKER_EGOMAN); EXPORT_CONSTANT_INT(PI_MAKER_SONY); EXPORT_CONSTANT_INT(PI_MAKER_QISDA); - - EXPORT_CONSTANT_STRING_ARRAY(PI_MODEL_NAMES, piModelNames, 5); + EXPORT_CONSTANT_INT(PI_MAKER_MBEST); + + EXPORT_CONSTANT_STRING_ARRAY(PI_MODEL_NAMES, piModelNames, 7); EXPORT_CONSTANT_STRING_ARRAY(PI_REVISION_NAMES, piRevisionNames, 5); - EXPORT_CONSTANT_STRING_ARRAY(PI_MAKER_NAMES, piMakerNames, 4); + EXPORT_CONSTANT_STRING_ARRAY(PI_MAKER_NAMES, piMakerNames, 5); + + EXPORT_CONSTANT_INT(FSEL_INPT); + EXPORT_CONSTANT_INT(FSEL_OUTP); + EXPORT_CONSTANT_INT(FSEL_ALT0); + EXPORT_CONSTANT_INT(FSEL_ALT1); + EXPORT_CONSTANT_INT(FSEL_ALT2); + EXPORT_CONSTANT_INT(FSEL_ALT3); + EXPORT_CONSTANT_INT(FSEL_ALT4); + EXPORT_CONSTANT_INT(FSEL_ALT5); } - diff --git a/src/wiringPi.h b/src/wiringPi.h index f6cde55..03bfb54 100644 --- a/src/wiringPi.h +++ b/src/wiringPi.h @@ -2,7 +2,16 @@ #define _WPI_WIRING_PI_H_ #include "addon.h" - + + #define FSEL_INPT 0b000 + #define FSEL_OUTP 0b001 + #define FSEL_ALT0 0b100 + #define FSEL_ALT1 0b101 + #define FSEL_ALT2 0b110 + #define FSEL_ALT3 0b111 + #define FSEL_ALT4 0b011 + #define FSEL_ALT5 0b010 + DECLARE_EXPORT_INIT(wiringPi); -#endif \ No newline at end of file +#endif diff --git a/src/wiringPiI2C.cc b/src/wiringPiI2C.cc index 38203be..3172e58 100644 --- a/src/wiringPiI2C.cc +++ b/src/wiringPiI2C.cc @@ -158,7 +158,11 @@ IMPLEMENT(wiringPiI2CSetupInterface) { CHECK_ARGUMENT_TYPE_STRING(0); CHECK_ARGUMENT_TYPE_INT32(1); - String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + String::Utf8Value device(GET_ARGUMENT_AS_STRING(0)); + #else + String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + #endif int devId = GET_ARGUMENT_AS_INT32(1); int res = ::wiringPiI2CSetupInterface(*device, devId); diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc index 710bee2..e4c0512 100644 --- a/src/wiringPiISR.cc +++ b/src/wiringPiISR.cc @@ -1,62 +1,71 @@ #include "wiringPiISR.h" #include -#include -#include #include using namespace v8; -typedef struct js_work_t { - uv_work_t req; - int pin; - unsigned int delta; -} js_work_t; +typedef struct interrupt_t { + int pin; + unsigned int delta; + unsigned long int previous_timestamp; +} interrupt_t; +#if NODE_VERSION_AT_LEAST(0, 11, 0) + typedef v8::Persistent > CopyablePersistentFunction; +#else + typedef v8::Persistent CopyablePersistentFunction; +#endif typedef void (*NATIVE_INTERRUPT_HANDLER_T)(void); -static NATIVE_INTERRUPT_HANDLER_T nativeInterruptHandlers[64]; -static unsigned long int lastInterruptMicroseconds[64]; -static std::map > interruptCallbackMapping; +static uv_async_t async_handlers[64]; +static interrupt_t interrupt_data[64]; +static NATIVE_INTERRUPT_HANDLER_T interrupt_handlers[64]; +static CopyablePersistentFunction interrupt_callbacks[64]; #define DEFINE_NATIVE_INTERRUPT_HANDLER(pin) \ static void nativeInterruptHandler##pin(void) { \ processNativeInterrupt(pin); \ } - -#define REGISTER_NATIVE_INTERRUPT_HANDLER(pin) nativeInterruptHandlers[pin] = &nativeInterruptHandler##pin - -#define GET_NATIVE_INTERRUPT_HANDLER(pin) nativeInterruptHandlers[pin] - -static void processInterrupt(uv_work_t* req, int status) { - js_work_t* work = static_cast(req->data); - - Persistent callback = interruptCallbackMapping[work->pin]; - - Local argv[] = { - Local::New(Uint32::New(work->delta)) - }; - - callback->Call(Context::GetCurrent()->Global(), 1, argv); - - delete work; -} -static void UV_NOP(uv_work_t*) {} +#define REGISTER_NATIVE_INTERRUPT_HANDLER(pin) interrupt_handlers[pin] = &nativeInterruptHandler##pin void processNativeInterrupt(int pin) { unsigned int now = ::micros(); - - js_work_t* work = new js_work_t; - work->req.data = work; - work->pin = pin; - work->delta = now - lastInterruptMicroseconds[pin]; - - int r = uv_queue_work(uv_default_loop(), &work->req, &UV_NOP, &processInterrupt); - if (r != 0) { - delete work; - } - - lastInterruptMicroseconds[pin] = now; + + uv_async_t* handle = &async_handlers[pin]; + interrupt_t* data = &interrupt_data[pin]; + data->pin = pin; + data->delta = now - data->previous_timestamp; + handle->data = (void*)data; + + uv_async_send(handle); + + data->previous_timestamp = now; +} + +#if NODE_VERSION_AT_LEAST(0, 11, 0) +static void dispatchInterrupt(uv_async_t* handle) { +#else +static void dispatchInterrupt(uv_async_t* handle, int status) { +#endif + interrupt_t* data = (interrupt_t*)handle->data; + + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Local callback = v8::Local::New(isolate, interrupt_callbacks[data->pin]); + #else + v8::Local callback = v8::Local::New(interrupt_callbacks[data->pin]); + #endif + + Local argv[] = { + UINT32(data->delta) + }; + + #if NODE_VERSION_AT_LEAST(0, 11, 0) + callback->Call(isolate->GetCurrentContext()->Global(), 1, argv); + #else + callback->Call(Context::GetCurrent()->Global(), 1, argv); + #endif } DEFINE_NATIVE_INTERRUPT_HANDLER(0); @@ -127,28 +136,54 @@ DEFINE_NATIVE_INTERRUPT_HANDLER(63); DECLARE(wiringPiISR); IMPLEMENT(wiringPiISR) { SCOPE_OPEN(); - + SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, edgeType); SET_ARGUMENT_NAME(2, callback); - + CHECK_ARGUMENTS_LENGTH_EQUAL(3); - + CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); CHECK_ARGUMENT_TYPE_FUNCTION(2); - + int pin = GET_ARGUMENT_AS_INT32(0); int edgeType = GET_ARGUMENT_AS_INT32(1); - Persistent callback = GET_ARGUMENT_AS_PERSISTENT_FUNCTION(2); - + + #if NODE_VERSION_AT_LEAST(0, 11, 0) + Persistent callback(isolate, GET_ARGUMENT_AS_LOCAL_FUNCTION(2)); + #else + Persistent callback = GET_ARGUMENT_AS_PERSISTENT_FUNCTION(2); + #endif + CHECK_ARGUMENT_IN_INTS(1, edgeType, (INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH, INT_EDGE_SETUP)); - - interruptCallbackMapping.insert(std::pair >(pin, callback)); - lastInterruptMicroseconds[pin] = ::micros(); - - ::wiringPiISR(pin, edgeType, GET_NATIVE_INTERRUPT_HANDLER(pin)); - + + interrupt_callbacks[pin] = callback; + interrupt_data[pin].previous_timestamp = ::micros(); + + ::wiringPiISR(pin, edgeType, interrupt_handlers[pin]); + + uv_async_init(uv_default_loop(), &async_handlers[pin], &dispatchInterrupt); + uv_ref((uv_handle_t*)&async_handlers[pin]); + + SCOPE_CLOSE(UNDEFINED()); +} + +DECLARE(wiringPiISRCancel); +IMPLEMENT(wiringPiISRCancel) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + ::wiringPiISRCancel(pin); + uv_close((uv_handle_t*)&async_handlers[pin], NULL); + SCOPE_CLOSE(UNDEFINED()); } @@ -217,11 +252,12 @@ IMPLEMENT_EXPORT_INIT(wiringPiISR) { REGISTER_NATIVE_INTERRUPT_HANDLER(61); REGISTER_NATIVE_INTERRUPT_HANDLER(62); REGISTER_NATIVE_INTERRUPT_HANDLER(63); - + EXPORT_FUNCTION(wiringPiISR); - + EXPORT_FUNCTION(wiringPiISRCancel); + EXPORT_CONSTANT_INT(INT_EDGE_FALLING); EXPORT_CONSTANT_INT(INT_EDGE_RISING); EXPORT_CONSTANT_INT(INT_EDGE_BOTH); EXPORT_CONSTANT_INT(INT_EDGE_SETUP); -} \ No newline at end of file +} diff --git a/src/wiringPiSPI.cc b/src/wiringPiSPI.cc index a8210f6..c0a0ee5 100644 --- a/src/wiringPiSPI.cc +++ b/src/wiringPiSPI.cc @@ -4,6 +4,7 @@ DECLARE(wiringPiSPIGetFd); DECLARE(wiringPiSPIDataRW); DECLARE(wiringPiSPISetup); +DECLARE(wiringPiSPISetupMode); // Func : int wiringPiSPIGetFd(int channel) @@ -63,7 +64,7 @@ IMPLEMENT(wiringPiSPISetup) { CHECK_ARGUMENT_TYPE_INT32(1); int channel = GET_ARGUMENT_AS_INT32(0); - int speed = GET_ARGUMENT_AS_INT32(0); + int speed = GET_ARGUMENT_AS_INT32(1); CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); @@ -72,8 +73,34 @@ IMPLEMENT(wiringPiSPISetup) { SCOPE_CLOSE(INT32(res)); } +IMPLEMENT(wiringPiSPISetupMode) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, channel); + SET_ARGUMENT_NAME(1, speed); + SET_ARGUMENT_NAME(2, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int channel = GET_ARGUMENT_AS_INT32(0); + int speed = GET_ARGUMENT_AS_INT32(1); + int mode = GET_ARGUMENT_AS_INT32(2); + + CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); + CHECK_ARGUMENT_IN_INTS(2, mode, (0, 1, 2, 3)); + + int res = ::wiringPiSPISetupMode(channel, speed, mode); + + SCOPE_CLOSE(INT32(res)); +} + IMPLEMENT_EXPORT_INIT(wiringPiSPI) { EXPORT_FUNCTION(wiringPiSPIGetFd); EXPORT_FUNCTION(wiringPiSPIDataRW); EXPORT_FUNCTION(wiringPiSPISetup); + EXPORT_FUNCTION(wiringPiSPISetupMode); } \ No newline at end of file diff --git a/src/wiringSerial.cc b/src/wiringSerial.cc index 55360f6..3fb621e 100644 --- a/src/wiringSerial.cc +++ b/src/wiringSerial.cc @@ -23,7 +23,11 @@ IMPLEMENT(serialOpen) { CHECK_ARGUMENT_TYPE_STRING(0); CHECK_ARGUMENT_TYPE_INT32(1); - String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + String::Utf8Value device(GET_ARGUMENT_AS_STRING(0)); + #else + String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + #endif int baudrate = GET_ARGUMENT_AS_INT32(1); int res = ::serialOpen(*device, baudrate); @@ -102,7 +106,11 @@ IMPLEMENT(serialPuts) { CHECK_ARGUMENT_TYPE_STRING(1); int fd = GET_ARGUMENT_AS_INT32(0); - String::AsciiValue string(GET_ARGUMENT_AS_STRING(1)); + #if NODE_VERSION_AT_LEAST(0, 11, 0) + String::Utf8Value string(GET_ARGUMENT_AS_STRING(1)); + #else + String::AsciiValue string(GET_ARGUMENT_AS_STRING(1)); + #endif ::serialPuts(fd, *string); diff --git a/src/wpi.cc b/src/wpi.cc index f04c705..4d718e9 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -2,6 +2,9 @@ #include NODE_MODULE_INIT() { + #if NODE_VERSION_AT_LEAST(0, 11, 0) + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + #endif INIT(wiringPi); INIT(softPwm); INIT(softServo);