Commit 1e117d08 authored by Ryan Day's avatar Ryan Day
Browse files

new parser working for sign-on!

parent 89a1c16c
Loading
Loading
Loading
Loading

examples/pinoccio.js

0 → 100644
+51 −0
Original line number Diff line number Diff line

var test = require('tape');
var stk500 = require('../stk500');
var serialport = require('serialport');
var intel_hex = require('intel-hex');
var fs = require('fs');

var data = fs.readFileSync(__dirname+'/../../panda-attack/bootstrap.hex')+'';
var hex = intel_hex.parse(data).data;


var pageSize = 256;
var baud = 115200;
var delay1 = 10; //minimum is 2.5us, so anything over 1 fine?
var delay2 = 1;
var signature = new Buffer([0x1e, 0x98, 0x01]);
var options = {
  timeout:0xc8,
  stabDelay:0x64,
  cmdexeDelay:0x19,
  synchLoops:0x20,
  byteDelay:0x00,
  pollValue:0x53,
  pollIndex:0x03
};


var comName = '/dev/ttyACM0';

var serialPort = new serialport.SerialPort(comName, {
  baudrate: baud,
  parser: serialport.parsers.raw
}, function(){
  console.log('opened!',serialPort.opened);
  console.log(serialPort);
});

var flasher = stk500(serialPort);

flasher.parser.on('rawinput',function(buf){
  console.log("->",buf.toString('hex'));
})

flasher.parser.on('raw',function(buf){
  console.log("<-",buf.toString('hex'));
})

flasher.sync(2,function(err,data){
  console.log('callback',err,data)
})
//([0x10, 0xc8, 0x64, 0x19, 0x20, 0x00, 0x53, 0x03, ----  0xac, 0x53, 0x00, 0x00], function(err, resp) {

index.js

0 → 100644
+6 −0
Original line number Diff line number Diff line

//default to v2
module.exports = require('./stk500v2');
module.exports.v2 = module.exports;
module.exports.v1 = false;//todo
+73 −73
Original line number Diff line number Diff line
 
// STK message constants
module.exports.MESSAGE_START = '\x1B'
module.exports.TOKEN         = '\x0E'
module.exports.MESSAGE_START = 0x1B
module.exports.TOKEN         = 0x0E

// STK general command constants
module.exports.CMD_SIGN_ON               = '\x01'
module.exports.CMD_SET_PARAMETER         = '\x02'
module.exports.CMD_GET_PARAMETER         = '\x03'
module.exports.CMD_SET_DEVICE_PARAMETERS = '\x04'
module.exports.CMD_OSCCAL                = '\x05'
module.exports.CMD_LOAD_ADDRESS          = '\x06'
module.exports.CMD_FIRMWARE_UPGRADE      = '\x07'
module.exports.CMD_SIGN_ON               = 0x01
module.exports.CMD_SET_PARAMETER         = 0x02
module.exports.CMD_GET_PARAMETER         = 0x03
module.exports.CMD_SET_DEVICE_PARAMETERS = 0x04
module.exports.CMD_OSCCAL                = 0x05
module.exports.CMD_LOAD_ADDRESS          = 0x06
module.exports.CMD_FIRMWARE_UPGRADE      = 0x07

