var async = require("async"); var spawn = require("child_process").spawn; var SerialPort = require("serialport"); var path = require("path"); var test = require("tape"); const exec = path.join(process.env.IDF_PATH, "components", "esptool_py", "esptool", "esptool.py"); const portString = "/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_SERIAL_ID-if00-port0"; const buildPath = path.join(__dirname, "lora32", "build"); var args = [ "--chip", "esp32", "--baud", "460800", "--before", "default_reset", "--after", "hard_reset", "write_flash", "-z", "--flash_mode", "dio", "--flash_freq", "40m", "--flash_size", "detect", "0x1000", path.join(buildPath, "bootloader/bootloader.bin"), "0x10000", path.join(buildPath, "lora32.bin"), "0x8000", path.join(buildPath, "partitions_singleapp.bin") ]; function flash(port, cb) { console.log("Flashing devices at %s", port); var cp = spawn(exec, ["--port", port].concat(args)); cp.on("exit", function(code) { console.log("%s\nexited: %d", port, code); cb(code === 0 ? null : new Error("exited non-zero: " + code)); }); } function toggleReset(sp) { sp.set({ dtr: false }, function() { setTimeout(function() { sp.set({ dtr: true }); }, 1000); }); } function serial(port, cb) { var to = -1; var buf = ""; var sp = new SerialPort(port, { baudRate: 115200 }); sp.once("open", function() { console.log("port open %s", port); sp.on("data", onData); toggleReset(sp); }); function done(reason) { console.log("%s ready%s", port, reason || ""); cb(null, sp); sp.removeListener("data", onData); } function onData(chunk) { buf += chunk.toString(); clearTimeout(to); to = setTimeout(function() { done(" (timeout)"); }, 3000); if(buf.indexOf("set_spread") !== -1) { clearTimeout(to); done(" (got set_spreadfactor)"); } } } async.series([ function(next) { if(process.env.NOFLASH) { return next(null); } async.parallel([ function(done) { flash(portString.replace("SERIAL_ID", "0001"), done); }, function(done) { flash(portString.replace("SERIAL_ID", "0002"), done); }], next); }, function(next) { async.parallel({ dev1: function(done) { serial(portString.replace("SERIAL_ID", "0001"), done); }, dev2: function(done) { serial(portString.replace("SERIAL_ID", "0002"), done); } }, next); } ], function(err, results) { var ports = results[1]; console.log("init done"); var buf = ""; var message = "test"; test.onFinish(function() { console.log("Cleaning up"); ports.dev1.close(); ports.dev2.close(); }); test(function(t) { t.plan(1); ports.dev1.on("data", function onData(chunk) { //process.stdout.write(chunk); buf += chunk.toString(); if(buf.indexOf(`msg: ${message}`) !== -1) { ports.dev1.removeListener("data", onData); t.pass("got round-trip message!"); } }); ports.dev2.on("data", function(chunk) { //process.stdout.write(chunk); }); ports.dev2.write(`send${message}\n`); }, "round-trip message"); test(function(t) { t.plan(2); var sf = 9; var msg = `sf${sf}\n`; testSetSpreadFactor(ports.dev1); testSetSpreadFactor(ports.dev2); function testSetSpreadFactor(port) { var buf = ""; port.on("data", function onData(c) { buf += c.toString(); if(buf.indexOf(`spreadfactor: ${sf}`) !== -1) { t.pass("spreadfactor set"); port.removeListener("data", onData); } }); port.write(msg); }; }, "spreadfactor"); test(function(t) { t.plan(4); var i = 0; async.doUntil(function(done) { var write = ports["dev" + (1 + i % 2)]; var read = ports["dev" + (1 + (i + 1) % 2)]; var buf = ""; var msg = `tick${i}`; read.on("data", function onData(c) { buf += c.toString(); if(buf.indexOf(msg) !== -1) { t.pass("got message " + i); read.removeListener("data", onData); done(null); } }); write.write(`send${msg}\n`); }, function() { return ++i > 5; }) }, "exchange"); });