This commit is contained in:
e2002
2022-10-31 10:15:17 +03:00
parent bfb6cd822a
commit ef14938dbe
33 changed files with 1860 additions and 176 deletions

View File

@@ -57,4 +57,6 @@
\
![ёRadio](images/img27.jpg)\
\
![ёRadio](images/img28.jpg)
![ёRadio](images/img28.jpg)\
\
![ёRadio](images/img29.jpg)

View File

@@ -45,7 +45,8 @@ https://aliexpress.com/item/32965676064.html
- or **LCD1602** 16x2 I2C https://aliexpress.com/item/32305776560.html
- or **LCD1602** 16x2 without I2C https://aliexpress.com/item/32305776560.html
- or **SSD1327** 1.5' 128x128 I2C https://aliexpress.com/item/1005001414175498.html
- or **ILI9341** 3.2'320x240 SPI https://aliexpress.com/item/33048191074.html
- or **ILI9341** 3.2' 320x240 SPI https://aliexpress.com/item/33048191074.html
- or **ILI9341** 2.8' 320x240 SPI https://aliexpress.com/item/1005004502250619.html
- or **SSD1305 (SSD1309)** 2.4' 128x64 SPI/I2C https://aliexpress.com/item/32950307344.html
- or **SH1107** 0.96' 128x64 I2C https://aliexpress.com/item/4000551696674.html
- or **GC9106** 0.96' 160x80 SPI (looks like ST7735S, but it's not him) https://aliexpress.com/item/32947890530.html
@@ -53,6 +54,7 @@ https://aliexpress.com/item/32965676064.html
- or **LCD2004** 20x4 without I2C https://aliexpress.com/item/32783128355.html
- or **ILI9225** 2.0' 220x176 SPI https://aliexpress.com/item/32952021835.html
- or **Nextion displays** - [more info](https://github.com/e2002/yoradio/tree/main/nextion)
- or **ST7796** 3.5' 480x320 SPI https://aliexpress.com/item/1005004632953455.html?sku_id=12000029911293172
##### Controls
- Three tact buttons https://www.aliexpress.com/item/32907144687.html
@@ -299,6 +301,16 @@ Work is in progress...
---
## Version history
#### v0.8.03b
- added support for ST7796 display
- added support for capacitive touch GT911
- HSPI bus support added - DSP_HSPI, VS_HSPI, TS_HSPI options More details in examples/myoptions.h
- changed the method of connecting the touchscreen in myoptions.h Now instead of specifying TS_CS, you must specify TS_MODEL (by default TS_MODEL_UNDEFINED) More details in examples/myoptions.h
- new parameters TS_SDA, TS_SCL, TS_INT, TS_RST for GT911 touchscreen
- new parameters LIGHT_SENSOR and AUTOBACKLIGHT - to automatically adjust the brightness of the display. More details in examples/myoptions.h
- new parameter LED_INVERT (true/false) - to invert the behavior of the built-in LED
- fixed bug with extra sign } in humidity value
#### v0.8.02b
- fixed artifacts when displaying the volume level
- changes in mytheme.h . Added colors COLOR_PL_CURRENT, COLOR_PL_CURRENT_BG, COLOR_PL_CURRENT_FILL. Details in [exsamples/mytheme.h](exsamples/mytheme.h)

View File

@@ -10,6 +10,7 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
********************************************************/
#define LED_BUILTIN 2 /* Onboard LED Pin */
//#define LED_INVERT false /* Invert Onboard LED? */
#define L10N_LANGUAGE EN /* Language (EN, RU). More info in yoRadio/locale/displayL10n_(en|ru).h
/* DSP_MODEL. See description/available values in https://github.com/e2002/yoradio/wiki/Available-display-models */
@@ -25,11 +26,14 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
*/
/******************************************/
/* SPI PINS. SCL(SCK, CLK) must be connected to pin 18
SDA(MOSI, DIN, SDI) must be connected to pin 23 */
/* VSPI PINS. SCL(SCK, CLK) must be connected to pin 18
SDA(MOSI, DIN, SDI) must be connected to pin 23 */
//#define TFT_CS 5 /* SPI CS pin */
//#define TFT_RST 15 /* SPI RST pin. set to -1 and connect to Esp EN pin */
//#define TFT_DC 4 /* SPI DC/RS pin */
/* HSPI PINS. SCL(SCK, CLK) must be connected to pin 14
SDA(MOSI, DIN, SDI) must be connected to pin 13 */
//#define DSP_HSPI false /* Use HSPI for display */
/******************************************/
/* NEXTION */
@@ -47,13 +51,17 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
//#define I2S_LRC 25 /* WSEL Left Right Clock */
/******************************************/
/* VS1053 PINS. VS1053 SCK must be connected to pin 18
VS1053 MISO must be connected to pin 19
VS1053 MOSI must be connected to pin 23 */
/* VS1053 VSPI PINS. VS1053 SCK must be connected to pin 18
VS1053 MISO must be connected to pin 19
VS1053 MOSI must be connected to pin 23 */
//#define VS1053_CS 255 /* XCS pin. Should be set to 255 if the board is not used */
//#define VS1053_DCS 25 /* XDCS pin. */
//#define VS1053_DREQ 26 /* DREQ pin. */
//#define VS1053_RST -1 /* XRESET pin. Set to -1 if connected to Esp EN pin */
/* VS1053 HSPI PINS. VS1053 SCK must be connected to pin 14
VS1053 MISO must be connected to pin 12
VS1053 MOSI must be connected to pin 13 */
//#define VS_HSPI false /* Use HSPI for VS */
/******************************************/
/* ENCODER */
@@ -94,11 +102,25 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
/******************************************/
/* TOUCHSCREEN */
/* SPI PINS. CLK must be connected to pin 18
DIN must be connected to pin 23
DO must be connected to pin 19
IRQ - not connected */
//#define TS_CS 255 /* Touch screen CS pin
//#define TS_MODEL TS_MODEL_UNDEFINED /* See description/available values in yoRadio/src/core/options.h */
/* Resistive SPI touch screen */
/* TS VSPI PINS. CLK must be connected to pin 18
DIN must be connected to pin 23
DO must be connected to pin 19
IRQ - not connected */
//#define TS_CS 255 /* Touch screen CS pin */
/* TS HSPI PINS. CLK must be connected to pin 14
DIN must be connected to pin 13
DO must be connected to pin 12
IRQ - not connected */
//#define TS_HSPI false /* Use HSPI for Touch screen */
/* Capacitive I2C touch screen */
//#define TS_SDA 33
//#define TS_SCL 32
//#define TS_INT 21
//#define TS_RST 25
/******************************************/
/* Other settings. */
@@ -118,12 +140,9 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
//#define ROTATE_90 false /* Optional 90 degree rotation for square displays */
//#define WAKE_PIN 255 /* Wake Pin (for manual wakeup from sleep mode. can match with BTN_XXXX, ENC_BTNB, ENC2_BTNB. must be one of: 0,2,4,12,13,14,15,25,26,27,32,33,34,35,36,39) */
/* For sample #define ENC_BTNB 36 - next line - #define WAKE_PIN ENC_BTNB */
/* VU settings. See the default settings for your display in file yoRadio/display_vu.h */
/************************************************************************************************************************************************************************************/
/* vu left | vu top | band width | band height | band space | num of bands | fade speed | horisontal | Max Bands Color | Min Bands Color */
/************************************************************************************************************************************************************************************/
//#define VU_PARAMS2 { VU_X = 4, VU_Y = 60, VU_BW = 10, VU_BH = 34, VU_BS = 2, VU_NB = 8, VU_FS = 2, VU_HOR = 0, VU_COLOR_MAX = TFT_LOGO, VU_COLOR_MIN = SILVER }
/************************************************************************************************************************************************************************************/
//#define LIGHT_SENSOR 255 /* Light sensor */
//#define AUTOBACKLIGHT(x) *function* /* Autobacklight function. See options.h for exsample */
/******************************************/
/* IR control */
//#define IR_PIN 255

BIN
images/img29.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

View File

