diff --git a/yoRadio/data/www/script.js.gz b/yoRadio/data/www/script.js.gz
index f1b23ed..cf6f1f1 100644
Binary files a/yoRadio/data/www/script.js.gz and b/yoRadio/data/www/script.js.gz differ
diff --git a/yoRadio/data/www/style.css.gz b/yoRadio/data/www/style.css.gz
index 35d35ff..6808f8e 100644
Binary files a/yoRadio/data/www/style.css.gz and b/yoRadio/data/www/style.css.gz differ
diff --git a/yoRadio/locale/displayL10n_en.h b/yoRadio/locale/displayL10n_en.h
index 506b84f..9530245 100644
--- a/yoRadio/locale/displayL10n_en.h
+++ b/yoRadio/locale/displayL10n_en.h
@@ -65,6 +65,7 @@ const char const_DlgLost[] PROGMEM = "* LOST *";
const char const_DlgUpdate[] PROGMEM = "* UPDATING *";
const char const_DlgNextion[] PROGMEM = "* NEXTION *";
const char const_getWeather[] PROGMEM = "";
+const char const_waitForSD[] PROGMEM = "WAIT FOR SD";
const char apNameTxt[] PROGMEM = "AP NAME";
const char apPassTxt[] PROGMEM = "PASSWORD";
diff --git a/yoRadio/locale/displayL10n_ru.h b/yoRadio/locale/displayL10n_ru.h
index 8b94931..95900af 100644
--- a/yoRadio/locale/displayL10n_ru.h
+++ b/yoRadio/locale/displayL10n_ru.h
@@ -65,6 +65,7 @@ const char const_DlgLost[] PROGMEM = "ОТКЛЮЧЕНО";
const char const_DlgUpdate[] PROGMEM = "ОБНОВЛЕНИЕ";
const char const_DlgNextion[] PROGMEM = "NEXTION";
const char const_getWeather[] PROGMEM = "";
+const char const_waitForSD[] PROGMEM = "ОЖИДАНИЕ SD";
const char apNameTxt[] PROGMEM = "ТОЧКА ДОСТУПА";
const char apPassTxt[] PROGMEM = "ПАРОЛЬ";
diff --git a/yoRadio/src/AsyncWebServer/AsyncTCP.cpp b/yoRadio/src/AsyncWebServer/AsyncTCP.cpp
index 0af17fd..d27cf97 100644
--- a/yoRadio/src/AsyncWebServer/AsyncTCP.cpp
+++ b/yoRadio/src/AsyncWebServer/AsyncTCP.cpp
@@ -201,6 +201,9 @@ static void _async_service_task(void *pvParameters){
}
#endif
}
+#if ATCP_TASK_DELAY>0
+ vTaskDelay(ATCP_TASK_DELAY);
+#endif
}
vTaskDelete(NULL);
_async_service_task_handle = NULL;
@@ -218,7 +221,7 @@ static bool _start_async_task(){
return false;
}
if(!_async_service_task_handle){
- xTaskCreateUniversal(_async_service_task, "async_tcp", XTASK_MEM_SIZE, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);
+ xTaskCreateUniversal(_async_service_task, "async_tcp", XTASK_MEM_SIZE, NULL, XTASK_PRIOTITY, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);
if(!_async_service_task_handle){
return false;
}
diff --git a/yoRadio/src/AsyncWebServer/AsyncTCP.h b/yoRadio/src/AsyncWebServer/AsyncTCP.h
index 31a3df2..ca57ff8 100644
--- a/yoRadio/src/AsyncWebServer/AsyncTCP.h
+++ b/yoRadio/src/AsyncWebServer/AsyncTCP.h
@@ -32,7 +32,7 @@ extern "C" {
//If core is not defined, then we are running in Arduino or PIO
#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE
- #define CONFIG_ASYNC_TCP_RUNNING_CORE 0 //any available core (-1)
+ #define CONFIG_ASYNC_TCP_RUNNING_CORE 1 //any available core (-1)
#endif
#ifndef CONFIG_ASYNC_TCP_USE_WDT
@@ -40,7 +40,13 @@ extern "C" {
#endif
#ifndef XTASK_MEM_SIZE
- #define XTASK_MEM_SIZE 8192 / 2
+ #define XTASK_MEM_SIZE 6144 // 8192 / 2
+#endif
+#ifndef XTASK_PRIOTITY
+ #define XTASK_PRIOTITY 3 //3
+#endif
+#ifndef ATCP_TASK_DELAY
+ #define ATCP_TASK_DELAY 2
#endif
#ifndef XQUEUE_SIZE
diff --git a/yoRadio/src/audioI2S/Audio.cpp b/yoRadio/src/audioI2S/Audio.cpp
index f72fda1..bed5189 100644
--- a/yoRadio/src/audioI2S/Audio.cpp
+++ b/yoRadio/src/audioI2S/Audio.cpp
@@ -711,14 +711,14 @@ bool Audio::connecttoFS(fs::FS &fs, const char* path, uint32_t resumeFilePos) {
m_file_size = audiofile.size();//TEST loop
cardLock(false);
char* afn = NULL; // audioFileName
-cardLock(true);
+//cardLock(true);
#ifdef SDFATFS_USED
audiofile.getName(chbuf, sizeof(chbuf));
afn = strdup(chbuf);
#else
afn = strdup(audiofile.name());
#endif
-cardLock(false);
+//cardLock(false);
uint8_t dotPos = lastIndexOf(afn, ".");
for(uint8_t i = dotPos + 1; i < strlen(afn); i++){
afn[i] = toLowerCase(afn[i]);
@@ -1553,7 +1553,8 @@ int Audio::read_ID3_Header(uint8_t *data, size_t len) {
AUDIO_INFO("file has no mp3 tag, skip metadata");
m_audioDataSize = m_contentlength;
AUDIO_INFO("Audio-Length: %u", m_audioDataSize);
- if(audio_progress) audio_progress(295903, m_audioDataSize);
+ //if(audio_progress) audio_progress(295903, m_audioDataSize);
+ if(audio_progress) audio_progress(0, m_audioDataSize);
return -1; // error, no ID3 signature found
}
ID3version = *(data + 3);
@@ -3034,14 +3035,14 @@ void Audio::processLocalFile() {
} //TEST loop
f_stream = false;
m_streamType = ST_NONE;
-cardLock(true);
+//cardLock(true);
#ifdef SDFATFS_USED
audiofile.getName(chbuf, sizeof(chbuf));
char *afn =strdup(chbuf);
#else
char *afn =strdup(audiofile.name()); // store temporary the name
#endif
-cardLock(false);
+//cardLock(false);
stopSong();
if(m_codec == CODEC_MP3) MP3Decoder_FreeBuffers();
if(m_codec == CODEC_AAC) AACDecoder_FreeBuffers();
@@ -4399,9 +4400,9 @@ bool Audio::setPinout(uint8_t BCLK, uint8_t LRC, uint8_t DOUT, int8_t DIN, int8_
//---------------------------------------------------------------------------------------------------------------------
uint32_t Audio::getFileSize() {
if(!audiofile) return 0;
- cardLock(true);
+ //cardLock(true);
uint32_t s = audiofile.size();
- cardLock(false);
+ //cardLock(false);
return s;
}
//---------------------------------------------------------------------------------------------------------------------
diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp
index 2cdf56f..410401b 100644
--- a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp
+++ b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp
@@ -152,6 +152,7 @@ Audio::Audio(uint8_t _cs_pin, uint8_t _dcs_pin, uint8_t _dreq_pin, uint8_t spi,
m_endFillByte=0;
curvol=50;
m_LFcount=0;
+ mutex_pl = xSemaphoreCreateMutex();
}
Audio::~Audio(){
// destructor
@@ -302,7 +303,7 @@ void Audio::begin(){
pinMode(dreq_pin, INPUT); // DREQ is an input
pinMode(cs_pin, OUTPUT); // The SCI and SDI signals
pinMode(dcs_pin, OUTPUT);
- mutex_pl = xSemaphoreCreateMutex();
+ //mutex_pl = xSemaphoreCreateMutex();
DCS_HIGH();
CS_HIGH();
delay(170);
@@ -743,9 +744,9 @@ void Audio::processLocalFile() {
f_stream = false;
m_f_localfile = false;
- cardLock(true);
+ //cardLock(true);
char *afn =strdup(audiofile.name()); // store temporary the name
- cardLock(false);
+ //cardLock(false);
stopSong();
sprintf(chbuf, "End of file \"%s\"", afn);
if(audio_info) audio_info(chbuf);
@@ -2153,7 +2154,8 @@ int Audio::read_MP3_Header(uint8_t *data, size_t len) {
if(audio_info) audio_info("file has no mp3 tag, skip metadata");
m_audioDataSize = m_contentlength;
sprintf(chbuf, "Audio-Length: %u", m_audioDataSize);
- if(audio_progress) audio_progress(295903, m_audioDataSize);
+ //if(audio_progress) audio_progress(295903, m_audioDataSize);
+ if(audio_progress) audio_progress(0, m_audioDataSize);
if(audio_info) audio_info(chbuf);
return -1; // error, no ID3 signature found
}
@@ -2482,9 +2484,9 @@ void Audio::showID3Tag(const char* tag, const char* value){
//---------------------------------------------------------------------------------------------------------------------
uint32_t Audio::getFileSize(){
if (!audiofile) return 0;
- cardLock(true);
+ //cardLock(true);
uint32_t s = audiofile.size();
- cardLock(false);
+ //cardLock(false);
return s;
}
//---------------------------------------------------------------------------------------------------------------------
diff --git a/yoRadio/src/core/config.cpp b/yoRadio/src/core/config.cpp
index f795046..e54e6d0 100644
--- a/yoRadio/src/core/config.cpp
+++ b/yoRadio/src/core/config.cpp
@@ -7,9 +7,14 @@
Config config;
-#if DSP_HSPI || TS_HSPI || VS_HSPI || SD_HSPI
+#if DSP_HSPI || TS_HSPI || VS_HSPI
SPIClass SPI2(HSPI);
#endif
+#if defined(SD_SPIPINS) || SD_HSPI
+SPIClass SDSPI(HSPI);
+#endif
+#define SDL() if(player.mutex_pl!=NULL) player.cardLock(true)
+#define SDU() vTaskDelay(2); if(player.mutex_pl!=NULL) player.cardLock(false)
void u8fix(char *src){
char last = src[strlen(src)-1];
@@ -32,6 +37,13 @@ void Config::init() {
emptyFS = true;
#if IR_PIN!=255
irindex=-1;
+#endif
+#if defined(SD_SPIPINS) || SD_HSPI
+ #if !defined(SD_SPIPINS)
+ SDSPI.begin();
+ #else
+ SDSPI.begin(SD_SPIPINS); // SCK, MISO, MOSI
+ #endif
#endif
eepromRead(EEPROM_START, store);
if (store.config_set != 4262) setDefaults();
@@ -50,25 +62,112 @@ void Config::init() {
emptyFS = _isFSempty();
if(emptyFS) BOOTLOG("SPIFFS is empty!");
ssidsCount = 0;
- sdResumePos = 0;
- if(SDC_CS!=255){
- if(!SD.begin(SDC_CS)){
- store.play_mode=PM_WEB;
- Serial.println("##[ERROR]#\tCard Mount Failed");
+ _cardStatus = CS_NONE;
+ mountSDbusy = false;
+ if(SDC_CS!=255) randomSeed(analogRead(SDC_CS));
+ backupSDStation = 0;
+ //checkSD();
+ _bootDone=false;
+ bootInfo();
+}
+
+bool Config::_sdCardIsConnected() {
+ if(SD.sectorSize()<1) return false;
+ SDL();
+ uint8_t buff[SD.sectorSize()] = { 0 };
+ bool bread = SD.readRAW(buff, 1);
+ if(SD.sectorSize()>0 && !bread) SD.end();
+ SDU();
+ return bread;
+}
+
+bool Config::_sdBegin(){
+ bool out;
+ SDL();
+#if defined(SD_SPIPINS) || SD_HSPI
+ out = SD.begin(SDC_CS, SDSPI);
+#else
+ out = SD.begin(SDC_CS);
+#endif
+ SDU();
+ return out;
+}
+
+void Config::checkSD(){
+ if(SDC_CS==255) return;
+ mountSDbusy = true;
+ cardStatus_e prevCardStatus = _cardStatus;
+ if(_sdCardIsConnected()){
+ if(_cardStatus==CS_NONE || _cardStatus==CS_PRESENT || _cardStatus==CS_EJECTED) {
+ _cardStatus=CS_PRESENT;
}else{
- if(store.play_mode==PM_SDCARD) initSDPlaylist();
+ _cardStatus=CS_MOUNTED;
}
+ if(_cardStatus==CS_PRESENT && store.play_mode==PM_WEB && SD_AUTOPLAY && prevCardStatus==CS_EJECTED) config.changeMode(PM_SDCARD);
+ }else{
+ if(_cardStatus==CS_MOUNTED || _cardStatus==CS_PRESENT || _cardStatus==CS_EJECTED){
+ if(_cardStatus!=CS_EJECTED && store.play_mode==PM_SDCARD && SD_AUTOPLAY) config.changeMode(PM_WEB);
+ _cardStatus=CS_EJECTED;
+ }
+ backupSDStation = 0;
+ }
+ mountSDbusy = false;
+}
+
+void Config::_mountSD(){
+ if(SDC_CS==255 || mountSDbusy || display.mode()==SDCHANGE) return;
+ mountSDbusy = true;
+ if(SD.sectorSize()<1) SDinit = _sdBegin();
+ if(!_sdCardIsConnected()) {
+ if(store.play_mode==PM_SDCARD){
+ SDinit = false;
+ }
+ }else{
+ if(!SDinit){
+ if(!_sdBegin()){
+ Serial.println("##[ERROR]#\tCard Mount Failed");
+ }else{
+ SDinit = true;
+ }
+ }
+ }
+ mountSDbusy = false;
+}
+
+void Config::initPlaylistMode(){
+ sdResumePos = 0;
+ SDinit = false;
+ if(SDC_CS!=255){
+ if(!_sdBegin()){
+ store.play_mode=PM_WEB;
+ Serial.println("SD Mount Failed");
+ }else{
+ Serial.println("SD Mounted");
+ if(store.play_mode==PM_SDCARD) {
+ if(_cardStatus!=CS_MOUNTED){
+ _cardStatus=CS_MOUNTED;
+ if(_bootDone) Serial.println("Waiting for SD card indexing..."); else BOOTLOG("Waiting for SD card indexing...");
+ initSDPlaylist();
+ }else{
+ if(backupSDStation==0) {
+ store.lastStation = random(1, store.countStation);
+ backupSDStation = store.lastStation;
+ }else store.lastStation = backupSDStation;
+ }
+ }
+ SDinit = true;
+ }
+ }else{
+ store.play_mode=PM_WEB;
}
if(store.play_mode==PM_WEB && !emptyFS) initPlaylist();
if (store.lastStation == 0 && store.countStation > 0) {
- store.lastStation = 1;
+ store.lastStation = store.play_mode==PM_WEB?1:random(1, store.countStation);
save();
}
-
+ _bootDone = true;
loadStation(store.lastStation);
-
- bootInfo();
}
void Config::_initHW(){
@@ -218,12 +317,51 @@ void Config::save() {
store.lastStation = ls;
store.play_mode = pm;
}
+
void Config::setSnuffle(bool sn){
sdSnuffle=sn;
save();
if(sdSnuffle) player.next();
//player blah blah blah
}
+
+void Config::changeMode(int newmode){
+ if(SDC_CS==255) return;
+ if(!SDinit) {
+ _mountSD();
+ if(!SDinit){
+ Serial.println("##[ERROR]#\tSD Not Found");
+ netserver.requestOnChange(GETPLAYERMODE, 0);
+ return;
+ }
+ }
+ if(store.play_mode==PM_SDCARD) store.lastStation = config.backupLastStation;
+ if(newmode<0){
+ store.play_mode++;
+ if(store.play_mode > MAX_PLAY_MODE){
+ store.play_mode=0;
+ }
+ }else{
+ store.play_mode=(playMode_e)newmode;
+ }
+ save();
+ if(store.play_mode==PM_SDCARD && _cardStatus!=CS_MOUNTED){
+ display.putRequest(NEWMODE, SDCHANGE);
+ while(display.mode()!=SDCHANGE)
+ delay(10);
+ delay(50);
+ }
+ initPlaylistMode();
+
+ if (store.smartstart == 1) player.sendCommand({PR_PLAY, store.lastStation});
+ else
+ player.sendCommand({PR_STOP, 0});
+ netserver.requestOnChange(GETPLAYERMODE, 0);
+ netserver.requestOnChange(GETMODE, 0);
+ display.putRequest(NEWMODE, PLAYER);
+ display.putRequest(NEWSTATION);
+}
+
#if IR_PIN!=255
void Config::saveIR(){
eepromWrite(EEPROM_START_IR, ircodes);
@@ -325,10 +463,9 @@ void Config::initPlaylist() {
}
bool endsWith (const char* base, const char* str) {
-//fb
int slen = strlen(str) - 1;
const char *p = base + strlen(base) - 1;
- while(p > base && isspace(*p)) p--; // rtrim
+ while(p > base && isspace(*p)) p--;
p -= slen;
if (p < base) return false;
return (strncmp(p, str, slen) == 0);
@@ -338,11 +475,12 @@ bool Config::checkNoMedia(const char* path){
char nomedia[BUFLEN]= {0};
strlcat(nomedia, path, BUFLEN);
strlcat(nomedia, "/.nomedia", BUFLEN);
- return SD.exists(nomedia);
+ SDL(); bool nm = SD.exists(nomedia); SDU();
+ return nm;
}
void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels){
- File root = SD.open(dirname);
+ SDL(); File root = SD.open(dirname); SDU();
if(!root){
Serial.println("##[ERROR]#\tFailed to open directory");
return;
@@ -352,9 +490,9 @@ void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8
return;
}
- File file = root.openNextFile();
+ SDL(); File file = root.openNextFile(); SDU();
uint32_t pos = 0;
-
+ //vTaskDelay(5);
while(file){
if(file.isDirectory()){
@@ -368,19 +506,22 @@ void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8
plSDindex.write((byte *) &pos, 4);
}
}
- file = root.openNextFile();
+ SDL(); file = root.openNextFile(); SDU();
}
}
void Config::indexSDPlaylist() {
+ mountSDbusy = true;
File playlist = SPIFFS.open(PLAYLIST_SD_PATH, "w");
if (!playlist) {
+ mountSDbusy = false;
return;
}
File index = SPIFFS.open(INDEX_SD_PATH, "w");
listSD(playlist, index, "/", 2);
index.close();
playlist.close();
+ mountSDbusy = false;
}
void Config::initSDPlaylist() {
@@ -390,6 +531,7 @@ void Config::initSDPlaylist() {
File index = SPIFFS.open(INDEX_SD_PATH, "r");
store.countStation = index.size() / 4;
store.lastStation = random(1, store.countStation);
+ backupSDStation = store.lastStation;
index.close();
save();
}
@@ -715,9 +857,10 @@ void Config::bootInfo() {
BOOTLOG("flipscreen:\t%s", store.flipscreen?"true":"false");
BOOTLOG("invertdisplay:\t%s", store.invertdisplay?"true":"false");
BOOTLOG("showweather:\t%s", store.showweather?"true":"false");
- BOOTLOG("buttons:\tleft=%d, center=%d, right=%d, up=%d, down=%d, pullup=%s", BTN_LEFT, BTN_CENTER, BTN_RIGHT, BTN_UP, BTN_DOWN, BTN_INTERNALPULLUP?"true":"false");
+ BOOTLOG("buttons:\tleft=%d, center=%d, right=%d, up=%d, down=%d, mode=%d, pullup=%s", BTN_LEFT, BTN_CENTER, BTN_RIGHT, BTN_UP, BTN_DOWN, BTN_MODE, BTN_INTERNALPULLUP?"true":"false");
BOOTLOG("encoders:\tl1=%d, b1=%d, r1=%d, pullup=%s, l2=%d, b2=%d, r2=%d, pullup=%s", ENC_BTNL, ENC_BTNB, ENC_BTNR, ENC_INTERNALPULLUP?"true":"false", ENC2_BTNL, ENC2_BTNB, ENC2_BTNR, ENC2_INTERNALPULLUP?"true":"false");
BOOTLOG("ir:\t\t%d", IR_PIN);
+ if(SDC_CS!=255) BOOTLOG("SD:\t\t%d", SDC_CS);
BOOTLOG("------------------------------------------------");
}
diff --git a/yoRadio/src/core/config.h b/yoRadio/src/core/config.h
index 21a2b9d..181dc14 100644
--- a/yoRadio/src/core/config.h
+++ b/yoRadio/src/core/config.h
@@ -36,6 +36,7 @@
#define MAX_PLAY_MODE 1
enum playMode_e : uint8_t { PM_WEB=0, PM_SDCARD=1 };
+enum cardStatus_e : uint8_t { CS_NONE=0, CS_PRESENT=1, CS_MOUNTED=2, CS_EJECTED=3 };
enum BitrateFormat { BF_UNCNOWN, BF_MP3, BF_AAC, BF_FLAC, BF_OGG, BF_WAV };
void u8fix(char *src);
@@ -159,8 +160,11 @@ class Config {
uint16_t sleepfor;
uint32_t sdResumePos;
uint16_t backupLastStation;
+ uint16_t backupSDStation;
bool sdSnuffle;
bool emptyFS;
+ bool SDinit;
+ bool mountSDbusy;
public:
Config() {};
void save();
@@ -190,6 +194,8 @@ class Config {
void setBitrateFormat(BitrateFormat fmt) { configFmt = fmt; }
void initPlaylist();
void indexPlaylist();
+ void initSDPlaylist();
+ void indexSDPlaylist();
uint8_t fillPlMenu(int from, uint8_t count, bool fromNextion=false);
char * stationByNum(uint16_t num);
void setTimezone(int8_t tzh, int8_t tzm);
@@ -201,19 +207,26 @@ class Config {
void bootInfo();
void doSleepW();
void setSnuffle(bool sn);
+ void changeMode(int newmode=-1);
+ void initPlaylistMode();
+ void checkSD();
+ cardStatus_e getSDStatus(){ return _cardStatus; };
private:
template
int eepromWrite(int ee, const T& value);
template int eepromRead(int ee, T& value);
+ cardStatus_e _cardStatus;
+ bool _bootDone;
void setDefaults();
Ticker _sleepTimer;
static void doSleep();
uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
void listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels);
- void initSDPlaylist();
- void indexSDPlaylist();
bool checkNoMedia(const char* path);
void _initHW();
bool _isFSempty();
+ bool _sdCardIsConnected();
+ void _mountSD();
+ bool _sdBegin();
char _stationBuf[BUFLEN/2];
};
diff --git a/yoRadio/src/core/controls.cpp b/yoRadio/src/core/controls.cpp
index 13b2a59..5eeb5dc 100644
--- a/yoRadio/src/core/controls.cpp
+++ b/yoRadio/src/core/controls.cpp
@@ -41,7 +41,7 @@ constexpr uint8_t nrOfButtons = sizeof(button) / sizeof(button[0]);
#endif
#endif
-#if TS_MODEL!=TS_MODEL_UNDEFINED
+#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
#include "touchscreen.h"
TouchScreen touchscreen;
#endif
@@ -114,7 +114,7 @@ void initControls() {
button[i].setPressTicks(BTN_PRESS_TICKS);
}
#endif
-#if TS_MODEL!=TS_MODEL_UNDEFINED
+#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
touchscreen.init();
#endif
#if IR_PIN!=255
@@ -129,7 +129,7 @@ void initControls() {
}
void loopControls() {
- if(display.mode()==LOST || display.mode()==UPDATING) return;
+ if(display.mode()==LOST || display.mode()==UPDATING || display.mode()==SDCHANGE) return;
if (ctrls_on_loop) ctrls_on_loop();
#if ENC_BTNL!=255
encoder1Loop();
@@ -151,7 +151,7 @@ void loopControls() {
#if IR_PIN!=255
irLoop();
#endif
-#if TS_MODEL!=TS_MODEL_UNDEFINED
+#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
touchscreen.loop();
#endif
}
@@ -504,15 +504,7 @@ void onBtnClick(int id) {
break;
}
case EVT_BTNMODE: {
- if(SDC_CS==255) break;
- if(config.store.play_mode==PM_SDCARD) config.store.lastStation = config.backupLastStation;
- config.store.play_mode++;
- if(config.store.play_mode > MAX_PLAY_MODE){
- config.store.play_mode=0;
- }
-
- config.save();
- ESP.restart();
+ config.changeMode();
break;
}
default: break;
@@ -560,7 +552,7 @@ void setEncAcceleration(uint16_t acc){
#endif
}
void flipTS(){
-#if TS_MODEL!=TS_MODEL_UNDEFINED
+#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
touchscreen.flip();
#endif
}
diff --git a/yoRadio/src/core/display.cpp b/yoRadio/src/core/display.cpp
index c0e29e1..e9d4b82 100644
--- a/yoRadio/src/core/display.cpp
+++ b/yoRadio/src/core/display.cpp
@@ -286,6 +286,7 @@ void Display::_swichMode(displayMode_e newmode) {
if (newmode == LOST) _showDialog(const_DlgLost);
if (newmode == UPDATING) _showDialog(const_DlgUpdate);
if (newmode == SLEEPING) _showDialog("SLEEPING");
+ if (newmode == SDCHANGE) _showDialog(const_waitForSD);
if (newmode == INFO || newmode == SETTINGS || newmode == TIMEZONE || newmode == WIFI) _showDialog(const_DlgNextion);
if (newmode == NUMBERS) _showDialog("");
if (newmode == STATIONS) {
@@ -419,6 +420,10 @@ void Display::loop() {
#endif*/
break;
}
+ case WAITFORSD: {
+ if(_bootstring) _bootstring->setText(const_waitForSD);
+ break;
+ }
case DSPRSSI: if(_rssi){ _setRSSI(request.payload); } if (_heapbar && config.store.audioinfo) _heapbar->setValue(player.isRunning()?player.inBufferFilled():0); break;
case PSTART: _layoutChange(true); break;
case PSTOP: _layoutChange(false); break;
diff --git a/yoRadio/src/core/display.h b/yoRadio/src/core/display.h
index 9afb8fb..a514063 100644
--- a/yoRadio/src/core/display.h
+++ b/yoRadio/src/core/display.h
@@ -8,11 +8,11 @@
#include "../displays/dspcore.h"
-enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI, CLEAR, SLEEPING };
+enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI, CLEAR, SLEEPING, SDCHANGE };
enum pages_e : uint8_t { PG_PLAYER=0, PG_DIALOG=1, PG_PLAYLIST=2 };
//enum dialogType_e : uint8_t { DG_NONE=0, DG_VOLUME=1, DG_LOST=2, DG_UPDATING=3, DG_NEXTION=4 };
-enum displayRequestType_e { BOOTSTRING, NEWMODE, CLOCK, NEWTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL, DBITRATE, AUDIOINFO, SHOWVUMETER, DSPRSSI, SHOWWEATHER, NEWWEATHER, PSTOP, PSTART, DSP_START };
+enum displayRequestType_e { BOOTSTRING, NEWMODE, CLOCK, NEWTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL, DBITRATE, AUDIOINFO, SHOWVUMETER, DSPRSSI, SHOWWEATHER, NEWWEATHER, PSTOP, PSTART, DSP_START, WAITFORSD };
struct requestParams_t
{
displayRequestType_e type;
diff --git a/yoRadio/src/core/netserver.cpp b/yoRadio/src/core/netserver.cpp
index 8354926..dc195ac 100644
--- a/yoRadio/src/core/netserver.cpp
+++ b/yoRadio/src/core/netserver.cpp
@@ -199,7 +199,17 @@ void NetServer::processQueue(){
uint8_t clientId = request.clientId;
switch (request.type) {
case PLAYLIST: getPlaylist(clientId); break;
- case PLAYLISTSAVED: config.indexPlaylist(); config.initPlaylist(); getPlaylist(clientId); break;
+ case PLAYLISTSAVED: {
+ if(config.store.play_mode==PM_SDCARD) {
+ // config.indexSDPlaylist();
+ config.initSDPlaylist();
+ }
+ if(config.store.play_mode==PM_WEB){
+ // config.indexPlaylist();
+ config.initPlaylist();
+ }
+ getPlaylist(clientId); break;
+ }
case GETACTIVE: {
bool dbgact = false, nxtn=false;
String act = F("\"group_wifi\",");
@@ -231,27 +241,30 @@ void NetServer::processQueue(){
sprintf (wsbuf, "{\"act\":[%s]}", act.c_str());
break;
}
- case GETMODE: sprintf (wsbuf, "{\"pmode\":\"%s\"}", network.status == CONNECTED ? "player" : "ap"); break;
- case GETINDEX: requestOnChange(STATION, clientId); requestOnChange(TITLE, clientId); requestOnChange(VOLUME, clientId); requestOnChange(EQUALIZER, clientId); requestOnChange(BALANCE, clientId); requestOnChange(BITRATE, clientId); requestOnChange(MODE, clientId); if (config.store.play_mode==PM_SDCARD) { requestOnChange(SDPOS, clientId); requestOnChange(SDLEN, clientId); requestOnChange(SDSNUFFLE, clientId); } return; break;
- case GETSYSTEM: sprintf (wsbuf, "{\"sst\":%d,\"aif\":%d,\"vu\":%d,\"softr\":%d}", config.store.smartstart != 2, config.store.audioinfo, config.store.vumeter, config.store.softapdelay); break;
- case GETSCREEN: sprintf (wsbuf, "{\"flip\":%d,\"inv\":%d,\"nump\":%d,\"tsf\":%d,\"tsd\":%d,\"dspon\":%d,\"br\":%d,\"con\":%d}", config.store.flipscreen, config.store.invertdisplay, config.store.numplaylist, config.store.fliptouch, config.store.dbgtouch, config.store.dspon, config.store.brightness, config.store.contrast); break;
- case GETTIMEZONE: sprintf (wsbuf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}", config.store.tzHour, config.store.tzMin, config.store.sntp1, config.store.sntp2); break;
- case GETWEATHER: sprintf (wsbuf, "{\"wen\":%d,\"wlat\":\"%s\",\"wlon\":\"%s\",\"wkey\":\"%s\"}", config.store.showweather, config.store.weatherlat, config.store.weatherlon, config.store.weatherkey); break;
- case GETCONTROLS: sprintf (wsbuf, "{\"vols\":%d,\"enca\":%d,\"irtl\":%d}", config.store.volsteps, config.store.encacc, config.store.irtlp); break;
- case DSPON: sprintf (wsbuf, "{\"dspontrue\":%d}", 1); break;
- case STATION: requestOnChange(STATIONNAME, clientId); requestOnChange(ITEM, clientId); break;
- case STATIONNAME: sprintf (wsbuf, "{\"nameset\": \"%s\"}", config.station.name); break;
- case ITEM: sprintf (wsbuf, "{\"current\": %d}", config.store.lastStation); break;
- case TITLE: sprintf (wsbuf, "{\"meta\": \"%s\"}", config.station.title); telnet.printf("##CLI.META#: %s\n> ", config.station.title); break;
- case VOLUME: sprintf (wsbuf, "{\"vol\": %d}", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume); break;
- case NRSSI: sprintf (wsbuf, "{\"rssi\": %d}", rssi); /*rssi = 255;*/ break;
- case SDPOS: sprintf (wsbuf, "{\"sdpos\": %d,\"sdend\": %d,\"sdtpos\": %d,\"sdtend\": %d}", player.getFilePos(), player.getFileSize(), player.getAudioCurrentTime(), player.getAudioFileDuration()); break;
- case SDLEN: sprintf (wsbuf, "{\"sdmin\": %d,\"sdmax\": %d}", player.sd_min, player.sd_max); break;
- case SDSNUFFLE: sprintf (wsbuf, "{\"snuffle\": %d}", config.sdSnuffle); break;
- case BITRATE: sprintf (wsbuf, "{\"bitrate\": %d}", config.station.bitrate); break;
- case MODE: sprintf (wsbuf, "{\"mode\": \"%s\"}", player.status() == PLAYING ? "playing" : "stopped"); telnet.info(); break;
- case EQUALIZER: sprintf (wsbuf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble); break;
- case BALANCE: sprintf (wsbuf, "{\"balance\": %d}", config.store.balance); break;
+ case GETMODE: sprintf (wsbuf, "{\"pmode\":\"%s\"}", network.status == CONNECTED ? "player" : "ap"); break;
+ case GETINDEX: requestOnChange(STATION, clientId); requestOnChange(TITLE, clientId); requestOnChange(VOLUME, clientId); requestOnChange(EQUALIZER, clientId); requestOnChange(BALANCE, clientId); requestOnChange(BITRATE, clientId); requestOnChange(MODE, clientId); requestOnChange(SDINIT, clientId);requestOnChange(GETPLAYERMODE, clientId); if (config.store.play_mode==PM_SDCARD) { requestOnChange(SDPOS, clientId); requestOnChange(SDLEN, clientId); requestOnChange(SDSNUFFLE, clientId); } return; break;
+ case GETSYSTEM: sprintf (wsbuf, "{\"sst\":%d,\"aif\":%d,\"vu\":%d,\"softr\":%d}", config.store.smartstart != 2, config.store.audioinfo, config.store.vumeter, config.store.softapdelay); break;
+ case GETSCREEN: sprintf (wsbuf, "{\"flip\":%d,\"inv\":%d,\"nump\":%d,\"tsf\":%d,\"tsd\":%d,\"dspon\":%d,\"br\":%d,\"con\":%d}", config.store.flipscreen, config.store.invertdisplay, config.store.numplaylist, config.store.fliptouch, config.store.dbgtouch, config.store.dspon, config.store.brightness, config.store.contrast); break;
+ case GETTIMEZONE: sprintf (wsbuf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}", config.store.tzHour, config.store.tzMin, config.store.sntp1, config.store.sntp2); break;
+ case GETWEATHER: sprintf (wsbuf, "{\"wen\":%d,\"wlat\":\"%s\",\"wlon\":\"%s\",\"wkey\":\"%s\"}", config.store.showweather, config.store.weatherlat, config.store.weatherlon, config.store.weatherkey); break;
+ case GETCONTROLS: sprintf (wsbuf, "{\"vols\":%d,\"enca\":%d,\"irtl\":%d}", config.store.volsteps, config.store.encacc, config.store.irtlp); break;
+ case DSPON: sprintf (wsbuf, "{\"dspontrue\":%d}", 1); break;
+ case STATION: requestOnChange(STATIONNAME, clientId); requestOnChange(ITEM, clientId); break;
+ case STATIONNAME: sprintf (wsbuf, "{\"nameset\": \"%s\"}", config.station.name); break;
+ case ITEM: sprintf (wsbuf, "{\"current\": %d}", config.store.lastStation); break;
+ case TITLE: sprintf (wsbuf, "{\"meta\": \"%s\"}", config.station.title); telnet.printf("##CLI.META#: %s\n> ", config.station.title); break;
+ case VOLUME: sprintf (wsbuf, "{\"vol\": %d}", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume); break;
+ case NRSSI: sprintf (wsbuf, "{\"rssi\": %d}", rssi); /*rssi = 255;*/ break;
+ case SDPOS: sprintf (wsbuf, "{\"sdpos\": %d,\"sdend\": %d,\"sdtpos\": %d,\"sdtend\": %d}", player.getFilePos(), player.getFileSize(), player.getAudioCurrentTime(), player.getAudioFileDuration()); break;
+ case SDLEN: sprintf (wsbuf, "{\"sdmin\": %d,\"sdmax\": %d}", player.sd_min, player.sd_max); break;
+ case SDSNUFFLE: sprintf (wsbuf, "{\"snuffle\": %d}", config.sdSnuffle); break;
+ case BITRATE: sprintf (wsbuf, "{\"bitrate\": %d}", config.station.bitrate); break;
+ case MODE: sprintf (wsbuf, "{\"mode\": \"%s\"}", player.status() == PLAYING ? "playing" : "stopped"); telnet.info(); break;
+ case EQUALIZER: sprintf (wsbuf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble); break;
+ case BALANCE: sprintf (wsbuf, "{\"balance\": %d}", config.store.balance); break;
+ case SDINIT: sprintf (wsbuf, "{\"sdinit\": %d}", SDC_CS!=255); break;
+ case GETPLAYERMODE: sprintf (wsbuf, "{\"playermode\": \"%s\"}", config.store.play_mode==PM_SDCARD?"modesd":"modeweb"); break;
+ case CHANGEMODE: config.changeMode(newConfigMode); return; break;
default: break;
}
if (strlen(wsbuf) > 0) {
@@ -308,6 +321,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
if (strcmp(cmd, "getcontrols") == 0 ) { requestOnChange(GETCONTROLS, clientId); return; }
if (strcmp(cmd, "getweather") == 0 ) { requestOnChange(GETWEATHER, clientId); return; }
if (strcmp(cmd, "getactive") == 0 ) { requestOnChange(GETACTIVE, clientId); return; }
+ if (strcmp(cmd, "newmode") == 0 ) { newConfigMode = atoi(val); requestOnChange(CHANGEMODE, 0); return; }
if (strcmp(cmd, "smartstart") == 0) {
byte valb = atoi(val);
config.store.smartstart = valb == 1 ? 1 : 2;
@@ -527,6 +541,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
player.setVol(v);
}
if (strcmp(cmd, "sdpos") == 0) {
+ return;
if (config.store.play_mode==PM_SDCARD){
config.sdResumePos = 0;
if(!player.isRunning()){
@@ -536,6 +551,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
player.setFilePos(atoi(val)-player.sd_min);
}
}
+ return;
}
if (strcmp(cmd, "snuffle") == 0) {
config.setSnuffle(strcmp(val, "true") == 0);
@@ -657,6 +673,7 @@ bool NetServer::importPlaylist() {
}
void NetServer::requestOnChange(requestType_e request, uint8_t clientId) {
+ if(nsQueue==NULL) return;
nsRequestParams_t nsrequest;
nsrequest.type = request;
nsrequest.clientId = clientId;
@@ -667,13 +684,13 @@ String processor(const String& var) { // %Templates%
if (var == "ACTION") return (network.status == CONNECTED && !config.emptyFS)?"webboard":"";
if (var == "UPLOADWIFI") return (network.status == CONNECTED)?" hidden":"";
if (var == "VERSION") return YOVERSION;
- if (var == "MODE") {
+ /*if (var == "MODE") {
if(config.store.play_mode==PM_SDCARD) {
return "modescard";
}else{
return "modeweb";
}
- }
+ }*/
return String();
}
diff --git a/yoRadio/src/core/netserver.h b/yoRadio/src/core/netserver.h
index 695ab71..a538a9b 100644
--- a/yoRadio/src/core/netserver.h
+++ b/yoRadio/src/core/netserver.h
@@ -5,10 +5,10 @@
#include "../AsyncWebServer/ESPAsyncWebServer.h"
#include "AsyncUDP.h"
-enum requestType_e : uint8_t { PLAYLIST=1, STATION=2, STATIONNAME=3, ITEM=4, TITLE=5, VOLUME=6, NRSSI=7, BITRATE=8, MODE=9, EQUALIZER=10, BALANCE=11, PLAYLISTSAVED=12, GETMODE=13, GETINDEX=14, GETACTIVE=15, GETSYSTEM=16, GETSCREEN=17, GETTIMEZONE=18, GETWEATHER=19, GETCONTROLS=20, DSPON=21, SDPOS=22, SDLEN=23, SDSNUFFLE=24 };
+enum requestType_e : uint8_t { PLAYLIST=1, STATION=2, STATIONNAME=3, ITEM=4, TITLE=5, VOLUME=6, NRSSI=7, BITRATE=8, MODE=9, EQUALIZER=10, BALANCE=11, PLAYLISTSAVED=12, GETMODE=13, GETINDEX=14, GETACTIVE=15, GETSYSTEM=16, GETSCREEN=17, GETTIMEZONE=18, GETWEATHER=19, GETCONTROLS=20, DSPON=21, SDPOS=22, SDLEN=23, SDSNUFFLE=24, SDINIT=25, GETPLAYERMODE=26, CHANGEMODE=27 };
enum import_e : uint8_t { IMDONE=0, IMPL=1, IMWIFI=2 };
const char emptyfs_html[] PROGMEM = R"(
-ёRadio - WEB Board Uploader