// STK ISP command constants
module.exports.CMD_ENTER_PROGMODE_ISP  = '\x10'
module.exports.CMD_LEAVE_PROGMODE_ISP  = '\x11'
module.exports.CMD_CHIP_ERASE_ISP      = '\x12'
module.exports.CMD_PROGRAM_FLASH_ISP   = '\x13'
module.exports.CMD_READ_FLASH_ISP      = '\x14'
module.exports.CMD_PROGRAM_EEPROM_ISP  = '\x15'
module.exports.CMD_READ_EEPROM_ISP     = '\x16'
module.exports.CMD_PROGRAM_FUSE_ISP    = '\x17'
module.exports.CMD_READ_FUSE_ISP       = '\x18'
module.exports.CMD_PROGRAM_LOCK_ISP    = '\x19'
module.exports.CMD_READ_LOCK_ISP       = '\x1A'
module.exports.CMD_READ_SIGNATURE_ISP  = '\x1B'
module.exports.CMD_READ_OSCCAL_ISP     = '\x1C'
module.exports.CMD_SPI_MULTI           = '\x1D'
module.exports.CMD_ENTER_PROGMODE_ISP  = 0x10
module.exports.CMD_LEAVE_PROGMODE_ISP  = 0x11
module.exports.CMD_CHIP_ERASE_ISP      = 0x12
module.exports.CMD_PROGRAM_FLASH_ISP   = 0x13
module.exports.CMD_READ_FLASH_ISP      = 0x14
module.exports.CMD_PROGRAM_EEPROM_ISP  = 0x15
module.exports.CMD_READ_EEPROM_ISP     = 0x16
module.exports.CMD_PROGRAM_FUSE_ISP    = 0x17
module.exports.CMD_READ_FUSE_ISP       = 0x18
module.exports.CMD_PROGRAM_LOCK_ISP    = 0x19
module.exports.CMD_READ_LOCK_ISP       = 0x1A
module.exports.CMD_READ_SIGNATURE_ISP  = 0x1B
module.exports.CMD_READ_OSCCAL_ISP     = 0x1C
module.exports.CMD_SPI_MULTI           = 0x1D

// STK PP command constants
module.exports.CMD_ENTER_PROGMODE_PP   = '\x20'
module.exports.CMD_LEAVE_PROGMODE_PP   = '\x21'
module.exports.CMD_CHIP_ERASE_PP       = '\x22'
module.exports.CMD_PROGRAM_FLASH_PP    = '\x23'
module.exports.CMD_READ_FLASH_PP       = '\x24'
module.exports.CMD_PROGRAM_EEPROM_PP   = '\x25'
module.exports.CMD_READ_EEPROM_PP      = '\x26'
module.exports.CMD_PROGRAM_FUSE_PP     = '\x27'
module.exports.CMD_READ_FUSE_PP        = '\x28'
module.exports.CMD_PROGRAM_LOCK_PP     = '\x29'
module.exports.CMD_READ_LOCK_PP        = '\x2A'
module.exports.CMD_READ_SIGNATURE_PP   = '\x2B'
module.exports.CMD_READ_OSCCAL_PP      = '\x2C'
module.exports.CMD_SET_CONTROL_STACK   = '\x2D'
module.exports.CMD_ENTER_PROGMODE_PP   = 0x20
module.exports.CMD_LEAVE_PROGMODE_PP   = 0x21
module.exports.CMD_CHIP_ERASE_PP       = 0x22
module.exports.CMD_PROGRAM_FLASH_PP    = 0x23
module.exports.CMD_READ_FLASH_PP       = 0x24
module.exports.CMD_PROGRAM_EEPROM_PP   = 0x25
module.exports.CMD_READ_EEPROM_PP      = 0x26
module.exports.CMD_PROGRAM_FUSE_PP     = 0x27
module.exports.CMD_READ_FUSE_PP        = 0x28
module.exports.CMD_PROGRAM_LOCK_PP     = 0x29
module.exports.CMD_READ_LOCK_PP        = 0x2A
module.exports.CMD_READ_SIGNATURE_PP   = 0x2B
module.exports.CMD_READ_OSCCAL_PP      = 0x2C
module.exports.CMD_SET_CONTROL_STACK   = 0x2D