@@ -0,0 +1,341 @@
#include "../core/options.h"
#if DSP_MODEL==DSP_ST7796
/*!
* These displays use SPI to communicate, 4 or 5 pins are required
* to interface (RST is optional).
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section dependencies Dependencies
*
* This library depends on <a href="https://github.com/adafruit/Adafruit_GFX">
* Adafruit_GFX</a> being present on your system. Please make sure you have
* installed the latest version before using this library.
*
* @section author Author
*
* Written by Limor "ladyada" Fried for Adafruit Industries.
*
* @section license License
*
* BSD license, all text here must be included in any redistribution.
*
*/
#include "Adafruit_ST7796S_kbv.h"
#ifndef ARDUINO_STM32_FEATHER
#include "pins_arduino.h"
#ifndef RASPI
#include "wiring_private.h"
#endif
#endif
#include <limits.h>
#if defined(ARDUINO_ARCH_ARC32) || defined(ARDUINO_MAXIM)
#define SPI_DEFAULT_FREQ 16000000
// Teensy 3.0, 3.1/3.2, 3.5, 3.6
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || \
defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define SPI_DEFAULT_FREQ 40000000
#elif defined(__AVR__) || defined(TEENSYDUINO)
#define SPI_DEFAULT_FREQ 8000000
#elif defined(ESP8266) || defined(ESP32)
#define SPI_DEFAULT_FREQ 40000000
#elif defined(RASPI)
#define SPI_DEFAULT_FREQ 80000000
#elif defined(ARDUINO_ARCH_STM32F1)
#define SPI_DEFAULT_FREQ 36000000
#else
#define SPI_DEFAULT_FREQ 24000000 ///< Default SPI data clock frequency
#endif
#define MADCTL_MY 0x80 ///< Bottom to top
#define MADCTL_MX 0x40 ///< Right to left
#define MADCTL_MV 0x20 ///< Reverse Mode
#define MADCTL_ML 0x10 ///< LCD refresh Bottom to top
#define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
#define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
#define MADCTL_MH 0x04 ///< LCD refresh right to left
/**************************************************************************/
/*!
@brief Instantiate Adafruit ST7796S driver with software SPI
@param cs Chip select pin #
@param dc Data/Command pin #
@param mosi SPI MOSI pin #
@param sclk SPI Clock pin #
@param rst Reset pin # (optional, pass -1 if unused)
@param miso SPI MISO pin # (optional, pass -1 if unused)
*/
/**************************************************************************/
Adafruit_ST7796S_kbv::Adafruit_ST7796S_kbv(int8_t cs, int8_t dc, int8_t mosi,
int8_t sclk, int8_t rst, int8_t miso)
: Adafruit_SPITFT(ST7796S_TFTWIDTH, ST7796S_TFTHEIGHT, cs, dc, mosi, sclk,
rst, miso) {}
/**************************************************************************/
/*!
@brief Instantiate Adafruit ST7796S driver with hardware SPI using the
default SPI peripheral.
@param cs Chip select pin # (OK to pass -1 if CS tied to GND).
@param dc Data/Command pin # (required).
@param rst Reset pin # (optional, pass -1 if unused).
*/
/**************************************************************************/
Adafruit_ST7796S_kbv::Adafruit_ST7796S_kbv(int8_t cs, int8_t dc, int8_t rst)
: Adafruit_SPITFT(ST7796S_TFTWIDTH, ST7796S_TFTHEIGHT, cs, dc, rst) {}
#if !defined(ESP8266)
/**************************************************************************/
/*!
@brief Instantiate Adafruit ST7796S driver with hardware SPI using
a specific SPI peripheral (not necessarily default).
@param spiClass Pointer to SPI peripheral (e.g. &SPI or &SPI1).
@param dc Data/Command pin # (required).
@param cs Chip select pin # (optional, pass -1 if unused and
CS is tied to GND).
@param rst Reset pin # (optional, pass -1 if unused).
*/
/**************************************************************************/
Adafruit_ST7796S_kbv::Adafruit_ST7796S_kbv(SPIClass *spiClass, int8_t dc, int8_t cs,
int8_t rst)
: Adafruit_SPITFT(ST7796S_TFTWIDTH, ST7796S_TFTHEIGHT, spiClass, cs, dc,
rst) {}
#endif // end !ESP8266
/**************************************************************************/
/*!
@brief Instantiate Adafruit ST7796S driver using parallel interface.
@param busWidth If tft16 (enumeration in Adafruit_SPITFT.h), is a
16-bit interface, else 8-bit.
@param d0 Data pin 0 (MUST be a byte- or word-aligned LSB of a
PORT register -- pins 1-n are extrapolated from this).
@param wr Write strobe pin # (required).
@param dc Data/Command pin # (required).
@param cs Chip select pin # (optional, pass -1 if unused and CS
is tied to GND).
@param rst Reset pin # (optional, pass -1 if unused).
@param rd Read strobe pin # (optional, pass -1 if unused).
*/
/**************************************************************************/
Adafruit_ST7796S_kbv::Adafruit_ST7796S_kbv(tftBusWidth busWidth, int8_t d0, int8_t wr,
int8_t dc, int8_t cs, int8_t rst, int8_t rd)
: Adafruit_SPITFT(ST7796S_TFTWIDTH, ST7796S_TFTHEIGHT, busWidth, d0, wr, dc,
cs, rst, rd) {}
// clang-format off
static const uint8_t PROGMEM initcmd[] = {
// (COMMAND_BYTE), n, data_bytes....
0x01, 0x80, // Soft reset, then delay 150 ms
0xF0, 1, 0xC3, // ?? Unlock Manufacturer
0xF0, 1, 0x96,
#if 0
#elif 0 //LCDWIKI
0x36, 1, 0x68,
0x3A, 1, 0x05,
0 0xB0, 1, 0x80,
0xB6, 2, 0x00, 0x02,
0xB5, 4, 0x02, 0x03, 0x00, 0x04,
0xB1, 2, 0x80, 0x10,
0xB4, 1, 0x00,
0xB7, 1, 0xC6,
0xC5, 1, 0x24,
0xE4, 1, 0x31,
0xE8, 8, 0x40, 0x8A, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33,
0xC2, 1, 0xA7,
0xE0, 14, 0xF0, 0x09, 0x13, 0x12, 0x12, 0x2B, 0x3C, 0x44, 0x4B, 0x1B, 0x18, 0x17, 0x1D, 0x21,
0xE1, 14, 0xF0, 0x09, 0x13, 0x0C, 0x0D, 0x27, 0x3B, 0x44, 0x4D, 0x0B, 0x17 ,0x17, 0x1D, 0x21,
0x36, 1, 0x48,
#elif 0 //TFT_eSPI
0x36, 1, 0x48,
0x3A, 1, 0x05, //Interlace Pixel Format [XX]
0xB4, 1, 0x01, //Inversion Control [01]
0xB6, 3, 0x80, 0x02, 0x3B, // Display Function Control [80 02 3B]
0xE8, 8, 0x40, 0x8A, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33, //Adjustment Control 3 [40 8A 00 00 25 0A 38 33]
0xC1, 1, 0x06, //Power Control 2 [13]
0xC2, 1, 0xA7, //Power Control 3 [A?]
0xC5, 1, 0x18, //VCOM=0.9 [1C]
//0x11, 0x80, //delay 150 ms
(0xE0), 14, 0xF0, 0x09, 0x0B, 0x06, 0x04, 0x15, 0x2F, 0x54, 0x42, 0x3C, 0x17, 0x14, 0x18, 0x1B, //PVGAMCTRL: Positive Voltage Gamma control
(0xE1), 14, 0xE0, 0x09, 0x0B, 0x06, 0x04, 0x03, 0x2B, 0x43, 0x42, 0x3B, 0x16, 0x14, 0x17, 0x1B, //NVGAMCTRL: Negative Voltage Gamma control
#else
// 0xC0, 2, 0x10, 0x10, //Power Control 1 [80 25]
// 0xC1, 1, 0x41, //Power Control 2 [13]
0xC5, 1, 0x1C, //VCOM Control 1 [1C]
0x36, 1, 0x48, //Memory Access [00]
0x3A, 1, 0x55, //565
0xB0, 1, 0x80, //Interface [00]
//0xB1, 2, 0xB0, 0x11, //Frame Rate Control [A0 10]
0xB4, 1, 0x01, //Inversion Control [01]
0xB6, 3, 0x80, 0x02, 0x3B, // Display Function Control [80 02 3B] .kbv SS=1, NL=480
0xB7, 1, 0xC6, //Entry Mode [06]
// 0x3A, 1, 0x66, //Interlace Pixel Format [XX]
// 0xF7, 4, 0xA9, 0x51, 0x2C, 0x82, //Adjustment Control 3 [A9 51 2C 82]
#endif
0xF0, 1, 0x69, //?? lock manufacturer commands
0xF0, 1, 0x3C, //
0x11, 0x80, // Exit Sleep, then delay 150 ms
0x29, 0x80, // Main screen turn on, delay 150 ms
0x00 // End of list
};
// clang-format on
/**************************************************************************/
/*!
@brief Initialize ST7796S chip
Connects to the ST7796S over SPI and sends initialization procedure commands
@param freq Desired SPI clock frequency
*/
/**************************************************************************/
void Adafruit_ST7796S_kbv::begin(uint32_t freq) {
if (!freq)
freq = SPI_DEFAULT_FREQ;
initSPI(freq);
if (_rst < 0) { // If no hardware reset pin...
sendCommand(ST7796S_SWRESET); // Engage software reset
delay(150);
}
uint8_t cmd, x, numArgs;
const uint8_t *addr = initcmd;
while ((cmd = pgm_read_byte(addr++)) > 0) {
x = pgm_read_byte(addr++);
numArgs = x & 0x7F;
sendCommand(cmd, addr, numArgs);
addr += numArgs;
if (x & 0x80)
delay(150);
}
_width = ST7796S_TFTWIDTH;
_height = ST7796S_TFTHEIGHT;
}
/**************************************************************************/
/*!
@brief Set origin of (0,0) and orientation of TFT display
@param m The index for rotation, from 0-3 inclusive
*/
/**************************************************************************/
void Adafruit_ST7796S_kbv::setRotation(uint8_t m) {
rotation = m % 4; // can't be higher than 3
switch (rotation) {
case 0:
m = (MADCTL_MX | MADCTL_BGR);
_width = ST7796S_TFTWIDTH;
_height = ST7796S_TFTHEIGHT;
break;
case 1:
m = (MADCTL_MV | MADCTL_BGR);
_width = ST7796S_TFTHEIGHT;
_height = ST7796S_TFTWIDTH;
break;
case 2:
m = (MADCTL_MY | MADCTL_ML | MADCTL_BGR);
_width = ST7796S_TFTWIDTH;
_height = ST7796S_TFTHEIGHT;
break;
case 3:
m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_ML | MADCTL_BGR);
_width = ST7796S_TFTHEIGHT;
_height = ST7796S_TFTWIDTH;
break;
}
sendCommand(ST7796S_MADCTL, &m, 1);
setScrollMargins(0, 0); //.kbv
scrollTo(0);
}
/**************************************************************************/
/*!
@brief Enable/Disable display color inversion
@param invert True to invert, False to have normal color
*/
/**************************************************************************/
void Adafruit_ST7796S_kbv::invertDisplay(bool invert) {
sendCommand(invert ? ST7796S_INVON : ST7796S_INVOFF);
}
/**************************************************************************/
/*!
@brief Scroll display memory
@param y How many pixels to scroll display by
*/
/**************************************************************************/
void Adafruit_ST7796S_kbv::scrollTo(uint16_t y) {
uint8_t data[2];
data[0] = y >> 8;
data[1] = y & 0xff;
sendCommand(ST7796S_VSCRSADD, (uint8_t *)data, 2);
}
/**************************************************************************/
/*!
@brief Set the height of the Top and Bottom Scroll Margins
@param top The height of the Top scroll margin
@param bottom The height of the Bottom scroll margin
*/
/**************************************************************************/
void Adafruit_ST7796S_kbv::setScrollMargins(uint16_t top, uint16_t bottom) {
// TFA+VSA+BFA must equal 480
if (top + bottom <= ST7796S_TFTHEIGHT) {
uint16_t middle = ST7796S_TFTHEIGHT - top - bottom;
uint8_t data[6];
data[0] = top >> 8;
data[1] = top & 0xff;
data[2] = middle >> 8;
data[3] = middle & 0xff;
data[4] = bottom >> 8;
data[5] = bottom & 0xff;
sendCommand(ST7796S_VSCRDEF, (uint8_t *)data, 6);
}
}
/**************************************************************************/
/*!
@brief Set the "address window" - the rectangle we will write to RAM with
the next chunk of SPI data writes. The ST7796S will automatically wrap
the data as each row is filled
@param x1 TFT memory 'x' origin
@param y1 TFT memory 'y' origin
@param w Width of rectangle
@param h Height of rectangle
*/
/**************************************************************************/
void Adafruit_ST7796S_kbv::setAddrWindow(uint16_t x1, uint16_t y1, uint16_t w,
uint16_t h) {
uint16_t x2 = (x1 + w - 1), y2 = (y1 + h - 1);
writeCommand(ST7796S_CASET); // Column address set
SPI_WRITE16(x1);
SPI_WRITE16(x2);
writeCommand(ST7796S_PASET); // Row address set
SPI_WRITE16(y1);
SPI_WRITE16(y2);
writeCommand(ST7796S_RAMWR); // Write to RAM
}
/**************************************************************************/
/*!
@brief Read 8 bits of data from ST7796S configuration memory. NOT from RAM!
This is highly undocumented/supported, it's really a hack but kinda
works?
@param commandByte The command register to read data from
@param index The byte index into the command to read from
@return Unsigned 8-bit data read from ST7796S register
*/
/**************************************************************************/
uint8_t Adafruit_ST7796S_kbv::readcommand8(uint8_t commandByte, uint8_t index) {
uint8_t data = 0x10 + index, ret;
sendCommand(0xFB, &data, 1); // Set Index Register
ret = Adafruit_SPITFT::readcommand8(commandByte);
data = 0x00;
sendCommand(0xFB, &data, 1); // Set Index Register
return ret;
}
#endif

View File

