ocoge/local_modules/rgpio/rgpio.cpp

337 lines
11 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();
}
// 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は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();
}
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)