mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-25 08:59:49 +00:00
855 lines
28 KiB
C++
855 lines
28 KiB
C++
|
/** PIGPIO デーモンを Node.js から利用するモジュール ** */
|
|||
|
/** 関数名・書式は Python Interface に準拠 ******************* */
|
|||
|
|
|||
|
#include <napi.h>
|
|||
|
#include <pigpiod_if2.h>
|
|||
|
#include <unistd.h>
|
|||
|
#include <string>
|
|||
|
|
|||
|
using namespace Napi;
|
|||
|
|
|||
|
// pigpio デーモンに接続
|
|||
|
Promise _pigpioStart(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _pigpioStart").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsString() || !info[1].IsString())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _pigpioStart").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
std::string addrStr = info[0].As<String>().Utf8Value();
|
|||
|
std::string portStr = info[1].As<String>().Utf8Value();
|
|||
|
deferred.Resolve(Number::New(env, pigpio_start(addrStr.c_str(), portStr.c_str())));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
// pigpio デーモンとの接続を閉じる
|
|||
|
Promise _pigpioStop(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 1)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "IInvalid argument count: _pigpioStop").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid aargument types: _pigpioStop").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
pigpio_stop(pi);
|
|||
|
deferred.Resolve(env.Null());
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// GPIO 端子のモードを設定
|
|||
|
Promise _setMode(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _setMode").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _setMode").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned gpio = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned mode = info[2].As<Number>().Uint32Value();
|
|||
|
|
|||
|
deferred.Resolve(Number::New(env, set_mode(pi, gpio, mode)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// GPIOの内部プルアップ/ダウン抵抗の設定/クリア
|
|||
|
Promise _setPullUpDown(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _setPullUpDown").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _setPullUpDown").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned gpio = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned pud = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, set_pull_up_down(pi, gpio, pud)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// GPIOの電圧を読む
|
|||
|
Promise _gpioRead(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _gpioRead").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _gpioRead").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned gpio = info[1].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, gpio_read(pi, gpio)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// GPIO の電圧をセットする
|
|||
|
Promise _gpioWrite(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _gpioWrite").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _gpioWrite").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned gpio = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned value = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, gpio_write(pi, gpio, value)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// サーボパルス幅をセットする
|
|||
|
Promise _setServoPulsewidth(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _setServoPulsewidth").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _setServoPulsewidth").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned user_gpio = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned pulsewidth = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, set_servo_pulsewidth(pi, user_gpio, pulsewidth)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// PWM周波数を設定する
|
|||
|
Promise _setPwmFrequency(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _setPwmFrequency").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _setPwmFrequency").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned user_gpio = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned frequency = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, set_PWM_frequency(pi, user_gpio, frequency)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// PWMのデューティ比を指定して出力を開始する
|
|||
|
Promise _setPwmDutycycle(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _setPwmDutycycle").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _setPwmDutycycle").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned user_gpio = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned dutycycle = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, set_PWM_dutycycle(pi, user_gpio, dutycycle)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// シリアルポートを開く
|
|||
|
Promise _serialOpen(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _serialOpen").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsString() || !info[2].IsNumber() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _serialOpen").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
std::string ser_tty = info[1].As<String>().Utf8Value();
|
|||
|
unsigned baud = info[2].As<Number>().Uint32Value();
|
|||
|
unsigned ser_flags = info[3].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, serial_open(pi, (char *)ser_tty.c_str(), baud, ser_flags)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// シリアルポートを閉じる
|
|||
|
Promise _serialClose(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _serialClose").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _serialClose").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, serial_close(pi, handle)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// シリアルデバイスからデータを読む
|
|||
|
Promise _serialRead(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _serialRead").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _serialRead").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned count = info[2].As<Number>().Uint32Value();
|
|||
|
|
|||
|
char buf[count];
|
|||
|
int rxCount = serial_read(pi, handle, buf, count);
|
|||
|
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
|
|||
|
deferred.Resolve(outBuf);
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// シリアルデバイスにバイト列を書き込む(data: string)
|
|||
|
Promise _serialWrite(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _serialWrite").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _serialWrite").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
auto buf = info[2].As<Buffer<char>>();
|
|||
|
|
|||
|
int count = buf.Length();
|
|||
|
deferred.Resolve(Number::New(env, serial_write(pi, handle, buf.Data(), count)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// シリアルデバイスから読み出し可能なバイト数を返す
|
|||
|
Promise _serialDataAvailable(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _serialDataAvailable").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _serialDataAvailable").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, serial_data_available(pi, handle)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// I2Cバスアドレスのデバイスのハンドルを返す
|
|||
|
Promise _i2cOpen(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cOpen").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cOpen").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned i2c_bus = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_addr = info[2].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_flags = info[3].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, i2c_open(pi, i2c_bus, i2c_addr, i2c_flags)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
// オープン済みI2Cハンドルを閉じる
|
|||
|
Promise _i2cClose(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cClose").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cClose").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, i2c_close(pi, handle)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// デバイスに1バイトを送る
|
|||
|
Promise _i2cWriteByte(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cWriteByte").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cWriteByte").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned bVal = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, i2c_write_byte(pi, handle, bVal)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
// デバイスから1バイトを受け取る
|
|||
|
Promise _i2cReadByte(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cReadByte").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[0].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cReadByte").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, i2c_read_byte(pi, handle)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに1バイトを書き込む
|
|||
|
Promise _i2cWriteByteData(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cWriteByteData").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cWriteByteData").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_reg = info[2].As<Number>().Uint32Value();
|
|||
|
unsigned bVal = info[3].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, i2c_write_byte_data(pi, handle, i2c_reg, bVal)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから1バイトを読み込む
|
|||
|
Promise _i2cReadByteData(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cReadByteData").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cReadByteData").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_reg = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, i2c_read_byte_data(pi, handle, i2c_reg)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタからcountバイトを読み込む。countは1~32。
|
|||
|
Promise _i2cReadI2cBlockData(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cReadI2cBlockData").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cReadI2cBlockData").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2cReg = info[2].As<Number>().Uint32Value();
|
|||
|
unsigned count = info[3].As<Number>().Uint32Value();
|
|||
|
char buf[count];
|
|||
|
int rxCount = i2c_read_i2c_block_data(pi, handle, i2cReg, buf, count);
|
|||
|
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
|
|||
|
deferred.Resolve(outBuf);
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに最大32バイトのデータを書き込む。
|
|||
|
Promise _i2cWriteI2cBlockData(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 5)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cWriteI2cBlockData").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsBuffer() || !info[4].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cWriteI2cBlockData").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_reg = info[2].As<Number>().Uint32Value();
|
|||
|
auto buf = info[3].As<Buffer<char>>();
|
|||
|
unsigned count = info[4].As<Number>().Uint32Value();
|
|||
|
|
|||
|
// if (count < 0)
|
|||
|
// count = buf.Length();
|
|||
|
deferred.Resolve(Number::New(env, i2c_write_i2c_block_data(pi, handle, i2c_reg, buf.Data(), count)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから単一の16ビットワードを読み取る
|
|||
|
Promise _i2cReadWordData(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cReadWordData").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cReadWordData").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_reg = info[2].As<Number>().Uint32Value();
|
|||
|
deferred.Resolve(Number::New(env, i2c_read_word_data(pi, handle, i2c_reg)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに単一の16ビットワードを書き込む
|
|||
|
Promise _i2cWriteWordData(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cWriteWordData").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cWriteWordData").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_reg = info[2].As<Number>().Uint32Value();
|
|||
|
unsigned wVal = info[3].As<Number>().Uint32Value();
|
|||
|
|
|||
|
deferred.Resolve(Number::New(env, i2c_write_word_data(pi, handle, i2c_reg, wVal)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// i2c デバイスからデータを受け取る
|
|||
|
Promise _i2cReadDevice(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 3)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cReadDevice").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cReadDevice").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned count = info[2].As<Number>().Uint32Value();
|
|||
|
|
|||
|
char buf[count];
|
|||
|
int rxCount = i2c_read_device(pi, handle, buf, count);
|
|||
|
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
|
|||
|
deferred.Resolve(outBuf);
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
// i2c デバイスにバイト列を送る(data: buffer)
|
|||
|
Promise _i2cWriteDevice(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
auto deferred = Napi::Promise::Deferred::New(env);
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cWriteDevice").Value());
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
deferred.Reject(
|
|||
|
Napi::TypeError::New(env, "Invalid argument types: _i2cWriteDevice").Value());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
auto buf = info[2].As<Buffer<char>>();
|
|||
|
unsigned count = info[3].As<Number>().Uint32Value();
|
|||
|
|
|||
|
// if (count < 0)
|
|||
|
// count = buf.Length();
|
|||
|
deferred.Resolve(Number::New(env, i2c_write_device(pi, handle, buf.Data(), count)));
|
|||
|
}
|
|||
|
return deferred.Promise();
|
|||
|
}
|
|||
|
|
|||
|
/******** 同期処理関数 ********/
|
|||
|
// pigpio デーモンに接続
|
|||
|
Value _pigpiodStartSync(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument count: _pigpioStartSync")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else if (!info[0].IsString() || !info[1].IsString())
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument types: _pigpioStartSync").ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
std::string ipaddr = info[0].As<String>().Utf8Value();
|
|||
|
std::string port = info[1].As<String>().Utf8Value();
|
|||
|
return Number::New(env, pigpio_start(addrStr.c_str(), portStr.c_str()));
|
|||
|
}
|
|||
|
}
|
|||
|
// pigpio デーモンとの接続を閉じる
|
|||
|
Value _pigpioStopSync(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
if (info.Length() != 1)
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument count: _pigpioStopSync")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber())
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument types: _pigpioStop")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int sbc = info[0].As<Number>().Int32Value();
|
|||
|
pigpio_stop(pi);
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
}
|
|||
|
// I2Cバスアドレスのデバイスのハンドルを返す
|
|||
|
Value _i2cOpenSync(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cOpen")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument types: _i2cOpen")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned i2c_bus = info[1].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_addr = info[2].As<Number>().Uint32Value();
|
|||
|
unsigned i2c_flags = info[3].As<Number>().Uint32Value();
|
|||
|
return Number::New(env, i2c_open(pi, i2c_bus, i2c_addr, i2c_flags));
|
|||
|
}
|
|||
|
}
|
|||
|
// オープン済みI2Cハンドルを閉じる
|
|||
|
Value _i2cCloseSync(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cClose")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument types: _i2cClose")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
return Number::New(env, i2c_close(pi, handle));
|
|||
|
}
|
|||
|
}
|
|||
|
// デバイスから1バイトを受け取る
|
|||
|
Value _i2cReadByteSync(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
if (info.Length() != 2)
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cReadByteSync")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[0].IsNumber())
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument types: _i2cReadByteSync")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
return Number::New(env, i2c_read_byte(pi, handle));
|
|||
|
}
|
|||
|
}
|
|||
|
// i2c デバイスにバイト列を送る(data: buffer)
|
|||
|
Value _i2cWriteDeviceSync(const CallbackInfo &info)
|
|||
|
{
|
|||
|
Env env = info.Env();
|
|||
|
if (info.Length() != 4)
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument count: _i2cWriteDevice")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer() || !info[3].IsNumber())
|
|||
|
{
|
|||
|
TypeError::New(env, "Invalid argument types: _i2cWriteDevice")
|
|||
|
.ThrowAsJavaScriptException();
|
|||
|
return env.Null();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int pi = info[0].As<Number>().Int32Value();
|
|||
|
unsigned handle = info[1].As<Number>().Uint32Value();
|
|||
|
auto buf = info[2].As<Buffer<char>>();
|
|||
|
unsigned count = info[3].As<Number>().Uint32Value();
|
|||
|
|
|||
|
return Number::New(env, i2c_write_device(pi, handle, buf.Data(), count));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Object
|
|||
|
Init(Env env, Object exports)
|
|||
|
{
|
|||
|
exports.Set(String::New(env, "_gpiod_start"), Function::New(env, _pigpioStart));
|
|||
|
exports.Set(String::New(env, "_gpiod_stop"), Function::New(env, _pigpioStop));
|
|||
|
exports.Set(String::New(env, "_set_mode"), Function::New(env, _setMode));
|
|||
|
exports.Set(String::New(env, "_set_pull_up_down"), Function::New(env, _setPullUpDown));
|
|||
|
exports.Set(String::New(env, "_gpio_read"), Function::New(env, _gpioRead));
|
|||
|
exports.Set(String::New(env, "_gpio_write"), Function::New(env, _gpioWrite));
|
|||
|
exports.Set(String::New(env, "_set_servo_pulsewidth"), Function::New(env, _setServoPulsewidth));
|
|||
|
exports.Set(String::New(env, "_set_PWM_frequency"), Function::New(env, _setPwmFrequency));
|
|||
|
exports.Set(String::New(env, "_set_PWM_dutycycle"), Function::New(env, _setPwmDutycycle));
|
|||
|
exports.Set(String::New(env, "_serial_open"), Function::New(env, _serialOpen));
|
|||
|
exports.Set(String::New(env, "_serial_close"), Function::New(env, _serialClose));
|
|||
|
exports.Set(String::New(env, "_serial_read"), Function::New(env, _serialRead));
|
|||
|
exports.Set(String::New(env, "_serial_write"), Function::New(env, _serialWrite));
|
|||
|
exports.Set(String::New(env, "_i2c_open"), Function::New(env, _i2cOpen));
|
|||
|
exports.Set(String::New(env, "_i2c_close"), Function::New(env, _i2cClose));
|
|||
|
exports.Set(String::New(env, "_i2c_write_byte"), Function::New(env, _i2cWriteByte));
|
|||
|
exports.Set(String::New(env, "_i2c_read_byte"), Function::New(env, _i2cReadByte));
|
|||
|
exports.Set(String::New(env, "_i2c_write_byte_data"), Function::New(env, _i2cWriteByteData));
|
|||
|
exports.Set(String::New(env, "_i2c_read_byte_data"), Function::New(env, _i2cReadByteData));
|
|||
|
exports.Set(String::New(env, "_i2c_write_i2c_block_data"), Function::New(env, _i2cWriteI2cBlockData));
|
|||
|
exports.Set(String::New(env, "_i2c_read_i2c_block_data"), Function::New(env, _i2cReadI2cBlockData));
|
|||
|
exports.Set(String::New(env, "_i2c_read_word_data"), Function::New(env, _i2cReadWordData));
|
|||
|
exports.Set(String::New(env, "_i2c_write_word_data"), Function::New(env, _i2cWriteWordData));
|
|||
|
exports.Set(String::New(env, "_i2c_write_device"), Function::New(env, _i2cWriteDevice));
|
|||
|
exports.Set(String::New(env, "_i2c_read_device"), Function::New(env, _i2cReadDevice));
|
|||
|
return exports;
|
|||
|
}
|
|||
|
|
|||
|
NODE_API_MODULE(pigpio, Init)
|