docs: function Unpi(config) {
      var pRules,
          self = this;
  
      if (config !== undefined && (typeof config !== 'object' || Array.isArray(config)))
          throw new TypeError('config should be an object if given.');
  
      EventEmitter.call(this);
  
      this.config = config || {};
      this.config.lenBytes = this.config.lenBytes || 2;
  
      pRules = [
          ru._unpiHeader('sof'),
          ru._unpiLength('len', this.config.lenBytes),
          ru._unpiCmd0('type', 'subsys'),
          ru.uint8('cmd'),
          ru._unpiPayload('payload'),
          ru.uint8('fcs')
      ];
  
      this.concentrate = Concentrate();
      this.parser = DChunks().join(pRules).compile();
  
      this.parser.on('parsed', function (result) {
          var cmd0 = (result.type << 5) | result.subsys,
              preBufLen = self.config.lenBytes + 2,
              preBuf = new Buffer(preBufLen);
  
          if (self.config.lenBytes === 1) {
              preBuf.writeUInt8(result.len, 0);
              preBuf.writeUInt8(cmd0, 1);
              preBuf.writeUInt8(result.cmd, 2);
          } else {
              preBuf.writeUInt16LE(result.len, 0);
              preBuf.writeUInt8(cmd0, 2);
              preBuf.writeUInt8(result.cmd, 3);
          }
          result.csum = checksum(preBuf, result.payload);
  
          self.emit('data', result);
          if (result.csum !== result.fcs)
              self.emit('error', new Error('Invalid checksum.'), result);
      });
  
      if (this.config.phy) {
          this.config.phy.pipe(this.parser);
          this.concentrate.pipe(this.config.phy);
      }
  
      this.on('error', function (e) {
          // [DEBUG]
          // console.log(e);
      });
  }