ocoge/local_modules/rgpio/rgpio.cpp

605 lines
19 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.

/** lgpio を Node.js から利用するモジュール ** */
/** 関数名・書式は lgpio Python に準拠 ******************* */
#include <napi.h>
#include <rgpio.h>
#include <unistd.h>
#include <string>
using namespace Napi;
// rgpio デーモンに接続
Promise _rgpiodStart(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());
}
if (!info[0].IsString() || !info[1].IsString())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
std::string ipaddr = info[0].As<String>().Utf8Value();
std::string port = info[1].As<String>().Utf8Value();
deferred.Resolve(Number::New(env, rgpiod_start(ipaddr.c_str(), port.c_str())));
}
return deferred.Promise();
}
// rgpioデーモンとの接続を閉じる
Promise _rgpiodStop(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 1)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
if (!info[0].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
rgpiod_stop(sbc);
deferred.Resolve(env.Null());
}
return deferred.Promise();
}
// gpiochipデバイスを開く
Promise _gpiochipOpen(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());
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
int gpioDev = info[1].As<Number>().Int32Value();
deferred.Resolve(Number::New(env, gpiochip_open(sbc, gpioDev)));
}
return deferred.Promise();
}
// gpiochipデバイスを閉じる
Promise _gpiochipClose(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());
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Int32Value();
deferred.Resolve(Number::New(env, gpiochip_close(sbc, handle)));
}
return deferred.Promise();
}
// GPIO のモードを出力にする(ことを要求?)
Promise _gpioClaimOutput(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());
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Int32Value();
int gpio = info[2].As<Number>().Int32Value();
deferred.Resolve(Number::New(env, gpio_claim_output(sbc, handle, 0, gpio, 0)));
}
return deferred.Promise();
}
// GPIO のモードを入力にする(ことを要求?)
// GPIOの電圧を読む
// GPIO の電圧をセットする
Promise _gpioWrite(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());
}
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 sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Int32Value();
int gpio = info[2].As<Number>().Int32Value();
int value = info[3].As<Number>().Int32Value();
deferred.Resolve(Number::New(env, gpio_write(sbc, handle, gpio, value)));
}
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: _serialOpen").Value());
}
else if (!info[0].IsNumber() || !info[1].IsString() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types: _serialOpen").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
std::string ser_tty = info[1].As<String>().Utf8Value();
int baud = info[2].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, serial_open(sbc, (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 sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, serial_close(sbc, 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 sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Uint32Value();
int count = info[2].As<Number>().Uint32Value();
char buf[count];
int rxCount = serial_read(sbc, 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 sbc = info[0].As<Number>().Int32Value();
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(sbc, 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 sbc = 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(sbc, 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 sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_close(sbc, 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 sbc = 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(sbc, 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 sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_read_byte(sbc, 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 sbc = 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(sbc, 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 sbc = 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(sbc, handle, i2c_reg)));
}
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 sbc = 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(sbc, handle, i2cReg, buf, count);
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
deferred.Resolve(outBuf);
}
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 sbc = 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(sbc, 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").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = 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(sbc, 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 sbc = 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(sbc, 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 sbc = 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(sbc, 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 sbc = 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(sbc, handle, buf.Data(), count)));
}
return deferred.Promise();
}
Object
Init(Env env, Object exports)
{
exports.Set(String::New(env, "_gpiod_start"), Function::New(env, _rgpiodStart));
exports.Set(String::New(env, "_gpiod_stop"), Function::New(env, _rgpiodStop));
exports.Set(String::New(env, "_gpiochip_open"), Function::New(env, _gpiochipOpen));
exports.Set(String::New(env, "_gpiochip_close"), Function::New(env, _gpiochipClose));
exports.Set(String::New(env, "_gpio_claim_output"), Function::New(env, _gpioClaimOutput));
exports.Set(String::New(env, "_gpio_write"), Function::New(env, _gpioWrite));
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_read_i2c_block_data"), Function::New(env, _i2cReadI2cBlockData));
exports.Set(String::New(env, "_i2c_write_i2c_block_data"), Function::New(env, _i2cWriteI2cBlockData));
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(rgpio, Init)