@@ -0,0 +1,129 @@
/*
* Adafruit_ST7796S_kbv class inherits from Adafruit_GFX, Adafruit_SPITFT class and the Arduino Print class.
* Adafruit_ST7796S_kbv written by David Prentice
*
* Any use of Adafruit_ST7796S_kbv class and examples is dependent on Adafruit and Arduino licenses
* The license texts are in the accompanying license.txt file
*/
/*!
* @file Adafruit_ST7796S_kbv.h
*
* These displays use SPI to communicate, 4 or 5 pins are required
* to interface (RST is optional IF YOU ADD A PULLUP RESISTOR).
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
*
* This library depends on <a href="https://github.com/adafruit/Adafruit_GFX">
* Adafruit_GFX</a> being present on your system. Please make sure you have
* installed the latest version before using this library.
*
* Adafruit_GFX, Adafruit_SPITFT written by Limor "ladyada" Fried for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*
*/
#ifndef _ADAFRUIT_ST7796S_KBV_H_
#define _ADAFRUIT_ST7796S_KBV_H_
#include "Adafruit_GFX.h"
#include "Arduino.h"
#include "Print.h"
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <SPI.h>
#define ST7796S_TFTWIDTH 320 ///< ST7796S max TFT width
#define ST7796S_TFTHEIGHT 480 ///< ST7796S max TFT height
#define ST7796S_NOP 0x00 ///< No-op register
#define ST7796S_SWRESET 0x01 ///< Software reset register
#define ST7796S_RDDID 0x04 ///< Read display identification information
#define ST7796S_RDDST 0x09 ///< Read Display Status
#define ST7796S_SLPIN 0x10 ///< Enter Sleep Mode
#define ST7796S_SLPOUT 0x11 ///< Sleep Out
#define ST7796S_PTLON 0x12 ///< Partial Mode ON
#define ST7796S_NORON 0x13 ///< Normal Display Mode ON
#define ST7796S_RDMODE 0x0A ///< Read Display Power Mode
#define ST7796S_RDMADCTL 0x0B ///< Read Display MADCTL
#define ST7796S_RDPIXFMT 0x0C ///< Read Display Pixel Format
#define ST7796S_RDIMGFMT 0x0D ///< Read Display Image Format
#define ST7796S_RDSELFDIAG 0x0F ///< Read Display Self-Diagnostic Result
#define ST7796S_INVOFF 0x20 ///< Display Inversion OFF
#define ST7796S_INVON 0x21 ///< Display Inversion ON
#define ST7796S_GAMMASET 0x26 ///< Gamma Set
#define ST7796S_DISPOFF 0x28 ///< Display OFF
#define ST7796S_DISPON 0x29 ///< Display ON
#define ST7796S_CASET 0x2A ///< Column Address Set
#define ST7796S_PASET 0x2B ///< Page Address Set
#define ST7796S_RAMWR 0x2C ///< Memory Write
#define ST7796S_RAMRD 0x2E ///< Memory Read
#define ST7796S_PTLAR 0x30 ///< Partial Area
#define ST7796S_VSCRDEF 0x33 ///< Vertical Scrolling Definition
#define ST7796S_MADCTL 0x36 ///< Memory Access Control
#define ST7796S_VSCRSADD 0x37 ///< Vertical Scrolling Start Address
#define ST7796S_PIXFMT 0x3A ///< COLMOD: Pixel Format Set
// Color definitions
#define ST7796S_BLACK 0x0000 ///< 0, 0, 0
#define ST7796S_NAVY 0x000F ///< 0, 0, 123
#define ST7796S_DARKGREEN 0x03E0 ///< 0, 125, 0
#define ST7796S_DARKCYAN 0x03EF ///< 0, 125, 123
#define ST7796S_MAROON 0x7800 ///< 123, 0, 0
#define ST7796S_PURPLE 0x780F ///< 123, 0, 123
#define ST7796S_OLIVE 0x7BE0 ///< 123, 125, 0
#define ST7796S_LIGHTGREY 0xC618 ///< 198, 195, 198
#define ST7796S_DARKGREY 0x7BEF ///< 123, 125, 123
#define ST7796S_BLUE 0x001F ///< 0, 0, 255
#define ST7796S_GREEN 0x07E0 ///< 0, 255, 0
#define ST7796S_CYAN 0x07FF ///< 0, 255, 255
#define ST7796S_RED 0xF800 ///< 255, 0, 0
#define ST7796S_MAGENTA 0xF81F ///< 255, 0, 255
#define ST7796S_YELLOW 0xFFE0 ///< 255, 255, 0
#define ST7796S_WHITE 0xFFFF ///< 255, 255, 255
#define ST7796S_ORANGE 0xFD20 ///< 255, 165, 0
#define ST7796S_GREENYELLOW 0xAFE5 ///< 173, 255, 41
#define ST7796S_PINK 0xFC18 ///< 255, 130, 198
/**************************************************************************/
/*!
@brief Class to manage hardware interface with ST7796S chipset
*/
/**************************************************************************/
class Adafruit_ST7796S_kbv : public Adafruit_SPITFT {
public:
Adafruit_ST7796S_kbv(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
int8_t _RST = -1, int8_t _MISO = -1);
Adafruit_ST7796S_kbv(int8_t _CS, int8_t _DC, int8_t _RST = -1);
#if !defined(ESP8266)
Adafruit_ST7796S_kbv(SPIClass *spiClass, int8_t dc, int8_t cs = -1,
int8_t rst = -1);
#endif // end !ESP8266
Adafruit_ST7796S_kbv(tftBusWidth busWidth, int8_t d0, int8_t wr, int8_t dc,
int8_t cs = -1, int8_t rst = -1, int8_t rd = -1);
void begin(uint32_t freq = 0);
void setRotation(uint8_t r);
void invertDisplay(bool i);
void scrollTo(uint16_t y);
void setScrollMargins(uint16_t top, uint16_t bottom);
// Transaction API not used by GFX
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
uint8_t readcommand8(uint8_t reg, uint8_t index = 0);
};
#endif // _ADAFRUIT_ST7796SH_

View File

@@ -0,0 +1,168 @@
#if TS_MODEL==TS_MODEL_GT911
#include "Arduino.h"
#include "TAMC_GT911.h"
#include <Wire.h>
TAMC_GT911::TAMC_GT911(uint8_t _sda, uint8_t _scl, uint8_t _int, uint8_t _rst, uint16_t _width, uint16_t _height) :
pinSda(_sda), pinScl(_scl), pinInt(_int), pinRst(_rst), width(_width), height(_height) {
}
void TAMC_GT911::begin(uint8_t _addr) {
addr = _addr;
Wire.begin(pinSda, pinScl);
reset();
}
void TAMC_GT911::reset() {
pinMode(pinInt, OUTPUT);
pinMode(pinRst, OUTPUT);
digitalWrite(pinInt, 0);
digitalWrite(pinRst, 0);
delay(10);
digitalWrite(pinInt, addr==GT911_ADDR2);
delay(1);
digitalWrite(pinRst, 1);
delay(5);
digitalWrite(pinInt, 0);
delay(50);
pinMode(pinInt, INPUT);
// attachInterrupt(pinInt, TAMC_GT911::onInterrupt, RISING);
delay(50);
readBlockData(configBuf, GT911_CONFIG_START, GT911_CONFIG_SIZE);
setResolution(width, height);
}
void TAMC_GT911::calculateChecksum() {
uint8_t checksum = 0;
for (uint8_t i=0; i<GT911_CONFIG_SIZE; i++) {
checksum += configBuf[i];
}
checksum = (~checksum) + 1;
configBuf[GT911_CONFIG_CHKSUM - GT911_CONFIG_START] = checksum;
}
// void ARDUINO_ISR_ATTR TAMC_GT911::onInterrupt() {
// read();
// TAMC_GT911::onRead();
// }
void TAMC_GT911::reflashConfig() {
calculateChecksum();
writeByteData(GT911_CONFIG_CHKSUM, configBuf[GT911_CONFIG_CHKSUM-GT911_CONFIG_START]);
writeByteData(GT911_CONFIG_FRESH, 1);
}
void TAMC_GT911::setRotation(uint8_t rot) {
rotation = rot;
}
void TAMC_GT911::setResolution(uint16_t _width, uint16_t _height) {
configBuf[GT911_X_OUTPUT_MAX_LOW - GT911_CONFIG_START] = lowByte(_width);
configBuf[GT911_X_OUTPUT_MAX_HIGH - GT911_CONFIG_START] = highByte(_width);
configBuf[GT911_Y_OUTPUT_MAX_LOW - GT911_CONFIG_START] = lowByte(_height);
configBuf[GT911_Y_OUTPUT_MAX_HIGH - GT911_CONFIG_START] = highByte(_height);
reflashConfig();
}
// void TAMC_GT911::setOnRead(void (*isr)()) {
// onRead = isr;
// }
void TAMC_GT911::read(void) {
// Serial.println("TAMC_GT911::read");
uint8_t data[7];
uint8_t pointInfo = readByteData(GT911_POINT_INFO);
uint8_t bufferStatus = pointInfo >> 7 & 1;
isLargeDetect = pointInfo >> 6 & 1;
touches = pointInfo & 0xF;
// Serial.print("bufferStatus: ");Serial.println(bufferStatus);
// Serial.print("largeDetect: ");Serial.println(isLargeDetect);
// Serial.print("proximityValid: ");Serial.println(proximityValid);
// Serial.print("haveKey: ");Serial.println(haveKey);
// Serial.print("touches: ");Serial.println(touches);
isTouched = touches > 0;
if (bufferStatus == 1 && isTouched) {
for (uint8_t i=0; i<touches; i++) {
readBlockData(data, GT911_POINT_1 + i * 8, 7);
points[i] = readPoint(data);
}
}
writeByteData(GT911_POINT_INFO, 0);
}
TP_Point TAMC_GT911::readPoint(uint8_t *data) {
uint16_t temp;
uint8_t id = data[0];
uint16_t x = data[1] + (data[2] << 8);
uint16_t y = data[3] + (data[4] << 8);
uint16_t size = data[5] + (data[6] << 8);
switch (rotation){
case ROTATION_NORMAL:
x = width - x;
y = height - y;
break;
case ROTATION_LEFT:
temp = x;
x = width - y;
y = temp;
break;
case ROTATION_INVERTED:
x = x;
y = y;
break;
case ROTATION_RIGHT:
temp = x;
x = y;
y = height - temp;
break;
default:
break;
}
return TP_Point(id, x, y, size);
}
void TAMC_GT911::writeByteData(uint16_t reg, uint8_t val) {
Wire.beginTransmission(addr);
Wire.write(highByte(reg));
Wire.write(lowByte(reg));
Wire.write(val);
Wire.endTransmission();
}
uint8_t TAMC_GT911::readByteData(uint16_t reg) {
uint8_t x;
Wire.beginTransmission(addr);
Wire.write(highByte(reg));
Wire.write(lowByte(reg));
Wire.endTransmission();
Wire.requestFrom(addr, (uint8_t)1);
x = Wire.read();
return x;
}
void TAMC_GT911::writeBlockData(uint16_t reg, uint8_t *val, uint8_t size) {
Wire.beginTransmission(addr);
Wire.write(highByte(reg));
Wire.write(lowByte(reg));
// Wire.write(val, size);
for (uint8_t i=0; i<size; i++) {
Wire.write(val[i]);
}
Wire.endTransmission();
}
void TAMC_GT911::readBlockData(uint8_t *buf, uint16_t reg, uint8_t size) {
Wire.beginTransmission(addr);
Wire.write(highByte(reg));
Wire.write(lowByte(reg));
Wire.endTransmission();
Wire.requestFrom(addr, size);
for (uint8_t i=0; i<size; i++) {
buf[i] = Wire.read();
}
}
TP_Point::TP_Point(void) {
id = x = y = size = 0;
}
TP_Point::TP_Point(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _size) {
id = _id;
x = _x;
y = _y;
size = _size;
}
bool TP_Point::operator==(TP_Point point) {
return ((point.x == x) && (point.y == y) && (point.size == size));
}
bool TP_Point::operator!=(TP_Point point) {
return ((point.x != x) || (point.y != y) || (point.size != size));
}
#endif

View File

