ocoge/local_modules/@ocoge.club/pigpio/pigpio.cpp
2022-05-24 22:11:10 +09:00

682 lines
22 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** 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").Value());
}
else if (!info[0].IsString() || !info[1].IsString())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").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").Value());
}
else if (!info[0].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid aargument types").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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int gpio = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int gpio = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int gpio = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int user_gpio = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int user_gpio = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int user_gpio = info[1].As<Number>().Uint32Value();
unsigned int 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() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsString() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
std::string ser_tty = info[1].As<String>().Utf8Value();
unsigned int baud = info[2].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, serial_open(pi, (char *)ser_tty.c_str(), baud, 0)));
}
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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int 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();
}
// I2Cバスアドレスのデバイスのハンドルを返す
Promise _i2cOpen(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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int i2c_bus = info[1].As<Number>().Uint32Value();
unsigned int i2c_addr = info[2].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_open(pi, i2c_bus, i2c_addr, 0)));
}
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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[0].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_read_byte_data(pi, handle, i2c_reg)));
}
return deferred.Promise();
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに最大バイトのデータを書き込む。
Promise _i2cWriteI2cBlockData(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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsBuffer())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
auto buf = info[3].As<Buffer<char>>();
unsigned int count = buf.Length();
deferred.Resolve(Number::New(env, i2c_write_i2c_block_data(pi, handle, i2c_reg, buf.Data(), count)));
}
return deferred.Promise();
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタからcountバイトを読み込む。countは132。
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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2cReg = info[2].As<Number>().Uint32Value();
unsigned int 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ハンドルに関連付けられているデバイスの指定されたレジスタから単一の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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
unsigned int 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int 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() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
auto buf = info[2].As<Buffer<char>>();
unsigned int count = buf.Length();
deferred.Resolve(Number::New(env, i2c_write_device(pi, handle, buf.Data(), count)));
}
return deferred.Promise();
}
Object
Init(Env env, Object exports)
{
exports.Set(String::New(env, "_pigpio_start"), Function::New(env, _pigpioStart));
exports.Set(String::New(env, "_pigpio_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)