flashmagic.js
Version:
NXP LPC Microprocessor Programmer
119 lines (118 loc) • 4.39 kB
JavaScript
;
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var RAMAddress_1 = require('./RAMAddress');
var RAMWriter_1 = require('./RAMWriter');
var ROMWriter_1 = require('./ROMWriter');
var UserCode = require('./UserCode');
var events_1 = require('events');
function toBuffer(data) {
return Buffer.isBuffer(data) ? data : new Buffer(data, 'binary');
}
var Programmer = (function (_super) {
__extends(Programmer, _super);
function Programmer(isp, destAddr, length, srcAddr, chunkSize) {
if (srcAddr === void 0) { srcAddr = RAMAddress_1.RAMAddress.BASE + 1024 * 10; }
if (chunkSize === void 0) { chunkSize = 4096; }
_super.call(this);
this.isp = isp;
this.destAddr = destAddr;
this.length = length;
this.srcAddr = srcAddr;
this.chunkSize = chunkSize;
this.uploader = new RAMWriter_1.RAMWriter(isp);
this.writer = new ROMWriter_1.ROMWriter(isp, destAddr, length);
}
Programmer.prototype.program = function (readable) {
var _this = this;
this.writer.eraseBlock().then(function () { return _this.doProgram(readable); });
return this;
};
Programmer.prototype.doProgram = function (readable) {
var _this = this;
var buffer = new Buffer(this.chunkSize);
var offset;
var ended = false;
var startEmitted = false;
var resetBuffer = function () {
offset = 0;
buffer.fill(0);
_this.uploader.address = new RAMAddress_1.RAMAddress(_this.srcAddr);
};
var emitStart = function () {
if (!startEmitted) {
startEmitted = true;
_this.emit('start');
}
};
var finish = function () {
emitStart();
if (offset) {
_this.emit('chunk', buffer.slice(0, offset));
_this.doProgramBuffer(buffer)
.then(function () { return _this.emit('end'); })
.catch(function (error) { return _this.emit('error', error); });
}
else {
_this.emit('end');
}
};
resetBuffer();
readable.on('open', emitStart);
readable.on('error', function () { return _this.emit('error'); });
readable.on('end', function () {
ended = readable['isPaused']();
if (!ended) {
finish();
}
});
readable.on('data', function (data) {
var chunk = toBuffer(data);
readable.pause();
function next() {
if (chunk.length) {
process.nextTick(loop);
}
else if (ended) {
finish();
}
else {
readable.resume();
}
}
var loop = function () {
var written = Math.min(buffer.length - offset, chunk.length);
chunk.copy(buffer, offset, 0, written);
offset += written;
chunk = chunk.slice(written);
if (offset === buffer.length) {
emitStart();
_this.emit('chunk', buffer, _this.writer.address);
_this.doProgramBuffer(buffer)
.then(resetBuffer)
.then(next)
.catch(function (error) { return _this.emit('error', error); });
}
else {
next();
}
};
loop();
});
};
Programmer.prototype.doProgramBuffer = function (buffer) {
var _this = this;
var ramAddr = this.uploader.address;
if (this.writer.address === 0) {
console.log('Patching vector table...');
UserCode.validateVectorTable(buffer);
}
return this.uploader.writeToRAM(buffer)
.then(function () { return _this.writer.copyRAMToFlash(ramAddr, buffer.length); });
};
return Programmer;
}(events_1.EventEmitter));
exports.Programmer = Programmer;