@@ -0,0 +1,189 @@
#ifndef TAMC_GT911_H
#define TAMC_GT911_H
#include "Arduino.h"
#include <Wire.h>
#define GT911_ADDR1 (uint8_t)0x5D
#define GT911_ADDR2 (uint8_t)0x14
#define ROTATION_LEFT (uint8_t)0
#define ROTATION_INVERTED (uint8_t)1
#define ROTATION_RIGHT (uint8_t)2
#define ROTATION_NORMAL (uint8_t)3
// Real-time command (Write only)
#define GT911_COMMAND (uint16_t)0x8040
#define GT911_ESD_CHECK (uint16_t)0x8041
#define GT911_COMMAND_CHECK (uint16_t)0x8046
// Configuration information (R/W)
#define GT911_CONFIG_START (uint16_t)0x8047
#define GT911_CONFIG_VERSION (uint16_t)0x8047
#define GT911_X_OUTPUT_MAX_LOW (uint16_t)0x8048
#define GT911_X_OUTPUT_MAX_HIGH (uint16_t)0x8049
#define GT911_Y_OUTPUT_MAX_LOW (uint16_t)0x804A
#define GT911_Y_OUTPUT_MAX_HIGH (uint16_t)0x804B
#define GT911_TOUCH_NUMBER (uint16_t)0x804C
#define GT911_MODULE_SWITCH_1 (uint16_t)0x804D
#define GT911_MODULE_SWITCH_2 (uint16_t)0x804E
#define GT911_SHAKE_COUNT (uint16_t)0x804F
#define GT911_FILTER (uint16_t)0x8050
#define GT911_LARGE_TOUCH (uint16_t)0x8051
#define GT911_NOISE_REDUCTION (uint16_t)0x8052
#define GT911_SCREEN_TOUCH_LEVEL (uint16_t)0x8053
#define GT911_SCREEN_RELEASE_LEVEL (uint16_t)0x8054
#define GT911_LOW_POWER_CONTROL (uint16_t)0x8055
#define GT911_REFRESH_RATE (uint16_t)0x8056
#define GT911_X_THRESHOLD (uint16_t)0x8057
#define GT911_Y_THRESHOLD (uint16_t)0x8058
#define GT911_X_SPEED_LIMIT (uint16_t)0x8059 //Reserve
#define GT911_Y_SPEED_LIMIT (uint16_t)0x805A //Reserve
#define GT911_SPACE_TOP_BOTTOM (uint16_t)0x805B
#define GT911_SPACE_LEFT_RIGHT (uint16_t)0x805C
#define GT911_MINI_FILTER (uint16_t)0x805D
#define GT911_STRETCH_R0 (uint16_t)0x805E
#define GT911_STRETCH_R1 (uint16_t)0x805F
#define GT911_STRETCH_R2 (uint16_t)0x8060
#define GT911_STRETCH_RM (uint16_t)0x8061
#define GT911_DRV_GROUPA_NUM (uint16_t)0x8062
#define GT911_DRV_GROUPB_NUM (uint16_t)0x8063
#define GT911_SENSOR_NUM (uint16_t)0x8064
#define GT911_FREQ_A_FACTOR (uint16_t)0x8065
#define GT911_FREQ_B_FACTOR (uint16_t)0x8066
#define GT911_PANEL_BIT_FREQ_L (uint16_t)0x8067
#define GT911_PANEL_BIT_FREQ_H (uint16_t)0x8068
#define GT911_PANEL_SENSOR_TIME_L (uint16_t)0x8069 //Reserve
#define GT911_PANEL_SENSOR_TIME_H (uint16_t)0x806A
#define GT911_PANEL_TX_GAIN (uint16_t)0x806B
#define GT911_PANEL_RX_GAIN (uint16_t)0x806C
#define GT911_PANEL_DUMP_SHIFT (uint16_t)0x806D
#define GT911_DRV_FRAME_CONTROL (uint16_t)0x806E
#define GT911_CHARGING_LEVEL_UP (uint16_t)0x806F
#define GT911_MODULE_SWITCH3 (uint16_t)0x8070
#define GT911_GESTURE_DIS (uint16_t)0X8071
#define GT911_GESTURE_LONG_PRESS_TIME (uint16_t)0x8072
#define GT911_X_Y_SLOPE_ADJUST (uint16_t)0X8073
#define GT911_GESTURE_CONTROL (uint16_t)0X8074
#define GT911_GESTURE_SWITCH1 (uint16_t)0X8075
#define GT911_GESTURE_SWITCH2 (uint16_t)0X8076
#define GT911_GESTURE_REFRESH_RATE (uint16_t)0x8077
#define GT911_GESTURE_TOUCH_LEVEL (uint16_t)0x8078
#define GT911_NEWGREENWAKEUPLEVEL (uint16_t)0x8079
#define GT911_FREQ_HOPPING_START (uint16_t)0x807A
#define GT911_FREQ_HOPPING_END (uint16_t)0X807B
#define GT911_NOISE_DETECT_TIMES (uint16_t)0x807C
#define GT911_HOPPING_FLAG (uint16_t)0X807D
#define GT911_HOPPING_THRESHOLD (uint16_t)0X807E
#define GT911_NOISE_THRESHOLD (uint16_t)0X807F //Reserve
#define GT911_NOISE_MIN_THRESHOLD (uint16_t)0X8080
#define GT911_HOPPING_SENSOR_GROUP (uint16_t)0X8082
#define GT911_HOPPING_SEG1_NORMALIZE (uint16_t)0X8083
#define GT911_HOPPING_SEG1_FACTOR (uint16_t)0X8084
#define GT911_MAIN_CLOCK_AJDUST (uint16_t)0X8085
#define GT911_HOPPING_SEG2_NORMALIZE (uint16_t)0X8086
#define GT911_HOPPING_SEG2_FACTOR (uint16_t)0X8087
#define GT911_HOPPING_SEG3_NORMALIZE (uint16_t)0X8089
#define GT911_HOPPING_SEG3_FACTOR (uint16_t)0X808A
#define GT911_HOPPING_SEG4_NORMALIZE (uint16_t)0X808C
#define GT911_HOPPING_SEG4_FACTOR (uint16_t)0X808D
#define GT911_HOPPING_SEG5_NORMALIZE (uint16_t)0X808F
#define GT911_HOPPING_SEG5_FACTOR (uint16_t)0X8090
#define GT911_HOPPING_SEG6_NORMALIZE (uint16_t)0X8092
#define GT911_KEY_1 (uint16_t)0X8093
#define GT911_KEY_2 (uint16_t)0X8094
#define GT911_KEY_3 (uint16_t)0X8095
#define GT911_KEY_4 (uint16_t)0X8096
#define GT911_KEY_AREA (uint16_t)0X8097
#define GT911_KEY_TOUCH_LEVEL (uint16_t)0X8098
#define GT911_KEY_LEAVE_LEVEL (uint16_t)0X8099
#define GT911_KEY_SENS_1_2 (uint16_t)0X809A
#define GT911_KEY_SENS_3_4 (uint16_t)0X809B
#define GT911_KEY_RESTRAIN (uint16_t)0X809C
#define GT911_KEY_RESTRAIN_TIME (uint16_t)0X809D
#define GT911_GESTURE_LARGE_TOUCH (uint16_t)0X809E
#define GT911_HOTKNOT_NOISE_MAP (uint16_t)0X80A1
#define GT911_LINK_THRESHOLD (uint16_t)0X80A2
#define GT911_PXY_THRESHOLD (uint16_t)0X80A3
#define GT911_GHOT_DUMP_SHIFT (uint16_t)0X80A4
#define GT911_GHOT_RX_GAIN (uint16_t)0X80A5
#define GT911_FREQ_GAIN0 (uint16_t)0X80A6
#define GT911_FREQ_GAIN1 (uint16_t)0X80A7
#define GT911_FREQ_GAIN2 (uint16_t)0X80A8
#define GT911_FREQ_GAIN3 (uint16_t)0X80A9
#define GT911_COMBINE_DIS (uint16_t)0X80B3
#define GT911_SPLIT_SET (uint16_t)0X80B4
#define GT911_SENSOR_CH0 (uint16_t)0X80B7
#define GT911_DRIVER_CH0 (uint16_t)0X80D5
#define GT911_CONFIG_CHKSUM (uint16_t)0X80FF
#define GT911_CONFIG_FRESH (uint16_t)0X8100
#define GT911_CONFIG_SIZE (uint16_t)0xFF-0x46
// Coordinate information
#define GT911_PRODUCT_ID (uint16_t)0X8140
#define GT911_FIRMWARE_VERSION (uint16_t)0X8140
#define GT911_RESOLUTION (uint16_t)0X8140
#define GT911_VENDOR_ID (uint16_t)0X8140
#define GT911_IMFORMATION (uint16_t)0X8140
#define GT911_POINT_INFO (uint16_t)0X814E
#define GT911_POINT_1 (uint16_t)0X814F
#define GT911_POINT_2 (uint16_t)0X8157
#define GT911_POINT_3 (uint16_t)0X815F
#define GT911_POINT_4 (uint16_t)0X8167
#define GT911_POINT_5 (uint16_t)0X816F
#define GT911_POINTS_REG {GT911_POINT_1, GT911_POINT_2, GT911_POINT_3, GT911_POINT_4, GT911_POINT_5}
class TP_Point {
public:
TP_Point(void);
TP_Point(uint8_t id, uint16_t x, uint16_t y, uint16_t size);
bool operator==(TP_Point);
bool operator!=(TP_Point);
uint8_t id;
uint16_t x;
uint16_t y;
uint8_t size;
};
class TAMC_GT911 {
public:
TAMC_GT911(uint8_t _sda, uint8_t _scl, uint8_t _int, uint8_t _rst, uint16_t _width, uint16_t _height);
void begin(uint8_t _addr=GT911_ADDR1);
void reset();
void setRotation(uint8_t rot);
void setResolution(uint16_t _width, uint16_t _height);
// void setOnRead(void (*isr)());
uint8_t getGesture(void);
void read(void);
uint8_t isLargeDetect;
uint8_t touches = 0;
bool isTouched = false;
// uint8_t gesture = NO_GESTURE;
TP_Point points[5];
private:
void calculateChecksum();
void reflashConfig();
// static void ARDUINO_ISR_ATTR onInterrupt();
TP_Point readPoint(uint8_t *data);
// void (*onRead)();
void writeByteData(uint16_t reg, uint8_t val);
uint8_t readByteData(uint16_t reg);
void writeBlockData(uint16_t reg, uint8_t *val, uint8_t size);
void readBlockData(uint8_t *buf, uint16_t reg, uint8_t size);
uint8_t rotation = ROTATION_NORMAL;
uint8_t addr;
uint8_t pinSda;
uint8_t pinScl;
uint8_t pinInt;
uint8_t pinRst;
uint16_t width;
uint16_t height;
uint8_t configBuf[GT911_CONFIG_SIZE];
// uint8_t *configBuf;
};
#endif // TAMC_GT911_H

View File

