/** lgpio を Node.js から利用するモジュール ** */ /** 関数名・書式は lgpio Python に準拠 ******************* */ #include #include #include #include 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().Utf8Value(); std::string port = info[1].As().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().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().Int32Value(); int gpioDev = info[1].As().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().Int32Value(); int handle = info[1].As().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().Int32Value(); int handle = info[1].As().Int32Value(); int gpio = info[2].As().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().Int32Value(); int handle = info[1].As().Int32Value(); int gpio = info[2].As().Int32Value(); int value = info[3].As().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().Int32Value(); unsigned int i2c_bus = info[1].As().Uint32Value(); unsigned int i2c_addr = info[2].As().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().Int32Value(); unsigned int handle = info[1].As().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().Int32Value(); unsigned int handle = info[1].As().Uint32Value(); unsigned int i2c_reg = info[2].As().Uint32Value(); unsigned int bVal = info[3].As().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().Int32Value(); unsigned int handle = info[1].As().Uint32Value(); unsigned int i2cReg = info[2].As().Uint32Value(); unsigned int count = info[3].As().Uint32Value(); char buf[count]; int rxCount = i2c_read_i2c_block_data(sbc, handle, i2cReg, buf, count); auto outBuf = Buffer::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().Int32Value(); unsigned int handle = info[1].As().Uint32Value(); unsigned int i2c_reg = info[2].As().Uint32Value(); auto buf = info[3].As>(); 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().Int32Value(); unsigned int handle = info[1].As().Uint32Value(); unsigned int i2c_reg = info[2].As().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)