123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- "use strict";
- var SerialPort = require("serialport").SerialPort;
- var bufferpack = require("bufferpack");
- var slip = require("slip");
- // ../esptool.py --port /dev/cu.SLAB_USBtoUART --baud 115200 \
- // write_flash --flash_freq 80m --flash_mode qio --flash_size 32m \
- // 0x0000 "boot_v1.4(b1).bin" 0x1000 espruino_esp8266_user1.bin \
- // 0x3FC000 esp_init_data_default.bin 0x3FE000 blank.bin
- // Marriage of ESPTOOL-CK and ESPTOOL.py
- const formats = {
- bootloader_packet_header: "<B(direction)B(command)H(size)I(checksum)"
- };
- const commands = {
- CMD0: 0x00,
- CMD1: 0x01,
- FLASH_DOWNLOAD_BEGIN: 0x02,
- FLASH_DOWNLOAD_DATA: 0x03,
- FLASH_DOWNLOAD_DONE: 0x04,
- RAM_DOWNLOAD_BEGIN: 0x05,
- RAM_DOWNLOAD_END: 0x06,
- RAM_DOWNLOAD_DATA: 0x07,
- SYNC_FRAME: 0x08,
- WRITE_REGISTER: 0x09,
- READ_REGISTER: 0x0A,
- SET_FLASH_PARAMS: 0x0B,
- NO_COMMAND: 0xFF
- };
- const SYNC_FRAME = new Buffer("\x07\x07\x12\x20" + "\x55".repeat(32));
- function slipReadParser(emitter, buffer) {
- // This is the pyramid of doom right?
- var decoder = new slip.Decoder({
- onMessage: (msg) => {
- emitter.emit('data', msg);
- }
- });
- debug("Got buffer", buffer.length);
- decoder.decode(buffer);
- }
- var debug = function() {};
- function delay(time) {
- return new Promise((resolve) => {
- debug("Sleepy time", time);
- setTimeout(resolve, time);
- });
- }
- class EspBoard {
- constructor(port) {
- this.port = port;
- }
- resetIntoBootLoader() {
- // RTS - Request To Send
- // DTR - Data Terminal Ready
- return new Promise((resolve, reject) => {
- this.port.set({
- rts: true,
- dtr: true
- }, function(error, result) {
- if (error) {
- reject(error);
- }
- resolve(result);
- });
- }).then(() => {
- return delay(5);
- }).then(() => {
- this.port.set({rts: false}, (error, result) => {
- debug("Second go", error, result);
- });
- }).then(() => {
- return delay(250);
- }).then(() => {
- this.port.set({dtr: false}, (error, result) => {
- debug("Third go", error, result);
- });
- });
- }
- }
- class EspComm {
- constructor(config) {
- this.port = new SerialPort(config.portName, {
- baudRate: config.baudRate,
- parser: slipReadParser
- }, false);
- var BoardFactory = config.BoardFactory ? config.BoardFactory : EspBoard;
- this.board = new BoardFactory(this.port);
- if (config.debug) {
- debug = config.debug;
- }
- this.isOpen = false;
- this.config = config;
- }
- open() {
- return new Promise((resolve, reject) => {
- this.port.open((error) => {
- debug("Opening port...", this.port);
- if (error) {
- reject(error);
- } else {
- resolve();
- }
- });
- }).then(() => {
- return this.sync();
- });
- }
- close() {
- this.port.close();
- this.isOpen = false;
- }
- calculateChecksum(data) {
- var result = 0xEF;
- for (var i = 0; i < data.length; i++) {
- result ^= data[i];
- }
- return result;
- }
- sync() {
- return this.board.resetIntoBootLoader()
- .then(() => {
- return new Promise((resolve, reject) => {
- this.port.flush((error) => {
- if (error) {
- reject(error);
- }
- resolve();
- });
- }).then(() => {
- return this.sendCommand(commands.SYNC_FRAME, SYNC_FRAME)
- .then((result) => {
- // There is some magic here
- debug("Should we retry 7 times??");
- });
- });
- });
- }
- // TODO:csd - How to make the commands pretty?
- // https://github.com/themadinventor/esptool/blob/master/esptool.py#L108
- // https://github.com/igrr/esptool-ck/blob/master/espcomm/espcomm.c#L103
- sendCommand(command, data) {
- // ???:csd - Is this how you do OO anymore?
- var port = this.port;
- return new Promise((resolve, reject) => {
- var sendHeader = bufferpack.pack(formats.bootloader_packet_header, [0x00, command, data.length, this.calculateChecksum(data)]);
- port.write(slip.encode(sendHeader), (err, result) => {
- debug("Sending header", err, result);
- });
- port.write(slip.encode(data), (err, result) => {
- debug("Sending budy", err, result);
- });
- port.on('data', (buffer) => {
- debug("Port got data", buffer);
- var receiveHeader = bufferpack.unpack(formats.bootloader_packet_header, buffer.readInt8(0));
- // FIXME:csd - Sanity check here regarding direction???
- resolve({
- header: receiveHeader,
- // Result follows the header
- data: buffer.slice(8)
- });
- });
- });
- }
- }
- module.exports = EspComm;
|