UNPKG

wifirm

Version:

Upload new firmware onto Boards with WiFiMCU-Compatible bootloaders.

134 lines (103 loc) 4.08 kB
#! /usr/bin/env node const pkg = require(__dirname + '/package.json'); const prog = require('commander'); const lightYModem = require('particle-ymodem'); const SerialPort = require('serialport').SerialPort; const fs = require('fs'); const async = require('async'); const progressbar = require('progressbar'); const defaultBaudrate = 115200; const highestBaudrate = 230400; var port = null; prog .version(pkg.version) .option('-D, --device <path>','Specify the serial port to use') .option('-b, --baudrate <baud> [optional]','Set a specific baudrate (Default: ' + defaultBaudrate + ')') .option('-f, --file <path>','Binary firmware file to upload') .parse(process.argv); var argError = function (error) { console.error("Error:", error); }; // Check arguments and initialize everything async.waterfall([ // Check if specified file exists and can be read function fileArgCheck (callback) { if (prog.file === undefined) return callback("No file to upload was specified"); fs.access(prog.file, fs.R_OK, function (err) { if (err) return callback("The file \"" + prog.file + "\" can't be read. " + "Please make sure that it exists and you have the right permissions."); else return callback(null); }); }, // Check if baudrate is supplied and a valid int, else throw error or set default function baudrateArgCheck (callback) { if (!prog.baudrate) prog.baudrate = defaultBaudrate; else if (prog.baudrate > 0 && prog.baudrate <= highestBaudrate) prog.baudrate = parseInt(prog.baudrate); else return callback("The specified baudrate is invalid"); return callback(null); }, // Check if device-argument and open serial port function deviceArgCheck (callback) { if (prog.device === undefined) return callback("No serial port was specified."); // Open serial port (check existance and access) port = new SerialPort(prog.device, {baudrate: prog.baudrate}, false); port.open(function (err) { if (err) return callback("Can't open the serial port: " + err.message); else { console.log("Serial Port opened! -> Using \"" + prog.device + "\" with baudrate", prog.baudrate); return callback(); } }); }, // Check if device is in Bootloader and then enter upload mode function bootloaderCheck (callback) { console.log("Waiting for WiFiMCU to enter Bootloader"); var bootloaderCheck = function () { port.write('help\n'); } var checkInterval = setInterval(bootloaderCheck, 5000); bootloaderCheck(); var inBootloader = false; var dataRecvFunc = function (data) { if (!inBootloader) { //console.log("Data: " + data); if (data.indexOf("WiFiMCU Bootloader") > -1) { inBootloader = true; // We are in the bootloader!!! console.log("In bootloader-mode, entering upload mode"); // Stop the "help" commands and don't call this method anymore clearInterval(checkInterval); dataRecvFunc = function () {return;}; setTimeout(function () { port.write('1\n'); setTimeout(callback, 500); }, 500); }} } port.on('data', dataRecvFunc); }, // Upload file now function uploadFile (callback) { var logCallback = console.log; var modem = new lightYModem(); var file = fs.readFileSync(prog.file); fs.writeFileSync("/tmp/fileout", file); console.log("Reopening serial port."); port.close(); port = new SerialPort(prog.device, {baudrate: prog.baudrate}, false); console.log("Initiating upload..."); var progress = progressbar.create().step('upload').setTotal(1000); var progressCallback = function(val){ progress.setTick(Math.round(val.current/val.total * 1000));} var serialLog = ""; modem.transfer(file, port, progressCallback, (data) => { serialLog += data; }, () => { console.log("Serial port closed, exiting..."); process.exit(0); }); } ], function (error) { if(error) argError(error); });