diff --git a/Firmware/pong/README.md b/Firmware/pong/README.md new file mode 100644 index 0000000..971b51f --- /dev/null +++ b/Firmware/pong/README.md @@ -0,0 +1,145 @@ +NodeJS Wrapper for SparkFun Edison OLED Block +============================================= + +Developing a node app for your Edison? Need to use the OLED display from SparkFun, GPIO pins or SPI? You're in luck! + +Features + + * OLED + * GPIO + * SPI + +NOTES + + * This has only been tested with the SparkFun Edison OLED Block, but GPIO and SPI should (may possibly) work with other hardware. + * SPI - need to use a CS pin on Edison other than the default pin 23 (GP110), the MRAA library won't work. This library works using a pin of your choosing (tested with pin 9 (GP111)). + * GPIO pin mraa /edison reference mapping may be useful - https://github.com/intel-iot-devkit/mraa/blob/master/docs/edison.md#intelr-breakout-board + * The files in the Tests folder are meant to be run on an Intel Edison as they interact with the hardware. + +Installation +============ +This module is only designed to work on the Intel Edison. + +``` +$ npm install edison-oled +``` + +You may need to use the --unsafe-perm option if you get the warning "cannot run in wd". + +``` +$ npm install edison-oled --unsafe-perm +``` +API +============ +Example using the OLED screen + +```javascript +var edison = require('edison-oled'); + +//create Oled +var oled = new edison.Oled(); + +//setup input buttons +var btnUp = new edison.Gpio(47, edison.INPUT); +var btnDown = new edison.Gpio(44, edison.INPUT); +var btnLeft = new edison.Gpio(165, edison.INPUT); +var btnRight = new edison.Gpio(45, edison.INPUT); +var btnSelect = new edison.Gpio(48, edison.INPUT); +var btnA = new edison.Gpio(49, edison.INPUT); +var btnB = new edison.Gpio(46, edison.INPUT); + +//setup screen +oled.begin(); +oled.clear(0); +oled.display(); +oled.setFontType(0); + +//draw on screen +oled.clear(); +oled.setCursor(14, 5); +oled.print("Press A"); +oled.setCursor(2, 13); +oled.print("for single"); +oled.setCursor(14, 30); +oled.print("Press B"); +oled.setCursor(6, 38); +oled.print("for multi"); +oled.display(); + +//wait for user to make a choice using Button A or Button B +while (btnA.pinRead() == edison.HIGH && btnB.pinRead() == edison.HIGH) {} + +``` + +Example uses SPI and GPIO to communicate with OLED hardware (not a complete example, see test-spi.js for full code) + +```javascript +var edison = require('edison-oled'); + +//setup pins needed for SPI +var cspin = new edison.Gpio(111, edison.OUTPUT, edison.HIGH); //chip select --> edison_oled.c code uses 111 mraa uses 9 +var dcpin = new edison.Gpio(14, edison.OUTPUT, edison.HIGH); //data/command --> edison_oled.c code uses 14 mraa uses 36 +var rstpin = new edison.Gpio(15, edison.OUTPUT, edison.HIGH); //reset --> edison_oled.c code uses 15 mraa uses 48 +var sclkpin = new edison.Gpio(109, edison.SPI, edison.HIGH); //sclk --> edison_oled.c code uses 109 mraa uses 10 +var mosipin = new edison.Gpio(115, edison.SPI, edison.HIGH); //mosi --> edison_oled.c code uses 115 mraa uses 11 +var misopin = new edison.Gpio(114, edison.SPI, edison.HIGH); //miso --> edison_oled.c code uses 114 mraa uses 24 + +//create spi +var spi = new edison.Spi(edison.SPI_MODE_0, 10000000, false, cspin); + +//reset screen +rstpin.pinWrite(edison.HIGH); +//should add a wait time here for a few milliseconds +rstpin.pinWrite(edison.LOW); +//should add a wait time here for a few milliseconds +rstpin.pinWrite(edison.HIGH); + +//send commands to OLED +dcpin.pinWrite(edison.LOW); // DC pin LOW +spi.transferData(edison.DISPLAYOFF); +spi.transferData(edison.SETDISPLAYCLOCKDIV); +spi.transferData(0x80); + +//send data to OLED +dcpin.pinWrite(edison.HIGH); //DC pin HIGH +spi.transferData(0xFF); + +``` + +SparkFun Edison OLED Block +=========================== + +![SparkFun Edison OLED Block](https://cdn.sparkfun.com//assets/parts/1/0/0/3/6/13035-01.jpg) + +[*SparkFun Edison OLED Block(DEV-13035)*](https://www.sparkfun.com/products/13035) + +Equip your Edison with a graphic display using the Edison OLED board! This board features a 0.66", 64x48 pixel monochrome OLED. + +To add some control over your Edison and the OLED, this board also includes a small joystick and a pair of push-buttons. Use them to create a game, file navigator, or more! + +Repository Contents +------------------- +* **/Firmware** - Example Pong sketch to demonstrate OLED Functionality. +* **/Hardware** - All Eagle design files (.brd, .sch) +* **/Production** - Test bed files and production panel files + +Documentation +-------------- +* **[Hookup Guide](https://learn.sparkfun.com/tutorials/sparkfun-blocks-for-intel-edison---oled-block)** - Basic hookup guide for the OLED Block. +* **[SparkFun Fritzing repo](https://github.com/sparkfun/Fritzing_Parts)** - Fritzing diagrams for SparkFun products. +* **[SparkFun 3D Model repo](https://github.com/sparkfun/3D_Models)** - 3D models of SparkFun products. +* **[SparkFun Graphical Datasheets](https://github.com/sparkfun/Graphical_Datasheets)** -Graphical Datasheets for various SparkFun products. + + +License Information +------------------- + +This product is _**open source**_! + +Please review the LICENSE.md file for license information. + +If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. + +- Your friends at SparkFun. diff --git a/Firmware/pong/binding.gyp b/Firmware/pong/binding.gyp new file mode 100644 index 0000000..f39dcf3 --- /dev/null +++ b/Firmware/pong/binding.gyp @@ -0,0 +1,13 @@ +{ + 'targets': [ + { + 'target_name': 'edisonnodeaddon', + 'sources': [ 'oled/edison_oled_wrap.cpp', 'spi/edison_spi_wrap.cpp', 'gpio/edison_gpio_wrap.cpp', 'gpio/gpio_edison.cpp', 'spi/spi_port_edison.cpp', 'spi/spi_device_edison.cpp', 'oled/Edison_OLED.cpp', 'edison_node_addon.cpp' ], + 'include_dirs': [ + " +#include "oled/edison_oled_wrap.hpp" +#include "gpio/edison_gpio_wrap.hpp" +#include "spi/edison_spi_wrap.hpp" + +using namespace v8; + +void InitAll (v8::Local exports) { + EdisonOledWrap::Init(exports); + EdisonGpioWrap::Init(exports); + EdisonSpiWrap::Init(exports); +} + +NODE_MODULE(edisonoledaddon, InitAll) \ No newline at end of file diff --git a/Firmware/pong/gpio/edison_gpio_wrap.cpp b/Firmware/pong/gpio/edison_gpio_wrap.cpp new file mode 100644 index 0000000..c7ccb84 --- /dev/null +++ b/Firmware/pong/gpio/edison_gpio_wrap.cpp @@ -0,0 +1,146 @@ +/****************************************************************************** +MIT License + +Copyright (c) 2017 Brian Feldman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ +#include "../edison_node.hpp" +#include "edison_gpio_wrap.hpp" +#include "gpio.h" +#include "gpio_edison.h" +#include + +using namespace v8; + +Nan::Persistent EdisonGpioWrap::constructor; + +EdisonGpioWrap::EdisonGpioWrap() : m_gpio() { +} + +EdisonGpioWrap::~EdisonGpioWrap() { +} + +void EdisonGpioWrap::Init(v8::Local exports) { + Nan::HandleScope scope; + + // Prepare constructor template + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("Gpio").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + Nan::SetPrototypeMethod(tpl, "pinMode", pinMode); + Nan::SetPrototypeMethod(tpl, "pinWrite", pinWrite); + Nan::SetPrototypeMethod(tpl, "pinRead", pinRead); + + /* constants */ + /* PIN_MODE*/ + NODE_DEFINE_CONSTANT(exports, INPUT); + NODE_DEFINE_CONSTANT(exports, OUTPUT); + NODE_DEFINE_CONSTANT(exports, INPUT_PU); + NODE_DEFINE_CONSTANT(exports, INPUT_PD); + NODE_DEFINE_CONSTANT(exports, SPI); + NODE_DEFINE_CONSTANT(exports, I2C); + NODE_DEFINE_CONSTANT(exports, PWM); + NODE_DEFINE_CONSTANT(exports, ADC); + NODE_DEFINE_CONSTANT(exports, UART); + + /* PIN_VALUE */ + NODE_DEFINE_CONSTANT(exports, LOW); + NODE_DEFINE_CONSTANT(exports, HIGH); + NODE_DEFINE_CONSTANT(exports, NONE); + + constructor.Reset(tpl->GetFunction()); + exports->Set(Nan::New("Gpio").ToLocalChecked(), tpl->GetFunction()); +} + +void EdisonGpioWrap::New(const Nan::FunctionCallbackInfo& args) { + if (args.Length() < 2 || args.Length() > 3) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + int pinID = args[0]->Uint32Value(); + PIN_MODE mode = static_cast(args[1]->Uint32Value()); + PIN_VALUE value = LOW; + if (args.Length() == 3) { + value = static_cast(args[2]->Uint32Value()); + } + if (args.IsConstructCall()) { + // Invoked as constructor: `new EdisonGpioWrap(...)` + EdisonGpioWrap* obj = new EdisonGpioWrap(); + //gpio *gpioObj = new gpio(args[0]->Uint32Value(), static_cast(args[1]->Uint32Value()), static_cast(args[2]->Uint32Value())); + gpio *gpioObj = new gpio(pinID, mode, value); + obj->m_gpio = gpioObj; + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); + } else { + // Invoked as plain function `EdisonGpioWrap(...)`, turn into construct call. + //v8::Local cons = Nan::New(constructor); + //args.GetReturnValue().Set(cons->NewInstance()); + Nan::ThrowTypeError(ERROR_CREATE_INSTANCE_WITH_NEW); + } +} + +gpio* EdisonGpioWrap::getGpio() { + // this is needed by SPI wrapper + return m_gpio; +} + +void EdisonGpioWrap::setGpio(gpio *pin) { + // this is needed by SPI wrapper + m_gpio = pin; +} + +void EdisonGpioWrap::pinMode(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonGpioWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + gpio* gpioObj = wrap->m_gpio; + gpioObj->pinMode(static_cast(args[0]->Uint32Value())); + args.GetReturnValue().SetUndefined(); +} + +void EdisonGpioWrap::pinWrite(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonGpioWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + gpio* gpioObj = wrap->m_gpio; + gpioObj->pinWrite(static_cast(args[0]->Uint32Value())); + args.GetReturnValue().SetUndefined(); +} + +void EdisonGpioWrap::pinRead(const Nan::FunctionCallbackInfo& args) { + EdisonGpioWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + gpio* gpioObj = wrap->m_gpio; + int out = gpioObj->pinRead(); + args.GetReturnValue().Set(Nan::New(out)); +} diff --git a/Firmware/pong/gpio/edison_gpio_wrap.hpp b/Firmware/pong/gpio/edison_gpio_wrap.hpp new file mode 100644 index 0000000..abc5595 --- /dev/null +++ b/Firmware/pong/gpio/edison_gpio_wrap.hpp @@ -0,0 +1,30 @@ +#ifndef EDISON_GPIO_WRAP_H +#define EDISON_GPIO_WRAP_H + +#include + +#include "../edison_node.hpp" +#include "gpio.h" +#include "gpio_edison.h" + +class EdisonGpioWrap : public Nan::ObjectWrap { + public: + static void Init(v8::Local exports); + static void New(const Nan::FunctionCallbackInfo& args); + + gpio* getGpio(); + void setGpio(gpio *pin); + + EdisonGpioWrap(); + private: + ~EdisonGpioWrap(); + + static void pinMode(const Nan::FunctionCallbackInfo& args); + static void pinWrite(const Nan::FunctionCallbackInfo& args); + static void pinRead(const Nan::FunctionCallbackInfo& args); + + gpio* m_gpio; + static Nan::Persistent constructor; +}; + +#endif \ No newline at end of file diff --git a/Firmware/pong/index.js b/Firmware/pong/index.js new file mode 100644 index 0000000..c962fd6 --- /dev/null +++ b/Firmware/pong/index.js @@ -0,0 +1 @@ +module.exports = require('./build/Release/edisonnodeaddon'); \ No newline at end of file diff --git a/Firmware/pong/oled/edison_oled_wrap.cpp b/Firmware/pong/oled/edison_oled_wrap.cpp new file mode 100644 index 0000000..e5d1206 --- /dev/null +++ b/Firmware/pong/oled/edison_oled_wrap.cpp @@ -0,0 +1,765 @@ +/****************************************************************************** +MIT License + +Copyright (c) 2017 Brian Feldman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ +#include "../edison_node.hpp" +#include "edison_oled_wrap.hpp" +#include "Edison_OLED.h" +#include + +using namespace v8; + +Nan::Persistent EdisonOledWrap::constructor; + +const char* ToCString(const String::Utf8Value& value) { + return *value ? *value : ""; +} + +EdisonOledWrap::EdisonOledWrap() : m_oled() { +} + +EdisonOledWrap::~EdisonOledWrap() { +} + +void EdisonOledWrap::Init(v8::Local exports) { + Nan::HandleScope scope; + + // Prepare constructor template + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("Oled").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + Nan::SetPrototypeMethod(tpl, "begin", begin); + + Nan::SetPrototypeMethod(tpl, "write", write); + Nan::SetPrototypeMethod(tpl, "print", print); + + Nan::SetPrototypeMethod(tpl, "command", command); + Nan::SetPrototypeMethod(tpl, "data", data); + Nan::SetPrototypeMethod(tpl, "setColumnAddress", setColumnAddress); + Nan::SetPrototypeMethod(tpl, "setPageAddress", setPageAddress); + + Nan::SetPrototypeMethod(tpl, "clear", clear); + Nan::SetPrototypeMethod(tpl, "invert", invert); + Nan::SetPrototypeMethod(tpl, "contrast", contrast); + Nan::SetPrototypeMethod(tpl, "display", display); + Nan::SetPrototypeMethod(tpl, "setCursor", setCursor); + + Nan::SetPrototypeMethod(tpl, "pixel", pixel); + Nan::SetPrototypeMethod(tpl, "line", line); + Nan::SetPrototypeMethod(tpl, "lineH", lineH); + Nan::SetPrototypeMethod(tpl, "lineV", lineV); + Nan::SetPrototypeMethod(tpl, "rect", rect); + Nan::SetPrototypeMethod(tpl, "rectFill", rectFill); + Nan::SetPrototypeMethod(tpl, "circle", circle); + Nan::SetPrototypeMethod(tpl, "circleFill", circleFill); + Nan::SetPrototypeMethod(tpl, "drawChar", drawChar); + + Nan::SetPrototypeMethod(tpl, "drawBitmap", drawBitmap); + + Nan::SetPrototypeMethod(tpl, "getLCDWidth", getLCDWidth); + Nan::SetPrototypeMethod(tpl, "getLCDHeight", getLCDHeight); + Nan::SetPrototypeMethod(tpl, "setColor", setColor); + Nan::SetPrototypeMethod(tpl, "setDrawMode", setDrawMode); + + Nan::SetPrototypeMethod(tpl, "getFontWidth", getFontWidth); + Nan::SetPrototypeMethod(tpl, "getFontHeight", getFontHeight); + Nan::SetPrototypeMethod(tpl, "getTotalFonts", getTotalFonts); + Nan::SetPrototypeMethod(tpl, "getFontType", getFontType); + Nan::SetPrototypeMethod(tpl, "setFontType", setFontType); + Nan::SetPrototypeMethod(tpl, "getFontStartChar", getFontStartChar); + Nan::SetPrototypeMethod(tpl, "getFontTotalChar", getFontTotalChar); + + /* + these exist in Edison_OLED.h but not in cpp file. + Nan::SetPrototypeMethod(tpl, "scrollRight", scrollRight); + Nan::SetPrototypeMethod(tpl, "scrollLeft", scrollLeft); + Nan::SetPrototypeMethod(tpl, "scrollVertRight", scrollVertRight); + Nan::SetPrototypeMethod(tpl, "scrollVertLeft", scrollVertLeft); + */ + Nan::SetPrototypeMethod(tpl, "scrollStop", scrollStop); + Nan::SetPrototypeMethod(tpl, "flipVertical", flipVertical); + Nan::SetPrototypeMethod(tpl, "flipHorizontal", flipHorizontal); + + /* constants */ + NODE_DEFINE_CONSTANT(exports, BLACK); // 0 + NODE_DEFINE_CONSTANT(exports, WHITE); // 1 + + NODE_DEFINE_CONSTANT(exports, LCDWIDTH); // 64 + NODE_DEFINE_CONSTANT(exports, LCDHEIGHT); // 48 + NODE_DEFINE_CONSTANT(exports, FONTHEADERSIZE); // 6 + + NODE_DEFINE_CONSTANT(exports, NORM); // 0 + NODE_DEFINE_CONSTANT(exports, XOR); // 1 + + NODE_DEFINE_CONSTANT(exports, PAGE); // 0 + NODE_DEFINE_CONSTANT(exports, ALL); // 1 + + NODE_DEFINE_CONSTANT(exports, SETCONTRAST); // 0x81 + NODE_DEFINE_CONSTANT(exports, DISPLAYALLONRESUME); // 0xA4 + NODE_DEFINE_CONSTANT(exports, DISPLAYALLON); // 0xA5 + NODE_DEFINE_CONSTANT(exports, NORMALDISPLAY); // 0xA6 + NODE_DEFINE_CONSTANT(exports, INVERTDISPLAY); // 0xA7 + NODE_DEFINE_CONSTANT(exports, DISPLAYOFF); // 0xAE + NODE_DEFINE_CONSTANT(exports, DISPLAYON); // 0xAF + NODE_DEFINE_CONSTANT(exports, SETDISPLAYOFFSET); // 0xD3 + NODE_DEFINE_CONSTANT(exports, SETCOMPINS); // 0xDA + NODE_DEFINE_CONSTANT(exports, SETVCOMDESELECT); // 0xDB + NODE_DEFINE_CONSTANT(exports, SETDISPLAYCLOCKDIV); // 0xD5 + NODE_DEFINE_CONSTANT(exports, SETPRECHARGE); // 0xD9 + NODE_DEFINE_CONSTANT(exports, SETMULTIPLEX); // 0xA8 + NODE_DEFINE_CONSTANT(exports, SETLOWCOLUMN); // 0x00 + NODE_DEFINE_CONSTANT(exports, SETHIGHCOLUMN); // 0x10 + NODE_DEFINE_CONSTANT(exports, SETSTARTLINE); // 0x40 + NODE_DEFINE_CONSTANT(exports, MEMORYMODE); // 0x20 + NODE_DEFINE_CONSTANT(exports, COMSCANINC); // 0xC0 + NODE_DEFINE_CONSTANT(exports, COMSCANDEC); // 0xC8 + NODE_DEFINE_CONSTANT(exports, SEGREMAP); // 0xA0 + NODE_DEFINE_CONSTANT(exports, CHARGEPUMP); // 0x8D + NODE_DEFINE_CONSTANT(exports, EXTERNALVCC); // 0x01 + NODE_DEFINE_CONSTANT(exports, SWITCHCAPVCC); // 0x02 + +// Scroll + NODE_DEFINE_CONSTANT(exports, ACTIVATESCROLL); // 0x2F + NODE_DEFINE_CONSTANT(exports, DEACTIVATESCROLL); // 0x2E + NODE_DEFINE_CONSTANT(exports, SETVERTICALSCROLLAREA); // 0xA3 + NODE_DEFINE_CONSTANT(exports, RIGHTHORIZONTALSCROLL); // 0x26 + NODE_DEFINE_CONSTANT(exports, LEFT_HORIZONTALSCROLL); // 0x27 + NODE_DEFINE_CONSTANT(exports, VERTICALRIGHTHORIZONTALSCROLL); // 0x29 + NODE_DEFINE_CONSTANT(exports, VERTICALLEFTHORIZONTALSCROLL); // 0x2A + + constructor.Reset(tpl->GetFunction()); + exports->Set(Nan::New("Oled").ToLocalChecked(), tpl->GetFunction()); +} + +void EdisonOledWrap::New(const Nan::FunctionCallbackInfo& args) { + if (args.IsConstructCall()) { + // Invoked as constructor: `new EdisonOledWrap(...)` + EdisonOledWrap* obj = new EdisonOledWrap(); + edOLED *oled = new edOLED(); + obj->m_oled = oled; + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); + } else { + // Invoked as plain function `EdisonOledWrap(...)`, turn into construct call. + //v8::Local cons = Nan::New(constructor); + //args.GetReturnValue().Set(cons->NewInstance()); + Nan::ThrowTypeError(ERROR_CREATE_INSTANCE_WITH_NEW); + } +} + +void EdisonOledWrap::begin(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->begin(); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::write(const Nan::FunctionCallbackInfo& args){ + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + + unsigned char out = oled->write(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::print(const Nan::FunctionCallbackInfo& args){ + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + String::Utf8Value str(args[0]); + oled->print(ToCString(str)); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::command(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->command(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::data(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->data(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::setColumnAddress(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->setColumnAddress(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::setPageAddress(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->setPageAddress(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::clear(const Nan::FunctionCallbackInfo& args){ + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 0 : + oled->clear(0x00); + break; + case 1 : + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->clear(args[0]->Uint32Value() & 0xFF); + break; + case 2 : + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->clear(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::invert(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->invert(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::contrast(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->contrast(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::display(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->display(); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::setCursor(const Nan::FunctionCallbackInfo& args){ + if (args.Length() != 2) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->setCursor(args[0]->Uint32Value() & 0xFF,args[1]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::pixel(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 2 : + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->pixel(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF); + break; + case 4 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->pixel(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::line(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 4 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->line(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF); + break; + case 6 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber() || !args[5]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->line(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF, args[5]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::lineH(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 3 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->lineH(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF); + break; + case 5 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->lineH(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::lineV(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 3 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->lineV(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF); + break; + case 5 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->lineV(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::rect(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 4 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->rect(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF); + break; + case 6 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber() || !args[5]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->rect(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF, args[5]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::rectFill(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 4 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->rectFill(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF); + break; + case 6 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber() || !args[5]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->rectFill(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF, args[5]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::circle(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 3 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->circle(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF); + break; + case 5 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->circle(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::circleFill(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 3 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->circleFill(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF); + break; + case 5 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->circleFill(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::drawChar(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + switch (args.Length()) { + case 3 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->drawChar(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF); + break; + case 5 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + oled->drawChar(args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value() & 0xFF, args[2]->Uint32Value() & 0xFF, args[3]->Uint32Value() & 0xFF, args[4]->Uint32Value() & 0xFF); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::drawBitmap(const Nan::FunctionCallbackInfo& args) { + //this is not implemented in the wrapped object, so throw an error + throw "Not implemented"; +} + +void EdisonOledWrap::getLCDWidth(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getLCDWidth(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::getLCDHeight(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getLCDHeight(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::setColor(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->setColor(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::setDrawMode(const Nan::FunctionCallbackInfo& args) { + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->setDrawMode(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::getFontWidth(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getFontWidth(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::getFontHeight(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getFontHeight(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::getTotalFonts(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getTotalFonts(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::getFontType(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getFontType(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::setFontType(const Nan::FunctionCallbackInfo& args){ + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->setFontType(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::getFontStartChar(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getFontStartChar(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonOledWrap::getFontTotalChar(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + unsigned char out = oled->getFontTotalChar(); + //args.GetReturnValue().Set(Nan::New(out).ToLocalChecked()); + args.GetReturnValue().Set(Nan::New(out)); +} + +/* +These exist in Edison_OLED.h but not in CPP file. +void EdisonOledWrap::scrollRight(const Nan::FunctionCallbackInfo& args){ + if (args.Length() == 2) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->scrollRight(args[0]->Uint32Value() & 0xFF,args[1]->Uint32Value() & 0xFF); + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::scrollLeft(const Nan::FunctionCallbackInfo& args){ + if (args.Length() == 2) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->scrollLeft(args[0]->Uint32Value() & 0xFF,args[1]->Uint32Value() & 0xFF); + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::scrollVertRight(const Nan::FunctionCallbackInfo& args){ + if (args.Length() == 2) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->scrollVertRight(args[0]->Uint32Value() & 0xFF,args[1]->Uint32Value() & 0xFF); + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::scrollVertLeft(const Nan::FunctionCallbackInfo& args){ + if (args.Length() == 2) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->scrollVertLeft(args[0]->Uint32Value() & 0xFF,args[1]->Uint32Value() & 0xFF); + } + args.GetReturnValue().SetUndefined(); +} +*/ + +void EdisonOledWrap::scrollStop(const Nan::FunctionCallbackInfo& args) { + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->scrollStop(); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::flipVertical(const Nan::FunctionCallbackInfo& args){ + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->flipVertical(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} + +void EdisonOledWrap::flipHorizontal(const Nan::FunctionCallbackInfo& args){ + if (args.Length() != 1) { + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonOledWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + edOLED* oled = wrap->m_oled; + oled->flipHorizontal(args[0]->Uint32Value() & 0xFF); + args.GetReturnValue().SetUndefined(); +} \ No newline at end of file diff --git a/Firmware/pong/oled/edison_oled_wrap.hpp b/Firmware/pong/oled/edison_oled_wrap.hpp new file mode 100644 index 0000000..9359919 --- /dev/null +++ b/Firmware/pong/oled/edison_oled_wrap.hpp @@ -0,0 +1,78 @@ +#ifndef EDISON_OLED_WRAP_H +#define EDISON_OLED_WRAP_H + +#include + +#include "../edison_node.hpp" +#include "Edison_OLED.h" + +class EdisonOledWrap : public Nan::ObjectWrap { + public: + static void Init(v8::Local exports); + static void New(const Nan::FunctionCallbackInfo& args); + + EdisonOledWrap(); + private: + ~EdisonOledWrap(); + + static void begin(const Nan::FunctionCallbackInfo& args); + + static void write(const Nan::FunctionCallbackInfo& args); + static void print(const Nan::FunctionCallbackInfo& args); + + // RAW LCD functions + static void command(const Nan::FunctionCallbackInfo& args); + static void data(const Nan::FunctionCallbackInfo& args); + static void setColumnAddress(const Nan::FunctionCallbackInfo& args); + static void setPageAddress(const Nan::FunctionCallbackInfo& args); + + // LCD Draw functions + static void clear(const Nan::FunctionCallbackInfo& args); + static void invert(const Nan::FunctionCallbackInfo& args); + static void contrast(const Nan::FunctionCallbackInfo& args); + static void display(const Nan::FunctionCallbackInfo& args); + static void setCursor(const Nan::FunctionCallbackInfo& args); + + static void pixel(const Nan::FunctionCallbackInfo& args); + static void line(const Nan::FunctionCallbackInfo& args); + static void lineH(const Nan::FunctionCallbackInfo& args); + static void lineV(const Nan::FunctionCallbackInfo& args); + static void rect(const Nan::FunctionCallbackInfo& args); + static void rectFill(const Nan::FunctionCallbackInfo& args); + static void circle(const Nan::FunctionCallbackInfo& args); + static void circleFill(const Nan::FunctionCallbackInfo& args); + static void drawChar(const Nan::FunctionCallbackInfo& args); + + static void drawBitmap(const Nan::FunctionCallbackInfo& args); + + static void getLCDWidth(const Nan::FunctionCallbackInfo& args); + static void getLCDHeight(const Nan::FunctionCallbackInfo& args); + static void setColor(const Nan::FunctionCallbackInfo& args); + static void setDrawMode(const Nan::FunctionCallbackInfo& args); + + // Font functions + static void getFontWidth(const Nan::FunctionCallbackInfo& args); + static void getFontHeight(const Nan::FunctionCallbackInfo& args); + static void getTotalFonts(const Nan::FunctionCallbackInfo& args); + static void getFontType(const Nan::FunctionCallbackInfo& args); + static void setFontType(const Nan::FunctionCallbackInfo& args); + static void getFontStartChar(const Nan::FunctionCallbackInfo& args); + static void getFontTotalChar(const Nan::FunctionCallbackInfo& args); + + // LCD Rotate Scroll functions + /* + these exist in Edison_OLED.h but not in cpp file. + static void scrollRight(const Nan::FunctionCallbackInfo& args); + static void scrollLeft(const Nan::FunctionCallbackInfo& args); + static void scrollVertRight(const Nan::FunctionCallbackInfo& args); + static void scrollVertLeft(const Nan::FunctionCallbackInfo& args); + */ + static void scrollStop(const Nan::FunctionCallbackInfo& args); + static void flipVertical(const Nan::FunctionCallbackInfo& args); + static void flipHorizontal(const Nan::FunctionCallbackInfo& args); + + edOLED* m_oled; + static Nan::Persistent constructor; +}; + +#endif \ No newline at end of file diff --git a/Firmware/pong/package.json b/Firmware/pong/package.json new file mode 100644 index 0000000..1e47038 --- /dev/null +++ b/Firmware/pong/package.json @@ -0,0 +1,48 @@ +{ + "name": "edison-oled", + "version": "0.0.5", + "description": "Node wrapper for Sparkfun Edison OLED Block. Includes wrappers around OLED, GPIO and SPI classes.", + "license": "MIT", + "keywords": [ + "intel", + "edison", + "sparkfun", + "oled", + "spi", + "gpio", + "node", + "graphic", + "display", + "64x48", + "monochrome", + "mezzanine", + "breakout", + "board" + ], + "author": { + "name": "Brian Feldman " + }, + "contributors": [ + { + "name": "see original project", + "url": "https://github.com/sparkfun/Edison_OLED_Block/graphs/contributors" + } + ], + "main": "./index.js", + "repository": { + "type": "git", + "url": "https://github.com/bfeldman74/Edison_OLED_Block" + }, + "bugs": { + "url": "https://github.com/bfeldman74/Edison_OLED_Block/issues" + }, + "dependencies": { + "nan": "2.5.0" + }, + "config": { + "unsafe-perm": true + }, + "scripts": { + "preinstall": "npm update nan && node-gyp configure && node-gyp rebuild" + } +} diff --git a/Firmware/pong/spi/edison_spi_wrap.cpp b/Firmware/pong/spi/edison_spi_wrap.cpp new file mode 100644 index 0000000..af17db4 --- /dev/null +++ b/Firmware/pong/spi/edison_spi_wrap.cpp @@ -0,0 +1,198 @@ +#include "../edison_node.hpp" +#include "edison_spi_wrap.hpp" +#include "../gpio/edison_gpio_wrap.hpp" +#include "../gpio/gpio.h" +#include "../gpio/gpio_edison.h" +#include "spi.h" +#include + +using namespace v8; + +Nan::Persistent EdisonSpiWrap::constructor; + +EdisonSpiWrap::EdisonSpiWrap() : m_device() { +} + +EdisonSpiWrap::~EdisonSpiWrap() { +} + +void EdisonSpiWrap::Init(v8::Local exports) { + Nan::HandleScope scope; + + // Prepare constructor template + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("Spi").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + Nan::SetPrototypeMethod(tpl, "transferData", transferData); + Nan::SetPrototypeMethod(tpl, "customCS", customCS); + Nan::SetPrototypeMethod(tpl, "CSLow", CSLow); + Nan::SetPrototypeMethod(tpl, "CSHigh", CSHigh); + Nan::SetPrototypeMethod(tpl, "doLSBFirst", doLSBFirst); + Nan::SetPrototypeMethod(tpl, "getSPIMode", getSPIMode); + //Nan::SetPrototypeMethod(tpl, "getCSPin", getCSPin); + + /* + #define SPI_CPHA 0x01 + #define SPI_CPOL 0x02 + */ + NODE_DEFINE_CONSTANT(exports, SPI_MODE_0); //(0|0) + NODE_DEFINE_CONSTANT(exports, SPI_MODE_1); //(0|SPI_CPHA) + NODE_DEFINE_CONSTANT(exports, SPI_MODE_2); //(SPI_CPOL|0) + NODE_DEFINE_CONSTANT(exports, SPI_MODE_3); //(SPI_CPOL|SPI_CPHA) + + constructor.Reset(tpl->GetFunction()); + exports->Set(Nan::New("Spi").ToLocalChecked(), tpl->GetFunction()); +} + +void EdisonSpiWrap::New(const Nan::FunctionCallbackInfo& args) { + + if (args.IsConstructCall()) { + // Invoked as constructor: `new EdisonSpiWrap(...)` + EdisonSpiWrap* obj = new EdisonSpiWrap(); + unsigned char spiMode = SPI_MODE_0; + long speed = 1000000; + bool lsbFirst = false; + spiPort *port = new spiPort(); + + switch (args.Length()) { + case 0 : + //device = new spiDevice(port); + break; + case 1 : + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + //device = new spiDevice(port, args[0]->Uint32Value() & 0xFF); + spiMode = args[0]->Uint32Value() & 0xFF; + break; + case 2 : + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + //device = new spiDevice(port, args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value()); + spiMode = args[0]->Uint32Value() & 0xFF; + speed = args[1]->Uint32Value(); + break; + case 3 : + case 4 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsBoolean()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + spiMode = args[0]->Uint32Value() & 0xFF; + speed = args[1]->Uint32Value(); + lsbFirst = Nan::To(args[2]).FromJust(); + //device = new spiDevice(port, args[0]->Uint32Value() & 0xFF, args[1]->Uint32Value(), lsbFirst); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + + if (args.Length() == 4) { + if (!args[3]->IsObject()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + EdisonGpioWrap* pin = ObjectWrap::Unwrap(args[3]->ToObject()); + obj->m_pin = pin->getGpio(); + spiDevice *device = new spiDevice(port, spiMode, speed, lsbFirst, obj->m_pin); + //spiDevice *device = new spiDevice(port, spiMode, speed, lsbFirst, gpioPin); + //obj->m_pin = gpioPin; + obj->m_port = port; + obj->m_device = device; + obj->Wrap(args.This()); + } + else { + spiDevice *device2 = new spiDevice(port, spiMode, speed, lsbFirst); + obj->m_port = port; + obj->m_device = device2; + obj->Wrap(args.This()); + } + args.GetReturnValue().Set(args.This()); + } else { + // Invoked as plain function `EdisonSpiWrap(...)`, turn into construct call. + //v8::Local cons = Nan::New(constructor); + //args.GetReturnValue().Set(cons->NewInstance()); + Nan::ThrowTypeError(ERROR_CREATE_INSTANCE_WITH_NEW); + } +} + +void EdisonSpiWrap::transferData(const Nan::FunctionCallbackInfo& args) { + EdisonSpiWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + spiDevice* device = wrap->m_device; + unsigned char dataOut; //= args[0]->Uint32Value() & 0xFF; + unsigned char dataIn; //= args[1]->Uint32Value() & 0xFF; + bool deselect; // = Nan::To(args[3]).FromJust(); + switch (args.Length()) { + case 1 : + if (!args[0]->IsNumber()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + dataOut = args[0]->Uint32Value() & 0xFF; + device->transferData(&dataOut); + break; + case 4 : + if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsBoolean()) { + Nan::ThrowTypeError(ERROR_ARGUMENTS_WRONG_TYPE); + return; + } + dataOut = args[0]->Uint32Value() & 0xFF; + dataIn = args[1]->Uint32Value() & 0xFF; + deselect = Nan::To(args[3]).FromJust(); + device->transferData(&dataOut, &dataIn, args[2]->Uint32Value(), deselect); + break; + default: + Nan::ThrowTypeError(ERROR_WRONG_NUMBER_OF_ARGUMENTS); + return; + break; + } + args.GetReturnValue().SetUndefined(); +} + +void EdisonSpiWrap::customCS(const Nan::FunctionCallbackInfo& args) { + EdisonSpiWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + spiDevice* device = wrap->m_device; + bool out = device->customCS(); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonSpiWrap::CSLow(const Nan::FunctionCallbackInfo& args) { + EdisonSpiWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + spiDevice* device = wrap->m_device; + device->CSLow(); + args.GetReturnValue().SetUndefined(); +} + +void EdisonSpiWrap::CSHigh(const Nan::FunctionCallbackInfo& args) { + EdisonSpiWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + spiDevice* device = wrap->m_device; + device->CSHigh(); + args.GetReturnValue().SetUndefined(); +} + +void EdisonSpiWrap::doLSBFirst(const Nan::FunctionCallbackInfo& args) { + EdisonSpiWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + spiDevice* device = wrap->m_device; + bool out = device->doLSBFirst(); + args.GetReturnValue().Set(Nan::New(out)); +} + +void EdisonSpiWrap::getSPIMode(const Nan::FunctionCallbackInfo& args) { + EdisonSpiWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + spiDevice* device = wrap->m_device; + int out = device->getSPIMode(); + args.GetReturnValue().Set(Nan::New(out)); +} +/* +void EdisonSpiWrap::getCSPin(const Nan::FunctionCallbackInfo& args) { + EdisonSpiWrap* wrap = ObjectWrap::Unwrap(args.Holder()); + args.GetReturnValue().SetUndefined(); +} +*/ diff --git a/Firmware/pong/spi/edison_spi_wrap.hpp b/Firmware/pong/spi/edison_spi_wrap.hpp new file mode 100644 index 0000000..f4d16f7 --- /dev/null +++ b/Firmware/pong/spi/edison_spi_wrap.hpp @@ -0,0 +1,36 @@ +#ifndef EDISON_SPI_WRAP_H +#define EDISON_SPI_WRAP_H + +#include + +#include "../edison_node.hpp" +#include "../gpio/edison_gpio_wrap.hpp" +#include "../gpio/gpio.h" +#include "../gpio/gpio_edison.h" +#include "spi.h" + +class EdisonSpiWrap : public Nan::ObjectWrap { + public: + static void Init(v8::Local exports); + static void New(const Nan::FunctionCallbackInfo& args); + + EdisonSpiWrap(); + private: + ~EdisonSpiWrap(); + + static void transferData(const Nan::FunctionCallbackInfo& args); + static void customCS(const Nan::FunctionCallbackInfo& args); + static void CSLow(const Nan::FunctionCallbackInfo& args); + static void CSHigh(const Nan::FunctionCallbackInfo& args); + static void doLSBFirst(const Nan::FunctionCallbackInfo& args); + static void getSPIMode(const Nan::FunctionCallbackInfo& args); + static void getCSPin(const Nan::FunctionCallbackInfo& args); + + //gpio* m_pin; + gpio* m_pin; + spiPort* m_port; + spiDevice* m_device; + static Nan::Persistent constructor; +}; + +#endif \ No newline at end of file diff --git a/Firmware/pong/spi/spi_device_edison.cpp b/Firmware/pong/spi/spi_device_edison.cpp index 919e630..785a32c 100644 --- a/Firmware/pong/spi/spi_device_edison.cpp +++ b/Firmware/pong/spi/spi_device_edison.cpp @@ -1,3 +1,26 @@ +/****************************************************************************** +MIT License + +Copyright (c) 2017 Brian Feldman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ #include #include #include diff --git a/Firmware/pong/tests/test-oled-all.js b/Firmware/pong/tests/test-oled-all.js new file mode 100644 index 0000000..17f7fda --- /dev/null +++ b/Firmware/pong/tests/test-oled-all.js @@ -0,0 +1,322 @@ +'use strict'; +var edison = require('../index.js'); + +/* +screen is 64 X 48 +*/ +var lcdWidth = edison.LCDWIDTH; +var lcdHeight = edison.LCDHEIGHT; + +var oled = new edison.Oled(); + +var btnUp = new edison.Gpio(47, edison.INPUT); +var btnDown = new edison.Gpio(44, edison.INPUT); +var btnLeft = new edison.Gpio(165, edison.INPUT); +var btnRight = new edison.Gpio(45, edison.INPUT); +var btnSelect = new edison.Gpio(48, edison.INPUT); +var btnA = new edison.Gpio(49, edison.INPUT); +var btnB = new edison.Gpio(46, edison.INPUT); + +var sleepTime = 1000; + +var sleep = function(ms) { + var now = new Date().getTime(); + while(new Date().getTime() < now + ms){ /* do nothing */ } +}; + +var setupOled = function() { + console.log('--setup screen'); + oled.begin(); + oled.clear(0); + oled.display(); + oled.setFontType(0); + + lcdWidth = oled.getLCDWidth(); + console.log('---width: ' + lcdWidth); + lcdHeight = oled.getLCDHeight(); + console.log('---height: ' + lcdHeight); + +}; + +var clearScreen = function() { + console.log('--clearing screen'); + oled.clear(1); + oled.display(); +}; + +var startScreen = function() { + console.log('--show start'); + + oled.clear(); + oled.setCursor(14, 5); + oled.print("Press A"); + oled.setCursor(2, 13); + oled.print("for single"); + oled.setCursor(14, 30); + oled.print("Press B"); + oled.setCursor(6, 38); + oled.print("for multi"); + oled.display(); +}; + +var drawRectangle = function() { + console.log('--draw retangle'); + oled.clear(); + oled.rect(3, 3, 58, 45); + oled.rectFill(15, 15, 34, 18); + oled.display(); +} + +var drawCircle = function() { + console.log('--draw circle'); + oled.clear(); + oled.circle(32, 24, 20); + oled.circleFill(32, 24, 10); + oled.display(); +} + +var drawLine = function() { + console.log('--draw line'); + oled.clear(); + oled.line(0, 0, lcdWidth, lcdHeight); + oled.line(lcdWidth, 0, 0, lcdHeight); + + oled.lineH(0, parseInt((lcdHeight/2), 10), lcdWidth); + oled.lineV(parseInt((lcdWidth/2), 10), 0, lcdHeight); + oled.display(); +} + +var drawPixel = function() { + console.log('--draw pixel'); + oled.clear(); + var x = 0; + var y = 0; + for (var i = 0; i <= 100; i++) { + x = Math.floor(Math.random() * lcdWidth) + 1; + y = Math.floor(Math.random() * lcdHeight) + 1; + oled.pixel(x, y); + } + oled.display(); +} + +var drawChar = function() { + console.log('--draw char'); + oled.clear(); + var x = 0; + var y = 0; + var c = 0; + for (var i = 0; i <= 5; i++) { + x = Math.floor(Math.random() * 54) + 10; + //y = Math.floor(Math.random() * 40) + 5; + y = i * 8; + c = Math.floor(Math.random() * 26) + 97; + oled.drawChar(x, y, c); + } + oled.display(); +} + +var gameOverScreen = function() { + console.log('--show game over'); + + oled.clear(0); + oled.setCursor(14, 5); + oled.print("Game"); + oled.setCursor(14, 13); + oled.print("Over"); + oled.setCursor(14, 30); + oled.print("Play"); + oled.setCursor(14, 38); + oled.print("again?"); + oled.display(); +}; + +var invertScreen = function(inv) { + console.log('--invert'); + oled.invert(inv); +} + +var invertWithCommand = function(inv) { + console.log('--test command - invert screen'); + if (inv == 1) { + oled.command(0xA7); + } else { + oled.command(0xA6); + } +} + +var testData = function() { + console.log('--test data , setPageAddress and setColumnAddress'); + oled.clear(0); + for (var i=0;i<8; i++) + { + oled.setPageAddress(i); + oled.setColumnAddress(0); + for (var j=0; j<0x80; j++) + { + if (j % 2 == 0) { + oled.data(0xFF); + } else { + oled.data(0x00); + } + + } + } +} + +var changeColor = function() { + console.log('--change color'); + oled.clear(0, 0xFF); + oled.setColor(edison.BLACK); //black + oled.setCursor(2, 13); + oled.print("Black Text"); + oled.display(); + oled.setColor(edison.WHITE); //white +} + +var changeMode = function() { + console.log('--change mode'); + oled.clear(0, 0xFF); + oled.setDrawMode(edison.XOR); //XOR + oled.setCursor(4, 13); + oled.print("XOR MODE"); + oled.display(); + oled.setDrawMode(edison.NORM); //NORM +} + +var changeFont = function() { + console.log('--change font'); + console.log('---- total fonts: ' + oled.getTotalFonts()); + console.log('---- font type: ' + oled.getFontType()); + console.log('---- font width: ' + oled.getFontWidth()); + console.log('---- font height: ' + oled.getFontHeight()); + console.log('---- font start character: ' + oled.getFontStartChar()); + console.log('---- font total characters: ' + oled.getFontTotalChar()); + oled.clear(0); + oled.setFontType(1); //font8x16 + oled.setCursor(4, 4); + oled.print("Font 8X16"); + oled.display(); + oled.setFontType(2); //sevensegment + oled.setCursor(4, 25); + oled.print("7-S"); + oled.display(); + oled.setFontType(3); //fontlargenumber + oled.setCursor(44, 25); + oled.print("LG"); + oled.display(); + oled.setFontType(0); //font 5X7 +} + +var flipScreen = function () { + console.log('--flip screen & scroll stop'); + console.log('---calling scroll stop just to test it'); + oled.scrollStop(); + oled.clear(0); + oled.setCursor(12, 4); + oled.print("Flip Me"); + oled.display(); + oled.flipVertical(1); + sleep(sleepTime); + oled.flipHorizontal(1); + sleep(sleepTime); + oled.flipVertical(0); + sleep(sleepTime); + oled.flipHorizontal(0); + + oled.display(); +} + +var buttonScreenInstructions = function(moveType, btnName) { + oled.clear(0); + oled.setCursor(4, 4); + oled.print(moveType); + oled.setCursor(4, 16); + oled.print(btnName); + oled.display(); +} + +var buttonTest = function() { + console.log('--buttons'); + + console.log('press Button A:'); + buttonScreenInstructions("Press", "btn A"); + while (btnA.pinRead() == edison.HIGH) {} + console.log('pressed A: ' + btnA.pinRead()); + console.log('Button A pressed.'); + + console.log('press Button B:'); + buttonScreenInstructions("Press", "btn B"); + while (btnB.pinRead() == edison.HIGH) {} + console.log('Button B pressed.'); + + console.log('press Select:'); + buttonScreenInstructions("Press", "stick"); + while (btnSelect.pinRead() == edison.HIGH) {} + console.log('Button Select pressed.'); + + console.log('move joystick up:'); + buttonScreenInstructions("Move", "up"); + while (btnUp.pinRead() == edison.HIGH) {} + console.log('joystick pressed up.'); + + console.log('move joystick down:'); + buttonScreenInstructions("Move", "down"); + while (btnDown.pinRead() == edison.HIGH) {} + console.log('joystick pressed down.'); + + console.log('move joystick left:'); + buttonScreenInstructions("Move", "left"); + while (btnLeft.pinRead() == edison.HIGH) {} + console.log('joystick pressed left.'); + + console.log('move joystick right:'); + buttonScreenInstructions("Move", "right"); + while (btnRight.pinRead() == edison.HIGH) {} + console.log('joystick pressed right.'); +} + +var cleanUp = function() { + oled.clear(0); + oled.display(); +} + +setupOled(); + +startScreen(); +sleep(sleepTime); +flipScreen() +sleep(sleepTime); +drawRectangle(); +sleep(sleepTime); +invertScreen(1); +sleep(sleepTime); +invertScreen(0); +sleep(sleepTime); +drawCircle(); +sleep(sleepTime); +invertWithCommand(1); +sleep(sleepTime); +invertWithCommand(0); +sleep(sleepTime); +drawLine(); +sleep(sleepTime); +drawPixel(); +sleep(sleepTime); +drawChar(); +sleep(sleepTime); +testData(); +sleep(sleepTime); +changeColor(); +sleep(sleepTime); +changeMode(); +sleep(sleepTime); +changeFont(); +sleep(sleepTime); +buttonTest(); +sleep(sleepTime); +gameOverScreen(); +sleep(sleepTime); + +cleanUp(); + +console.log('All done.'); diff --git a/Firmware/pong/tests/test-oled-buttons.js b/Firmware/pong/tests/test-oled-buttons.js new file mode 100644 index 0000000..c4e54f3 --- /dev/null +++ b/Firmware/pong/tests/test-oled-buttons.js @@ -0,0 +1,96 @@ +'use strict'; +var edison = require('../index.js'); + +var oled = new edison.Oled(); + +var btnUp = new edison.Gpio(47, edison.INPUT); +var btnDown = new edison.Gpio(44, edison.INPUT); +var btnLeft = new edison.Gpio(165, edison.INPUT); +var btnRight = new edison.Gpio(45, edison.INPUT); +var btnSelect = new edison.Gpio(48, edison.INPUT); +var btnA = new edison.Gpio(49, edison.INPUT); +var btnB = new edison.Gpio(46, edison.INPUT); + +var sleepTime = 1000; + +var sleep = function(ms) { + var now = new Date().getTime(); + while(new Date().getTime() < now + ms){ /* do nothing */ } +}; + +var setupOled = function() { + console.log('--setup screen'); + oled.begin(); + oled.clear(0); + oled.display(); + oled.setFontType(0); +}; + +var clearScreen = function() { + console.log('--clearing screen'); + oled.clear(1); + oled.display(); +}; + +var buttonScreenInstructions = function(moveType, btnName) { + oled.clear(0); + oled.setCursor(4, 4); + oled.print(moveType); + oled.setCursor(4, 16); + oled.print(btnName); + oled.display(); +} + +var buttonTest = function() { + console.log('--buttons'); + + console.log('press Button A:'); + buttonScreenInstructions("Press", "btn A"); + while (btnA.pinRead() == edison.HIGH) {} + console.log('pressed A: ' + btnA.pinRead()); + console.log('Button A pressed.'); + + console.log('press Button B:'); + buttonScreenInstructions("Press", "btn B"); + while (btnB.pinRead() == edison.HIGH) {} + console.log('Button B pressed.'); + + console.log('press Select:'); + buttonScreenInstructions("Press", "stick"); + while (btnSelect.pinRead() == edison.HIGH) {} + console.log('Button Select pressed.'); + + console.log('move joystick up:'); + buttonScreenInstructions("Move", "up"); + while (btnUp.pinRead() == edison.HIGH) {} + console.log('joystick pressed up.'); + + console.log('move joystick down:'); + buttonScreenInstructions("Move", "down"); + while (btnDown.pinRead() == edison.HIGH) {} + console.log('joystick pressed down.'); + + console.log('move joystick left:'); + buttonScreenInstructions("Move", "left"); + while (btnLeft.pinRead() == edison.HIGH) {} + console.log('joystick pressed left.'); + + console.log('move joystick right:'); + buttonScreenInstructions("Move", "right"); + while (btnRight.pinRead() == edison.HIGH) {} + console.log('joystick pressed right.'); +} + +var cleanUp = function() { + oled.clear(0); + oled.display(); +} + +setupOled(); +sleep(sleepTime); +buttonTest(); +sleep(sleepTime); + +cleanUp(); + +console.log('All done.'); diff --git a/Firmware/pong/tests/test-oled-screen.js b/Firmware/pong/tests/test-oled-screen.js new file mode 100644 index 0000000..03748ac --- /dev/null +++ b/Firmware/pong/tests/test-oled-screen.js @@ -0,0 +1,263 @@ +'use strict'; +var edison = require('../index.js'); + +/* +screen is 64 X 48 +*/ +var lcdWidth = edison.LCDWIDTH; +var lcdHeight = edison.LCDHEIGHT; + +var oled = new edison.Oled(); + +var sleepTime = 1000; + +var sleep = function(ms) { + var now = new Date().getTime(); + while(new Date().getTime() < now + ms){ /* do nothing */ } +}; + +var setupOled = function() { + console.log('--setup screen'); + oled.begin(); + oled.clear(0); + oled.display(); + oled.setFontType(0); + + lcdWidth = oled.getLCDWidth(); + console.log('---width: ' + lcdWidth); + lcdHeight = oled.getLCDHeight(); + console.log('---height: ' + lcdHeight); + +}; + +var clearScreen = function() { + console.log('--clearing screen'); + oled.clear(1); + oled.display(); +}; + +var startScreen = function() { + console.log('--show start'); + + oled.clear(); + oled.setCursor(14, 5); + oled.print("Press A"); + oled.setCursor(2, 13); + oled.print("for single"); + oled.setCursor(14, 30); + oled.print("Press B"); + oled.setCursor(6, 38); + oled.print("for multi"); + oled.display(); +}; + +var drawRectangle = function() { + console.log('--draw retangle'); + oled.clear(); + oled.rect(3, 3, 58, 45); + oled.rectFill(15, 15, 34, 18); + oled.display(); +} + +var drawCircle = function() { + console.log('--draw circle'); + oled.clear(); + oled.circle(32, 24, 20); + oled.circleFill(32, 24, 10); + oled.display(); +} + +var drawLine = function() { + console.log('--draw line'); + oled.clear(); + oled.line(0, 0, lcdWidth, lcdHeight); + oled.line(lcdWidth, 0, 0, lcdHeight); + + oled.lineH(0, parseInt((lcdHeight/2), 10), lcdWidth); + oled.lineV(parseInt((lcdWidth/2), 10), 0, lcdHeight); + oled.display(); +} + +var drawPixel = function() { + console.log('--draw pixel'); + oled.clear(); + var x = 0; + var y = 0; + for (var i = 0; i <= 100; i++) { + x = Math.floor(Math.random() * lcdWidth) + 1; + y = Math.floor(Math.random() * lcdHeight) + 1; + oled.pixel(x, y); + } + oled.display(); +} + +var drawChar = function() { + console.log('--draw char'); + oled.clear(); + var x = 0; + var y = 0; + var c = 0; + for (var i = 0; i <= 5; i++) { + x = Math.floor(Math.random() * 54) + 10; + //y = Math.floor(Math.random() * 40) + 5; + y = i * 8; + c = Math.floor(Math.random() * 26) + 97; + oled.drawChar(x, y, c); + } + oled.display(); +} + +var gameOverScreen = function() { + console.log('--show game over'); + + oled.clear(0); + oled.setCursor(14, 5); + oled.print("Game"); + oled.setCursor(14, 13); + oled.print("Over"); + oled.setCursor(14, 30); + oled.print("Play"); + oled.setCursor(14, 38); + oled.print("again?"); + oled.display(); +}; + +var invertScreen = function(inv) { + console.log('--invert'); + oled.invert(inv); +} + +var invertWithCommand = function(inv) { + console.log('--test command - invert screen'); + if (inv == 1) { + oled.command(0xA7); + } else { + oled.command(0xA6); + } +} + +var testData = function() { + console.log('--test data , setPageAddress and setColumnAddress'); + oled.clear(0); + for (var i=0;i<8; i++) + { + oled.setPageAddress(i); + oled.setColumnAddress(0); + for (var j=0; j<0x80; j++) + { + if (j % 2 == 0) { + oled.data(0xFF); + } else { + oled.data(0x00); + } + + } + } +} + +var changeColor = function() { + console.log('--change color'); + oled.clear(0, 0xFF); + oled.setColor(edison.BLACK); //black + oled.setCursor(2, 13); + oled.print("Black Text"); + oled.display(); + oled.setColor(edison.WHITE); //white +} + +var changeMode = function() { + console.log('--change mode'); + oled.clear(0, 0xFF); + oled.setDrawMode(edison.XOR); //XOR + oled.setCursor(4, 13); + oled.print("XOR MODE"); + oled.display(); + oled.setDrawMode(edison.NORM); //NORM +} + +var changeFont = function() { + console.log('--change font'); + console.log('---- total fonts: ' + oled.getTotalFonts()); + console.log('---- font type: ' + oled.getFontType()); + console.log('---- font width: ' + oled.getFontWidth()); + console.log('---- font height: ' + oled.getFontHeight()); + console.log('---- font start character: ' + oled.getFontStartChar()); + console.log('---- font total characters: ' + oled.getFontTotalChar()); + oled.clear(0); + oled.setFontType(1); //font8x16 + oled.setCursor(4, 4); + oled.print("Font 8X16"); + oled.display(); + oled.setFontType(2); //sevensegment + oled.setCursor(4, 25); + oled.print("7-S"); + oled.display(); + oled.setFontType(3); //fontlargenumber + oled.setCursor(44, 25); + oled.print("LG"); + oled.display(); + oled.setFontType(0); //font 5X7 +} + +var flipScreen = function () { + console.log('--flip screen & scroll stop'); + console.log('---calling scroll stop just to test it'); + oled.scrollStop(); + oled.clear(0); + oled.setCursor(12, 4); + oled.print("Flip Me"); + oled.display(); + oled.flipVertical(1); + sleep(sleepTime); + oled.flipHorizontal(1); + sleep(sleepTime); + oled.flipVertical(0); + sleep(sleepTime); + oled.flipHorizontal(0); + + oled.display(); +} + +var cleanUp = function() { + oled.clear(0); + oled.display(); +} + +setupOled(); + +startScreen(); +sleep(sleepTime); +flipScreen() +sleep(sleepTime); +drawRectangle(); +sleep(sleepTime); +invertScreen(1); +sleep(sleepTime); +invertScreen(0); +sleep(sleepTime); +drawCircle(); +sleep(sleepTime); +invertWithCommand(1); +sleep(sleepTime); +invertWithCommand(0); +sleep(sleepTime); +drawLine(); +sleep(sleepTime); +drawPixel(); +sleep(sleepTime); +drawChar(); +sleep(sleepTime); +testData(); +sleep(sleepTime); +changeColor(); +sleep(sleepTime); +changeMode(); +sleep(sleepTime); +changeFont(); +sleep(sleepTime); +gameOverScreen(); +sleep(sleepTime); + +cleanUp(); + +console.log('All done.'); diff --git a/Firmware/pong/tests/test-spi.js b/Firmware/pong/tests/test-spi.js new file mode 100644 index 0000000..e1b4b3f --- /dev/null +++ b/Firmware/pong/tests/test-spi.js @@ -0,0 +1,281 @@ +'use strict'; +var edison = require('../index.js'); + +var edisonOled = function (edi) { + this._edison = edi + + this._fontType; + this._foreColor; + this._drawMode; + this._cursorX; + this._cursorY; + + this.screenmemory = new Array(384); + + console.log('setup pins'); + //pin mraa /edison reference mapping - https://github.com/intel-iot-devkit/mraa/blob/master/docs/edison.md#intelr-breakout-board + /* + MRAA CS PIN = 23 which is GP110 (110) on Edison + WE NEED CS PIN = 9 which is GP111 (111) on Edison + */ + this.cspin = new this._edison.Gpio(111, this._edison.OUTPUT, this._edison.HIGH); //chip select --> edison_oled.c code uses 111 mraa uses 9 + this.dcpin = new this._edison.Gpio(14, this._edison.OUTPUT, this._edison.HIGH); //data/command --> edison_oled.c code uses 14 mraa uses 36 + this.rstpin = new this._edison.Gpio(15, this._edison.OUTPUT, this._edison.HIGH); //reset --> edison_oled.c code uses 15 mraa uses 48 + this.sclkpin = new this._edison.Gpio(109, this._edison.SPI, this._edison.HIGH); //sclk --> edison_oled.c code uses 109 mraa uses 10 + this.mosipin = new this._edison.Gpio(115, this._edison.SPI, this._edison.HIGH); //mosi --> edison_oled.c code uses 115 mraa uses 11 + //var misopin = new this._edison.Gpio(114, this._edison.SPI, this._edison.HIGH); edison_oled.c code uses 114 mraa uses 24 + + console.log('pin values'); + console.log(this.cspin.pinRead()); + console.log(this.dcpin.pinRead()); + console.log(this.rstpin.pinRead()); + console.log(this.sclkpin.pinRead()); + console.log(this.mosipin.pinRead()); + + console.log('create spi'); + this._spi = new this._edison.Spi(this._edison.SPI_MODE_0, 10000000, false, this.cspin); + console.log('spi created'); + +}; + +edisonOled.prototype.usleep = function (delay) { + var waitTill = new Date(new Date().getTime() + delay); + while (waitTill > new Date()) { } +}; + +edisonOled.prototype.begin = function () { + + this.screenmemory.fill(0); + + this.setFontType(0); + this.setColor(this._edison.WHITE); + this.setDrawMode(this._edison.NORM); + this.setCursor(0, 0); + + this.spiSetup(); + + this.rstpin.pinWrite(this._edison.HIGH); //(digitalWrite(rstPin, HIGH); + this.usleep(5); // VDD (3.3V) goes high at start, lets just chill for 5 ms + this.rstpin.pinWrite(this._edison.LOW); // bring reset low + this.usleep(10); // wait 10ms + this.rstpin.pinWrite(this._edison.HIGH); //digitalWrite(rstPin, HIGH); + + this.command(this._edison.DISPLAYOFF); + + this.command(this._edison.SETDISPLAYCLOCKDIV); + this.command(0X80); + + this.command(this._edison.SETMULTIPLEX); // 0xA8 + this.command(0x2F); + + this.command(this._edison.SETDISPLAYOFFSET); // 0xD3 + this.command(0x0); // no offset + + this.command(this._edison.SETSTARTLINE | 0x0); // line #0 + + this.command(this._edison.CHARGEPUMP); // enable charge pump + this.command(0x14); + + this.command(this._edison.NORMALDISPLAY); // 0xA6 + this.command(this._edison.DISPLAYALLONRESUME); // 0xA4 + + this.command(this._edison.SEGREMAP | 0x1); + this.command(this._edison.COMSCANDEC); + + this.command(this._edison.SETCOMPINS); // 0xDA + this.command(0x12); + + this.command(this._edison.SETCONTRAST); // 0x81 + this.command(0x8F); + + this.command(this._edison.SETPRECHARGE); // 0xd9 + this.command(0xF1); + + this.command(this._edison.SETVCOMDESELECT); // 0xDB + this.command(0x40); + + this.command(this._edison.DISPLAYON); + + this.clear(this._edison.ALL); +}; + +edisonOled.prototype.command = function (c) { + this.dcpin.pinWrite(this._edison.LOW); // DC pin LOW + this.spiTransfer(c); +}; + +edisonOled.prototype.data = function (c) { + this.dcpin.pinWrite(this._edison.HIGH); //DC pin HIGH + this.spiTransfer(c); +}; + +edisonOled.prototype.setPageAddress = function (add) { + add = 0xb0 | add; + this.command(add); + return; +}; + +edisonOled.prototype.setColumnAddress = function (add) { + this.command((0x10 | (add >> 4)) + 0x02); + this.command((0x0f & add)); + return; +} + +edisonOled.prototype.clear = function (mode, c) { + // unsigned char page=6, col=0x40; + + if (!c) { + c = 0; + } + + if (mode == this._edison.ALL) { + for (var i= 0; i < 8; i++) + { + this.setPageAddress(i); + this.setColumnAddress(0); + for (var j= 0; j < 0x80; j++) + { + this.data(c); + } + } + } + else { + this.screenmemory.fill(c); // (64 x 48) / 8 = 384 + this.display(); + } +}; + +edisonOled.prototype.display = function () { + var i, j; + for (i = 0; i < 6; i++) { + this.setPageAddress(i); + this.setColumnAddress(0); + for (j = 0; j < 0x40; j++) { + this.data(this.screenmemory[i * 0x40 + j]); + } + } +}; + +edisonOled.prototype.pixel = function(x, y, color, mode) +{ + if ((x < 0) || (x >= this._edison.LCDWIDTH) || (y < 0) || (y >= this._edison.LCDHEIGHT)) + return; + + if (!color) { + color = this._foreColor; + } + if (!mode) { + mode = this._drawMode; + } + console.log('pixel: ' + x + ', ' + y + ' ' + color + ' ' + mode); + if (mode == this._edison.XOR) { + if (color == this._edison.WHITE) + this.screenmemory[x + (y / 8) * this._edison.LCDWIDTH] ^= (1 << (y % 8)); + } + else { + if (color == this._edison.WHITE) + this.screenmemory[x + (y / 8) * this._edison.LCDWIDTH] |= (1 << (y % 8)); + else + this.screenmemory[x + (y / 8) * this._edison.LCDWIDTH] &= ~(1 << (y % 8)); + } +} + +edisonOled.prototype.setCursor = function (x, y) { + this._cursorX = x; + this._cursorY = y; +}; + +edisonOled.prototype.setFontType = function (type) { + this._fontType = type; + return true; +}; + +edisonOled.prototype.setColor = function (color) { + this._foreColor = color; +}; + +edisonOled.prototype.setDrawMode = function (mode) +{ + this._drawMode = mode; +} + +edisonOled.prototype.spiSetup = function () { +}; + +edisonOled.prototype.flipVertical = function(flip) { + if (flip) { + this.command(edison.COMSCANINC); + } + else { + this.command(edison.COMSCANDEC); + } +}; + +edisonOled.prototype.flipHorizontal = function(flip) { + if (flip) { + this.command(edison.SEGREMAP | 0x0); + } + else { + this.command(edison.SEGREMAP | 0x1); + } +}; + +edisonOled.prototype.spiTransfer = function (data) { + this._spi.transferData(data); +}; + +var runTest = function () { + //sparkfun logo should appear on the screen + oled.screenmemory = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x0F, 0x07, 0x07, 0x06, 0x06, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x07, 0x0F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xFD, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x07, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ]; + console.log('show sparkfun logo'); + oled.display(); + oled.usleep(2500); + console.log('flip vertical'); + oled.flipVertical(true); + oled.usleep(2500); + console.log('flip horizontal'); + oled.flipHorizontal(true); + oled.usleep(2500); + console.log('flip vertical'); + oled.flipVertical(false); + oled.usleep(2500); + console.log('flip horizontal'); + oled.flipHorizontal(false); + oled.usleep(2500); +}; + +var oled = new edisonOled(edison); + +oled.begin(); +runTest(); +oled.clear(edison.ALL); diff --git a/README.md b/README.md index 8e7f1c4..8802f3b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,112 @@ +NodeJS Wrapper for SparkFun Edison OLED Block +============================================= + +Developing a node app for your Edison? Need to use the OLED display from SparkFun, GPIO pins or SPI? You're in luck! + +Features + + * OLED + * GPIO + * SPI + +NOTES + + * This has only been tested with the SparkFun Edison OLED Block, but GPIO and SPI should (may possibly) work with other hardware. + * SPI - need to use a CS pin on Edison other than the default pin 23 (GP110), the MRAA library won't work. This library works using a pin of your choosing (tested with pin 9 (GP111)). + * GPIO pin mraa /edison reference mapping may be useful - https://github.com/intel-iot-devkit/mraa/blob/master/docs/edison.md#intelr-breakout-board + * The files in the Tests folder are meant to be run on an Intel Edison as they interact with the hardware. + +Installation +============ +This module is only designed to work on the Intel Edison. + +``` +$ npm install edison-oled +``` + +You may need to use the --unsafe-perm option if you get the warning "cannot run in wd". + +``` +$ npm install edison-oled --unsafe-perm +``` + +API +============ +Example using the OLED screen + +```javascript +var edison = require('edison-oled'); + +//create Oled +var oled = new edison.Oled(); + +//setup input buttons +var btnUp = new edison.Gpio(47, edison.INPUT); +var btnDown = new edison.Gpio(44, edison.INPUT); +var btnLeft = new edison.Gpio(165, edison.INPUT); +var btnRight = new edison.Gpio(45, edison.INPUT); +var btnSelect = new edison.Gpio(48, edison.INPUT); +var btnA = new edison.Gpio(49, edison.INPUT); +var btnB = new edison.Gpio(46, edison.INPUT); + +//setup screen +oled.begin(); +oled.clear(0); +oled.display(); +oled.setFontType(0); + +//draw on screen +oled.clear(); +oled.setCursor(14, 5); +oled.print("Press A"); +oled.setCursor(2, 13); +oled.print("for single"); +oled.setCursor(14, 30); +oled.print("Press B"); +oled.setCursor(6, 38); +oled.print("for multi"); +oled.display(); + +//wait for user to make a choice using Button A or Button B +while (btnA.pinRead() == edison.HIGH && btnB.pinRead() == edison.HIGH) {} + +``` + +Example uses SPI and GPIO to communicate with OLED hardware (not a complete example, see test-spi.js for full code) + +```javascript +var edison = require('edison-oled'); + +//setup pins needed for SPI +var cspin = new edison.Gpio(111, edison.OUTPUT, edison.HIGH); //chip select --> edison_oled.c code uses 111 mraa uses 9 +var dcpin = new edison.Gpio(14, edison.OUTPUT, edison.HIGH); //data/command --> edison_oled.c code uses 14 mraa uses 36 +var rstpin = new edison.Gpio(15, edison.OUTPUT, edison.HIGH); //reset --> edison_oled.c code uses 15 mraa uses 48 +var sclkpin = new edison.Gpio(109, edison.SPI, edison.HIGH); //sclk --> edison_oled.c code uses 109 mraa uses 10 +var mosipin = new edison.Gpio(115, edison.SPI, edison.HIGH); //mosi --> edison_oled.c code uses 115 mraa uses 11 +var misopin = new edison.Gpio(114, edison.SPI, edison.HIGH); //miso --> edison_oled.c code uses 114 mraa uses 24 + +//create spi +var spi = new edison.Spi(edison.SPI_MODE_0, 10000000, false, cspin); + +//reset screen +rstpin.pinWrite(edison.HIGH); +//should add a wait time here for a few milliseconds +rstpin.pinWrite(edison.LOW); +//should add a wait time here for a few milliseconds +rstpin.pinWrite(edison.HIGH); + +//send commands to OLED +dcpin.pinWrite(edison.LOW); // DC pin LOW +spi.transferData(edison.DISPLAYOFF); +spi.transferData(edison.SETDISPLAYCLOCKDIV); +spi.transferData(0x80); + +//send data to OLED +dcpin.pinWrite(edison.HIGH); //DC pin HIGH +spi.transferData(0xFF); + +``` + SparkFun Edison OLED Block ===========================