// STK HVSP command constants
module.exports.CMD_ENTER_PROGMODE_HVSP = '\x30'
module.exports.CMD_LEAVE_PROGMODE_HVSP = '\x31'
module.exports.CMD_CHIP_ERASE_HVSP     = '\x32'
module.exports.CMD_PROGRAM_FLASH_HVSP  = '\x33'
module.exports.CMD_READ_FLASH_HVSP     = '\x34'
module.exports.CMD_PROGRAM_EEPROM_HVSP = '\x35'
module.exports.CMD_READ_EEPROM_HVSP    = '\x36'
module.exports.CMD_PROGRAM_FUSE_HVSP   = '\x37'
module.exports.CMD_READ_FUSE_HVSP      = '\x38'
module.exports.CMD_PROGRAM_LOCK_HVSP   = '\x39'
module.exports.CMD_READ_LOCK_HVSP      = '\x3A'
module.exports.CMD_READ_SIGNATURE_HVSP = '\x3B'
module.exports.CMD_READ_OSCCAL_HVSP    = '\x3C'
module.exports.CMD_ENTER_PROGMODE_HVSP = 0x30
module.exports.CMD_LEAVE_PROGMODE_HVSP = 0x31
module.exports.CMD_CHIP_ERASE_HVSP     = 0x32
module.exports.CMD_PROGRAM_FLASH_HVSP  = 0x33
module.exports.CMD_READ_FLASH_HVSP     = 0x34
module.exports.CMD_PROGRAM_EEPROM_HVSP = 0x35
module.exports.CMD_READ_EEPROM_HVSP    = 0x36
module.exports.CMD_PROGRAM_FUSE_HVSP   = 0x37
module.exports.CMD_READ_FUSE_HVSP      = 0x38
module.exports.CMD_PROGRAM_LOCK_HVSP   = 0x39
module.exports.CMD_READ_LOCK_HVSP      = 0x3A
module.exports.CMD_READ_SIGNATURE_HVSP = 0x3B
module.exports.CMD_READ_OSCCAL_HVSP    = 0x3C

// STK status constants
// Success
module.exports.STATUS_CMD_OK = '\x00'
module.exports.STATUS_CMD_OK = 0x00
// Warnings
module.exports.STATUS_CMD_TOUT          = '\x80'
module.exports.STATUS_RDY_BSY_TOUT      = '\x81'
module.exports.STATUS_SET_PARAM_MISSING = '\x82'
module.exports.STATUS_CMD_TOUT          = 0x80
module.exports.STATUS_RDY_BSY_TOUT      = 0x81
module.exports.STATUS_SET_PARAM_MISSING = 0x82
// Errors
module.exports.STATUS_CMD_FAILED  = '\xC0'
module.exports.STATUS_CKSUM_ERROR = '\xC1'
module.exports.STATUS_CMD_UNKNOWN = '\xC9'
module.exports.STATUS_CMD_FAILED  = 0xC0
module.exports.STATUS_CKSUM_ERROR = 0xC1
module.exports.STATUS_CMD_UNKNOWN = 0xC9

// STK parameter constants
module.exports.STATUS_BUILD_NUMBER_LOW  = '\x80'
module.exports.STATUS_BUILD_NUMBER_HIGH = '\x81'
module.exports.STATUS_HW_VER            = '\x90'
module.exports.STATUS_SW_MAJOR          = '\x91'
module.exports.STATUS_SW_MINOR          = '\x92'
module.exports.STATUS_VTARGET           = '\x94'
module.exports.STATUS_VADJUST           = '\x95'
module.exports.STATUS_OSC_PSCALE        = '\x96'
module.exports.STATUS_OSC_CMATCH        = '\x97'
module.exports.STATUS_SCK_DURATION      = '\x98'
module.exports.STATUS_TOPCARD_DETECT    = '\x9A'
module.exports.STATUS_STATUS            = '\x9C'
module.exports.STATUS_DATA              = '\x9D'
module.exports.STATUS_RESET_POLARITY    = '\x9E'
module.exports.STATUS_CONTROLLER_INIT   = '\x9F'
module.exports.STATUS_BUILD_NUMBER_LOW  = 0x80
module.exports.STATUS_BUILD_NUMBER_HIGH = 0x81
module.exports.STATUS_HW_VER            = 0x90
module.exports.STATUS_SW_MAJOR          = 0x91
module.exports.STATUS_SW_MINOR          = 0x92
module.exports.STATUS_VTARGET           = 0x94
module.exports.STATUS_VADJUST           = 0x95
module.exports.STATUS_OSC_PSCALE        = 0x96
module.exports.STATUS_OSC_CMATCH        = 0x97
module.exports.STATUS_SCK_DURATION      = 0x98
module.exports.STATUS_TOPCARD_DETECT    = 0x9A
module.exports.STATUS_STATUS            = 0x9C
module.exports.STATUS_DATA              = 0x9D
module.exports.STATUS_RESET_POLARITY    = 0x9E
module.exports.STATUS_CONTROLLER_INIT   = 0x9F

