Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahAndrews committed Aug 6, 2020
1 parent 9e92cd8 commit 2ba22cc
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 44 deletions.
7 changes: 5 additions & 2 deletions binding.gyp
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
'targets': [
{
'target_name': 'cbus-native',
'sources': [ 'src/cbus.cc' ],
'target_name': 'expansion-hub-fw-update-mode-native',
'sources': [
'src/addon.cc',
'src/EnterFirmwareUpdateMode.cc'
],
'include_dirs': [
"src/",
"d2xx/",
Expand Down
8 changes: 3 additions & 5 deletions lib/binding.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
const addon = require('../build/Release/cbus-native');
import {promisify} from "util";
const addon = require('../build/Release/expansion-hub-fw-update-mode-native');

console.log("addon:");
console.log(addon);

exports.getFtdiDevices = addon.getFtdiDevices;
exports.enterExpansionHubFirmwareUpdateMode = promisify(addon.enterExpansionHubFirmwareUpdateMode);
92 changes: 92 additions & 0 deletions src/EnterFirmwareUpdateMode.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include "EnterFirmwareUpdateMode.h"
#include <ftd2xx.h>
#include <napi.h>
#include <thread>
#include <stdexcept>

#define MODE_CBUS (0x20)

// The reset and programming pins are active low.
#define MASK_PROGRAMMING_AND_RESET (0x30)
#define MASK_PROGRAMMING_ONLY (0x31)
#define MASK_RESET_ONLY (0x32)
#define MASK_NEITHER (0x33)

class Worker: public Napi::AsyncWorker {
public:
Worker(Napi::Function& callback, std::string serial)
: Napi::AsyncWorker(callback), serial(serial) {}

~Worker() {}

// Executed inside the worker-thread.
// It is not safe to access JS engine data structure
// here, so everything we need for input and output
// should go on `this`.
void Execute() {
FT_HANDLE ftHandle;
try {
FT_STATUS status;

status = FT_OpenEx(&serial, FT_OPEN_BY_SERIAL_NUMBER, &ftHandle);
if (status != FT_OK) throw new std::runtime_error("Error opening " + serial);

// Activate programming pin only
status = FT_SetBitMode(ftHandle, MASK_PROGRAMMING_ONLY, MODE_CBUS);
if (status != FT_OK) throw new std::runtime_error("Error setting programming pin");
std::this_thread::sleep_for(std::chrono::milliseconds(50));

// Activate programming and reset pins
status = FT_SetBitMode(ftHandle, MASK_PROGRAMMING_AND_RESET, MODE_CBUS);
if (status != FT_OK) throw new std::runtime_error("Error setting reset pins");
std::this_thread::sleep_for(std::chrono::milliseconds(50));

// Activate programming pin only
status = FT_SetBitMode(ftHandle, MASK_PROGRAMMING_ONLY, MODE_CBUS);
if (status != FT_OK) throw new std::runtime_error("Error un-setting reset pin");
std::this_thread::sleep_for(std::chrono::milliseconds(50));

// Activate no pins
status = FT_SetBitMode(ftHandle, MASK_NEITHER, MODE_CBUS);
if (status != FT_OK) throw new std::runtime_error("Error un-setting programming pin");
std::this_thread::sleep_for(std::chrono::milliseconds(50));

FT_Close(ftHandle);
} catch (const std::runtime_error& error) {
SetError(error.what());
if (ftHandle) {
FT_Close(ftHandle);
}
return;
}
}

private:
std::string serial;
std::string errorString;
};

void EnterFirmwareUpdateMode(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();

if (info.Length() != 2) {
Napi::TypeError::New(env, "Exactly 2 parameters must be provided")
.ThrowAsJavaScriptException();
}

if (!info[0].IsString()) {
Napi::TypeError::New(env, "First parameter is not a string")
.ThrowAsJavaScriptException();
}

if (!info[1].IsFunction()) {
Napi::TypeError::New(env, "Second parameter is not a function")
.ThrowAsJavaScriptException();
}

std::string serial = info[0].ToString().Utf8Value();
Napi::Function callback = info[1].As<Napi::Function>();

Worker* worker = new Worker(callback, serial);
worker->Queue();
}
8 changes: 8 additions & 0 deletions src/EnterFirmwareUpdateMode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef ENTER_FIRMWARE_UPDATE_MODE
#define ENTER_FIRMWARE_UPDATE_MODE

#include <napi.h>

void EnterFirmwareUpdateMode(const Napi::CallbackInfo& info);

#endif
10 changes: 10 additions & 0 deletions src/addon.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <napi.h>
#include "EnterFirmwareUpdateMode.h"

Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "enterExpansionHubFirmwareUpdateMode"),
Napi::Function::New(env, EnterFirmwareUpdateMode));
return exports;
}

NODE_API_MODULE(addon, Init)
27 changes: 0 additions & 27 deletions src/cbus.cc

This file was deleted.

18 changes: 8 additions & 10 deletions test/test_binding.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
const cbus = require("../dist/binding.js");
const binding = require("../dist/binding.js");
const assert = require("assert").strict;

console.log("cbus:");
console.log(cbus);
assert(cbus.getFtdiDevices, "The expected function is undefined");
assert(binding.enterExpansionHubFirmwareUpdateMode, "The expected function is undefined");

function testBasic()
async function testBasic()
{
const result = cbus.getFtdiDevices();
assert.equal(result, [], "Unexpected value returned");
// await binding.enterExpansionHubFirmwareUpdateMode("DQ16G720");
await binding.enterExpansionHubFirmwareUpdateMode("DQ16");
}

assert.doesNotThrow(testBasic, Error, "testBasic threw an expection");

console.log("Tests passed- everything looks OK!");
assert.doesNotReject(testBasic, Error, "testBasic threw an exception")
.then(() => console.log("Tests passed- everything looks OK!"))
.catch(error => console.log(`Tests failed: ${error}`));

0 comments on commit 2ba22cc

Please sign in to comment.