/** * The MIT License (MIT) * * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn * Copyright (c) 2018 by Fabrice Weinberg * Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de * * 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. * * ThingPulse invests considerable time and money to develop these open source libraries. * Please support us by buying our products (and not the clones) from * https://thingpulse.com * */ #include "OLEDDisplay.h" OLEDDisplay::OLEDDisplay(OLEDDISPLAY_GEOMETRY g) : _geometry(g), _displayIsOn(false) { } OLEDDisplay::~OLEDDisplay() { } // cppcheck-suppress unusedFunction void OLEDDisplay::displayOn() { sendCommand(DISPLAYON); _displayIsOn = true; } // cppcheck-suppress unusedFunction bool OLEDDisplay::isDisplayOn() const { return _displayIsOn; } // cppcheck-suppress unusedFunction void OLEDDisplay::displayOff() { sendCommand(DISPLAYOFF); _displayIsOn = false; } // cppcheck-suppress unusedFunction bool OLEDDisplay::isDisplayOff() const { return !_displayIsOn; } // cppcheck-suppress unusedFunction void OLEDDisplay::invertDisplay() { sendCommand(INVERTDISPLAY); } // cppcheck-suppress unusedFunction void OLEDDisplay::normalDisplay() { sendCommand(NORMALDISPLAY); } // cppcheck-suppress unusedFunction void OLEDDisplay::setContrast(uint8_t contrast, uint8_t precharge, uint8_t comdetect) { sendCommand(SETPRECHARGE); // 0xD9 sendCommand(precharge); // 0xF1 default, to lower the contrast, put 1-1F sendCommand(SETCONTRAST); sendCommand(contrast); // 0-255 sendCommand(SETVCOMDETECT); // 0xDB, (additionally needed to lower the contrast) sendCommand(comdetect); // 0x40 default, to lower the contrast, put 0 sendCommand(DISPLAYALLON_RESUME); sendCommand(NORMALDISPLAY); sendCommand(DISPLAYON); } // cppcheck-suppress unusedFunction void OLEDDisplay::setBrightness(uint8_t brightness) { uint8_t contrast = brightness * 1.171 - 43; if (brightness < 128) { // Magic values to get a smooth/ step-free transition contrast = brightness * 1.171; } uint8_t precharge = 241; if (brightness == 0) { precharge = 0; } uint8_t comdetect = brightness / 8; setContrast(contrast, precharge, comdetect); } // cppcheck-suppress unusedFunction void OLEDDisplay::resetOrientation() { sendCommand(SEGREMAP); sendCommand(COMSCANINC); } // cppcheck-suppress unusedFunction void OLEDDisplay::flipScreenVertically() { sendCommand(SEGREMAP | 0x01); sendCommand(COMSCANDEC); } // cppcheck-suppress unusedFunction void OLEDDisplay::mirrorScreen() { sendCommand(SEGREMAP); sendCommand(COMSCANDEC); } void OLEDDisplay::display(Bitmap *bitmap) { if (isDisplayOff()) { displayOn(); } internDisplay(bitmap); } // cppcheck-suppress unusedFunction void OLEDDisplay::clear() { } // cppcheck-suppress unusedFunction uint OLEDDisplay::getWidth() { switch (_geometry) { case GEOMETRY_128_64: case GEOMETRY_128_32: return 128; case GEOMETRY_64_48: case GEOMETRY_64_32: return 64; } return 0; } // cppcheck-suppress unusedFunction uint OLEDDisplay::getHeight() { switch (_geometry) { case GEOMETRY_128_64: return 64; case GEOMETRY_64_48: return 48; case GEOMETRY_128_32: case GEOMETRY_64_32: return 32; } return 0; } // cppcheck-suppress unusedFunction void OLEDDisplay::sendInitCommands() { sendCommand(DISPLAYOFF); sendCommand(SETDISPLAYCLOCKDIV); sendCommand(0xF0); // Increase speed of the display max ~96Hz sendCommand(SETMULTIPLEX); sendCommand(this->getHeight() - 1); sendCommand(SETDISPLAYOFFSET); sendCommand(0x00); if (_geometry == GEOMETRY_64_32) { sendCommand(0x00); } else { sendCommand(SETSTARTLINE); } sendCommand(CHARGEPUMP); sendCommand(0x14); sendCommand(MEMORYMODE); sendCommand(0x00); sendCommand(SEGREMAP); sendCommand(COMSCANINC); sendCommand(SETCOMPINS); if (_geometry == GEOMETRY_128_64 || _geometry == GEOMETRY_64_48 || _geometry == GEOMETRY_64_32) { sendCommand(0x12); } else if (_geometry == GEOMETRY_128_32) { sendCommand(0x02); } sendCommand(SETCONTRAST); if (_geometry == GEOMETRY_128_64 || _geometry == GEOMETRY_64_48 || _geometry == GEOMETRY_64_32) { sendCommand(0xCF); } else if (_geometry == GEOMETRY_128_32) { sendCommand(0x8F); } sendCommand(SETPRECHARGE); sendCommand(0xF1); sendCommand(SETVCOMDETECT); // 0xDB, (additionally needed to lower the contrast) sendCommand(0x40); // 0x40 default, to lower the contrast, put 0 sendCommand(DISPLAYALLON_RESUME); sendCommand(NORMALDISPLAY); sendCommand(0x2e); // stop scroll sendCommand(DISPLAYON); }