@@ -6,6 +6,10 @@
Config config;
#if DSP_HSPI || TS_HSPI || VS_HSPI
SPIClass SPI2(HSPI);
#endif
void u8fix(char *src){
char last = src[strlen(src)-1];
if ((uint8_t)last >= 0xC2) src[strlen(src)-1]='\0';

View File

@@ -2,6 +2,7 @@
#define config_h
#include "Arduino.h"
#include <Ticker.h>
#include <SPI.h>
#include "options.h"
#define EEPROM_SIZE 768
@@ -184,5 +185,9 @@ class Config {
};
extern Config config;
#if DSP_HSPI || TS_HSPI || VS_HSPI
extern SPIClass SPI2;
#endif
#endif

View File

@@ -42,9 +42,9 @@ yoEncoder encoder2 = yoEncoder(ENC2_BTNL, ENC2_BTNR, ENCODER2_STEPS, ENC2_INTERN
#endif
#endif
#if TS_CS!=255
#include <XPT2046_Touchscreen.h>
XPT2046_Touchscreen ts(TS_CS);
#if TS_MODEL!=TS_MODEL_UNDEFINED
#include "touchscreen.h"
TouchScreen touchscreen;
#endif
#if IR_PIN!=255
@@ -113,9 +113,8 @@ void initControls() {
button[i].setPressTicks(BTN_PRESS_TICKS);
}
#endif
#if TS_CS!=255
ts.begin();
ts.setRotation(config.store.fliptouch?3:1);
#if TS_MODEL!=TS_MODEL_UNDEFINED
touchscreen.init();
#endif
#if IR_PIN!=255
pinMode(IR_PIN, INPUT);
@@ -145,18 +144,15 @@ void loopControls() {
if (lpId >= 0) {
if (DSP_MODEL == DSP_DUMMY && (lpId == 4 || lpId == 5)) continue;
onBtnDuringLongPress(lpId);
yield();
}
yield();
}
#endif
#if IR_PIN!=255
irLoop();
#endif
#if TS_CS!=255
touchLoop();
#if TS_MODEL!=TS_MODEL_UNDEFINED
touchscreen.loop();
#endif
yield();
}
#if ENC_BTNL!=255
@@ -326,122 +322,6 @@ void irLoop() {
}
#endif // if IR_PIN!=255
#if TS_CS!=255
#ifndef TS_X_MIN
#define TS_X_MIN 400
#endif
#ifndef TS_X_MAX
#define TS_X_MAX 3800
#endif
#ifndef TS_Y_MIN
#define TS_Y_MIN 260
#endif
#ifndef TS_Y_MAX
#define TS_Y_MAX 3800
#endif
#ifndef TS_STEPS
#define TS_STEPS 40
#endif
boolean wastouched = true;
unsigned long touchdelay;
uint16_t touchVol, touchStation;
uint16_t oldTouchP[2];
tsDirection_e direct;
unsigned long touchLongPress;
tsDirection_e tsDirection(uint16_t x, uint16_t y) {
int16_t dX = x - oldTouchP[0];
int16_t dY = y - oldTouchP[1];
if (abs(dX) > 20 || abs(dY) > 20) {
if (abs(dX) > abs(dY)) {
if (dX > 0) {
return TSD_RIGHT;
} else {
return TSD_LEFT;
}
} else {
if (dY > 0) {
return TSD_DOWN;
} else {
return TSD_UP;
}
}
} else {
return TDS_REQUEST;
}
}
void touchLoop() {
if (!checklpdelay(100, touchdelay)) return;
boolean istouched = ts.touched();
if (istouched) {
TS_Point p = ts.getPoint();
uint16_t touchX = map(p.x, TS_X_MIN, TS_X_MAX, 0, dsp.width());
uint16_t touchY = map(p.y, TS_Y_MIN, TS_Y_MAX, 0, dsp.height());
if (!wastouched) { /* START TOUCH */
oldTouchP[0] = touchX;
oldTouchP[1] = touchY;
touchVol = touchX;
touchStation = touchY;
direct = TDS_REQUEST;
touchLongPress=millis();
} else { /* SWIPE TOUCH */
direct = tsDirection(touchX, touchY);
switch (direct) {
case TSD_LEFT:
case TSD_RIGHT: {
touchLongPress=millis();
if(display.mode()==PLAYER || display.mode()==VOL){
int16_t xDelta = map(abs(touchVol - touchX), 0, dsp.width(), 0, TS_STEPS);
display.putRequest(NEWMODE, VOL);
if (xDelta>1) {
controlsEvent((touchVol - touchX)<0);
touchVol = touchX;
}
}
break;
}
case TSD_UP:
case TSD_DOWN: {
touchLongPress=millis();
if(display.mode()==PLAYER || display.mode()==STATIONS){
int16_t yDelta = map(abs(touchStation - touchY), 0, dsp.height(), 0, TS_STEPS);
display.putRequest(NEWMODE, STATIONS);
if (yDelta>1) {
controlsEvent((touchStation - touchY)<0);
touchStation = touchY;
}
}
break;
}
default:
break;
}
}
if (config.store.dbgtouch) {
Serial.print(", x = ");
Serial.print(p.x);
Serial.print(", y = ");
Serial.println(p.y);
}
} else {
if (wastouched) {/* END TOUCH */
if (direct == TDS_REQUEST) {
uint32_t pressTicks = millis()-touchLongPress;
if( pressTicks < BTN_PRESS_TICKS*2){
if(pressTicks > 50) onBtnClick(EVT_BTNCENTER);
}else{
display.putRequest(NEWMODE, display.mode() == PLAYER ? STATIONS : PLAYER);
}
}
direct = TSD_STAY;
}
}
wastouched = istouched;
}
#endif // if TS_CS!=255
void onBtnLongPressStart(int id) {
switch ((controlEvt_e)id) {
case EVT_BTNLEFT:
@@ -629,7 +509,7 @@ void setEncAcceleration(uint16_t acc){
#endif
}
void flipTS(){
#if TS_CS!=255
ts.setRotation(config.store.fliptouch?3:1);
#if TS_MODEL!=TS_MODEL_UNDEFINED
touchscreen.flip();
#endif
}

View File

@@ -4,7 +4,7 @@
enum controlEvt_e { EVT_BTNLEFT, EVT_BTNCENTER, EVT_BTNRIGHT, EVT_ENCBTNB, EVT_BTNUP, EVT_BTNDOWN, EVT_ENC2BTNB };
enum tsDirection_e { TSD_STAY, TSD_LEFT, TSD_RIGHT, TSD_UP, TSD_DOWN, TDS_REQUEST };
//enum tsDirection_e { TSD_STAY, TSD_LEFT, TSD_RIGHT, TSD_UP, TSD_DOWN, TDS_REQUEST };
#if IR_PIN!=255
enum : uint8_t { IR_UP=0, IR_PREV=1, IR_PLAY=2, IR_NEXT=3, IR_DOWN=4, IR_1=5, IR_2=6, IR_3=7, IR_4=8, IR_5=9, IR_6=10, IR_7=11, IR_8=12, IR_9=13, IR_AST=14, IR_0=15, IR_HASH=16 };
@@ -17,7 +17,7 @@ void loopControls();
void encoderLoop();
void encoder2Loop();
void irLoop();
void touchLoop();
//void touchLoop();
void irNum(byte num);
void irBlink();
void controlsEvent(bool toRight, int8_t volDelta = 0);
@@ -27,7 +27,7 @@ void onBtnDoubleClick(int id);
void onBtnDuringLongPress(int id);
void onBtnLongPressStart(int id);
void onBtnLongPressStop(int id);
tsDirection_e tsDirection(uint16_t x, uint16_t y);
//tsDirection_e tsDirection(uint16_t x, uint16_t y);
void setIRTolerance(uint8_t tl);
void setEncAcceleration(uint16_t acc);

View File

@@ -49,6 +49,9 @@ void loopDspTask(void * pvParameters){
void Display::init() {
#ifdef USE_NEXTION
nextion.begin();
#endif
#if LIGHT_SENSOR!=255
analogSetAttenuation(ADC_0db);
#endif
_bootStep = 0;
dsp.initDisplay();
@@ -442,6 +445,10 @@ void Display::_title() {
}
void Display::_time(bool redraw) {
#if LIGHT_SENSOR!=255
config.store.brightness = AUTOBACKLIGHT(analogRead(LIGHT_SENSOR));
config.setBrightness();
#endif
_clock.draw();
/*#ifdef USE_NEXTION
nextion.printClock(network.timeinfo);

View File

@@ -110,4 +110,5 @@ class Display {
extern Display display;
#endif

View File

@@ -557,7 +557,7 @@ void NetServer::requestOnChange(requestType_e request, uint8_t clientId) {
#endif
if (BRIGHTNESS_PIN != 255 || nxtn || dbgact) act += F("\"group_brightness\",");
if (DSP_CAN_FLIPPED || dbgact) act += F("\"group_tft\",");
if (TS_CS != 255 || dbgact) act += F("\"group_touch\",");
if (TS_MODEL != TS_MODEL_UNDEFINED || dbgact) act += F("\"group_touch\",");
if (DSP_MODEL == DSP_NOKIA5110) act += F("\"group_nokia\",");
act += F("\"group_timezone\",");
if (SHOW_WEATHER || dbgact) act += F("\"group_weather\",");

View File

@@ -209,6 +209,7 @@ bool getWeather(char *wstr) {
}
char *tmpe;
char *tmps;
char *tmpc;
const char* cursor = line.c_str();
char desc[120], temp[20], hum[20], press[20], icon[5];
@@ -251,8 +252,9 @@ bool getWeather(char *wstr) {
if (tmps == NULL) { Serial.println("## OPENWEATHERMAP ###: humidity not found !"); return false;}
tmps += 10;
tmpe = strstr(tmps, ",\"");
tmpc = strstr(tmps, "}");
if (tmpe == NULL) { Serial.println("## OPENWEATHERMAP ###: humidity not found !"); return false;}
strlcpy(hum, tmps, tmpe - tmps + 1);
strlcpy(hum, tmps, tmpe - tmps + (tmpc>tmpe?1:0));
#ifdef USE_NEXTION
nextion.putcmdf("press_txt.txt=\"%dmm\"", pressi);

View File

@@ -1,7 +1,7 @@
#ifndef options_h
#define options_h
#define VERSION "0.8.02b"
#define VERSION "0.8.03b"
/*******************************************************
DO NOT EDIT THIS FILE.
@@ -41,6 +41,7 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#define DSP_SSD1305I2C 16 // 128x64 2.4' SSD1305 and SSD1309 I2C https://aliexpress.com/item/32950307344.html
#define DSP_ILI9225 17 // 220x176 2.0' https://aliexpress.com/item/32952021835.html
#define DSP_ST7789_240 18 // 240x240 1.3' https://aliexpress.com/item/32996979276.html
#define DSP_ST7796 19
/* !!! DSP_ST7789_240 requires further development when used in conjunction with the VS1053 module !!! See the link https://www.instructables.com/Adding-CS-Pin-to-13-LCD/ */
#define DSP_CUSTOM 101 // your display
@@ -48,6 +49,12 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#ifndef DSP_MODEL
#define DSP_MODEL DSP_DUMMY
#endif
#ifndef DSP_HSPI
#define DSP_HSPI false // use HSPI for displays (miso=12, mosi=13, clk=14) instead of VSPI (by default)
#endif
#ifndef LED_INVERT
#define LED_INVERT false // invert onboard LED?
#endif
/* TFT DISPLAY */
#ifndef TFT_CS
@@ -92,6 +99,9 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#ifndef VS1053_RST
#define VS1053_RST -1 // set to -1 if connected to Esp EN pin
#endif
#ifndef VS_HSPI
#define VS_HSPI false // use HSPI for VS1053 (miso=12, mosi=13, clk=14) instead of VSPI (by default)
#endif
/* I2S DAC */
#ifndef I2S_DOUT
@@ -167,8 +177,32 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#endif
/* TOUCH SCREEN */
#define TS_MODEL_UNDEFINED 0
#define TS_MODEL_XPT2046 1
#define TS_MODEL_GT911 2
#ifndef TS_MODEL
#define TS_MODEL TS_MODEL_UNDEFINED
#endif
#ifndef TS_CS
#define TS_CS 255
#define TS_CS 13
#endif
#ifndef TS_SDA
#define TS_SDA 33
#endif
#ifndef TS_SCL
#define TS_SCL 32
#endif
#ifndef TS_INT
#define TS_INT 21
#endif
#ifndef TS_RST
#define TS_RST 25
#endif
#ifndef TS_HSPI
#define TS_HSPI false // use HSPI for touchscreen (miso=12, mosi=13, clk=14) instead of VSPI (by default)
#endif
/* LCD DISPLAY */
@@ -218,6 +252,18 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#ifndef WAKE_PIN
#define WAKE_PIN 255 // Wake Pin (for manual wakeup from sleep mode. can match with BTN_XXXX, ENC_BTNB, ENC2_BTNB. must be one of: 0,2,4,12,13,14,15,25,26,27,32,33,34,35,36,39)
#endif
#ifndef LIGHT_SENSOR
#define LIGHT_SENSOR 255 // Light sensor
#endif
#ifndef AUTOBACKLIGHT
#ifndef AUTOBACKLIGHT_MAX
#define AUTOBACKLIGHT_MAX 2500
#endif
#ifndef AUTOBACKLIGHT_MIN
#define AUTOBACKLIGHT_MIN 12
#endif
#define AUTOBACKLIGHT(x) ({uint16_t _lh=(x>AUTOBACKLIGHT_MAX?AUTOBACKLIGHT_MAX:x); map(_lh, AUTOBACKLIGHT_MAX, 0, AUTOBACKLIGHT_MIN, 100);}) // autobacklight function
#endif
/*
*** ST7735 display submodel ***
INITR_BLACKTAB // 1.8' https://aliexpress.ru/item/1005002822797745.html

View File

@@ -11,9 +11,11 @@
Player player;
#if VS1053_CS!=255 && !I2S_INTERNAL
Player::Player(): Audio(VS1053_CS, VS1053_DCS, VS1053_DREQ) {
}
#if VS_HSPI
Player::Player(): Audio(VS1053_CS, VS1053_DCS, VS1053_DREQ, HSPI, 13, 12, 14) {}
#else
Player::Player(): Audio(VS1053_CS, VS1053_DCS, VS1053_DREQ) {}
#endif
void ResetChip(){
pinMode(VS1053_RST, OUTPUT);
digitalWrite(VS1053_RST, LOW);
@@ -116,7 +118,7 @@ void Player::zeroRequest() {
}
void Player::setOutputPins(bool isPlaying) {
digitalWrite(LED_BUILTIN, isPlaying);
digitalWrite(LED_BUILTIN, LED_INVERT?!isPlaying:isPlaying);
if(MUTE_PIN!=255) digitalWrite(MUTE_PIN, isPlaying?!MUTE_VAL:MUTE_VAL);
}

View File

@@ -0,0 +1,196 @@
#include "options.h"
#if TS_MODEL!=TS_MODEL_UNDEFINED
#include "touchscreen.h"
#include "config.h"
#include "controls.h"
#include "display.h"
#include "player.h"
#ifndef TS_X_MIN
#define TS_X_MIN 400
#endif
#ifndef TS_X_MAX
#define TS_X_MAX 3800
#endif
#ifndef TS_Y_MIN
#define TS_Y_MIN 260
#endif
#ifndef TS_Y_MAX
#define TS_Y_MAX 3800
#endif
#ifndef TS_STEPS
#define TS_STEPS 40
#endif
#if TS_MODEL==TS_MODEL_XPT2046
#ifdef TS_SPIPINS
SPIClass TSSPI(HSPI);
#endif
#include <XPT2046_Touchscreen.h>
XPT2046_Touchscreen ts(TS_CS);
typedef TS_Point TSPoint;
#elif TS_MODEL==TS_MODEL_GT911
#include "../GT911_Touchscreen/TAMC_GT911.h"
TAMC_GT911 ts = TAMC_GT911(TS_SDA, TS_SCL, TS_INT, TS_RST, 0, 0);
typedef TP_Point TSPoint;
#endif
void TouchScreen::init(){
#if TS_MODEL==TS_MODEL_XPT2046
#ifdef TS_SPIPINS
TSSPI.begin(TS_SPIPINS);
ts.begin(TSSPI);
#else
#if TS_HSPI
ts.begin(SPI2);
#else
ts.begin();
#endif
#endif
ts.setRotation(config.store.fliptouch?3:1);
#endif
#if TS_MODEL==TS_MODEL_GT911
ts.begin();
ts.setRotation(config.store.fliptouch?0:2);
#endif
_width = dsp.width();
_height = dsp.height();
#if TS_MODEL==TS_MODEL_GT911
ts.setResolution(_width, _height);
#endif
}
tsDirection_e TouchScreen::_tsDirection(uint16_t x, uint16_t y) {
int16_t dX = x - _oldTouchX;
int16_t dY = y - _oldTouchY;
if (abs(dX) > 20 || abs(dY) > 20) {
if (abs(dX) > abs(dY)) {
if (dX > 0) {
return TSD_RIGHT;
} else {
return TSD_LEFT;
}
} else {
if (dY > 0) {
return TSD_DOWN;
} else {
return TSD_UP;
}
}
} else {
return TDS_REQUEST;
}
}
void TouchScreen::flip(){
#if TS_MODEL==TS_MODEL_XPT2046
ts.setRotation(config.store.fliptouch?3:1);
#endif
#if TS_MODEL==TS_MODEL_GT911
ts.setRotation(config.store.fliptouch?0:2);
#endif
}
void TouchScreen::loop(){
uint16_t touchX, touchY;
static bool wastouched = true;
static uint32_t touchLongPress;
static tsDirection_e direct;
static uint16_t touchVol, touchStation;
if (!_checklpdelay(20, _touchdelay)) return;
#if TS_MODEL==TS_MODEL_GT911
ts.read();
#endif
bool istouched = _istouched();
if(istouched){
#if TS_MODEL==TS_MODEL_XPT2046
TSPoint p = ts.getPoint();
touchX = map(p.x, TS_X_MIN, TS_X_MAX, 0, _width);
touchY = map(p.y, TS_Y_MIN, TS_Y_MAX, 0, _height);
#elif TS_MODEL==TS_MODEL_GT911
TSPoint p = ts.points[0];
touchX = p.x;
touchY = p.y;
#endif
if (!wastouched) { /* START TOUCH */
_oldTouchX = touchX;
_oldTouchY = touchY;
touchVol = touchX;
touchStation = touchY;
direct = TDS_REQUEST;
touchLongPress=millis();
} else { /* SWIPE TOUCH */
direct = _tsDirection(touchX, touchY);
switch (direct) {
case TSD_LEFT:
case TSD_RIGHT: {
touchLongPress=millis();
if(display.mode()==PLAYER || display.mode()==VOL){
int16_t xDelta = map(abs(touchVol - touchX), 0, _width, 0, TS_STEPS);
display.putRequest(NEWMODE, VOL);
if (xDelta>1) {
controlsEvent((touchVol - touchX)<0);
touchVol = touchX;
}
}
break;
}
case TSD_UP:
case TSD_DOWN: {
touchLongPress=millis();
if(display.mode()==PLAYER || display.mode()==STATIONS){
int16_t yDelta = map(abs(touchStation - touchY), 0, _height, 0, TS_STEPS);
display.putRequest(NEWMODE, STATIONS);
if (yDelta>1) {
controlsEvent((touchStation - touchY)<0);
touchStation = touchY;
}
}
break;
}
default:
break;
}
}
if (config.store.dbgtouch) {
Serial.print(", x = ");
Serial.print(p.x);
Serial.print(", y = ");
Serial.println(p.y);
}
}else{
if (wastouched) {/* END TOUCH */
if (direct == TDS_REQUEST) {
uint32_t pressTicks = millis()-touchLongPress;
if( pressTicks < BTN_PRESS_TICKS*2){
if(pressTicks > 50) onBtnClick(EVT_BTNCENTER);
}else{
display.putRequest(NEWMODE, display.mode() == PLAYER ? STATIONS : PLAYER);
}
}
direct = TSD_STAY;
}
}
wastouched = istouched;
}
bool TouchScreen::_checklpdelay(int m, uint32_t &tstamp) {
if (millis() - tstamp > m) {
tstamp = millis();
return true;
} else {
return false;
}
}
bool TouchScreen::_istouched(){
#if TS_MODEL==TS_MODEL_XPT2046
return ts.touched();
#elif TS_MODEL==TS_MODEL_GT911
return ts.isTouched;
#endif
}
#endif // TS_MODEL!=TS_MODEL_UNDEFINED

View File

@@ -0,0 +1,23 @@
#ifndef touchscreen_h
#define touchscreen_h
#include "Arduino.h"
enum tsDirection_e { TSD_STAY, TSD_LEFT, TSD_RIGHT, TSD_UP, TSD_DOWN, TDS_REQUEST };
class TouchScreen {
public:
TouchScreen() {}
void init();
void loop();
void flip();
private:
uint16_t _oldTouchX, _oldTouchY, _width, _height;
uint32_t _touchdelay;
bool _checklpdelay(int m, uint32_t &tstamp);
tsDirection_e _tsDirection(uint16_t x, uint16_t y);
bool _istouched();
};
extern TouchScreen touchscreen;
#endif

View File

@@ -21,7 +21,7 @@
const ScrollConfig metaConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT, 3, WA_LEFT }, 140, true, MAX_WIDTH, 5000, 5, 30 };
const ScrollConfig title1Conf PROGMEM = {{ TFT_FRAMEWDT, 50, 2, WA_LEFT }, 140, true, MAX_WIDTH, 5000, 4, 30 };
const ScrollConfig title2Conf PROGMEM = {{ TFT_FRAMEWDT, 70, 2, WA_LEFT }, 140, true, MAX_WIDTH, 5000, 4, 30 };
const ScrollConfig playlistConf PROGMEM = {{ TFT_FRAMEWDT, 112, 2, WA_LEFT }, 140, true, MAX_WIDTH, 0, 2, 30 };
const ScrollConfig playlistConf PROGMEM = {{ TFT_FRAMEWDT, 112, 2, WA_LEFT }, 140, true, MAX_WIDTH, 1000, 2, 30 };
const ScrollConfig apTitleConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT, 3, WA_CENTER }, 140, false, MAX_WIDTH, 0, 4, 20 };
const ScrollConfig apSettConf PROGMEM = {{ TFT_FRAMEWDT, 240-TFT_FRAMEWDT-16, 2, WA_LEFT }, 140, false, MAX_WIDTH, 0, 4, 30 };
const ScrollConfig weatherConf PROGMEM = {{ 8, 87, 2, WA_LEFT }, 140, true, MAX_WIDTH, 0, 4, 30 };

