flashmagic.js
Version:
NXP LPC Microprocessor Programmer
120 lines (119 loc) • 4.42 kB
JavaScript
;
var Progress_1 = require('./Progress');
var FlashMagic = require('./index');
var dump = require('buffer-hexdump');
var program = require('commander');
var fs = require('fs');
var DEFAUL_COM_PORT = '/dev/tty.usbmodemFD131';
var DEFAUL_BAUD_RATE = 115200;
var DEFAUL_CRYSTAL_CLOCK = 12000000;
var DEFAULT_PING_COMMAND = FlashMagic.InSystemProgramming.VLAB_MODE ? 'U' : 'J';
program
.option('-P, --port [port]', "serial port [" + DEFAUL_COM_PORT + "]", DEFAUL_COM_PORT)
.option('-B, --baudrate [baudrate]', "baudrate [" + DEFAUL_BAUD_RATE + "]", DEFAUL_BAUD_RATE)
.option('-V, --verbose', "make the operation more talkative", true)
.option('--cclk [cclk]', "crystal clock in Hz [" + (DEFAUL_CRYSTAL_CLOCK / 1000000).toFixed(3) + " MHz]", DEFAUL_CRYSTAL_CLOCK);
program.command('write')
.description('program file')
.option('-A, --address <address>', 'ROM address', parseInt)
.option('-I, --input <file>', 'input file', null)
.action(function (cmd) {
open()
.then(function (isp) { return programFile(isp, cmd.input, cmd.address); })
.then(function () { return process.exit(0); })
.catch(catchError);
});
program.command('ping')
.description('ping device')
.option('-C, --command <command>', "J (read part identification) or U (unlock) [" + DEFAULT_PING_COMMAND + "]", DEFAULT_PING_COMMAND)
.action(function (cmd) {
open()
.then(function (isp) { return pingDevice(isp, cmd.command); })
.catch(catchError);
});
program.command('read')
.description('read memory')
.option('-A, --address <address>', 'memory address', parseInt)
.option('-L, --length <length>', 'length', parseInt)
.option('-O, --output <file>', 'output file', null)
.action(function (cmd) {
open()
.then(function (isp) {
var reader = new FlashMagic.MemoryReader(isp);
return reader.readFully({
address: cmd.address,
length: cmd.length
});
})
.then(function (buffer) {
if (cmd.output) {
fs.writeFileSync(cmd.output, buffer, { encoding: 'binary' });
console.log(buffer.length + " bytes written to " + cmd.output);
}
else {
console.log(dump(buffer));
}
process.exit(0);
})
.catch(catchError);
});
program.parse(process.argv);
if (program.args.length === 0) {
program.help();
}
function programFile(isp, path, address) {
var size = fs.statSync(path).size;
var count = 0;
var programmer = new FlashMagic.Programmer(isp, address, size);
return new Promise(function (resolve, reject) {
var stream = fs.createReadStream(path);
var progress = new Progress_1.Progress();
programmer.program(stream)
.on('start', function () { return console.log("About to flash " + size + " bytes..."); })
.on('chunk', function (buffer) { count += buffer.length; progress.spin(count, size); })
.on('error', function (error) { return reject(error); })
.on('end', function () {
console.log(path + ": " + count + " bytes written");
stream.close();
resolve();
});
});
}
function pingDevice(isp, cmd) {
var count = 0;
(function loop() {
var start = Date.now();
issuePing(isp, cmd).then(function () {
console.log("seq=" + count++ + " time=" + (Date.now() - start) + " ms");
setTimeout(loop, 1000);
}).catch(function (error) {
console.error(error);
setTimeout(loop, 1000);
});
})();
}
function issuePing(isp, cmd) {
switch (cmd) {
case 'J':
return isp.readPartIdentification().then(function (partId) {
console.log(FlashMagic.toProcessorString(partId));
return isp;
});
case 'U':
return isp.unlock();
}
return Promise.resolve(isp);
}
function catchError(error) {
var stack = error['stack'];
console.error(stack ? stack : error);
process.exit(1);
}
function open() {
var path = program['port'];
var baudrate = ~~program['baudrate'];
var cclk = program['cclk'] / 1000;
var isp = new FlashMagic.InSystemProgramming(path, baudrate, cclk);
isp.verbose = !!program['verbose'];
return isp.open().then(function (isp) { return FlashMagic.handshake(isp); });
}