mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 17:05:52 +00:00
@@ -106,6 +106,7 @@ void UITask::renderCurrScreen() {
|
||||
_display->setColor(DisplayDriver::ORANGE);
|
||||
sprintf(tmp, "%d", _msgcount);
|
||||
_display->print(tmp);
|
||||
_display->setColor(DisplayDriver::YELLOW); // last color will be kept on T114
|
||||
} else {
|
||||
// render 'home' screen
|
||||
_display->setColor(DisplayDriver::BLUE);
|
||||
@@ -120,6 +121,7 @@ void UITask::renderCurrScreen() {
|
||||
_display->print(_version_info);
|
||||
|
||||
if (_connected) {
|
||||
_display->setColor(DisplayDriver::BLUE);
|
||||
//_display->printf("freq : %03.2f sf %d\n", _prefs.freq, _prefs.sf);
|
||||
//_display->printf("bw : %03.2f cr %d\n", _prefs.bw, _prefs.cr);
|
||||
} else if (_pin_code != 0) {
|
||||
@@ -128,6 +130,9 @@ void UITask::renderCurrScreen() {
|
||||
_display->setCursor(0, 43);
|
||||
sprintf(tmp, "Pin:%d", _pin_code);
|
||||
_display->print(tmp);
|
||||
_display->setColor(DisplayDriver::GREEN);
|
||||
} else {
|
||||
_display->setColor(DisplayDriver::LIGHT);
|
||||
}
|
||||
}
|
||||
_need_refresh = false;
|
||||
|
||||
1176
src/helpers/ui/OLEDDisplay.cpp
Normal file
1176
src/helpers/ui/OLEDDisplay.cpp
Normal file
File diff suppressed because it is too large
Load Diff
395
src/helpers/ui/OLEDDisplay.h
Normal file
395
src/helpers/ui/OLEDDisplay.h
Normal file
@@ -0,0 +1,395 @@
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OLEDDISPLAY_h
|
||||
#define OLEDDISPLAY_h
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
#ifdef ARDUINO
|
||||
#include <Arduino.h>
|
||||
#elif __MBED__
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
|
||||
#include <mbed.h>
|
||||
#define delay(x) wait_ms(x)
|
||||
#define yield() void()
|
||||
|
||||
/*
|
||||
* This is a little Arduino String emulation to keep the OLEDDisplay
|
||||
* library code in common between Arduino and mbed-os
|
||||
*/
|
||||
class String {
|
||||
public:
|
||||
String(const char *s) { _str = s; };
|
||||
int length() { return strlen(_str); };
|
||||
const char *c_str() { return _str; };
|
||||
void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {
|
||||
memcpy(buf, _str + index, std::min(bufsize, strlen(_str)));
|
||||
};
|
||||
private:
|
||||
const char *_str;
|
||||
};
|
||||
|
||||
#else
|
||||
#error "Unkown operating system"
|
||||
#endif
|
||||
|
||||
#include "OLEDDisplayFonts.h"
|
||||
|
||||
//#define DEBUG_OLEDDISPLAY(...) Serial.printf( __VA_ARGS__ )
|
||||
//#define DEBUG_OLEDDISPLAY(...) dprintf("%s", __VA_ARGS__ )
|
||||
|
||||
#ifndef DEBUG_OLEDDISPLAY
|
||||
#define DEBUG_OLEDDISPLAY(...)
|
||||
#endif
|
||||
|
||||
// Use DOUBLE BUFFERING by default
|
||||
#ifndef OLEDDISPLAY_REDUCE_MEMORY
|
||||
#define OLEDDISPLAY_DOUBLE_BUFFER
|
||||
#endif
|
||||
|
||||
// Header Values
|
||||
#define JUMPTABLE_BYTES 4
|
||||
|
||||
#define JUMPTABLE_LSB 1
|
||||
#define JUMPTABLE_SIZE 2
|
||||
#define JUMPTABLE_WIDTH 3
|
||||
#define JUMPTABLE_START 4
|
||||
|
||||
#define WIDTH_POS 0
|
||||
#define HEIGHT_POS 1
|
||||
#define FIRST_CHAR_POS 2
|
||||
#define CHAR_NUM_POS 3
|
||||
|
||||
|
||||
// Display commands
|
||||
#define CHARGEPUMP 0x8D
|
||||
#define COLUMNADDR 0x21
|
||||
#define COMSCANDEC 0xC8
|
||||
#define COMSCANINC 0xC0
|
||||
#define DISPLAYALLON 0xA5
|
||||
#define DISPLAYALLON_RESUME 0xA4
|
||||
#define DISPLAYOFF 0xAE
|
||||
#define DISPLAYON 0xAF
|
||||
#define EXTERNALVCC 0x1
|
||||
#define INVERTDISPLAY 0xA7
|
||||
#define MEMORYMODE 0x20
|
||||
#define NORMALDISPLAY 0xA6
|
||||
#define PAGEADDR 0x22
|
||||
#define SEGREMAP 0xA0
|
||||
#define SETCOMPINS 0xDA
|
||||
#define SETCONTRAST 0x81
|
||||
#define SETDISPLAYCLOCKDIV 0xD5
|
||||
#define SETDISPLAYOFFSET 0xD3
|
||||
#define SETHIGHCOLUMN 0x10
|
||||
#define SETLOWCOLUMN 0x00
|
||||
#define SETMULTIPLEX 0xA8
|
||||
#define SETPRECHARGE 0xD9
|
||||
#define SETSEGMENTREMAP 0xA1
|
||||
#define SETSTARTLINE 0x40
|
||||
#define SETVCOMDETECT 0xDB
|
||||
#define SWITCHCAPVCC 0x2
|
||||
|
||||
#ifndef _swap_int16_t
|
||||
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
|
||||
#endif
|
||||
|
||||
enum OLEDDISPLAY_COLOR {
|
||||
BLACK = 0,
|
||||
WHITE = 1,
|
||||
INVERSE = 2
|
||||
};
|
||||
|
||||
enum OLEDDISPLAY_TEXT_ALIGNMENT {
|
||||
TEXT_ALIGN_LEFT = 0,
|
||||
TEXT_ALIGN_RIGHT = 1,
|
||||
TEXT_ALIGN_CENTER = 2,
|
||||
TEXT_ALIGN_CENTER_BOTH = 3
|
||||
};
|
||||
|
||||
|
||||
enum OLEDDISPLAY_GEOMETRY {
|
||||
GEOMETRY_128_64 = 0,
|
||||
GEOMETRY_128_32 = 1,
|
||||
GEOMETRY_64_48 = 2,
|
||||
GEOMETRY_64_32 = 3,
|
||||
GEOMETRY_RAWMODE = 4,
|
||||
GEOMETRY_128_128 = 5
|
||||
};
|
||||
|
||||
enum HW_I2C {
|
||||
I2C_ONE,
|
||||
I2C_TWO
|
||||
};
|
||||
|
||||
typedef char (*FontTableLookupFunction)(const uint8_t ch);
|
||||
char DefaultFontTableLookup(const uint8_t ch);
|
||||
|
||||
|
||||
#ifdef ARDUINO
|
||||
class OLEDDisplay : public Print {
|
||||
#elif __MBED__
|
||||
class OLEDDisplay : public Stream {
|
||||
#else
|
||||
#error "Unkown operating system"
|
||||
#endif
|
||||
|
||||
public:
|
||||
OLEDDisplay();
|
||||
virtual ~OLEDDisplay();
|
||||
|
||||
uint16_t width(void) const { return displayWidth; };
|
||||
uint16_t height(void) const { return displayHeight; };
|
||||
|
||||
// Use this to resume after a deep sleep without resetting the display (what init() would do).
|
||||
// Returns true if connection to the display was established and the buffer allocated, false otherwise.
|
||||
bool allocateBuffer();
|
||||
|
||||
// Allocates the buffer and initializes the driver & display. Resets the display!
|
||||
// Returns false if buffer allocation failed, true otherwise.
|
||||
bool init();
|
||||
|
||||
// Free the memory used by the display
|
||||
void end();
|
||||
|
||||
// Cycle through the initialization
|
||||
void resetDisplay(void);
|
||||
|
||||
/* Drawing functions */
|
||||
// Sets the color of all pixel operations
|
||||
void setColor(OLEDDISPLAY_COLOR color);
|
||||
|
||||
// Returns the current color.
|
||||
OLEDDISPLAY_COLOR getColor();
|
||||
|
||||
// Draw a pixel at given position
|
||||
void setPixel(int16_t x, int16_t y);
|
||||
|
||||
// Draw a pixel at given position and color
|
||||
void setPixelColor(int16_t x, int16_t y, OLEDDISPLAY_COLOR color);
|
||||
|
||||
// Clear a pixel at given position FIXME: INVERSE is untested with this function
|
||||
void clearPixel(int16_t x, int16_t y);
|
||||
|
||||
// Draw a line from position 0 to position 1
|
||||
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
|
||||
|
||||
// Draw the border of a rectangle at the given location
|
||||
void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Fill the rectangle
|
||||
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Draw the border of a circle
|
||||
void drawCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Draw all Quadrants specified in the quads bit mask
|
||||
void drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads);
|
||||
|
||||
// Fill circle
|
||||
void fillCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Draw an empty triangle i.e. only the outline
|
||||
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
|
||||
|
||||
// Draw a solid triangle i.e. filled
|
||||
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
|
||||
|
||||
// Draw a line horizontally
|
||||
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draw a line vertically
|
||||
void drawVerticalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is
|
||||
// a unsigned byte value between 0 and 100
|
||||
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);
|
||||
|
||||
// Draw a bitmap in the internal image format
|
||||
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);
|
||||
|
||||
// Draw a XBM
|
||||
void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm);
|
||||
|
||||
// Draw icon 16x16 xbm format
|
||||
void drawIco16x16(int16_t x, int16_t y, const uint8_t *ico, bool inverse = false);
|
||||
|
||||
/* Text functions */
|
||||
|
||||
// Draws a string at the given location, returns how many chars have been written
|
||||
uint16_t drawString(int16_t x, int16_t y, const String &text);
|
||||
|
||||
// Draws a formatted string (like printf) at the given location
|
||||
void drawStringf(int16_t x, int16_t y, char* buffer, String format, ... );
|
||||
|
||||
// Draws a String with a maximum width at the given location.
|
||||
// If the given String is wider than the specified width
|
||||
// The text will be wrapped to the next line at a space or dash
|
||||
// returns 0 if everything fits on the screen or the numbers of characters in the
|
||||
// first line if not
|
||||
uint16_t drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text);
|
||||
|
||||
// Returns the width of the const char* with the current
|
||||
// font settings
|
||||
uint16_t getStringWidth(const char* text, uint16_t length, bool utf8 = false);
|
||||
|
||||
// Convencience method for the const char version
|
||||
uint16_t getStringWidth(const String &text);
|
||||
|
||||
// Specifies relative to which anchor point
|
||||
// the text is rendered. Available constants:
|
||||
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
|
||||
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);
|
||||
|
||||
// Sets the current font. Available default fonts
|
||||
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
|
||||
void setFont(const uint8_t *fontData);
|
||||
|
||||
// Set the function that will convert utf-8 to font table index
|
||||
void setFontTableLookupFunction(FontTableLookupFunction function);
|
||||
|
||||
/* Display functions */
|
||||
|
||||
// Turn the display on
|
||||
void displayOn(void);
|
||||
|
||||
// Turn the display offs
|
||||
void displayOff(void);
|
||||
|
||||
// Inverted display mode
|
||||
void invertDisplay(void);
|
||||
|
||||
// Normal display mode
|
||||
void normalDisplay(void);
|
||||
|
||||
// Set display contrast
|
||||
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
|
||||
// normal brightness & contrast: contrast = 100
|
||||
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);
|
||||
|
||||
// Convenience method to access
|
||||
virtual void setBrightness(uint8_t);
|
||||
|
||||
// Reset display rotation or mirroring
|
||||
void resetOrientation();
|
||||
|
||||
// Turn the display upside down
|
||||
void flipScreenVertically();
|
||||
|
||||
// Mirror the display (to be used in a mirror or as a projector)
|
||||
void mirrorScreen();
|
||||
|
||||
// Write the buffer to the display memory
|
||||
virtual void display(void) = 0;
|
||||
|
||||
// Clear the local pixel buffer
|
||||
void clear(void);
|
||||
|
||||
// Log buffer implementation
|
||||
|
||||
// This will define the lines and characters you can
|
||||
// print to the screen. When you exeed the buffer size (lines * chars)
|
||||
// the output may be truncated due to the size constraint.
|
||||
bool setLogBuffer(uint16_t lines, uint16_t chars);
|
||||
|
||||
// Draw the log buffer at position (x, y)
|
||||
void drawLogBuffer(uint16_t x, uint16_t y);
|
||||
|
||||
// Get screen geometry
|
||||
uint16_t getWidth(void);
|
||||
uint16_t getHeight(void);
|
||||
|
||||
// Implement needed function to be compatible with Print class
|
||||
size_t write(uint8_t c);
|
||||
size_t write(const char* s);
|
||||
|
||||
// Implement needed function to be compatible with Stream class
|
||||
#ifdef __MBED__
|
||||
int _putc(int c);
|
||||
int _getc() { return -1; };
|
||||
#endif
|
||||
|
||||
|
||||
uint8_t *buffer;
|
||||
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t *buffer_back;
|
||||
#endif
|
||||
|
||||
// Set the correct height, width and buffer for the geometry
|
||||
void setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width = 0, uint16_t height = 0);
|
||||
|
||||
protected:
|
||||
|
||||
OLEDDISPLAY_GEOMETRY geometry;
|
||||
|
||||
uint16_t displayWidth;
|
||||
uint16_t displayHeight;
|
||||
uint16_t displayBufferSize;
|
||||
|
||||
OLEDDISPLAY_TEXT_ALIGNMENT textAlignment;
|
||||
OLEDDISPLAY_COLOR color;
|
||||
|
||||
const uint8_t *fontData;
|
||||
|
||||
// State values for logBuffer
|
||||
uint16_t logBufferSize;
|
||||
uint16_t logBufferFilled;
|
||||
uint16_t logBufferLine;
|
||||
uint16_t logBufferMaxLines;
|
||||
char *logBuffer;
|
||||
|
||||
|
||||
// the header size of the buffer used, e.g. for the SPI command header
|
||||
int BufferOffset;
|
||||
virtual int getBufferOffset(void) = 0;
|
||||
|
||||
// Send a command to the display (low level function)
|
||||
virtual void sendCommand(uint8_t com) {(void)com;};
|
||||
|
||||
// Connect to the display
|
||||
virtual bool connect() { return false; };
|
||||
|
||||
// Send all the init commands
|
||||
virtual void sendInitCommands();
|
||||
|
||||
// converts utf8 characters to extended ascii
|
||||
char* utf8ascii(const String &s);
|
||||
|
||||
void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline));
|
||||
|
||||
uint16_t drawStringInternal(int16_t xMove, int16_t yMove, const char* text, uint16_t textLength, uint16_t textWidth, bool utf8);
|
||||
|
||||
FontTableLookupFunction fontTableLookupFunction;
|
||||
};
|
||||
|
||||
#endif
|
||||
1273
src/helpers/ui/OLEDDisplayFonts.cpp
Normal file
1273
src/helpers/ui/OLEDDisplayFonts.cpp
Normal file
File diff suppressed because it is too large
Load Diff
13
src/helpers/ui/OLEDDisplayFonts.h
Normal file
13
src/helpers/ui/OLEDDisplayFonts.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef OLEDDISPLAYFONTS_h
|
||||
#define OLEDDISPLAYFONTS_h
|
||||
|
||||
#ifdef ARDUINO
|
||||
#include <Arduino.h>
|
||||
#elif __MBED__
|
||||
#define PROGMEM
|
||||
#endif
|
||||
|
||||
extern const uint8_t ArialMT_Plain_10[] PROGMEM;
|
||||
extern const uint8_t ArialMT_Plain_16[] PROGMEM;
|
||||
extern const uint8_t ArialMT_Plain_24[] PROGMEM;
|
||||
#endif
|
||||
@@ -2,14 +2,9 @@
|
||||
|
||||
#include "ST7789Display.h"
|
||||
|
||||
bool ST7789Display::i2c_probe(TwoWire& wire, uint8_t addr) {
|
||||
return true;
|
||||
/*
|
||||
wire.beginTransmission(addr);
|
||||
uint8_t error = wire.endTransmission();
|
||||
return (error == 0);
|
||||
*/
|
||||
}
|
||||
#ifndef X_OFFSET
|
||||
#define X_OFFSET 16
|
||||
#endif
|
||||
|
||||
bool ST7789Display::begin() {
|
||||
if(!_isOn) {
|
||||
@@ -19,14 +14,11 @@ bool ST7789Display::begin() {
|
||||
digitalWrite(PIN_TFT_LEDA_CTL, LOW);
|
||||
digitalWrite(PIN_TFT_RST, HIGH);
|
||||
|
||||
display.init(135, 240);
|
||||
display.setRotation(2);
|
||||
display.setSPISpeed(40000000);
|
||||
display.fillScreen(ST77XX_BLACK);
|
||||
display.setTextColor(ST77XX_WHITE);
|
||||
display.setTextSize(2);
|
||||
display.cp437(true); // Use full 256 char 'Code Page 437' font
|
||||
|
||||
display.init();
|
||||
display.landscapeScreen();
|
||||
display.displayOn();
|
||||
setCursor(0,0);
|
||||
|
||||
_isOn = true;
|
||||
}
|
||||
return true;
|
||||
@@ -40,24 +32,28 @@ void ST7789Display::turnOff() {
|
||||
digitalWrite(PIN_TFT_VDD_CTL, HIGH);
|
||||
digitalWrite(PIN_TFT_LEDA_CTL, HIGH);
|
||||
digitalWrite(PIN_TFT_RST, LOW);
|
||||
// digitalWrite(PIN_TFT_VDD_CTL, LOW);
|
||||
// digitalWrite(PIN_TFT_LEDA_CTL, LOW);
|
||||
_isOn = false;
|
||||
}
|
||||
|
||||
void ST7789Display::clear() {
|
||||
display.fillScreen(ST77XX_BLACK);
|
||||
display.clear();
|
||||
}
|
||||
|
||||
void ST7789Display::startFrame(Color bkg) {
|
||||
display.fillScreen(0x00);
|
||||
display.setTextColor(ST77XX_WHITE);
|
||||
display.setTextSize(2);
|
||||
display.cp437(true); // Use full 256 char 'Code Page 437' font
|
||||
display.clear();
|
||||
}
|
||||
|
||||
void ST7789Display::setTextSize(int sz) {
|
||||
display.setTextSize(sz);
|
||||
switch(sz) {
|
||||
case 1 :
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
break;
|
||||
case 2 :
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
break;
|
||||
default:
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
}
|
||||
}
|
||||
|
||||
void ST7789Display::setColor(Color c) {
|
||||
@@ -87,31 +83,32 @@ void ST7789Display::setColor(Color c) {
|
||||
_color = ST77XX_WHITE;
|
||||
break;
|
||||
}
|
||||
display.setTextColor(_color);
|
||||
display.setRGB(_color);
|
||||
}
|
||||
|
||||
void ST7789Display::setCursor(int x, int y) {
|
||||
display.setCursor(x, y);
|
||||
_x = x + X_OFFSET;
|
||||
_y = y;
|
||||
}
|
||||
|
||||
void ST7789Display::print(const char* str) {
|
||||
display.print(str);
|
||||
display.drawString(_x, _y, str);
|
||||
}
|
||||
|
||||
void ST7789Display::fillRect(int x, int y, int w, int h) {
|
||||
display.fillRect(x, y, w, h, _color);
|
||||
display.fillRect(x + X_OFFSET, y, w, h);
|
||||
}
|
||||
|
||||
void ST7789Display::drawRect(int x, int y, int w, int h) {
|
||||
display.drawRect(x, y, w, h, _color);
|
||||
display.drawRect(x + X_OFFSET, y, w, h);
|
||||
}
|
||||
|
||||
void ST7789Display::drawXbm(int x, int y, const uint8_t* bits, int w, int h) {
|
||||
display.drawBitmap(x, y, bits, w, h, _color);
|
||||
display.drawBitmap(x+X_OFFSET, y, w, h, bits);
|
||||
}
|
||||
|
||||
void ST7789Display::endFrame() {
|
||||
// display.display();
|
||||
display.display();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -4,16 +4,18 @@
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_ST7789.h>
|
||||
#include <ST7789Spi.h>
|
||||
|
||||
class ST7789Display : public DisplayDriver {
|
||||
Adafruit_ST7789 display;
|
||||
ST7789Spi display;
|
||||
bool _isOn;
|
||||
uint16_t _color;
|
||||
int _x=0, _y=0;
|
||||
|
||||
bool i2c_probe(TwoWire& wire, uint8_t addr);
|
||||
public:
|
||||
ST7789Display() : DisplayDriver(135, 240), display(&SPI1, PIN_TFT_CS, PIN_TFT_DC, PIN_TFT_RST) { _isOn = false; }
|
||||
ST7789Display() : DisplayDriver(135, 240), display(&SPI1, PIN_TFT_RST, PIN_TFT_DC, PIN_TFT_CS, GEOMETRY_RAWMODE, 240, 135) {_isOn = false;}
|
||||
|
||||
// ST7789Display() : DisplayDriver(135, 240), display(PIN_TFT_CS, PIN_TFT_DC, PIN_TFT_SDA, PIN_TFT_SCL, PIN_TFT_RST) { _isOn = false; }
|
||||
bool begin();
|
||||
|
||||
|
||||
461
src/helpers/ui/ST7789Spi.h
Normal file
461
src/helpers/ui/ST7789Spi.h
Normal file
@@ -0,0 +1,461 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
* Copyright (c) 2024 by Heltec AutoMation
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ST7789Spi_h
|
||||
#define ST7789Spi_h
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <SPI.h>
|
||||
|
||||
|
||||
#define ST_CMD_DELAY 0x80 // special signifier for command lists
|
||||
|
||||
#define ST77XX_NOP 0x00
|
||||
#define ST77XX_SWRESET 0x01
|
||||
#define ST77XX_RDDID 0x04
|
||||
#define ST77XX_RDDST 0x09
|
||||
|
||||
#define ST77XX_SLPIN 0x10
|
||||
#define ST77XX_SLPOUT 0x11
|
||||
#define ST77XX_PTLON 0x12
|
||||
#define ST77XX_NORON 0x13
|
||||
|
||||
#define ST77XX_INVOFF 0x20
|
||||
#define ST77XX_INVON 0x21
|
||||
#define ST77XX_DISPOFF 0x28
|
||||
#define ST77XX_DISPON 0x29
|
||||
#define ST77XX_CASET 0x2A
|
||||
#define ST77XX_RASET 0x2B
|
||||
#define ST77XX_RAMWR 0x2C
|
||||
#define ST77XX_RAMRD 0x2E
|
||||
|
||||
#define ST77XX_PTLAR 0x30
|
||||
#define ST77XX_TEOFF 0x34
|
||||
#define ST77XX_TEON 0x35
|
||||
#define ST77XX_MADCTL 0x36
|
||||
#define ST77XX_COLMOD 0x3A
|
||||
|
||||
#define ST77XX_MADCTL_MY 0x80
|
||||
#define ST77XX_MADCTL_MX 0x40
|
||||
#define ST77XX_MADCTL_MV 0x20
|
||||
#define ST77XX_MADCTL_ML 0x10
|
||||
#define ST77XX_MADCTL_RGB 0x00
|
||||
|
||||
#define ST77XX_RDID1 0xDA
|
||||
#define ST77XX_RDID2 0xDB
|
||||
#define ST77XX_RDID3 0xDC
|
||||
#define ST77XX_RDID4 0xDD
|
||||
|
||||
// Some ready-made 16-bit ('565') color settings:
|
||||
#define ST77XX_BLACK 0x0000
|
||||
#define ST77XX_WHITE 0xFFFF
|
||||
#define ST77XX_RED 0xF800
|
||||
#define ST77XX_GREEN 0x07E0
|
||||
#define ST77XX_BLUE 0x001F
|
||||
#define ST77XX_CYAN 0x07FF
|
||||
#define ST77XX_MAGENTA 0xF81F
|
||||
#define ST77XX_YELLOW 0xFFE0
|
||||
#define ST77XX_ORANGE 0xFC00
|
||||
|
||||
#define LED_A_ON LOW
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#undef LED_A_ON
|
||||
#define LED_A_ON HIGH
|
||||
#define rtos_free free
|
||||
#define rtos_malloc malloc
|
||||
//SPIClass SPI1(HSPI);
|
||||
#endif
|
||||
class ST7789Spi : public OLEDDisplay {
|
||||
private:
|
||||
uint8_t _rst;
|
||||
uint8_t _dc;
|
||||
uint8_t _cs;
|
||||
uint8_t _ledA;
|
||||
int _miso;
|
||||
int _mosi;
|
||||
int _clk;
|
||||
SPIClass * _spi;
|
||||
SPISettings _spiSettings;
|
||||
uint16_t _RGB=0xFFFF;
|
||||
uint8_t _buffheight;
|
||||
public:
|
||||
/* pass _cs as -1 to indicate "do not use CS pin", for cases where it is hard wired low */
|
||||
ST7789Spi(SPIClass *spiClass,uint8_t _rst, uint8_t _dc, uint8_t _cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_RAWMODE,uint16_t width=240,uint16_t height=135,int mosi=-1,int miso=-1,int clk=-1) {
|
||||
this->_spi = spiClass;
|
||||
this->_rst = _rst;
|
||||
this->_dc = _dc;
|
||||
this->_cs = _cs;
|
||||
this->_mosi=mosi;
|
||||
this->_miso=miso;
|
||||
this->_clk=clk;
|
||||
//this->_ledA = _ledA;
|
||||
_spiSettings = SPISettings(40000000, MSBFIRST, SPI_MODE0);
|
||||
setGeometry(g,width,height);
|
||||
}
|
||||
|
||||
bool connect(){
|
||||
this->_buffheight=displayHeight / 8;
|
||||
this->_buffheight+=displayHeight % 8 ? 1:0;
|
||||
pinMode(_cs, OUTPUT);
|
||||
pinMode(_dc, OUTPUT);
|
||||
//pinMode(_ledA, OUTPUT);
|
||||
if (_cs != (uint8_t) -1) {
|
||||
pinMode(_cs, OUTPUT);
|
||||
}
|
||||
pinMode(_rst, OUTPUT);
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
_spi->begin(_clk,_miso,_mosi,-1);
|
||||
#else
|
||||
_spi->begin();
|
||||
#endif
|
||||
_spi->setClockDivider (SPI_CLOCK_DIV2);
|
||||
|
||||
// Pulse Reset low for 10ms
|
||||
digitalWrite(_rst, HIGH);
|
||||
delay(1);
|
||||
digitalWrite(_rst, LOW);
|
||||
delay(10);
|
||||
digitalWrite(_rst, HIGH);
|
||||
_spi->begin ();
|
||||
//digitalWrite(_ledA, LED_A_ON);
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
|
||||
uint16_t minBoundY = UINT16_MAX;
|
||||
uint16_t maxBoundY = 0;
|
||||
|
||||
uint16_t minBoundX = UINT16_MAX;
|
||||
uint16_t maxBoundX = 0;
|
||||
|
||||
uint16_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < _buffheight; y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
//Serial.printf("x %d y %d\r\n",x,y);
|
||||
uint16_t pos = x + y * displayWidth;
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = min(minBoundY, y);
|
||||
maxBoundY = max(maxBoundY, y);
|
||||
minBoundX = min(minBoundX, x);
|
||||
maxBoundX = max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
if (minBoundY == UINT16_MAX) return;
|
||||
|
||||
set_CS(LOW);
|
||||
_spi->beginTransaction(_spiSettings);
|
||||
|
||||
for (y = minBoundY; y <= maxBoundY; y++)
|
||||
{
|
||||
for(int temp = 0; temp<8;temp++)
|
||||
{
|
||||
//setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
|
||||
setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
|
||||
//setAddrWindow(y*8+temp,minBoundX,1,maxBoundX-minBoundX+1);
|
||||
uint32_t const pixbufcount = maxBoundX-minBoundX+1;
|
||||
uint16_t *pixbuf = (uint16_t *)rtos_malloc(2 * pixbufcount);
|
||||
for (x = minBoundX; x <= maxBoundX; x++)
|
||||
{
|
||||
pixbuf[x-minBoundX] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0;
|
||||
}
|
||||
#ifdef ESP_PLATFORM
|
||||
_spi->transferBytes((uint8_t *)pixbuf, NULL, 2 * pixbufcount);
|
||||
#else
|
||||
_spi->transfer(pixbuf, NULL, 2 * pixbufcount);
|
||||
#endif
|
||||
rtos_free(pixbuf);
|
||||
}
|
||||
}
|
||||
_spi->endTransaction();
|
||||
set_CS(HIGH);
|
||||
|
||||
#else
|
||||
set_CS(LOW);
|
||||
_spi->beginTransaction(_spiSettings);
|
||||
uint8_t x, y;
|
||||
for (y = 0; y < _buffheight; y++)
|
||||
{
|
||||
for(int temp = 0; temp<8;temp++)
|
||||
{
|
||||
//setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
|
||||
//setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
|
||||
setAddrWindow(y*8+temp,0,1,displayWidth);
|
||||
uint32_t const pixbufcount = displayWidth;
|
||||
uint16_t *pixbuf = (uint16_t *)rtos_malloc(2 * pixbufcount);
|
||||
for (x = 0; x < displayWidth; x++)
|
||||
{
|
||||
pixbuf[x] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0;
|
||||
}
|
||||
#ifdef ESP_PLATFORM
|
||||
_spi->transferBytes((uint8_t *)pixbuf, NULL, 2 * pixbufcount);
|
||||
#else
|
||||
_spi->transfer(pixbuf, NULL, 2 * pixbufcount);
|
||||
#endif
|
||||
rtos_free(pixbuf);
|
||||
}
|
||||
}
|
||||
_spi->endTransaction();
|
||||
set_CS(HIGH);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void resetOrientation() {
|
||||
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MX;
|
||||
sendCommand(ST77XX_MADCTL);
|
||||
WriteData(madctl);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
virtual void flipScreenVertically() {
|
||||
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MY;
|
||||
sendCommand(ST77XX_MADCTL);
|
||||
WriteData(madctl);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
virtual void mirrorScreen() {
|
||||
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MX|ST77XX_MADCTL_MY;
|
||||
sendCommand(ST77XX_MADCTL);
|
||||
WriteData(madctl);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
virtual void landscapeScreen() {
|
||||
|
||||
|
||||
uint8_t madctl = ST77XX_MADCTL_RGB;
|
||||
sendCommand(ST77XX_MADCTL);
|
||||
WriteData(madctl);
|
||||
delay(10);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void setRGB(uint16_t c)
|
||||
{
|
||||
|
||||
this->_RGB=0x00|c>>8|c<<8&0xFF00;
|
||||
}
|
||||
|
||||
void displayOn(void) {
|
||||
//sendCommand(DISPLAYON);
|
||||
}
|
||||
|
||||
void displayOff(void) {
|
||||
//sendCommand(DISPLAYOFF);
|
||||
}
|
||||
|
||||
void drawBitmap(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *xbm) {
|
||||
int16_t widthInXbm = (width + 7) / 8;
|
||||
uint8_t data = 0;
|
||||
|
||||
for(int16_t y = 0; y < height; y++) {
|
||||
for(int16_t x = 0; x < width; x++ ) {
|
||||
if (x & 7) {
|
||||
data <<= 1; // Move a bit
|
||||
} else { // Read new data every 8 bit
|
||||
data = pgm_read_byte(xbm + (x / 8) + y * widthInXbm);
|
||||
}
|
||||
// if there is a bit draw it
|
||||
if (data & 0x80) {
|
||||
setPixel(xMove + x, yMove + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#define ST77XX_MADCTL_MY 0x80
|
||||
//#define ST77XX_MADCTL_MX 0x40
|
||||
//#define ST77XX_MADCTL_MV 0x20
|
||||
//#define ST77XX_MADCTL_ML 0x10
|
||||
protected:
|
||||
// Send all the init commands
|
||||
virtual void sendInitCommands()
|
||||
{
|
||||
sendCommand(ST77XX_SWRESET); // 1: Software reset, no args, w/delay
|
||||
delay(150);
|
||||
|
||||
sendCommand(ST77XX_SLPOUT); // 2: Out of sleep mode, no args, w/delay
|
||||
delay(10);
|
||||
|
||||
sendCommand(ST77XX_COLMOD); // 3: Set color mode, 16-bit color
|
||||
WriteData(0x55);
|
||||
delay(10);
|
||||
|
||||
sendCommand(ST77XX_MADCTL); // 4: Mem access ctrl (directions), Row/col addr, bottom-top refresh
|
||||
WriteData(0x08);
|
||||
|
||||
sendCommand(ST77XX_CASET); // 5: Column addr set,
|
||||
WriteData(0x00);
|
||||
WriteData(0x00); // XSTART = 0
|
||||
WriteData(0x00);
|
||||
WriteData(240); // XEND = 240
|
||||
|
||||
sendCommand(ST77XX_RASET); // 6: Row addr set,
|
||||
WriteData(0x00);
|
||||
WriteData(0x00); // YSTART = 0
|
||||
WriteData(320>>8);
|
||||
WriteData(320&0xFF); // YSTART = 320
|
||||
|
||||
sendCommand(ST77XX_SLPOUT); // 7: hack
|
||||
delay(10);
|
||||
|
||||
sendCommand(ST77XX_NORON); // 8: Normal display on, no args, w/delay
|
||||
delay(10);
|
||||
|
||||
sendCommand(ST77XX_DISPON); // 9: Main screen turn on, no args, delay
|
||||
delay(10);
|
||||
|
||||
sendCommand(ST77XX_INVON); // 10: invert
|
||||
delay(10);
|
||||
|
||||
//uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MX;
|
||||
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MX;
|
||||
sendCommand(ST77XX_MADCTL);
|
||||
WriteData(madctl);
|
||||
delay(10);
|
||||
setRGB(ST77XX_GREEN);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
x += (320-displayWidth)/2;
|
||||
y += (240-displayHeight)/2;
|
||||
uint32_t xa = ((uint32_t)x << 16) | (x + w - 1);
|
||||
uint32_t ya = ((uint32_t)y << 16) | (y + h - 1);
|
||||
|
||||
writeCommand(ST77XX_CASET); // Column addr set
|
||||
SPI_WRITE32(xa);
|
||||
|
||||
writeCommand(ST77XX_RASET); // Row addr set
|
||||
SPI_WRITE32(ya);
|
||||
|
||||
writeCommand(ST77XX_RAMWR); // write to RAM
|
||||
}
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
inline void set_CS(bool level) {
|
||||
if (_cs != (uint8_t) -1) {
|
||||
digitalWrite(_cs, level);
|
||||
}
|
||||
};
|
||||
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
|
||||
set_CS(HIGH);
|
||||
digitalWrite(_dc, LOW);
|
||||
set_CS(LOW);
|
||||
_spi->beginTransaction(_spiSettings);
|
||||
_spi->transfer(com);
|
||||
_spi->endTransaction();
|
||||
set_CS(HIGH);
|
||||
digitalWrite(_dc, HIGH);
|
||||
}
|
||||
|
||||
inline void WriteData(uint8_t data) __attribute__((always_inline)){
|
||||
digitalWrite(_cs, LOW);
|
||||
_spi->beginTransaction(_spiSettings);
|
||||
_spi->transfer(data);
|
||||
_spi->endTransaction();
|
||||
digitalWrite(_cs, HIGH);
|
||||
}
|
||||
void SPI_WRITE32(uint32_t l)
|
||||
{
|
||||
_spi->transfer(l >> 24);
|
||||
_spi->transfer(l >> 16);
|
||||
_spi->transfer(l >> 8);
|
||||
_spi->transfer(l);
|
||||
}
|
||||
void writeCommand(uint8_t cmd) {
|
||||
digitalWrite(_dc, LOW);
|
||||
_spi->transfer(cmd);
|
||||
digitalWrite(_dc, HIGH);
|
||||
}
|
||||
|
||||
// Private functions
|
||||
void setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width, uint16_t height) {
|
||||
this->geometry = g;
|
||||
|
||||
switch (g) {
|
||||
case GEOMETRY_128_128:
|
||||
this->displayWidth = 128;
|
||||
this->displayHeight = 128;
|
||||
break;
|
||||
case GEOMETRY_128_64:
|
||||
this->displayWidth = 128;
|
||||
this->displayHeight = 64;
|
||||
break;
|
||||
case GEOMETRY_128_32:
|
||||
this->displayWidth = 128;
|
||||
this->displayHeight = 32;
|
||||
break;
|
||||
case GEOMETRY_64_48:
|
||||
this->displayWidth = 64;
|
||||
this->displayHeight = 48;
|
||||
break;
|
||||
case GEOMETRY_64_32:
|
||||
this->displayWidth = 64;
|
||||
this->displayHeight = 32;
|
||||
break;
|
||||
case GEOMETRY_RAWMODE:
|
||||
this->displayWidth = width > 0 ? width : 128;
|
||||
this->displayHeight = height > 0 ? height : 64;
|
||||
break;
|
||||
}
|
||||
uint8_t tmp=displayHeight % 8;
|
||||
uint8_t _buffheight=displayHeight / 8;
|
||||
|
||||
if(tmp!=0)
|
||||
_buffheight++;
|
||||
this->displayBufferSize = displayWidth * _buffheight ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -60,6 +60,9 @@ build_flags =
|
||||
extends = Heltec_t114
|
||||
build_flags =
|
||||
${Heltec_t114.build_flags}
|
||||
-I src/helpers/ui
|
||||
-D ST7789
|
||||
-D DISPLAY_CLASS=ST7789Display
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D BLE_PIN_CODE=123456
|
||||
@@ -69,23 +72,17 @@ build_flags =
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Heltec_t114.build_src_filter}
|
||||
+<helpers/nrf52/*.cpp>
|
||||
+<helpers/nrf52/T114Board.cpp>
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<../examples/companion_radio/main.cpp>
|
||||
lib_deps =
|
||||
${Heltec_t114.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_t114_companion_radio_ble_screen]
|
||||
extends = env:Heltec_t114_companion_radio_ble
|
||||
build_flags = ${env:Heltec_t114_companion_radio_ble.build_flags}
|
||||
-I src/helpers/ui
|
||||
-D ST7789
|
||||
-D DISPLAY_CLASS=ST7789Display
|
||||
build_src_filter = ${env:Heltec_t114_companion_radio_ble.build_src_filter}
|
||||
+<../examples/companion_radio/UITask.cpp>
|
||||
+<helpers/ui/ST7789Display.cpp>
|
||||
lib_deps = ${env:Heltec_t114_companion_radio_ble.lib_deps}
|
||||
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
|
||||
+<helpers/ui/OLEDDisplay.cpp>
|
||||
+<helpers/ui/OLEDDisplayFonts.cpp>
|
||||
lib_deps =
|
||||
adafruit/Adafruit GFX Library @ ^1.12.1
|
||||
${Heltec_t114.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_t114_companion_radio_usb]
|
||||
extends = Heltec_t114
|
||||
|
||||
@@ -11,4 +11,5 @@ const uint32_t g_ADigitalPinMap[] = {
|
||||
|
||||
void initVariant()
|
||||
{
|
||||
pinMode(PIN_USER_BTN, INPUT);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user