View File

@@ -0,0 +1,68 @@
/*************************************************************************************
ST7796 480X320 displays configuration file.
Copy this file to yoRadio/src/displays/conf/displayST7789conf_custom.h
and modify it
More info on https://github.com/e2002/yoradio/wiki/Widgets#widgets-description
*************************************************************************************/
#ifndef displayST7789conf_h
#define displayST7789conf_h
#define DSP_WIDTH 480
#define DSP_HEIGHT 320
#define TFT_FRAMEWDT 10
#define MAX_WIDTH DSP_WIDTH-TFT_FRAMEWDT*2
#define PLMITEMS 11
#define PLMITEMLENGHT 40
#define PLMITEMHEIGHT 32
#define bootLogoTop 110
/* SROLLS */ /* {{ left, top, fontsize, align }, buffsize, uppercase, width, scrolldelay, scrolldelta, scrolltime } */
const ScrollConfig metaConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT, 4, WA_LEFT }, 140, true, MAX_WIDTH, 5000, 7, 40 };
const ScrollConfig title1Conf PROGMEM = {{ TFT_FRAMEWDT, 62, 2, WA_LEFT }, 140, true, MAX_WIDTH-6*2*7-6, 5000, 7, 40 };
const ScrollConfig title2Conf PROGMEM = {{ TFT_FRAMEWDT, 86, 2, WA_LEFT }, 140, true, MAX_WIDTH, 5000, 7, 40 };
const ScrollConfig playlistConf PROGMEM = {{ TFT_FRAMEWDT, 146, 3, WA_LEFT }, 140, true, MAX_WIDTH, 1000, 7, 40 };
const ScrollConfig apTitleConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT, 4, WA_CENTER }, 140, false, MAX_WIDTH, 0, 7, 40 };
const ScrollConfig apSettConf PROGMEM = {{ TFT_FRAMEWDT, 320-TFT_FRAMEWDT-16, 2, WA_LEFT }, 140, false, MAX_WIDTH, 0, 7, 40 };
const ScrollConfig weatherConf PROGMEM = {{ TFT_FRAMEWDT, 116, 2, WA_LEFT }, 140, true, MAX_WIDTH, 0, 7, 40 };
/* BACKGROUNDS */ /* {{ left, top, fontsize, align }, width, height, outlined } */
const FillConfig metaBGConf PROGMEM = {{ 0, 0, 0, WA_LEFT }, DSP_WIDTH, 50, false };
const FillConfig volbarConf PROGMEM = {{ TFT_FRAMEWDT, DSP_HEIGHT-TFT_FRAMEWDT-8, 0, WA_LEFT }, MAX_WIDTH, 8, true };
const FillConfig playlBGConf PROGMEM = {{ 0, 138, 0, WA_LEFT }, DSP_WIDTH, 36, false };
const FillConfig heapbarConf PROGMEM = {{ 0, DSP_HEIGHT-2, 0, WA_LEFT }, DSP_WIDTH, 2, false };
/* WIDGETS */ /* { left, top, fontsize, align } */
const WidgetConfig bootstrConf PROGMEM = { 0, 243, 1, WA_CENTER };
const WidgetConfig bitrateConf PROGMEM = { 6, 62, 2, WA_RIGHT };
const WidgetConfig voltxtConf PROGMEM = { 0, DSP_HEIGHT-38, 2, WA_CENTER };
const WidgetConfig iptxtConf PROGMEM = { TFT_FRAMEWDT, DSP_HEIGHT-38, 2, WA_LEFT };
const WidgetConfig rssiConf PROGMEM = { TFT_FRAMEWDT, DSP_HEIGHT-38, 2, WA_RIGHT };
const WidgetConfig numConf PROGMEM = { 0, 200, 70, WA_CENTER };
const WidgetConfig apNameConf PROGMEM = { TFT_FRAMEWDT, 88, 3, WA_CENTER };
const WidgetConfig apName2Conf PROGMEM = { TFT_FRAMEWDT, 120, 3, WA_CENTER };
const WidgetConfig apPassConf PROGMEM = { TFT_FRAMEWDT, 173, 3, WA_CENTER };
const WidgetConfig apPass2Conf PROGMEM = { TFT_FRAMEWDT, 205, 3, WA_CENTER };
const WidgetConfig clockConf PROGMEM = { 16, 224, 70, WA_RIGHT }; /* 52 is a fixed font size. do not change */
const WidgetConfig vuConf PROGMEM = { TFT_FRAMEWDT, 136, 1, WA_LEFT };
const WidgetConfig bootWdtConf PROGMEM = { 0, 216, 1, WA_CENTER };
const ProgressConfig bootPrgConf PROGMEM = { 90, 14, 4 };
/* BANDS */ /* { onebandwidth, onebandheight, bandsHspace, bandsVspace, numofbands, fadespeed } */
const VUBandsConfig bandsConf PROGMEM = { 32, 130, 4, 2, 10, 6 };
/* STRINGS */
const char numtxtFmt[] PROGMEM = "%d";
const char rssiFmt[] PROGMEM = "WiFi %d";
const char iptxtFmt[] PROGMEM = "%s";
const char voltxtFmt[] PROGMEM = "%d";
const char bitrateFmt[] PROGMEM = "%d kBs";
/* MOVES */ /* { left, top, width } */
const MoveConfig clockMove PROGMEM = { 0, 176, -1 };
const MoveConfig weatherMove PROGMEM = { 8, 120, MAX_WIDTH };
const MoveConfig weatherMoveVU PROGMEM = { 89, 120, 381 };
#endif

View File

