mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-22 15:49:48 +00:00
337 lines
11 KiB
C++
337 lines
11 KiB
C++
/** 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();
|
||
}
|
||
|
||
// 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").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 i2c_bus = info[1].As<Number>().Uint32Value();
|
||
unsigned int i2c_addr = info[2].As<Number>().Uint32Value();
|
||
int flags = 0;
|
||
deferred.Resolve(Number::New(env, i2c_open(sbc, i2c_bus, i2c_addr, 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").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();
|
||
}
|
||
|
||
// 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ハンドルに関連付けられているデバイスの指定されたレジスタから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").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ハンドルに関連付けられているデバイスの指定されたレジスタに最大32バイトのデータを書き込む。
|
||
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();
|
||
}
|
||
|
||
Object
|
||
Init(Env env, Object exports)
|
||
{
|
||
exports.Set(String::New(env, "_rgpiod_start"), Function::New(env, _rgpiodStart));
|
||
exports.Set(String::New(env, "_rgpiod_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, "_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_data"), Function::New(env, _i2cWriteByteData));
|
||
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));
|
||
return exports;
|
||
}
|
||
|
||
NODE_API_MODULE(rgpio, Init) |