This commit is contained in:
e2002
2025-09-01 14:02:02 +03:00
parent 5d49b0849e
commit f82f4e38cf
15 changed files with 185 additions and 47 deletions

View File

@@ -73,7 +73,8 @@ DspCore dsp;
Page *pages[] = { new Page(), new Page(), new Page(), new Page() };
#if !((DSP_MODEL==DSP_ST7735 && DTYPE==INITR_BLACKTAB) || DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7796 || DSP_MODEL==DSP_ILI9488 || DSP_MODEL==DSP_ILI9486 || DSP_MODEL==DSP_ILI9341 || DSP_MODEL==DSP_ILI9225)
#if !((DSP_MODEL==DSP_ST7735 && DTYPE==INITR_BLACKTAB) || DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7796 || DSP_MODEL==DSP_ILI9488 \
|| DSP_MODEL==DSP_ILI9486 || DSP_MODEL==DSP_ILI9341 || DSP_MODEL==DSP_ILI9225 || DSP_MODEL==DSP_ST7789_170)
#undef BITRATE_FULL
#define BITRATE_FULL false
#endif

View File

@@ -2,7 +2,7 @@
#define options_h
#pragma once
#define YOVERSION "0.9.693"
#define YOVERSION "0.9.700"
/*******************************************************
DO NOT EDIT THIS FILE.
@@ -51,7 +51,10 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#define DSP_ILI9486 22 // (Testing mode) 480x320 3.5' https://aliexpress.com/item/1005001999296476.html?sku_id=12000018365356568
#define DSP_SSD1322 23 // 256x64 2.8' https://aliexpress.com/item/1005003480981568.html
#define DSP_ST7920 24 // 128x64 2.6' https://aliexpress.com/item/32699482638.html
#define DSP_ST7789_76 25 // 284x76 2.25' https://aliexpress.ru/item/1005009016973081.html
#define DSP_ST7789_76 25 // 284x76 2.25' https://aliexpress.com/item/1005009016973081.html
#define DSP_2002 26 // 20x2 https://aliexpress.com/item/32812259852.html
#define DSP_2002I2C 27 // 20x2 https://aliexpress.com/item/32812259852.html
#define DSP_ST7789_170 28 // 320x170 1.9' https://aliexpress.com/item/1005008723378017.html
#define DSP_CUSTOM 101 // your display
#ifndef DSP_MODEL

View File

@@ -75,6 +75,7 @@ TimeKeeper::TimeKeeper(){
}
bool TimeKeeper::loop0(){ // core0 (display)
if (network.status != CONNECTED) return true;
uint32_t currentTime = millis();
static uint32_t _last1s = 0;
static uint32_t _last2s = 0;

View File

@@ -7,10 +7,13 @@
#ifndef displayLCD1602conf_h
#define displayLCD1602conf_h
#if DSP_MODEL==DSP_2002 || DSP_MODEL==DSP_2002I2C
#define DSP_WIDTH 20
#else
#define DSP_WIDTH 16
#endif
#define TFT_FRAMEWDT 0
#define MAX_WIDTH 16
#define MAX_WIDTH DSP_WIDTH
#define PLMITEMS 2
#define HIDE_IP

View File

@@ -0,0 +1,77 @@
/*************************************************************************************
ST7789 320x240 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 320
#define DSP_HEIGHT 170
#define TFT_FRAMEWDT 6
#define MAX_WIDTH DSP_WIDTH-TFT_FRAMEWDT*2
//#define PLMITEMS 11
//#define PLMITEMLENGHT 40
//#define PLMITEMHEIGHT 22
#define HIDE_TITLE2
#define HIDE_DATE
#if BITRATE_FULL
#define TITLE_FIX 44
#else
#define TITLE_FIX 0
#endif
#define bootLogoTop 34
/* SROLLS */ /* {{ left, top, fontsize, align }, buffsize, uppercase, width, scrolldelay, scrolldelta, scrolltime } */
const ScrollConfig metaConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT, 3, WA_LEFT }, 140, true, MAX_WIDTH, 5000, 5, 30 };
const ScrollConfig title1Conf PROGMEM = {{ TFT_FRAMEWDT, 42, 2, WA_LEFT }, 140, true, MAX_WIDTH-TITLE_FIX, 5000, 4, 30 };
const ScrollConfig title2Conf PROGMEM = {{ TFT_FRAMEWDT, 72, 2, WA_LEFT }, 140, true, MAX_WIDTH-TITLE_FIX, 5000, 4, 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, DSP_HEIGHT-TFT_FRAMEWDT-16, 2, WA_LEFT }, 140, false, MAX_WIDTH, 0, 4, 30 };
const ScrollConfig weatherConf PROGMEM = {{ TFT_FRAMEWDT, 64, 2, WA_LEFT }, 140, true, MAX_WIDTH, 0, 4, 30 };
/* BACKGROUNDS */ /* {{ left, top, fontsize, align }, width, height, outlined } */
const FillConfig metaBGConf PROGMEM = {{ 0, 0, 0, WA_LEFT }, DSP_WIDTH, 34, false };
const FillConfig metaBGConfInv PROGMEM = {{ 0, 38, 0, WA_LEFT }, DSP_WIDTH, 1, false };
const FillConfig volbarConf PROGMEM = {{ TFT_FRAMEWDT, DSP_HEIGHT-TFT_FRAMEWDT-6, 0, WA_LEFT }, MAX_WIDTH, 6, true };
const FillConfig playlBGConf PROGMEM = {{ 0, 107, 0, WA_LEFT }, DSP_WIDTH, 24, false };
const FillConfig heapbarConf PROGMEM = {{ 0, DSP_HEIGHT-1, 0, WA_LEFT }, DSP_WIDTH, 1, false };
/* WIDGETS */ /* { left, top, fontsize, align } */
const WidgetConfig bootstrConf PROGMEM = { 0, 142, 1, WA_CENTER };
const WidgetConfig bitrateConf PROGMEM = { 70, 191, 1, WA_LEFT };
const WidgetConfig voltxtConf PROGMEM = { 0, DSP_HEIGHT-23, 1, WA_CENTER };
const WidgetConfig iptxtConf PROGMEM = { TFT_FRAMEWDT, DSP_HEIGHT-23, 1, WA_LEFT };
const WidgetConfig rssiConf PROGMEM = { TFT_FRAMEWDT, DSP_HEIGHT-30, 2, WA_RIGHT };
const WidgetConfig numConf PROGMEM = { 0, 116, 0, WA_CENTER };
const WidgetConfig apNameConf PROGMEM = { TFT_FRAMEWDT, 46, 2, WA_CENTER };
const WidgetConfig apName2Conf PROGMEM = { TFT_FRAMEWDT, 70, 2, WA_CENTER };
const WidgetConfig apPassConf PROGMEM = { TFT_FRAMEWDT, 100, 2, WA_CENTER };
const WidgetConfig apPass2Conf PROGMEM = { TFT_FRAMEWDT, 124, 2, WA_CENTER };
const WidgetConfig clockConf PROGMEM = { TFT_FRAMEWDT*2, 139, 0, WA_RIGHT };
const WidgetConfig vuConf PROGMEM = { TFT_FRAMEWDT, 70, 1, WA_LEFT };
const WidgetConfig bootWdtConf PROGMEM = { 0, 122, 1, WA_CENTER };
const ProgressConfig bootPrgConf PROGMEM = { 90, 14, 4 };
const BitrateConfig fullbitrateConf PROGMEM = {{DSP_WIDTH-TFT_FRAMEWDT-40, 37, 2, WA_LEFT}, 42 };
/* BANDS */ /* { onebandwidth, onebandheight, bandsHspace, bandsVspace, numofbands, fadespeed } */
const VUBandsConfig bandsConf PROGMEM = { 24, 72, 4, 2, 8, 2 };
/* STRINGS */
const char numtxtFmt[] PROGMEM = "%d";
const char rssiFmt[] PROGMEM = "WiFi %d";
const char iptxtFmt[] PROGMEM = "\010 %s";
const char voltxtFmt[] PROGMEM = "\023\025%d";
const char bitrateFmt[] PROGMEM = "%d kBs";
/* MOVES */ /* { left, top, width } */
const MoveConfig clockMove PROGMEM = { TFT_FRAMEWDT, 139, 0 };
const MoveConfig weatherMove PROGMEM = { TFT_FRAMEWDT, 64, MAX_WIDTH-TITLE_FIX };
const MoveConfig weatherMoveVU PROGMEM = { 70, 64, MAX_WIDTH-70+TFT_FRAMEWDT-TITLE_FIX };
#endif