@@ -14,7 +14,11 @@
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
DspCore::DspCore(): Adafruit_GC9106Ex(TFT_CS, TFT_DC, TFT_RST) { }
#if DSP_HSPI
DspCore::DspCore(): Adafruit_GC9106Ex(&SPI2, TFT_DC, TFT_CS, TFT_RST) {}
#else
DspCore::DspCore(): Adafruit_GC9106Ex(TFT_CS, TFT_DC, TFT_RST) {}
#endif
#include "tools/utf8RusGFX.h"

View File

@@ -13,11 +13,8 @@ extern unsigned char yofont10x14[];
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
//SPIClass hspi(VSPI);
DspCore::DspCore(): TFT_22_ILI9225(TFT_RST, TFT_DC, TFT_CS, 0) {
}
DspCore::DspCore(): TFT_22_ILI9225(TFT_RST, TFT_DC, TFT_CS, 0) {}
#include "tools/utf8RusGFX.h"
@@ -97,7 +94,11 @@ void DspCore::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){
void DspCore::initDisplay() {
TAKE_MUTEX();
#if DSP_HSPI
begin(SPI2);
#else
begin();
#endif
invert();
flip();
setTextSize(1);

View File

@@ -10,9 +10,11 @@
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
DspCore::DspCore(): Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST) {
}
#if DSP_HSPI
DspCore::DspCore(): Adafruit_ILI9341(&SPI2, TFT_DC, TFT_CS, TFT_RST) {}
#else
DspCore::DspCore(): Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST) {}
#endif
#include "tools/utf8RusGFX.h"

View File

@@ -23,9 +23,11 @@ const unsigned char logo [] PROGMEM=
0xe0, 0x01, 0xff, 0xc0
};
DspCore::DspCore(): Adafruit_PCD8544(TFT_DC, TFT_CS, TFT_RST) {
}
#if DSP_HSPI
DspCore::DspCore(): Adafruit_PCD8544(TFT_DC, TFT_CS, TFT_RST, &SPI2) {}
#else
DspCore::DspCore(): Adafruit_PCD8544(TFT_DC, TFT_CS, TFT_RST) {}
#endif
#include "tools/utf8RusGFX.h"

View File

@@ -30,9 +30,11 @@ const unsigned char logo [] PROGMEM=
};
#if DSP_MODEL==DSP_SSD1305
DspCore::DspCore(): Adafruit_SSD1305(128, 64, &SPI, TFT_DC, TFT_RST, TFT_CS, DEF_SPI_FREQ) {
}
#if DSP_HSPI
DspCore::DspCore(): Adafruit_SSD1305(128, 64, &SPI2, TFT_DC, TFT_RST, TFT_CS, DEF_SPI_FREQ) {}
#else
DspCore::DspCore(): Adafruit_SSD1305(128, 64, &SPI, TFT_DC, TFT_RST, TFT_CS, DEF_SPI_FREQ) {}
#endif
#else
#include <Wire.h>
TwoWire I2CSSD1305 = TwoWire(0);

View File

@@ -14,9 +14,11 @@
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
DspCore::DspCore(): Adafruit_ST7735(&SPI, TFT_CS, TFT_DC, TFT_RST) {
}
#if DSP_HSPI
DspCore::DspCore(): Adafruit_ST7735(&SPI2, TFT_CS, TFT_DC, TFT_RST) {}
#else
DspCore::DspCore(): Adafruit_ST7735(&SPI, TFT_CS, TFT_DC, TFT_RST) {}
#endif
#include "tools/utf8RusGFX.h"

View File

@@ -15,7 +15,11 @@
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
#if DSP_HSPI
DspCore::DspCore(): Adafruit_ST7789(&SPI2, TFT_CS, TFT_DC, TFT_RST) {}
#else
DspCore::DspCore(): Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST) {}
#endif
#include "tools/utf8RusGFX.h"

View File

@@ -0,0 +1,216 @@
#include "../core/options.h"
#if DSP_MODEL==DSP_ST7796
#include "displayST7796.h"
//#include <SPI.h>
#include "fonts/bootlogo.h"
#include "../core/player.h"
#include "../core/config.h"
#include "../core/network.h"
#ifndef DEF_SPI_FREQ
#define DEF_SPI_FREQ 40000000UL /* set it to 0 for system default */
#endif
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
#if DSP_HSPI
DspCore::DspCore(): Adafruit_ST7796S_kbv(&SPI2, TFT_DC, TFT_CS, TFT_RST) {}
#else
DspCore::DspCore(): Adafruit_ST7796S_kbv(TFT_CS, TFT_DC, TFT_RST) {}
#endif
#include "tools/utf8RusGFX.h"
void DspCore::initDisplay() {
begin();
if(DEF_SPI_FREQ > 0) setSPISpeed(DEF_SPI_FREQ);
invert();
cp437(true);
flip();
setTextWrap(false);
setTextSize(1);
fillScreen(0x0000);
}
void DspCore::drawLogo(uint16_t top) { drawRGBBitmap((width() - 99) / 2, top, bootlogo2, 99, 64); }
void DspCore::drawPlaylist(uint16_t currentItem, char* currentItemText) {
for (byte i = 0; i < PLMITEMS; i++) {
plMenu[i][0] = '\0';
}
config.fillPlMenu(plMenu, currentItem - 5, PLMITEMS);
setTextSize(3);
int yStart = (height() / 2 - PLMITEMHEIGHT / 2) - PLMITEMHEIGHT * (PLMITEMS - 1) / 2 + 3;
for (byte i = 0; i < PLMITEMS; i++) {
if (i == 5) {
strlcpy(currentItemText, plMenu[i], PLMITEMLENGHT - 1);
} else {
setTextColor(config.theme.playlist[abs(i - 5)-1], config.theme.background);
setCursor(TFT_FRAMEWDT, yStart + i * PLMITEMHEIGHT);
fillRect(0, yStart + i * PLMITEMHEIGHT - 1, width(), PLMITEMHEIGHT - 6, config.theme.background);
print(utf8Rus(plMenu[i], true));
}
}
}
void DspCore::clearDsp(bool black) { fillScreen(black?0:config.theme.background); }
GFXglyph *pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c) {
return gfxFont->glyph + c;
}
uint8_t DspCore::_charWidth(unsigned char c){
GFXglyph *glyph = pgm_read_glyph_ptr(&DS_DIGI56pt7b, c - 0x20);
return pgm_read_byte(&glyph->xAdvance);
}
uint16_t DspCore::textWidth(const char *txt){
uint16_t w = 0, l=strlen(txt);
for(uint16_t c=0;c<l;c++) w+=_charWidth(txt[c]);
return w;
}
void DspCore::_getTimeBounds() {
_timewidth = textWidth(_timeBuf);
char buf[4];
strftime(buf, 4, "%H", &network.timeinfo);
_dotsLeft=textWidth(buf);
}
void DspCore::_clockSeconds(){
setTextSize(4);
setTextColor(config.theme.seconds, config.theme.background);
setCursor(width() - 8 - clockRightSpace - CHARWIDTH*4*2, clockTop-clockTimeHeight+1);
sprintf(_bufforseconds, "%02d", network.timeinfo.tm_sec);
print(_bufforseconds); /* print seconds */
setTextSize(1);
setFont(&DS_DIGI56pt7b);
setTextColor((network.timeinfo.tm_sec % 2 == 0) ? config.theme.clock : config.theme.background, config.theme.background);
setCursor(_timeleft+_dotsLeft, clockTop);
print(":"); /* print dots */
setFont();
}
void DspCore::_clockDate(){
if(_olddateleft>0)
dsp.fillRect(_olddateleft, clockTop+10, _olddatewidth, CHARHEIGHT, config.theme.background);
setTextColor(config.theme.date, config.theme.background);
setCursor(_dateleft, clockTop+15);
setTextSize(2);
print(_dateBuf); /* print date */
strlcpy(_oldDateBuf, _dateBuf, sizeof(_dateBuf));
_olddatewidth = _datewidth;
_olddateleft = _dateleft;
setTextSize(4);
setTextColor(config.theme.dow, config.theme.background);
setCursor(width() - 8 - clockRightSpace - CHARWIDTH*4*2, clockTop-CHARHEIGHT*4+4);
print(utf8Rus(dow[network.timeinfo.tm_wday], false)); /* print dow */
}
void DspCore::_clockTime(){
if(_oldtimeleft>0) dsp.fillRect(_oldtimeleft, clockTop-clockTimeHeight+1, _oldtimewidth, clockTimeHeight, config.theme.background);
_timeleft = width()-clockRightSpace-CHARWIDTH*4*2-24-_timewidth;
setTextSize(1);
setFont(&DS_DIGI56pt7b);
setTextColor(config.theme.clock, config.theme.background);
setCursor(_timeleft, clockTop);
print(_timeBuf);
setFont();
strlcpy(_oldTimeBuf, _timeBuf, sizeof(_timeBuf));
_oldtimewidth = _timewidth;
_oldtimeleft = _timeleft;
drawFastVLine(width()-clockRightSpace-CHARWIDTH*4*2-18, clockTop-clockTimeHeight, clockTimeHeight+4, config.theme.div); /*divider vert*/
drawFastHLine(width()-clockRightSpace-CHARWIDTH*4*2-18, clockTop-clockTimeHeight+37, 59, config.theme.div); /*divider hor*/
sprintf(_buffordate, "%2d %s %d", network.timeinfo.tm_mday,mnths[network.timeinfo.tm_mon], network.timeinfo.tm_year+1900);
strlcpy(_dateBuf, utf8Rus(_buffordate, true), sizeof(_dateBuf));
_datewidth = strlen(_dateBuf) * CHARWIDTH*2;
_dateleft = width() - 10 - clockRightSpace - _datewidth;
}
void DspCore::printClock(uint16_t top, uint16_t rightspace, uint16_t timeheight, bool redraw){
clockTop = top;
clockRightSpace = rightspace;
clockTimeHeight = timeheight;
strftime(_timeBuf, sizeof(_timeBuf), "%H:%M", &network.timeinfo);
if(strcmp(_oldTimeBuf, _timeBuf)!=0 || redraw){
_getTimeBounds();
_clockTime();
if(strcmp(_oldDateBuf, _dateBuf)!=0 || redraw) _clockDate();
}
_clockSeconds();
}
void DspCore::clearClock(){
dsp.fillRect(_timeleft, clockTop-clockTimeHeight, _timewidth+CHARWIDTH*3*2+24, clockTimeHeight+12+CHARHEIGHT, config.theme.background);
}
void DspCore::startWrite(void) {
TAKE_MUTEX();
Adafruit_ST7796S_kbv::startWrite();
}
void DspCore::endWrite(void) {
Adafruit_ST7796S_kbv::endWrite();
GIVE_MUTEX();
}
void DspCore::loop(bool force) {
}
void DspCore::charSize(uint8_t textsize, uint8_t& width, uint16_t& height){
width = textsize * CHARWIDTH;
height = textsize * CHARHEIGHT;
}
void DspCore::setTextSize(uint8_t s){
Adafruit_GFX::setTextSize(s);
}
void DspCore::flip(){
setRotation(config.store.flipscreen?3:1);
}
void DspCore::invert(){
invertDisplay(config.store.invertdisplay);
}
void DspCore::sleep(void) {
sendCommand(ST7796S_SLPIN); delay(150); sendCommand(ST7796S_DISPOFF); delay(150);
}
void DspCore::wake(void) {
sendCommand(ST7796S_DISPON); delay(150); sendCommand(ST7796S_SLPOUT); delay(150);
}
void DspCore::writePixel(int16_t x, int16_t y, uint16_t color) {
if(_clipping){
if ((x < _cliparea.left) || (x > _cliparea.left+_cliparea.width) || (y < _cliparea.top) || (y > _cliparea.top + _cliparea.height)) return;
}
Adafruit_ST7796S_kbv::writePixel(x, y, color);
}
void DspCore::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
if(_clipping){
if ((x < _cliparea.left) || (x >= _cliparea.left+_cliparea.width) || (y < _cliparea.top) || (y > _cliparea.top + _cliparea.height)) return;
}
Adafruit_ST7796S_kbv::writeFillRect(x, y, w, h, color);
}
void DspCore::setClipping(clipArea ca){
_cliparea = ca;
_clipping = true;
}
void DspCore::clearClipping(){
_clipping = false;
}
void DspCore::setNumFont(){
setFont(&DS_DIGI56pt7b);
setTextSize(1);
}
#endif

View File