// STK answer constants
module.exports.ANSWER_CKSUM_ERROR = '\xB0'
module.exports.ANSWER_CKSUM_ERROR = 0xB0
+49 −27
Original line number Diff line number Diff line
var c = require('./constants-v2');
var EventEmitter = require("events").EventEmitter;

module.exports = function(serialport){
module.exports = function(serialPort){

  var o = ext(
    new EventEmitter,
    {
    constants:c,
    port:serialport,
    port:serialPort,
    boundOpen:false,
    closed:false,
    // write
    _inc:-1,
@@ -30,22 +31,27 @@ module.exports = function(serialport){
      var timeout = this._commandTimeout(body[0]);

      var messageLen = new Buffer([0,0]);
      messageLen.writeUInt16BE(body.length);    
      messageLen.writeUInt16BE(body.length,0);    

      //MESSAGE_START,SEQUENCE_NUMBER,MESSAGE_SIZE,TOKEN,MESSAGE_BODY,CMD_READ/PROGRAM_FLASH/EEPROM,CHECKSUM
      var out = Buffer.concat(new Buffer([c.MESSAGE_START,this._seq(),messageLen[0],messageLen[1],c.TOKEN]),body);
      var out = Buffer.concat([new Buffer([c.MESSAGE_START,this._seq(),messageLen[0],messageLen[1],c.TOKEN]),body]);
     
 
      var checksum = this.checksum(out);
      this.queue.push({buf:Buffer.concat(out,new Buffer([checksum])),seq:this._inc,cb:cb,timeout:timeout});


      this._queue.push({buf:Buffer.concat([out,new Buffer([checksum])]),seq:this._inc,cb:cb,timeout:timeout});

      // if not waiting for another command to return. send this command
      this._send();
    },
    checksum:function(buf){

      var checksum = 0;
      for(var i=0;i<buf.length;++i){
        checksum ^= buf[i]; 
      }

      return checksum;
    },
    _seq:function(){
@@ -59,7 +65,7 @@ module.exports = function(serialport){
      //seconds for the CMD_READ/PROGRAM_FLASH/EEPROM commands, and 1
      //second for all other commands.
      timeout = 1000;
      if(body[0] === c.CMD_SIGN_ON) timeout = 200;
      if(typeByte === c.CMD_SIGN_ON) timeout = 200;
      else {
        // grab the constant names.
        var keys = Object.keys(c);
@@ -79,6 +85,15 @@ module.exports = function(serialport){
      if(this._current) return;
      if(!this._queue.length) return;   

      // if the serialport is not open yet.
      if(!serialPort.fd){
        var z = this;
        if(!this.boundOpen) serialPort.once('open',function(){
          z._send();
        });
        return;
      }

      var message = this._queue.shift();
      var current = this._current = {
        timeout:false,
@@ -90,7 +105,7 @@ module.exports = function(serialport){
      this.state = 0;  
      var z = this;

      this.port.write(buf);
      this.port.write(message.buf);
      this.port.drain(function(){
        if(current !== z._current) return z.emit('log',"current was no longer the current message after drain callback"); 
        current.timeout = setTimeout(function(){
@@ -99,7 +114,7 @@ module.exports = function(serialport){
          z._resolveCurrent(err);
        },message.timeout);
      });
      this.emit('rawinput',buf);
      this.emit('rawinput',message.buf);
    },
    _handle:function(data){
      var current = this._current;
@@ -115,16 +130,17 @@ module.exports = function(serialport){
      return {
        seq:-1,
        len:[],
        raw:[],
        message:[],
        checksum:0,
      }
    },
    _stateMachine:function(curByte){
      
      switch(state) {
      var pkt = this.pkt;
      switch(this.state) {
      case 0:
        // always reset packet.
        this.pkt = this._pkt();
        pkt = this.pkt = this._pkt();
        
        if (curByte !== 0x1b) {
          // the spec says "update statistics".
@@ -139,26 +155,26 @@ module.exports = function(serialport){
          this.state = 0;
          return this.emit('log','parser',"Invalid sequence number. back to start. got: " + curByte);
        }
        this.pkt.seq = curByte;
        pkt.seq = curByte;
        ++this.state;
        break;
      case 2:
        pkt.len.push(curByte);
        ++state;
        ++this.state;
        break;
      case 3:
        pkt.len.push(curByte);
        pkt.len = (pkt.messageLen[0] << 8) | pkt.messageLen[1];
        ++state;
        pkt.len = (pkt.len[0] << 8) | pkt.len[1];
        ++this.state;
        break;
      case 4:
        if (curByte !== 0x0e) {
          this.state = 0;
          this.pkt.error = new Error("Invalid message token byte. got: " + curByte);
          this.pkt.error.code = "E_PARSE";
          pkt.error = new Error("Invalid message token byte. got: " + curByte);
          pkt.error.code = "E_PARSE";
          return this.emit('log','parser',this.pkt.error);
        }
        ++state;
        ++this.state;
        // can stk500 send empty messages? probably not. avrdude doesnt support it.
        if(!pkt.len) ++state;
        break;
@@ -167,18 +183,20 @@ module.exports = function(serialport){
          // the message was corrupted in transit or some such error.
          // i could retry send the message for these errors!
          // i dont buffer the message right now TODO
          this.pkt.error = new Error("send checksum error");
          this.pkt.error.code = "E_STATUS_CKSUM";
          pkt.error = new Error("send checksum error");
          pkt.error.code = "E_STATUS_CKSUM";

          // TODO check to see if the first byte of all messages is a has errored byte.
          // this checksum error is the only error checked for in avrdude source
        }

        pkt.message.push(curByte);
        if (--pkt.len == 0) ++state;
        if (--pkt.len == 0) ++this.state;
        break;
      case 6:
        pkt.checksum = this.checksum(this.pkt.message);
        
        pkt.checksum = this.checksum(pkt.raw);

        pkt.checksum = (pkt.checksum === curByte) ? true : false;
        if(!pkt.checksum){
          pkt.error = new Error("recv cecksum didn't match");
@@ -188,9 +206,12 @@ module.exports = function(serialport){
        pkt.message = new Buffer(pkt.message);
        this.emit('data',pkt);
        this.state++;// sets state to 7. the parser is not interested in any other bytes until a message is queued.
        this._resolveCurrent(s.pkt.error?this.pkt.error:false,pkt);
        this._resolveCurrent(pkt.error?pkt.error:false,pkt);
        break;
      }

      pkt.raw.push(curByte);

    },
    _resolveCurrent:function(err,pkt){
      var toCall = this._current;
@@ -205,6 +226,8 @@ module.exports = function(serialport){
        this.queue = [];
      }

      clearTimeout(toCall.timeout);

      toCall.cb(err,pkt);
      if(q){
        var e = err;
@@ -220,7 +243,7 @@ module.exports = function(serialport){
    }
  });
 
  serialPort.on('data',dataHandler).on('error',cleanup).on('close',cleanup);
  serialPort.on('data',dataHandler).once('error',cleanup).once('close',cleanup);

  return o;

@@ -229,12 +252,11 @@ module.exports = function(serialport){
  };

  function cleanup(err){

    // prevent new commands from writing to serial.
    o.closed = true;
    // stop sending data
    serialPort.removeListener('data',dataHandler);
    serialPort.removeListener('error',cleanup);
    serialPort.removeListener('close',cleanup);

    if(!err) {
      err = new Error('serial closed.');
+10 −2
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
  "description": "STK500 in javascript",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    "test": "tape test/*.js"
  },
  "repository": {
    "type": "git",
@@ -29,5 +29,13 @@
  "bugs": {
    "url": "https://github.com/Pinoccio/js-stk500/issues"
  },
  "homepage": "https://github.com/Pinoccio/js-stk500"
  "homepage": "https://github.com/Pinoccio/js-stk500",
  "dependencies": {
    "buffer-equal": "0.0.1",
    "intel-hex": "^0.1.1",
  },
  "devDependencies": {
    "serialport": "^1.3.1",
    "tape": "^2.12.2"
  }
}
Loading