View File

@@ -1,5 +1,5 @@
#include "../core/options.h"
#if DSP_MODEL==DSP_1602I2C || DSP_MODEL==DSP_1602 || DSP_MODEL==DSP_2004 || DSP_MODEL==DSP_2004I2C
#if DSP_MODEL==DSP_1602I2C || DSP_MODEL==DSP_1602 || DSP_MODEL==DSP_2004 || DSP_MODEL==DSP_2004I2C || DSP_MODEL==DSP_2002 || DSP_MODEL==DSP_2002I2C
#include "dspcore.h"
#include <WiFi.h>
#include "../core/config.h"
@@ -33,6 +33,8 @@ void DspCore::initDisplay() {
#else
#ifdef LCD_2004
begin(20, 4);
#elif DSP_MODEL==DSP_2002 || DSP_MODEL==DSP_2002I2C
begin(20, 2);
#else
begin(16, 2);
#endif
@@ -50,7 +52,7 @@ void DspCore::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colo
}
uint16_t DspCore::width(){
#ifdef LCD_2004
#if defined(LCD_2004) || DSP_MODEL==DSP_2002 || DSP_MODEL==DSP_2002I2C
return 20;
#else
return 16;

View File

@@ -9,7 +9,11 @@
#define LCD_2004
#endif
#if DSP_MODEL==DSP_1602I2C || DSP_MODEL==DSP_2004I2C
#if DSP_MODEL==DSP_2002 || DSP_MODEL==DSP_2002I2C
#define LCD_2002
#endif
#if DSP_MODEL==DSP_1602I2C || DSP_MODEL==DSP_2004I2C || DSP_MODEL==DSP_2002I2C
#define LCD_I2C
#include "../LiquidCrystalI2C/LiquidCrystalI2CEx.h"
#else
@@ -18,8 +22,10 @@
#ifdef LCD_I2C
typedef LiquidCrystal_I2C yoDisplay;
#ifdef LCD_2004
#if defined(LCD_2004)
#define DSP_INIT LiquidCrystal_I2C(SCREEN_ADDRESS, 20, 4, I2C_SDA, I2C_SCL)
#elif defined(LCD_2002)
#define DSP_INIT LiquidCrystal_I2C(SCREEN_ADDRESS, 20, 2, I2C_SDA, I2C_SCL)
#else
#define DSP_INIT LiquidCrystal_I2C(SCREEN_ADDRESS, 16, 2, I2C_SDA, I2C_SCL)
#endif

View File

@@ -1,5 +1,5 @@
#include "../core/options.h"
#if DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7789_240 || DSP_MODEL==DSP_ST7789_76
#if DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7789_240 || DSP_MODEL==DSP_ST7789_76 || DSP_MODEL==DSP_ST7789_170
#include "dspcore.h"
#include "../core/config.h"
@@ -16,6 +16,8 @@ DspCore::DspCore(): Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST) {}
void DspCore::initDisplay() {
if(DSP_MODEL==DSP_ST7789_76){
init(76,284);
}else if(DSP_MODEL==DSP_ST7789_170){
init(170,320);
}else{
init(240,(DSP_MODEL==DSP_ST7789)?320:240);
}
@@ -30,7 +32,7 @@ void DspCore::initDisplay() {
void DspCore::clearDsp(bool black){ fillScreen(black?0:config.theme.background); }
void DspCore::flip(){
#if DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7789_76
#if DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7789_76 || DSP_MODEL==DSP_ST7789_170
setRotation(config.store.flipscreen?3:1);
#endif
#if DSP_MODEL==DSP_ST7789_240
@@ -41,7 +43,11 @@ void DspCore::flip(){
}
#endif
}
void DspCore::invert(){ invertDisplay(config.store.invertdisplay); }
void DspCore::invert(){ invertDisplay(
#if DSP_MODEL==DSP_ST7789_170
!
#endif
config.store.invertdisplay); }
void DspCore::sleep(void){ enableSleep(true); delay(150); enableDisplay(false); delay(150); }
void DspCore::wake(void){ enableDisplay(true); delay(150); enableSleep(false); delay(150); }

View File

@@ -23,6 +23,8 @@ typedef Adafruit_ST7789 yoDisplay;
#else
#if DSP_MODEL==DSP_ST7789
#include "conf/displayST7789conf.h"
#elif DSP_MODEL==DSP_ST7789_170
#include "conf/displayST7789_170conf.h"
#elif DSP_MODEL==DSP_ST7789_76
#include "conf/displayST7789_76conf.h"
#else

View File

@@ -26,7 +26,7 @@
#define DSP_OLED
#include "displayN5110.h"
#elif DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7789_240 // https://k210.org/images/content/uploads/yoradio/ST7789.jpg
#elif DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7789_240 || DSP_MODEL==DSP_ST7789_170 // https://k210.org/images/content/uploads/yoradio/ST7789.jpg
#define TIME_SIZE 52
#define PSFBUFFER
#include "displayST7789.h"
@@ -41,7 +41,7 @@
#define DSP_OLED
#include "displaySH1106.h"
#elif DSP_MODEL==DSP_1602I2C || DSP_MODEL==DSP_2004I2C || DSP_MODEL==DSP_1602 || DSP_MODEL==DSP_2004
#elif DSP_MODEL==DSP_1602I2C || DSP_MODEL==DSP_2004I2C || DSP_MODEL==DSP_1602 || DSP_MODEL==DSP_2004 || DSP_MODEL==DSP_2002 || DSP_MODEL==DSP_2002I2C
// https://k210.org/images/content/uploads/yoradio/DSP_1602.jpg
// https://k210.org/images/content/uploads/yoradio/DSP_2004.jpg
#define TIME_SIZE 1

View File

@@ -192,7 +192,7 @@ const GFXglyph DS_DIGI42pt7bGlyphs[] PROGMEM = {
{ 1888, 6, 43, 15, 4, -42 } // 0x3A ':'
};
const GFXfont DS_DIGI42pt7b PROGMEM = {
const GFXfont Clock_GFXfont PROGMEM = {
(uint8_t *)DS_DIGI42pt7bBitmaps,
(GFXglyph *)DS_DIGI42pt7bGlyphs, 0x20, 0x3A, 82 };

View File

@@ -313,7 +313,7 @@ const GFXglyph DS_DIGI56pt7bGlyphs[] PROGMEM = {
{ 3320, 7, 59, 24, 8, -58 } // 0x3A ':'
};
const GFXfont DS_DIGI56pt7b PROGMEM = {
const GFXfont Clock_GFXfont PROGMEM = {
(uint8_t *)DS_DIGI56pt7bBitmaps,
(GFXglyph *)DS_DIGI56pt7bGlyphs, 0x20, 0x3A, 110 };

View File

@@ -23,57 +23,77 @@ size_t strlen_utf8(const char* s) {
char* utf8Rus(const char* str, bool uppercase) {
static char out[BUFLEN];
int outPos = 0;
#ifdef DSP_LCD
#if defined(DSP_LCD) && !defined(LCD_RUS)
static const char* mapD0[] = {
"A","B","V","G","D","E","ZH","Z","I","Y",
"K","L","M","N","O","P","R","S","T","U",
"F","H","TS","CH","SH","SHCH","'","YU","'","E","YU","YA"
};
#endif
#if defined(DSP_LCD) && defined(LCD_RUS)
// except 0401 --> 0xa2 = Ё, 0451 --> 0xb5 = ё
static const unsigned char utf_recode[] PROGMEM =
{
0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4,0xa5,0xa6,0x4b,0xa7,0x4d,0x48,0x4f,
0xa8,0x50,0x43,0x54,0xa9,0xaa,0x58,0xe1,0xab,0xac,0xe2,0xad,0xae,0x62,0xaf,0xb0,0xb1,
0x61,0xb2,0xb3,0xb4,0xe3,0x65,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0x6f,
0xbe,0x70,0x63,0xbf,0x79,0xe4,0x78,0xe5,0xc0,0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7
};
#endif
for (int i = 0; str[i] && outPos < BUFLEN - 1; i++) {
uint8_t c = (uint8_t)str[i];
if (c == 0xD0 && str[i+1]) {
uint8_t n = (uint8_t)str[++i];
if (n == 0x81) { // Ё
#ifdef DSP_LCD
#if defined(DSP_LCD) && !defined(LCD_RUS)
const char* t = "YO";
for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t;
#else
out[outPos++] = uppercase ? 0xA8 : 0xB8;
#endif
} else if (n >= 144 && n <= 191) {
#ifdef DSP_LCD
#if defined(DSP_LCD) && !defined(LCD_RUS)
if(n>=176) n-=32;
const char* t = mapD0[n - 0x90];
for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t;
#else
uint8_t ch = n + 48;
if(n>=176 && uppercase) ch-=32;
out[outPos++] = ch;
#if defined(DSP_LCD) && defined(LCD_RUS)
if(n>=176) n-=32;
out[outPos++] = utf_recode[n - 0x90];
#else
uint8_t ch = n + 48;
if(n>=176 && uppercase) ch-=32;
out[outPos++] = ch;
#endif
#endif
}
} else if (c == 0xD1 && str[i+1]) {
uint8_t n = (uint8_t)str[++i];
if (n == 0x91) { // ё
#ifdef DSP_LCD
#if defined(DSP_LCD) && !defined(LCD_RUS)
const char* t = "YO";
for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t;
#else
out[outPos++] = uppercase ? 0xA8 : 0xB8;
#endif
} else if (n >= 128 && n <= 143) {
#ifdef DSP_LCD
#if defined(DSP_LCD) && !defined(LCD_RUS)
n+=16;
const char* t = mapD0[n - 128];
for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t;
#else
uint8_t ch = n + 112;
if(uppercase) ch-=32;
out[outPos++] = ch;
#if defined(DSP_LCD) && defined(LCD_RUS)
n+=16;
out[outPos++] = utf_recode[n - 128];
#else
uint8_t ch = n + 112;
if(uppercase) ch-=32;
out[outPos++] = ch;
#endif
#endif
}
} else { // ASCII
#ifdef DSP_LCD
#if defined(DSP_LCD) && !defined(LCD_RUS)
char ch = (char)toupper(c);
if (ch == 7) ch = (char)165;
if (ch == 9) ch = (char)223;

View File

@@ -601,12 +601,16 @@ void ClockWidget::init(WidgetConfig wconf, uint16_t fgcolor, uint16_t bgcolor){
else if(TIME_SIZE==19 || TIME_SIZE==2) _superfont=1;
else _superfont=0;
_space = (5*_superfont)/2; //magick
#ifndef HIDE_DATE
if(_fullclock){
_dateheight = _superfont<4?1:2;
_clockheight = _timeheight + _space + CHARHEIGHT * _dateheight;
} else {
_clockheight = _timeheight;
}
#else
_clockheight = _timeheight;
#endif
_getTimeBounds();
#ifdef PSFBUFFER
_fb = new psFrameBuffer(dsp.width(), dsp.height());
@@ -706,6 +710,7 @@ void ClockWidget::_printClock(bool force){
gfx.setTextColor(config.theme.dow, config.theme.background);
gfx.print(utf8Rus(LANG::dow[network.timeinfo.tm_wday], false));
sprintf(_tmp, "%2d %s %d", network.timeinfo.tm_mday,LANG::mnths[network.timeinfo.tm_mon], network.timeinfo.tm_year+1900);
#ifndef HIDE_DATE
strlcpy(_datebuf, utf8Rus(_tmp, true), sizeof(_datebuf));
uint16_t _datewidth = strlen(_datebuf) * CHARWIDTH*_dateheight;
gfx.setTextSize(_dateheight);
@@ -716,6 +721,7 @@ void ClockWidget::_printClock(bool force){
#endif
gfx.setTextColor(config.theme.date, config.theme.background);
gfx.print(_datebuf);
#endif
}
}
}
@@ -949,7 +955,6 @@ void PlayListWidget::_printPLitem(uint8_t pos, const char* item){
dsp.setTextColor(config.theme.playlist[plColor], config.theme.background);
dsp.setCursor(TFT_FRAMEWDT, _plYStart + pos * _plItemHeight);
dsp.fillRect(0, _plYStart + pos * _plItemHeight - 1, dsp.width(), _plItemHeight - 2, config.theme.background);
Serial.println(item);
dsp.print(utf8Rus(item, true));
}
}