@@ -0,0 +1,35 @@
#ifndef displayST7789_h
#define displayST7789_h
#include "../core/options.h"
#include "Arduino.h"
#include <Adafruit_GFX.h>
//#include <Adafruit_ST7796S_kbv.h>
#include "../Adafruit_ST7796S/Adafruit_ST7796S_kbv.h"
#include "fonts/DS_DIGI56pt7b.h" // https://tchapi.github.io/Adafruit-GFX-Font-Customiser/
#include "tools/l10n.h"
#define CHARWIDTH 6
#define CHARHEIGHT 8
typedef GFXcanvas16 Canvas;
#include "widgets/widgets.h"
#include "widgets/pages.h"
#if __has_include("conf/displayST7796conf_custom.h")
#include "conf/displayST7796conf_custom.h"
#else
#include "conf/displayST7796conf.h"
#endif
#define BOOT_PRG_COLOR 0xE68B
#define BOOT_TXT_COLOR 0xFFFF
#define PINK 0xF97F
class DspCore: public Adafruit_ST7796S_kbv {
#include "tools/commongfx.h"
};
extern DspCore dsp;
#endif

View File

@@ -34,6 +34,8 @@
#include "displayCustom.h"
#elif DSP_MODEL==DSP_ILI9225
#include "displayILI9225.h"
#elif DSP_MODEL==DSP_ST7796
#include "displayST7796.h"
#endif
//extern DspCore dsp;

View File

@@ -0,0 +1,320 @@
const uint8_t DS_DIGI56pt7bBitmaps[] PROGMEM = {
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xFF,
0xFF, 0xFF, 0xFF, 0xC7, 0x1F, 0xFF, 0xFF, 0xFF, 0xE3, 0xE3, 0xFF, 0xFF,
0xFF, 0xF1, 0xFC, 0x7F, 0xFF, 0xFF, 0xF8, 0xFF, 0x8F, 0xFF, 0xFF, 0xFC,
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00,
0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F,
0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0,
0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00,
0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01,
0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x00,
0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7D, 0xC0, 0x00, 0x00, 0x00, 0x0E,
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x01, 0x1C, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x80, 0x00, 0x00, 0x00,
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00,
0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F,
0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0,
0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00,
0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01,
0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00,
0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0x1F,
0xF1, 0xFF, 0xFF, 0xFF, 0xE3, 0xF8, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x7F,
0xFF, 0xFF, 0xFF, 0x8E, 0x3F, 0xFF, 0xFF, 0xFF, 0xF1, 0x1F, 0xFF, 0xFF,
0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x04, 0x18, 0x71,
0xE7, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xCF, 0x8E,
0x08, 0x00, 0x00, 0x00, 0x83, 0x8F, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xEF, 0xCF, 0x8F, 0x0E, 0x0C, 0x08, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xC4,
0x1F, 0xFF, 0xFF, 0xFF, 0xE3, 0x03, 0xFF, 0xFF, 0xFF, 0xF1, 0xC0, 0x7F,
0xFF, 0xFF, 0xF8, 0xF0, 0x0F, 0xFF, 0xFF, 0xFC, 0x7C, 0x00, 0x00, 0x00,
0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07,
0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00,
0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00,
0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07,
0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x07, 0xFF, 0xFF, 0xFF, 0x1F, 0x03, 0xFF, 0xFF, 0xFF,
0xE3, 0x81, 0xFF, 0xFF, 0xFF, 0xFC, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xE0, 0x08, 0x7F,
0xFF, 0xFF, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00,
0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00,
0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00,
0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03,
0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80,
0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00,
0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x00,
0x00, 0x00, 0x03, 0xE3, 0xFF, 0xFF, 0xFF, 0x00, 0xF1, 0xFF, 0xFF, 0xFF,
0xE0, 0x38, 0xFF, 0xFF, 0xFF, 0xFC, 0x0C, 0x7F, 0xFF, 0xFF, 0xFF, 0x82,
0x3F, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF,
0xFF, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF,
0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xE1,
0x07, 0xFF, 0xFF, 0xFF, 0xC3, 0x03, 0xFF, 0xFF, 0xFF, 0x87, 0x01, 0xFF,
0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00,
0x3F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x03, 0xFF, 0xFF, 0xFF, 0x1F, 0x07, 0xFF, 0xFF, 0xFF,
0x8E, 0x0F, 0xFF, 0xFF, 0xFF, 0xC4, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F,
0xFF, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF,
0xFF, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x1F,
0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x01, 0xFF, 0xFF, 0xFF, 0x1F,
0x03, 0xFF, 0xFF, 0xFF, 0x8F, 0x07, 0xFF, 0xFF, 0xFF, 0xC7, 0x0F, 0xFF,
0xFF, 0xFF, 0xE3, 0x1F, 0xFF, 0xFF, 0xFF, 0xF1, 0x3F, 0xFF, 0xFF, 0xFF,
0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00,
0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x3F,
0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0,
0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00,
0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01,
0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00,
0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F,
0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0,
0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00,
0x00, 0x1F, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x9F, 0xFF, 0xFF, 0xFE,
0x7D, 0xCF, 0xFF, 0xFF, 0xFF, 0xCE, 0x27, 0xFF, 0xFF, 0xFF, 0xF9, 0x03,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF,
0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xE1, 0x00, 0x00, 0x00, 0x00,
0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00,
0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01,
0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0,
0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00,
0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00,
0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x7C, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF,
0xFF, 0x88, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0,
0xE3, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x7F, 0xFF, 0xFF, 0xF8, 0x0F, 0x8F,
0xFF, 0xFF, 0xFC, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00,
0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F,
0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00,
0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00,
0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0,
0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00,
0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F,
0x80, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xE7, 0xFF,
0xFF, 0xFF, 0x80, 0x73, 0xFF, 0xFF, 0xFF, 0xF0, 0x09, 0xFF, 0xFF, 0xFF,
0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0,
0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x40, 0x00,
0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01,
0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0,
0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00,
0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00,
0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01,
0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0,
0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xFF,
0xFF, 0xFF, 0x1F, 0x01, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0xFF, 0xFF, 0xFF,
0xFC, 0x70, 0x7F, 0xFF, 0xFF, 0xFF, 0x8C, 0x3F, 0xFF, 0xFF, 0xFF, 0xF1,
0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F,
0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xFF, 0xFF,
0xFF, 0xFF, 0xC3, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0, 0xE3, 0xFF, 0xFF, 0xFF,
0xF0, 0x3C, 0x7F, 0xFF, 0xFF, 0xF8, 0x0F, 0x8F, 0xFF, 0xFF, 0xFC, 0x03,
0xF0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80,
0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00,
0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00,
0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00,
0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03,
0xF8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80,
0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00,
0x0F, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xE7, 0xFF, 0xFF, 0xFF, 0x80, 0x73,
0xFF, 0xFF, 0xFF, 0xF0, 0x09, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF,
0xF0, 0x08, 0x7F, 0xFF, 0xFF, 0xF8, 0x47, 0x00, 0x00, 0x00, 0x00, 0x3B,
0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80,
0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00,
0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07,
0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE,
0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00,
0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00,
0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF,
0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80,
0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00,
0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0x1F, 0xF1,
0xFF, 0xFF, 0xFF, 0xE3, 0xF8, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x7F, 0xFF,
0xFF, 0xFF, 0x8E, 0x3F, 0xFF, 0xFF, 0xFF, 0xF1, 0x1F, 0xFF, 0xFF, 0xFF,
0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC,
0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xF1, 0x07, 0xFF,
0xFF, 0xFF, 0xE3, 0x03, 0xFF, 0xFF, 0xFF, 0xC7, 0x01, 0xFF, 0xFF, 0xFF,
0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x3F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00,
0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF,
0xFF, 0xFF, 0x88, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x1F, 0xFF, 0xFF, 0xFF,
0xE3, 0xE3, 0xFF, 0xFF, 0xFF, 0xF1, 0xFC, 0x7F, 0xFF, 0xFF, 0xF8, 0xFF,
0x8F, 0xFF, 0xFF, 0xFC, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00,
0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00,
0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F,
0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00,
0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF,
0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00,
0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00,
0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F,
0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xE7,
0xFF, 0xFF, 0xFF, 0x9F, 0x73, 0xFF, 0xFF, 0xFF, 0xF3, 0x89, 0xFF, 0xFF,
0xFF, 0xFE, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF,
0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x08, 0x7F, 0xFF, 0xFF, 0xF8, 0x47,
0x00, 0x00, 0x00, 0x00, 0x3B, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00,
0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00,
0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F,
0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00,
0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF,
0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00,
0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00,
0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F,
0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xE3,
0xFF, 0xFF, 0xFF, 0x1F, 0xF1, 0xFF, 0xFF, 0xFF, 0xE3, 0xF8, 0xFF, 0xFF,
0xFF, 0xFC, 0x7C, 0x7F, 0xFF, 0xFF, 0xFF, 0x8E, 0x3F, 0xFF, 0xFF, 0xFF,
0xF1, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xFF,
0xFF, 0xFF, 0xFF, 0xC7, 0x1F, 0xFF, 0xFF, 0xFF, 0xE3, 0xE3, 0xFF, 0xFF,
0xFF, 0xF1, 0xFC, 0x7F, 0xFF, 0xFF, 0xF8, 0xFF, 0x8F, 0xFF, 0xFF, 0xFC,
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00,
0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F,
0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0,
0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00,
0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01,
0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00,
0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0x9F,
0x73, 0xFF, 0xFF, 0xFF, 0xF3, 0x89, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0xFF,
0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF,
0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x40, 0x00, 0x00, 0x00, 0x00,
0x38, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0,
0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00,
0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00,
0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01,
0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0,
0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00,
0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0x1F,
0x01, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0xFF, 0xFF, 0xFF, 0xFC, 0x70, 0x7F,
0xFF, 0xFF, 0xFF, 0x8C, 0x3F, 0xFF, 0xFF, 0xFF, 0xF1, 0x1F, 0xFF, 0xFF,
0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 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, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
};
const GFXglyph DS_DIGI56pt7bGlyphs[] PROGMEM = {
{ 0, 0, 0, 24, 0, 1 }, // 0x20 ' '
{ 0, 0, 0, 0, 0, 0 }, // 0x21 '!'
{ 0, 0, 0, 0, 0, 0 }, // 0x22 '"'
{ 0, 0, 0, 0, 0, 0 }, // 0x23 '#'
{ 0, 0, 0, 0, 0, 0 }, // 0x24 '$'
{ 0, 0, 0, 0, 0, 0 }, // 0x25 '%'
{ 0, 0, 0, 0, 0, 0 }, // 0x26 '&'
{ 0, 0, 0, 0, 0, 0 }, // 0x27 '''
{ 0, 0, 0, 0, 0, 0 }, // 0x28 '('
{ 0, 0, 0, 0, 0, 0 }, // 0x29 ')'
{ 0, 0, 0, 0, 0, 0 }, // 0x2A '*'
{ 0, 0, 0, 0, 0, 0 }, // 0x2B '+'
{ 0, 0, 0, 0, 0, 0 }, // 0x2C ','
{ 0, 0, 0, 0, 0, 0 }, // 0x2D '-'
{ 0, 0, 0, 0, 0, 0 }, // 0x2E '.'
{ 0, 0, 0, 0, 0, 0 }, // 0x2F '/'
{ 0, 42, 70, 54, 6, -69 }, // 0x30 '0'
{ 368, 7, 68, 29, 10, -68 }, // 0x31 '1'
{ 428, 42, 70, 54, 6, -69 }, // 0x32 '2'
{ 796, 40, 70, 54, 7, -69 }, // 0x33 '3'
{ 1146, 42, 68, 54, 6, -68 }, // 0x34 '4'
{ 1503, 42, 70, 54, 6, -69 }, // 0x35 '5'
{ 1871, 42, 70, 54, 6, -69 }, // 0x36 '6'
{ 2239, 40, 69, 54, 7, -69 }, // 0x37 '7'
{ 2584, 42, 70, 54, 6, -69 }, // 0x38 '8'
{ 2952, 42, 70, 54, 6, -69 }, // 0x39 '9'
{ 3320, 7, 59, 24, 8, -58 } // 0x3A ':'
};
const GFXfont DS_DIGI56pt7b PROGMEM = {
(uint8_t *)DS_DIGI56pt7bBitmaps,
(GFXglyph *)DS_DIGI56pt7bGlyphs, 0x20, 0x3A, 110 };
// Approx. 6564 bytes