diff --git a/build/oled.d.ts b/build/oled.d.ts new file mode 100644 index 0000000..3351092 --- /dev/null +++ b/build/oled.d.ts @@ -0,0 +1,129 @@ +/// +/// +import { Board, Pin } from "johnny-five"; +declare enum Protocol { + I2C = 0, + SPI = 1 +} +declare enum TransferType { + Command = 0, + Data = 1 +} +type Direction = 'left' | 'left diagonal' | 'right' | 'right diagonal'; +type Black = 0x00; +type White = 0x01 | 0xff; +type Color = Black | White; +type Pixel = [number, number, Color]; +interface OledOptions { + height?: number; + width?: number; + address?: number; + microview?: boolean; + secondaryPin?: number; + resetPin?: number; + data?: number; + command?: number; +} +interface Font { + monospace: boolean; + width: number; + height: number; + fontData: number[]; + lookup: string[]; +} +interface ScreenConfig { + multiplex: number; + compins: number; + coloffset: number; +} +interface SPIConfig { + dcPin: number; + ssPin: number; + rstPin: number; + clkPin: number; + mosiPin: number; +} +declare const _default: { + new (board: Board, five: any, opts: OledOptions): { + readonly HEIGHT: number; + readonly WIDTH: number; + readonly ADDRESS: number; + readonly PROTOCOL: Protocol; + readonly MICROVIEW: boolean; + readonly SECONDARYPIN: number; + readonly RESETPIN: number; + readonly DATA: number; + readonly COMMAND: number; + readonly board: Board; + readonly five: any; + readonly screenConfig: ScreenConfig; + readonly SPIconfig: SPIConfig; + dcPin: Pin; + ssPin: Pin; + clkPin: Pin; + mosiPin: Pin; + rstPin: Pin; + buffer: Buffer; + cursor_x: number; + cursor_y: number; + dirtyBytes: number[]; + _initialise(): void; + _setUpSPI(): void; + _setUpI2C(opts: OledOptions): void; + _transfer(type: TransferType, val: number): void; + _writeSPI(byte: number, mode: TransferType): void; + _readI2C(fn: (data: number) => void): void; + _waitUntilReady(callback: () => void): void; + setCursor(x: number, y: number): void; + _invertColor(color: Color): Color; + writeString(font: Font, size: number, string: string, color: Color, wrap: boolean, linespacing: number | null, sync?: boolean): void; + _drawChar(font: Font, byteArray: number[][], size: number, color: Color, sync?: boolean): void; + _readCharBytes(byteArray: number[]): number[][]; + _findCharBuf(font: Font, c: string): number[]; + update(): void; + dimDisplay(bool: boolean): void; + turnOffDisplay(): void; + turnOnDisplay(): void; + clearDisplay(sync?: boolean): void; + invertDisplay(bool: boolean): void; + drawBitmap(pixels: Color[], sync?: boolean): void; + _isSinglePixel(pixels: Pixel | Pixel[]): pixels is Pixel; + drawPixel(pixels: Pixel | Pixel[], sync?: boolean): void; + _updateDirtyBytes(byteArray: number[]): void; + drawLine(x0: number, y0: number, x1: number, y1: number, color: Color, sync?: boolean): void; + drawRect(x: number, y: number, w: number, h: number, color: Color, sync?: boolean): void; + fillRect(x: number, y: number, w: number, h: number, color: Color, sync?: boolean): void; + drawCircle(x0: number, y0: number, r: number, color: Color, sync?: boolean): void; + startScroll(dir: Direction, start: number, stop: number): void; + stopScroll(): void; + }; + readonly DISPLAY_OFF: number; + readonly DISPLAY_ON: number; + readonly SET_DISPLAY_CLOCK_DIV: number; + readonly SET_MULTIPLEX: number; + readonly SET_DISPLAY_OFFSET: number; + readonly SET_START_LINE: number; + readonly CHARGE_PUMP: number; + readonly EXTERNAL_VCC: boolean; + readonly MEMORY_MODE: number; + readonly SEG_REMAP: number; + readonly COM_SCAN_DEC: number; + readonly COM_SCAN_INC: number; + readonly SET_COM_PINS: number; + readonly SET_CONTRAST: number; + readonly SET_PRECHARGE: number; + readonly SET_VCOM_DETECT: number; + readonly DISPLAY_ALL_ON_RESUME: number; + readonly NORMAL_DISPLAY: number; + readonly COLUMN_ADDR: number; + readonly PAGE_ADDR: number; + readonly INVERT_DISPLAY: number; + readonly ACTIVATE_SCROLL: number; + readonly DEACTIVATE_SCROLL: number; + readonly SET_VERTICAL_SCROLL_AREA: number; + readonly RIGHT_HORIZONTAL_SCROLL: number; + readonly LEFT_HORIZONTAL_SCROLL: number; + readonly VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL: number; + readonly VERTICAL_AND_LEFT_HORIZONTAL_SCROLL: number; +}; +export = _default; diff --git a/build/oled.js b/build/oled.js new file mode 100644 index 0000000..04d7253 --- /dev/null +++ b/build/oled.js @@ -0,0 +1,553 @@ +"use strict"; +var _a; +var Protocol; +(function (Protocol) { + Protocol[Protocol["I2C"] = 0] = "I2C"; + Protocol[Protocol["SPI"] = 1] = "SPI"; +})(Protocol || (Protocol = {})); +var TransferType; +(function (TransferType) { + TransferType[TransferType["Command"] = 0] = "Command"; + TransferType[TransferType["Data"] = 1] = "Data"; +})(TransferType || (TransferType = {})); +module.exports = (_a = (function () { + function Oled(board, five, opts) { + this.HEIGHT = opts.height || 32; + this.WIDTH = opts.width || 128; + this.ADDRESS = opts.address || 0x3C; + this.PROTOCOL = (opts.address) ? Protocol.I2C : Protocol.SPI; + this.MICROVIEW = opts.microview || false; + this.SECONDARYPIN = opts.secondaryPin || 12; + this.RESETPIN = opts.resetPin || 4; + this.DATA = opts.data || 0x40; + this.COMMAND = opts.command || 0x00; + this.cursor_x = 0; + this.cursor_y = 0; + this.buffer = Buffer.alloc((this.WIDTH * this.HEIGHT) / 8); + this.buffer.fill(0x00); + this.dirtyBytes = []; + this.board = board; + this.five = five; + var config = { + '128x32': { + 'multiplex': 0x1F, + 'compins': 0x02, + 'coloffset': 0 + }, + '128x64': { + 'multiplex': 0x3F, + 'compins': 0x12, + 'coloffset': 0 + }, + '96x16': { + 'multiplex': 0x0F, + 'compins': 0x2, + 'coloffset': 0 + }, + '64x48': { + 'multiplex': 0x2F, + 'compins': 0x12, + 'coloffset': (this.MICROVIEW) ? 32 : 0 + } + }; + if (this.MICROVIEW) { + this.SPIconfig = { + 'dcPin': 8, + 'ssPin': 10, + 'rstPin': 7, + 'clkPin': 13, + 'mosiPin': 11 + }; + } + else if (this.PROTOCOL === Protocol.SPI) { + this.SPIconfig = { + 'dcPin': 11, + 'ssPin': this.SECONDARYPIN, + 'rstPin': 13, + 'clkPin': 10, + 'mosiPin': 9 + }; + } + var screenSize = "".concat(this.WIDTH, "x").concat(this.HEIGHT); + this.screenConfig = config[screenSize]; + if (this.PROTOCOL === Protocol.I2C) { + this._setUpI2C(opts); + } + else { + this._setUpSPI(); + } + this._initialise(); + } + Oled.prototype._initialise = function () { + var initSeq = [ + Oled.DISPLAY_OFF, + Oled.SET_DISPLAY_CLOCK_DIV, 0x80, + Oled.SET_MULTIPLEX, this.screenConfig.multiplex, + Oled.SET_DISPLAY_OFFSET, 0x00, + Oled.SET_START_LINE, + Oled.CHARGE_PUMP, 0x14, + Oled.MEMORY_MODE, 0x00, + Oled.SEG_REMAP, + Oled.COM_SCAN_DEC, + Oled.SET_COM_PINS, this.screenConfig.compins, + Oled.SET_CONTRAST, 0x8F, + Oled.SET_PRECHARGE, 0xF1, + Oled.SET_VCOM_DETECT, 0x40, + Oled.DISPLAY_ALL_ON_RESUME, + Oled.NORMAL_DISPLAY, + Oled.DISPLAY_ON + ]; + for (var i = 0; i < initSeq.length; i++) { + this._transfer(TransferType.Command, initSeq[i]); + } + }; + Oled.prototype._setUpSPI = function () { + this.dcPin = new this.five.Pin(this.SPIconfig.dcPin); + this.ssPin = new this.five.Pin(this.SPIconfig.ssPin); + this.clkPin = new this.five.Pin(this.SPIconfig.clkPin); + this.mosiPin = new this.five.Pin(this.SPIconfig.mosiPin); + this.rstPin = new this.five.Pin(this.SPIconfig.rstPin); + this.rstPin.low(); + this.rstPin.high(); + this.ssPin.high(); + }; + Oled.prototype._setUpI2C = function (opts) { + this.board.io.i2cConfig(opts); + this.rstPin = new this.five.Pin({ pin: this.RESETPIN, board: this.board }); + this.rstPin.low(); + this.rstPin.high(); + }; + Oled.prototype._transfer = function (type, val) { + var control; + if (type === TransferType.Data) { + control = this.DATA; + } + else if (type === TransferType.Command) { + control = this.COMMAND; + } + else { + return; + } + if (this.PROTOCOL === Protocol.I2C) { + this.board.io.i2cWrite(this.ADDRESS, [control, val]); + } + else { + this._writeSPI(val, type); + } + }; + Oled.prototype._writeSPI = function (byte, mode) { + if (mode === TransferType.Command) { + this.dcPin.low(); + } + else { + this.dcPin.high(); + } + this.ssPin.low(); + for (var bit = 7; bit >= 0; bit--) { + this.clkPin.low(); + if (byte & (1 << bit)) { + this.mosiPin.high(); + } + else { + this.mosiPin.low(); + } + this.clkPin.high(); + } + this.ssPin.high(); + }; + Oled.prototype._readI2C = function (fn) { + this.board.io.i2cReadOnce(this.ADDRESS, 1, function (data) { + fn(data); + }); + }; + Oled.prototype._waitUntilReady = function (callback) { + var oled = this; + var tick = function (callback) { + oled._readI2C(function (byte) { + var busy = byte >> 7 & 1; + if (!busy) { + callback(); + } + else { + console.log('I\'m busy!'); + setTimeout(tick, 0); + } + }); + }; + if (this.PROTOCOL === Protocol.I2C) { + setTimeout(function () { tick(callback); }, 0); + } + else { + callback(); + } + }; + Oled.prototype.setCursor = function (x, y) { + this.cursor_x = x; + this.cursor_y = y; + }; + Oled.prototype._invertColor = function (color) { + return (color === 0) ? 1 : 0; + }; + Oled.prototype.writeString = function (font, size, string, color, wrap, linespacing, sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + var wordArr = string.split(' '); + var len = wordArr.length; + var offset = this.cursor_x; + var padding = 0; + var letspace = 1; + var leading = linespacing || 2; + for (var i = 0; i < len; i += 1) { + if (i < len - 1) + wordArr[i] += ' '; + var stringArr = wordArr[i].split(''); + var slen = stringArr.length; + var compare = (font.width * size * slen) + (size * (len - 1)); + if (wrap && len > 1 && (offset >= (this.WIDTH - compare))) { + offset = 1; + this.cursor_y += (font.height * size) + size + leading; + this.setCursor(offset, this.cursor_y); + } + for (var i_1 = 0; i_1 < slen; i_1 += 1) { + var charBuf = this._findCharBuf(font, stringArr[i_1]); + var charBytes = this._readCharBytes(charBuf); + this._drawChar(font, charBytes, size, color, false); + this.fillRect(offset - padding, this.cursor_y, padding, (font.height * size), this._invertColor(color), false); + padding = (stringArr[i_1] === ' ') ? 0 : size + letspace; + offset += (font.width * size) + padding; + if (wrap && (offset >= (this.WIDTH - font.width - letspace))) { + offset = 1; + this.cursor_y += (font.height * size) + size + leading; + } + this.setCursor(offset, this.cursor_y); + } + } + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + Oled.prototype._drawChar = function (font, byteArray, size, color, sync) { + var x = this.cursor_x; + var y = this.cursor_y; + var c = 0; + var pagePos = 0; + for (var i = 0; i < byteArray.length; i += 1) { + pagePos = Math.floor(i / font.width) * 8; + for (var j = 0; j < 8; j += 1) { + var pixelState = (byteArray[i][j] === 1) ? color : this._invertColor(color); + var xpos = void 0; + var ypos = void 0; + if (size === 1) { + xpos = x + c; + ypos = y + j + pagePos; + this.drawPixel([xpos, ypos, pixelState], false); + } + else { + xpos = x + (i * size); + ypos = y + (j * size); + this.fillRect(xpos, ypos, size, size, pixelState, false); + } + } + c = (c < font.width - 1) ? c += 1 : 0; + } + }; + Oled.prototype._readCharBytes = function (byteArray) { + var bitArr = []; + var bitCharArr = []; + for (var i = 0; i < byteArray.length; i += 1) { + var byte = byteArray[i]; + for (var j = 0; j < 8; j += 1) { + var bit = byte >> j & 1; + bitArr.push(bit); + } + bitCharArr.push(bitArr); + bitArr = []; + } + return bitCharArr; + }; + Oled.prototype._findCharBuf = function (font, c) { + var charLength = Math.ceil((font.width * font.height) / 8); + var cBufPos = font.lookup.indexOf(c) * charLength; + return font.fontData.slice(cBufPos, cBufPos + charLength); + }; + Oled.prototype.update = function () { + var _this = this; + this._waitUntilReady(function () { + var displaySeq = [ + Oled.COLUMN_ADDR, + _this.screenConfig.coloffset, + _this.screenConfig.coloffset + _this.WIDTH - 1, + Oled.PAGE_ADDR, 0, (_this.HEIGHT / 8) - 1 + ]; + var displaySeqLen = displaySeq.length; + var bufferLen = _this.buffer.length; + for (var i = 0; i < displaySeqLen; i += 1) { + _this._transfer(TransferType.Command, displaySeq[i]); + } + for (var i = 0; i < bufferLen; i += 1) { + _this._transfer(TransferType.Data, _this.buffer[i]); + } + }); + this.dirtyBytes = []; + }; + Oled.prototype.dimDisplay = function (bool) { + var contrast; + if (bool) { + contrast = 0; + } + else { + contrast = 0xCF; + } + this._transfer(TransferType.Command, Oled.SET_CONTRAST); + this._transfer(TransferType.Command, contrast); + }; + Oled.prototype.turnOffDisplay = function () { + this._transfer(TransferType.Command, Oled.DISPLAY_OFF); + }; + Oled.prototype.turnOnDisplay = function () { + this._transfer(TransferType.Command, Oled.DISPLAY_ON); + }; + Oled.prototype.clearDisplay = function (sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + for (var i = 0; i < this.buffer.length; i += 1) { + if (this.buffer[i] !== 0x00) { + this.buffer[i] = 0x00; + if (this.dirtyBytes.indexOf(i) === -1) { + this.dirtyBytes.push(i); + } + } + } + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + Oled.prototype.invertDisplay = function (bool) { + if (bool) { + this._transfer(TransferType.Command, Oled.INVERT_DISPLAY); + } + else { + this._transfer(TransferType.Command, Oled.NORMAL_DISPLAY); + } + }; + Oled.prototype.drawBitmap = function (pixels, sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + for (var i = 0; i < pixels.length; i++) { + var x = Math.floor(i % this.WIDTH); + var y = Math.floor(i / this.WIDTH); + this.drawPixel([x, y, pixels[i]], false); + } + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + Oled.prototype._isSinglePixel = function (pixels) { + return typeof pixels[0] !== 'object'; + }; + Oled.prototype.drawPixel = function (pixels, sync) { + var _this = this; + var immed = (typeof sync === 'undefined') ? true : sync; + if (this._isSinglePixel(pixels)) + pixels = [pixels]; + pixels.forEach(function (el) { + var x = el[0], y = el[1], color = el[2]; + if (x > _this.WIDTH || y > _this.HEIGHT) + return; + var byte = 0; + var page = Math.floor(y / 8); + var pageShift = 0x01 << (y - 8 * page); + (page === 0) ? byte = x : byte = x + (_this.WIDTH * page); + if (color === 0) { + _this.buffer[byte] &= ~pageShift; + } + else { + _this.buffer[byte] |= pageShift; + } + if (_this.dirtyBytes.indexOf(byte) === -1) { + _this.dirtyBytes.push(byte); + } + }, this); + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + Oled.prototype._updateDirtyBytes = function (byteArray) { + var _this = this; + var blen = byteArray.length; + this._waitUntilReady(function () { + var pageStart = Infinity; + var pageEnd = 0; + var colStart = Infinity; + var colEnd = 0; + var any = false; + for (var i = 0; i < blen; i += 1) { + var b = byteArray[i]; + if ((b >= 0) && (b < _this.buffer.length)) { + var page = b / _this.WIDTH | 0; + if (page < pageStart) + pageStart = page; + if (page > pageEnd) + pageEnd = page; + var col = b % _this.WIDTH; + if (col < colStart) + colStart = col; + if (col > colEnd) + colEnd = col; + any = true; + } + } + if (!any) + return; + var displaySeq = [ + Oled.COLUMN_ADDR, colStart, colEnd, + Oled.PAGE_ADDR, pageStart, pageEnd + ]; + var displaySeqLen = displaySeq.length; + for (var i = 0; i < displaySeqLen; i += 1) { + _this._transfer(TransferType.Command, displaySeq[i]); + } + for (var i = pageStart; i <= pageEnd; i += 1) { + for (var j = colStart; j <= colEnd; j += 1) { + _this._transfer(TransferType.Data, _this.buffer[_this.WIDTH * i + j]); + } + } + }); + this.dirtyBytes = []; + }; + Oled.prototype.drawLine = function (x0, y0, x1, y1, color, sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + var dx = Math.abs(x1 - x0); + var sx = x0 < x1 ? 1 : -1; + var dy = Math.abs(y1 - y0); + var sy = y0 < y1 ? 1 : -1; + var err = (dx > dy ? dx : -dy) / 2; + while (true) { + this.drawPixel([x0, y0, color], false); + if (x0 === x1 && y0 === y1) + break; + var e2 = err; + if (e2 > -dx) { + err -= dy; + x0 += sx; + } + if (e2 < dy) { + err += dx; + y0 += sy; + } + } + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + Oled.prototype.drawRect = function (x, y, w, h, color, sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + this.drawLine(x, y, x + w, y, color, false); + this.drawLine(x, y + 1, x, y + h - 1, color, false); + this.drawLine(x + w, y + 1, x + w, y + h - 1, color, false); + this.drawLine(x, y + h - 1, x + w, y + h - 1, color, false); + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + ; + Oled.prototype.fillRect = function (x, y, w, h, color, sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + for (var i = x; i < x + w; i += 1) { + this.drawLine(i, y, i, y + h - 1, color, false); + } + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + Oled.prototype.drawCircle = function (x0, y0, r, color, sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + var f = 1 - r; + var ddF_x = 1; + var ddF_y = -2 * r; + var x = 0; + var y = r; + this.drawPixel([[x0, y0 + r, color], + [x0, y0 - r, color], + [x0 + r, y0, color], + [x0 - r, y0, color]], false); + while (x < y) { + if (f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + this.drawPixel([[x0 + x, y0 + y, color], + [x0 - x, y0 + y, color], + [x0 + x, y0 - y, color], + [x0 - x, y0 - y, color], + [x0 + y, y0 + x, color], + [x0 - y, y0 + x, color], + [x0 + y, y0 - x, color], + [x0 - y, y0 - x, color]], false); + } + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } + }; + ; + Oled.prototype.startScroll = function (dir, start, stop) { + var _this = this; + var cmdSeq = []; + switch (dir) { + case 'right': + cmdSeq.push(Oled.RIGHT_HORIZONTAL_SCROLL); + break; + case 'left': + cmdSeq.push(Oled.LEFT_HORIZONTAL_SCROLL); + break; + case 'left diagonal': + cmdSeq.push(Oled.SET_VERTICAL_SCROLL_AREA, 0x00, this.HEIGHT, Oled.VERTICAL_AND_LEFT_HORIZONTAL_SCROLL, 0x00, start, 0x00, stop, 0x01, Oled.ACTIVATE_SCROLL); + break; + case 'right diagonal': + cmdSeq.push(Oled.SET_VERTICAL_SCROLL_AREA, 0x00, this.HEIGHT, Oled.VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL, 0x00, start, 0x00, stop, 0x01, Oled.ACTIVATE_SCROLL); + break; + } + this._waitUntilReady(function () { + if (dir === 'right' || dir === 'left') { + cmdSeq.push(0x00, start, 0x00, stop, 0x00, 0xFF, Oled.ACTIVATE_SCROLL); + } + for (var i = 0; i < cmdSeq.length; i += 1) { + _this._transfer(TransferType.Command, cmdSeq[i]); + } + }); + }; + Oled.prototype.stopScroll = function () { + this._transfer(TransferType.Command, Oled.DEACTIVATE_SCROLL); + }; + return Oled; + }()), + _a.DISPLAY_OFF = 0xAE, + _a.DISPLAY_ON = 0xAF, + _a.SET_DISPLAY_CLOCK_DIV = 0xD5, + _a.SET_MULTIPLEX = 0xA8, + _a.SET_DISPLAY_OFFSET = 0xD3, + _a.SET_START_LINE = 0x00, + _a.CHARGE_PUMP = 0x8D, + _a.EXTERNAL_VCC = false, + _a.MEMORY_MODE = 0x20, + _a.SEG_REMAP = 0xA1, + _a.COM_SCAN_DEC = 0xC8, + _a.COM_SCAN_INC = 0xC0, + _a.SET_COM_PINS = 0xDA, + _a.SET_CONTRAST = 0x81, + _a.SET_PRECHARGE = 0xd9, + _a.SET_VCOM_DETECT = 0xDB, + _a.DISPLAY_ALL_ON_RESUME = 0xA4, + _a.NORMAL_DISPLAY = 0xA6, + _a.COLUMN_ADDR = 0x21, + _a.PAGE_ADDR = 0x22, + _a.INVERT_DISPLAY = 0xA7, + _a.ACTIVATE_SCROLL = 0x2F, + _a.DEACTIVATE_SCROLL = 0x2E, + _a.SET_VERTICAL_SCROLL_AREA = 0xA3, + _a.RIGHT_HORIZONTAL_SCROLL = 0x26, + _a.LEFT_HORIZONTAL_SCROLL = 0x27, + _a.VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29, + _a.VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A, + _a); diff --git a/oled.ts b/oled.ts index b118f51..58c1a3f 100644 --- a/oled.ts +++ b/oled.ts @@ -43,63 +43,63 @@ interface SPIConfig { export = class Oled { // Configuration - private readonly HEIGHT: number - private readonly WIDTH: number - private readonly ADDRESS: number - private readonly PROTOCOL: Protocol - private readonly MICROVIEW: boolean - private readonly SECONDARYPIN: number - private readonly RESETPIN: number - private readonly DATA: number - private readonly COMMAND: number - - private readonly board: Board - private readonly five: any - - private readonly screenConfig: ScreenConfig - private readonly SPIconfig: SPIConfig - - private dcPin: Pin - private ssPin: Pin - private clkPin: Pin - private mosiPin: Pin - private rstPin: Pin + /* private */ readonly HEIGHT: number + /* private */ readonly WIDTH: number + /* private */ readonly ADDRESS: number + /* private */ readonly PROTOCOL: Protocol + /* private */ readonly MICROVIEW: boolean + /* private */ readonly SECONDARYPIN: number + /* private */ readonly RESETPIN: number + /* private */ readonly DATA: number + /* private */ readonly COMMAND: number + + /* private */ readonly board: Board + /* private */ readonly five: any + + /* private */ readonly screenConfig: ScreenConfig + /* private */ readonly SPIconfig: SPIConfig + + /* private */ dcPin: Pin + /* private */ ssPin: Pin + /* private */ clkPin: Pin + /* private */ mosiPin: Pin + /* private */ rstPin: Pin // Commands - private static readonly DISPLAY_OFF: number = 0xAE - private static readonly DISPLAY_ON: number = 0xAF - private static readonly SET_DISPLAY_CLOCK_DIV: number = 0xD5 - private static readonly SET_MULTIPLEX: number = 0xA8 - private static readonly SET_DISPLAY_OFFSET: number = 0xD3 - private static readonly SET_START_LINE: number = 0x00 - private static readonly CHARGE_PUMP: number = 0x8D - private static readonly EXTERNAL_VCC: boolean = false - private static readonly MEMORY_MODE: number = 0x20 - private static readonly SEG_REMAP: number = 0xA1 // using 0xA0 will flip screen - private static readonly COM_SCAN_DEC: number = 0xC8 - private static readonly COM_SCAN_INC: number = 0xC0 - private static readonly SET_COM_PINS: number = 0xDA - private static readonly SET_CONTRAST: number = 0x81 - private static readonly SET_PRECHARGE: number = 0xd9 - private static readonly SET_VCOM_DETECT: number = 0xDB - private static readonly DISPLAY_ALL_ON_RESUME: number = 0xA4 - private static readonly NORMAL_DISPLAY: number = 0xA6 - private static readonly COLUMN_ADDR: number = 0x21 - private static readonly PAGE_ADDR: number = 0x22 - private static readonly INVERT_DISPLAY: number = 0xA7 - private static readonly ACTIVATE_SCROLL: number = 0x2F - private static readonly DEACTIVATE_SCROLL: number = 0x2E - private static readonly SET_VERTICAL_SCROLL_AREA: number = 0xA3 - private static readonly RIGHT_HORIZONTAL_SCROLL: number = 0x26 - private static readonly LEFT_HORIZONTAL_SCROLL: number = 0x27 - private static readonly VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL: number = 0x29 - private static readonly VERTICAL_AND_LEFT_HORIZONTAL_SCROLL: number = 0x2A + /* private */ static readonly DISPLAY_OFF: number = 0xAE + /* private */ static readonly DISPLAY_ON: number = 0xAF + /* private */ static readonly SET_DISPLAY_CLOCK_DIV: number = 0xD5 + /* private */ static readonly SET_MULTIPLEX: number = 0xA8 + /* private */ static readonly SET_DISPLAY_OFFSET: number = 0xD3 + /* private */ static readonly SET_START_LINE: number = 0x00 + /* private */ static readonly CHARGE_PUMP: number = 0x8D + /* private */ static readonly EXTERNAL_VCC: boolean = false + /* private */ static readonly MEMORY_MODE: number = 0x20 + /* private */ static readonly SEG_REMAP: number = 0xA1 // using 0xA0 will flip screen + /* private */ static readonly COM_SCAN_DEC: number = 0xC8 + /* private */ static readonly COM_SCAN_INC: number = 0xC0 + /* private */ static readonly SET_COM_PINS: number = 0xDA + /* private */ static readonly SET_CONTRAST: number = 0x81 + /* private */ static readonly SET_PRECHARGE: number = 0xd9 + /* private */ static readonly SET_VCOM_DETECT: number = 0xDB + /* private */ static readonly DISPLAY_ALL_ON_RESUME: number = 0xA4 + /* private */ static readonly NORMAL_DISPLAY: number = 0xA6 + /* private */ static readonly COLUMN_ADDR: number = 0x21 + /* private */ static readonly PAGE_ADDR: number = 0x22 + /* private */ static readonly INVERT_DISPLAY: number = 0xA7 + /* private */ static readonly ACTIVATE_SCROLL: number = 0x2F + /* private */ static readonly DEACTIVATE_SCROLL: number = 0x2E + /* private */ static readonly SET_VERTICAL_SCROLL_AREA: number = 0xA3 + /* private */ static readonly RIGHT_HORIZONTAL_SCROLL: number = 0x26 + /* private */ static readonly LEFT_HORIZONTAL_SCROLL: number = 0x27 + /* private */ static readonly VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL: number = 0x29 + /* private */ static readonly VERTICAL_AND_LEFT_HORIZONTAL_SCROLL: number = 0x2A // State - private buffer: Buffer - private cursor_x: number - private cursor_y: number - private dirtyBytes: number[] + /* private */ buffer: Buffer + /* private */ cursor_x: number + /* private */ cursor_y: number + /* private */ dirtyBytes: number[] public constructor (board: Board, five: any, opts: OledOptions) { this.HEIGHT = opts.height || 32 @@ -182,7 +182,7 @@ export = class Oled { this._initialise() } - private _initialise (): void { + /* private */ _initialise (): void { // sequence of bytes to initialise with const initSeq = [ Oled.DISPLAY_OFF, @@ -209,7 +209,7 @@ export = class Oled { } } - private _setUpSPI (): void { + /* private */ _setUpSPI (): void { // set up spi pins this.dcPin = new this.five.Pin(this.SPIconfig.dcPin) this.ssPin = new this.five.Pin(this.SPIconfig.ssPin) @@ -225,17 +225,17 @@ export = class Oled { this.ssPin.high() } - private _setUpI2C (opts: OledOptions): void { + /* private */ _setUpI2C (opts: OledOptions): void { // enable i2C in firmata this.board.io.i2cConfig(opts) // set up reset pin and hold high - this.rstPin = new this.five.Pin(this.RESETPIN) + this.rstPin = new this.five.Pin({pin: this.RESETPIN, board: this.board}) this.rstPin.low() this.rstPin.high() } // writes both commands and data buffers to this device - private _transfer (type: TransferType, val: number): void { + /* private */ _transfer (type: TransferType, val: number): void { let control: number if (type === TransferType.Data) { @@ -255,7 +255,7 @@ export = class Oled { } } - private _writeSPI (byte: number, mode: TransferType): void { + /* private */ _writeSPI (byte: number, mode: TransferType): void { // set dc to low if command byte, high if data byte if (mode === TransferType.Command) { this.dcPin.low() @@ -287,7 +287,7 @@ export = class Oled { } // read a byte from the oled - private _readI2C (fn: (data: number) => void): void { + /* private */ _readI2C (fn: (data: number) => void): void { this.board.io.i2cReadOnce(this.ADDRESS, 1, (data: number) => { fn(data) }) @@ -295,7 +295,7 @@ export = class Oled { // sometimes the oled gets a bit busy with lots of bytes. // Read the response byte to see if this is the case - private _waitUntilReady (callback: () => void): void { + /* private */ _waitUntilReady (callback: () => void): void { const oled = this const tick = (callback: () => void) => { @@ -325,7 +325,7 @@ export = class Oled { this.cursor_y = y } - private _invertColor(color: Color): Color { + /* private */ _invertColor(color: Color): Color { return (color === 0) ? 1 : 0 } @@ -391,7 +391,7 @@ export = class Oled { } // draw an individual character to the screen - private _drawChar (font: Font, byteArray: number[][], size: number, color: Color, sync?: boolean): void { + /* private */ _drawChar (font: Font, byteArray: number[][], size: number, color: Color, sync?: boolean): void { // take your positions... const x = this.cursor_x const y = this.cursor_y @@ -423,7 +423,7 @@ export = class Oled { } // get character bytes from the supplied font object in order to send to framebuffer - private _readCharBytes (byteArray: number[]): number[][] { + /* private */ _readCharBytes (byteArray: number[]): number[][] { let bitArr = [] const bitCharArr = [] // loop through each byte supplied for a char @@ -446,7 +446,7 @@ export = class Oled { } // find where the character exists within the font object - private _findCharBuf (font: Font, c: string): number[] { + /* private */ _findCharBuf (font: Font, c: string): number[] { const charLength = Math.ceil((font.width * font.height) / 8) // use the lookup array as a ref to find where the current char bytes start const cBufPos = font.lookup.indexOf(c) * charLength @@ -551,7 +551,7 @@ export = class Oled { } } - private _isSinglePixel(pixels: Pixel | Pixel[]): pixels is Pixel { + /* private */ _isSinglePixel(pixels: Pixel | Pixel[]): pixels is Pixel { return typeof pixels[0] !== 'object' } @@ -600,7 +600,7 @@ export = class Oled { } // looks at dirty bytes, and sends the updated bytes to the display - private _updateDirtyBytes (byteArray: number[]): void { + /* private */ _updateDirtyBytes (byteArray: number[]): void { const blen = byteArray.length this._waitUntilReady(() => { diff --git a/package.json b/package.json index bc0e54b..e733c90 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,10 @@ "tape": "^4.6.3", "temporal": "^0.5.0", "testdouble": "^3.1.0", - "typescript": "^3.7.5" + "typescript": "^4.0.0" }, "dependencies": { - "@types/johnny-five": "*", - "serialport": "8" + "@types/johnny-five": "*" }, "scripts": { "build": "tsc -b",