300 lines
8.3 KiB
JavaScript
300 lines
8.3 KiB
JavaScript
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var EventEmitter, LCD_BLINKOFF, LCD_BLINKON, LCD_CLEARDISPLAY, LCD_CURSORMOVE, LCD_CURSOROFF, LCD_CURSORON, LCD_CURSORSHIFT, LCD_DISPLAYCONTROL, LCD_DISPLAYMOVE, LCD_DISPLAYOFF, LCD_DISPLAYON, LCD_ENTRYLEFT, LCD_ENTRYMODESET, LCD_ENTRYRIGHT, LCD_ENTRYSHIFTDECREMENT, LCD_ENTRYSHIFTINCREMENT, LCD_FUNCTIONSET, LCD_MOVELEFT, LCD_MOVERIGHT, LCD_RETURNHOME, LCD_SETCGRAMADDR, LCD_SETDDRAMADDR, MCP23017_GPIOA, MCP23017_GPIOB, MCP23017_IOCON_BANK0, MCP23017_IOCON_BANK1, MCP23017_IODIRB, Plate, WireAdapter, flip, pollables,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
MCP23017_IOCON_BANK0 = 0x0A;
|
|
|
|
MCP23017_IOCON_BANK1 = 0x15;
|
|
|
|
MCP23017_GPIOA = 0x09;
|
|
|
|
MCP23017_IODIRB = 0x10;
|
|
|
|
MCP23017_GPIOB = 0x19;
|
|
|
|
LCD_CLEARDISPLAY = 0x01;
|
|
|
|
LCD_RETURNHOME = 0x02;
|
|
|
|
LCD_ENTRYMODESET = 0x04;
|
|
|
|
LCD_DISPLAYCONTROL = 0x08;
|
|
|
|
LCD_CURSORSHIFT = 0x10;
|
|
|
|
LCD_FUNCTIONSET = 0x20;
|
|
|
|
LCD_SETCGRAMADDR = 0x40;
|
|
|
|
LCD_SETDDRAMADDR = 0x80;
|
|
|
|
LCD_DISPLAYON = 0x04;
|
|
|
|
LCD_DISPLAYOFF = 0x00;
|
|
|
|
LCD_CURSORON = 0x02;
|
|
|
|
LCD_CURSOROFF = 0x00;
|
|
|
|
LCD_BLINKON = 0x01;
|
|
|
|
LCD_BLINKOFF = 0x00;
|
|
|
|
LCD_ENTRYRIGHT = 0x00;
|
|
|
|
LCD_ENTRYLEFT = 0x02;
|
|
|
|
LCD_ENTRYSHIFTINCREMENT = 0x01;
|
|
|
|
LCD_ENTRYSHIFTDECREMENT = 0x00;
|
|
|
|
LCD_DISPLAYMOVE = 0x08;
|
|
|
|
LCD_CURSORMOVE = 0x00;
|
|
|
|
LCD_MOVERIGHT = 0x04;
|
|
|
|
LCD_MOVELEFT = 0x00;
|
|
|
|
flip = [0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0C, 0x1C, 0x02, 0x12, 0x0A, 0x1A, 0x06, 0x16, 0x0E, 0x1E];
|
|
|
|
pollables = [LCD_CLEARDISPLAY, LCD_RETURNHOME];
|
|
|
|
EventEmitter = require('events').EventEmitter;
|
|
|
|
WireAdapter = require('./I2CBusWireAdapter');
|
|
|
|
Plate = (function(superClass) {
|
|
extend(Plate, superClass);
|
|
|
|
function Plate(device, address, pollInterval) {
|
|
this.ADDRESS = address;
|
|
this.PORTA = 0;
|
|
this.PORTB = 0;
|
|
this.DDRB = 0x10;
|
|
this.WIRE = new WireAdapter(device, address);
|
|
if (pollInterval == null) {
|
|
pollInterval = 200;
|
|
}
|
|
this.init();
|
|
this.BSTATE = 0;
|
|
if (pollInterval > 0) {
|
|
this.poll = setInterval((function(_this) {
|
|
return function() {
|
|
var cur, key;
|
|
cur = _this.buttonState();
|
|
if (cur !== _this.BSTATE) {
|
|
key = _this.BSTATE ^ cur;
|
|
_this.emit('button_change', key);
|
|
if (cur < _this.BSTATE) {
|
|
_this.emit('button_up', key);
|
|
} else {
|
|
_this.emit('button_down', key);
|
|
}
|
|
return _this.BSTATE = cur;
|
|
}
|
|
};
|
|
})(this), pollInterval);
|
|
}
|
|
}
|
|
|
|
Plate.prototype.colors = {
|
|
OFF: 0x00,
|
|
RED: 0x01,
|
|
GREEN: 0x02,
|
|
BLUE: 0x04,
|
|
YELLOW: 0x03,
|
|
TEAL: 0x06,
|
|
VIOLET: 0x05,
|
|
WHITE: 0x07,
|
|
ON: 0x07
|
|
};
|
|
|
|
Plate.prototype.buttons = {
|
|
SELECT: 0x01,
|
|
RIGHT: 0x02,
|
|
DOWN: 0x04,
|
|
UP: 0x08,
|
|
LEFT: 0x10
|
|
};
|
|
|
|
Plate.prototype.clear = function() {
|
|
return this.writeByte(LCD_CLEARDISPLAY);
|
|
};
|
|
|
|
Plate.prototype.home = function() {
|
|
return this.writeByte(LCD_RETURNHOME);
|
|
};
|
|
|
|
Plate.prototype.close = function() {
|
|
if (this.poll != null) {
|
|
return clearInterval(this.poll);
|
|
}
|
|
};
|
|
|
|
Plate.prototype.backlight = function(color) {
|
|
var c;
|
|
c = ~color;
|
|
this.PORTA = (this.PORTA & 0x3F) | ((c & 0x3) << 6);
|
|
this.PORTB = (this.PORTB & 0xFE) | ((c & 0x4) >> 2);
|
|
this.sendBytes(MCP23017_GPIOA, this.PORTA);
|
|
return this.sendBytes(MCP23017_GPIOB, this.PORTB);
|
|
};
|
|
|
|
Plate.prototype.message = function(text, clear) {
|
|
var i, j, len, line, lines, results;
|
|
if (clear) {
|
|
this.clear();
|
|
}
|
|
lines = text.split('\n');
|
|
results = [];
|
|
for (i = j = 0, len = lines.length; j < len; i = ++j) {
|
|
line = lines[i];
|
|
if (i === 1) {
|
|
this.writeByte(0xC0);
|
|
}
|
|
if (i < 2) {
|
|
results.push(this.writeByte(line, true));
|
|
} else {
|
|
results.push(void 0);
|
|
}
|
|
}
|
|
return results;
|
|
};
|
|
|
|
Plate.prototype.buttonState = function() {
|
|
var ret;
|
|
ret = this.WIRE.readByte(MCP23017_GPIOA);
|
|
return ret & 0x1F;
|
|
};
|
|
|
|
Plate.prototype.buttonName = function(val) {
|
|
switch (val) {
|
|
case this.buttons.SELECT:
|
|
return "SELECT";
|
|
case this.buttons.RIGHT:
|
|
return "RIGHT";
|
|
case this.buttons.UP:
|
|
return "UP";
|
|
case this.buttons.DOWN:
|
|
return "DOWN";
|
|
case this.buttons.LEFT:
|
|
return "LEFT";
|
|
default:
|
|
return void 0;
|
|
}
|
|
};
|
|
|
|
Plate.prototype.createChar = function(location, pattern) {
|
|
var data, j, len;
|
|
location = location & 0x7;
|
|
this.writeByte(LCD_SETCGRAMADDR | (location << 3));
|
|
for (j = 0, len = pattern.length; j < len; j++) {
|
|
data = pattern[j];
|
|
this.writeByte(data, true);
|
|
}
|
|
return this.clear();
|
|
};
|
|
|
|
Plate.prototype.init = function() {
|
|
var displaycontrol, displaymode, displayshift;
|
|
this.sendBytes(MCP23017_IOCON_BANK1, 0);
|
|
this.sendBytes(0, [0x3F, this.DDRB, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, this.PORTA, this.PORTB, this.PORTA, this.PORTB]);
|
|
this.sendBytes(MCP23017_IOCON_BANK0, 0xA0);
|
|
displayshift = LCD_CURSORMOVE | LCD_MOVERIGHT;
|
|
displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
|
|
displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
|
|
this.writeByte(0x33);
|
|
this.writeByte(0x32);
|
|
this.writeByte(0x28);
|
|
this.writeByte(LCD_CLEARDISPLAY);
|
|
this.writeByte(LCD_CURSORSHIFT | displayshift);
|
|
this.writeByte(LCD_ENTRYMODESET | displaymode);
|
|
this.writeByte(LCD_DISPLAYCONTROL | displaycontrol);
|
|
this.writeByte(LCD_RETURNHOME);
|
|
this.clear;
|
|
return this.backlight(0x0);
|
|
};
|
|
|
|
Plate.prototype.sendBytes = function(cmd, values) {
|
|
var data, reg;
|
|
reg = cmd;
|
|
if (typeof values === 'number') {
|
|
data = [];
|
|
data.push(values);
|
|
values = data;
|
|
}
|
|
return this.WIRE.writeBytes(cmd, values);
|
|
};
|
|
|
|
Plate.prototype.sendByte = function(value) {
|
|
return this.WIRE.writeByte(value);
|
|
};
|
|
|
|
Plate.prototype.maskOut = function(bitmask, value) {
|
|
var hi, lo;
|
|
hi = bitmask | flip[value >> 4];
|
|
lo = bitmask | flip[value & 0x0F];
|
|
return [hi | 0x20, hi, lo | 0x20, lo];
|
|
};
|
|
|
|
Plate.prototype.writeByte = function(value, char_mode) {
|
|
var bitmask, bits, data, hi, j, k, last, lo, ref;
|
|
char_mode = char_mode || false;
|
|
if (this.DDRB & 0x10) {
|
|
lo = (this.PORTB & 0x01) | 0x40;
|
|
hi = lo | 0x20;
|
|
this.sendBytes(MCP23017_GPIOB, lo);
|
|
while (true) {
|
|
this.sendByte(hi);
|
|
bits = this.readByte();
|
|
this.sendBytes(MCP23017_GPIOB, [lo, hi, lo]);
|
|
if ((bits & 0x2) === 0) {
|
|
break;
|
|
}
|
|
}
|
|
this.PORTB = lo;
|
|
this.DDRB &= 0xEF;
|
|
this.sendBytes(MCP23017_IODIRB, this.DDRB);
|
|
}
|
|
bitmask = this.PORTB & 0x01;
|
|
if (char_mode) {
|
|
bitmask |= 0x80;
|
|
}
|
|
if (typeof value === "string") {
|
|
last = value.length - 1;
|
|
data = [];
|
|
for (k = j = 0, ref = last; 0 <= ref ? j <= ref : j >= ref; k = 0 <= ref ? ++j : --j) {
|
|
if (value[k] != null) {
|
|
data = data.concat(this.maskOut(bitmask, value[k].charCodeAt(0)));
|
|
if (data.length >= 32 || k === last) {
|
|
this.sendBytes(MCP23017_GPIOB, data);
|
|
this.PORTB = data[data.length - 1];
|
|
data = [];
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
data = this.maskOut(bitmask, value);
|
|
this.sendBytes(MCP23017_GPIOB, data);
|
|
this.PORTB = data[data.length - 1];
|
|
}
|
|
if (!char_mode && pollables.indexOf(value) !== -1) {
|
|
this.DDRB |= 0x10;
|
|
return this.sendBytes(MCP23017_IODIRB, this.DDRB);
|
|
}
|
|
};
|
|
|
|
Plate.prototype.readByte = function() {
|
|
return this.WIRE.readByte();
|
|
};
|
|
|
|
return Plate;
|
|
|
|
})(EventEmitter);
|
|
|
|
module.exports = Plate;
|
|
|
|
}).call(this);
|