v0.9.220
This commit is contained in:
@@ -226,6 +226,15 @@ Work is in progress...
|
||||
|
||||
---
|
||||
## Version history
|
||||
#### v0.9.220
|
||||
- fixed SD prelist indexing error when switching Web>>SD
|
||||
- fixed a bug of switching to the next track when accidentally playing SD
|
||||
- fixed import of large playlists (tried). PS: import playlist size is limited by SPIFFS size (SPIFFS.totalBytes()/100*65-SPIFFS.usedBytes() = approximately 60kb )
|
||||
- new url parameter - http://YPRADIOIP/?clearspiffs - for clearing tails from SD playlist
|
||||
- optimization of the issuance of the WEB-interface
|
||||
- brought back the functionality of the track slider
|
||||
- fixing bugs in the application logic
|
||||
|
||||
#### v0.9.201
|
||||
- fixed a bug when importing a playlist
|
||||
|
||||
|
||||
Binary file not shown.
@@ -19,7 +19,7 @@
|
||||
*
|
||||
*/
|
||||
#include "../core/options.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#if DSP_MODEL==DSP_SSD1322
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
#define SSD1322_MODE_DATA digitalWrite(dcPin, HIGH); ///< Data mode
|
||||
|
||||
#if defined(SPI_HAS_TRANSACTION)
|
||||
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
|
||||
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
#define SPI_TRANSACTION_START TAKE_MUTEX(); spi->beginTransaction(spiSettings) ///< Pre-SPI
|
||||
#define SPI_TRANSACTION_END spi->endTransaction(); GIVE_MUTEX() ///< Post-SPI
|
||||
#else // SPI transactions likewise not present in older Arduino SPI lib
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../core/options.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#if DSP_MODEL==DSP_ST7920
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
@@ -10,8 +10,8 @@
|
||||
//This display is split into two halfs. Pages are 16bit long and pages are arranged in that way that are lied horizontaly instead of verticaly, unlike SSD1306 OLED, Nokia 5110 LCD, etc.
|
||||
//After 8 horizonral page is written, it jumps to half of the screen (Y = 32) and continues until 16 lines of page have been written. After that, we have set cursor in new line.
|
||||
|
||||
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
|
||||
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
#define st7920_swap(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
|
||||
|
||||
void ST7920::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "../core/options.h"
|
||||
#include "../core/spidog.h"
|
||||
#if VS1053_CS==255
|
||||
/*
|
||||
* Audio.cpp
|
||||
@@ -170,7 +171,6 @@ Audio::Audio(bool internalDAC /* = false */, uint8_t channelEnabled /* = I2S_DAC
|
||||
#ifdef AUDIO_LOG
|
||||
m_f_Log = true;
|
||||
#endif
|
||||
mutex_pl = xSemaphoreCreateMutex();
|
||||
clientsecure.setInsecure(); // if that can't be resolved update to ESP32 Arduino version 1.0.5-rc05 or higher
|
||||
m_f_channelEnabled = channelEnabled;
|
||||
m_f_internalDAC = internalDAC;
|
||||
@@ -315,7 +315,7 @@ void Audio::setDefaults() {
|
||||
vector_clear_and_shrink(m_playlistURL);
|
||||
vector_clear_and_shrink(m_playlistContent);
|
||||
m_hashQueue.clear(); m_hashQueue.shrink_to_fit(); // uint32_t vector
|
||||
if(config.store.play_mode!=PM_SDCARD){
|
||||
if(config.getMode()!=PM_SDCARD){
|
||||
client.stop();
|
||||
client.flush(); // release memory
|
||||
clientsecure.stop();
|
||||
@@ -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]);
|
||||
@@ -2458,9 +2458,9 @@ bool Audio::playChunk() {
|
||||
void Audio::cardLock(bool lock){
|
||||
#if (TFT_CS!=255) || (SDC_CS!=255)
|
||||
if(lock){
|
||||
xSemaphoreTake(mutex_pl, portMAX_DELAY);
|
||||
sdog.takeMutex();
|
||||
}else{
|
||||
xSemaphoreGive(mutex_pl);
|
||||
sdog.giveMutex();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3035,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();
|
||||
@@ -4400,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;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -210,7 +210,6 @@ public:
|
||||
void setVUmeter() {};
|
||||
void getVUlevel() {};
|
||||
uint8_t vuLeft, vuRight;
|
||||
SemaphoreHandle_t mutex_pl=NULL;
|
||||
bool eofHeader;
|
||||
esp_err_t i2s_mclk_pin_select(const uint8_t pin);
|
||||
uint32_t inBufferFilled(); // returns the number of stored bytes in the inputbuffer
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "../core/options.h"
|
||||
#include "../core/spidog.h"
|
||||
#if I2S_DOUT==255
|
||||
/*
|
||||
* vs1053_ext.cpp
|
||||
@@ -152,7 +153,6 @@ 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
|
||||
@@ -180,18 +180,18 @@ void Audio::control_mode_off()
|
||||
{
|
||||
CS_HIGH(); // End control mode
|
||||
spi_VS1053->endTransaction(); // Allow other SPI users
|
||||
xSemaphoreGive(mutex_pl);
|
||||
sdog.giveMutex();
|
||||
}
|
||||
void Audio::control_mode_on()
|
||||
{
|
||||
xSemaphoreTake(mutex_pl, portMAX_DELAY);
|
||||
sdog.takeMutex();
|
||||
spi_VS1053->beginTransaction(VS1053_SPI_CTL); // Prevent other SPI users
|
||||
DCS_HIGH(); // Bring slave in control mode
|
||||
CS_LOW();
|
||||
}
|
||||
void Audio::data_mode_on()
|
||||
{
|
||||
xSemaphoreTake(mutex_pl, portMAX_DELAY);
|
||||
sdog.takeMutex();
|
||||
spi_VS1053->beginTransaction(VS1053_SPI_DATA); // Prevent other SPI users
|
||||
CS_HIGH(); // Bring slave in data mode
|
||||
DCS_LOW();
|
||||
@@ -201,7 +201,7 @@ void Audio::data_mode_off()
|
||||
//digitalWrite(dcs_pin, HIGH); // End data mode
|
||||
DCS_HIGH();
|
||||
spi_VS1053->endTransaction(); // Allow other SPI users
|
||||
xSemaphoreGive(mutex_pl);
|
||||
sdog.giveMutex();
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
uint16_t Audio::read_register(uint8_t _reg)
|
||||
@@ -303,7 +303,6 @@ 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();
|
||||
DCS_HIGH();
|
||||
CS_HIGH();
|
||||
delay(170);
|
||||
@@ -573,10 +572,9 @@ void Audio::showstreamtitle(const char* ml) {
|
||||
void Audio::cardLock(bool lock){
|
||||
#if (SDC_CS!=255)
|
||||
if(lock){
|
||||
xSemaphoreTake(mutex_pl, portMAX_DELAY);
|
||||
sdog.takeMutex();
|
||||
}else{
|
||||
// digitalWrite(SDC_CS, HIGH);
|
||||
xSemaphoreGive(mutex_pl);
|
||||
sdog.giveMutex();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -744,9 +742,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);
|
||||
@@ -1612,7 +1610,7 @@ void Audio::setDefaults(){
|
||||
InBuff.resetBuffer();
|
||||
vector_clear_and_shrink(m_playlistURL);
|
||||
vector_clear_and_shrink(m_playlistContent);
|
||||
if(config.store.play_mode!=PM_SDCARD){
|
||||
if(config.getMode()!=PM_SDCARD){
|
||||
client.stop();
|
||||
client.flush(); // release memory
|
||||
clientsecure.stop();
|
||||
@@ -2484,9 +2482,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;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -310,7 +310,6 @@ public:
|
||||
bool setFilePos(uint32_t pos);
|
||||
uint32_t getAudioFileDuration();
|
||||
uint32_t getAudioCurrentTime();
|
||||
SemaphoreHandle_t mutex_pl=NULL;
|
||||
size_t bufferFilled();
|
||||
size_t bufferFree();
|
||||
size_t inBufferFilled(){ return bufferFilled(); }
|
||||
|
||||
@@ -112,17 +112,13 @@ void audio_id3data(const char *info){ //id3 metadata
|
||||
|
||||
void audio_eof_mp3(const char *info){ //end of file
|
||||
config.sdResumePos = 0;
|
||||
if(config.sdSnuffle){
|
||||
player.sendCommand({PR_PLAY, random(1, config.store.countStation)});
|
||||
}else{
|
||||
player.next();
|
||||
}
|
||||
}
|
||||
|
||||
void audio_eof_stream(const char *info){
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
if(!player.resumeAfterUrl) return;
|
||||
if (config.store.play_mode==PM_WEB){
|
||||
if (config.getMode()==PM_WEB){
|
||||
player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}else{
|
||||
player.setResumeFilePos( config.sdResumePos==0?0:config.sdResumePos-player.sd_min);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "display.h"
|
||||
#include "player.h"
|
||||
#include "netserver.h"
|
||||
#include "spidog.h"
|
||||
|
||||
Config config;
|
||||
|
||||
@@ -13,8 +14,6 @@ SPIClass SPI2(HSPI);
|
||||
#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];
|
||||
@@ -34,6 +33,7 @@ bool Config::_isFSempty() {
|
||||
|
||||
void Config::init() {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
sdog.begin();
|
||||
emptyFS = true;
|
||||
#if IR_PIN!=255
|
||||
irindex=-1;
|
||||
@@ -72,29 +72,37 @@ void Config::init() {
|
||||
}
|
||||
|
||||
bool Config::_sdCardIsConnected() {
|
||||
if(SD.sectorSize()<1) return false;
|
||||
SDL();
|
||||
#if SDC_CS!=255
|
||||
sdog.takeMutex();
|
||||
if(SD.sectorSize()<1) {
|
||||
sdog.giveMutex();
|
||||
return false;
|
||||
}
|
||||
uint8_t buff[SD.sectorSize()] = { 0 };
|
||||
bool bread = SD.readRAW(buff, 1);
|
||||
if(SD.sectorSize()>0 && !bread) SD.end();
|
||||
SDU();
|
||||
sdog.giveMutex();
|
||||
return bread;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Config::_sdBegin(){
|
||||
bool out;
|
||||
SDL();
|
||||
#if defined(SD_SPIPINS) || SD_HSPI
|
||||
bool out = false;
|
||||
#if SDC_CS!=255
|
||||
sdog.takeMutex();
|
||||
#if defined(SD_SPIPINS) || SD_HSPI
|
||||
out = SD.begin(SDC_CS, SDSPI);
|
||||
#else
|
||||
#else
|
||||
out = SD.begin(SDC_CS);
|
||||
#endif
|
||||
sdog.giveMutex();
|
||||
#endif
|
||||
SDU();
|
||||
return out;
|
||||
}
|
||||
|
||||
void Config::checkSD(){
|
||||
if(SDC_CS==255) return;
|
||||
#if SDC_CS!=255
|
||||
mountSDbusy = true;
|
||||
cardStatus_e prevCardStatus = _cardStatus;
|
||||
if(_sdCardIsConnected()){
|
||||
@@ -103,23 +111,34 @@ void Config::checkSD(){
|
||||
}else{
|
||||
_cardStatus=CS_MOUNTED;
|
||||
}
|
||||
if(_cardStatus==CS_PRESENT && store.play_mode==PM_WEB && SD_AUTOPLAY && prevCardStatus==CS_EJECTED) config.changeMode(PM_SDCARD);
|
||||
if(_cardStatus==CS_PRESENT && getMode()==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);
|
||||
if(_cardStatus!=CS_EJECTED && getMode()==PM_SDCARD && SD_AUTOPLAY) config.changeMode(PM_WEB);
|
||||
_cardStatus=CS_EJECTED;
|
||||
}
|
||||
backupSDStation = 0;
|
||||
}
|
||||
mountSDbusy = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Config::spiffsCleanup(){
|
||||
bool ret = (SPIFFS.exists(PLAYLIST_SD_PATH)) || (SPIFFS.exists(INDEX_SD_PATH)) || (SPIFFS.exists(INDEX_PATH));
|
||||
if(SPIFFS.exists(PLAYLIST_SD_PATH)) SPIFFS.remove(PLAYLIST_SD_PATH);
|
||||
if(SPIFFS.exists(INDEX_SD_PATH)) SPIFFS.remove(INDEX_SD_PATH);
|
||||
if(SPIFFS.exists(INDEX_PATH)) SPIFFS.remove(INDEX_PATH);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Config::_mountSD(){
|
||||
#if SDC_CS!=255
|
||||
if(SDC_CS==255 || mountSDbusy || display.mode()==SDCHANGE) return;
|
||||
mountSDbusy = true;
|
||||
if(SD.sectorSize()<1) SDinit = _sdBegin();
|
||||
sdog.takeMutex(); uint16_t ssz = SD.sectorSize(); sdog.giveMutex();
|
||||
if(ssz<1) SDinit = _sdBegin();
|
||||
if(!_sdCardIsConnected()) {
|
||||
if(store.play_mode==PM_SDCARD){
|
||||
if(getMode()==PM_SDCARD){
|
||||
SDinit = false;
|
||||
}
|
||||
}else{
|
||||
@@ -132,6 +151,7 @@ void Config::_mountSD(){
|
||||
}
|
||||
}
|
||||
mountSDbusy = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Config::initPlaylistMode(){
|
||||
@@ -143,12 +163,13 @@ void Config::initPlaylistMode(){
|
||||
Serial.println("SD Mount Failed");
|
||||
}else{
|
||||
Serial.println("SD Mounted");
|
||||
if(store.play_mode==PM_SDCARD) {
|
||||
if(getMode()==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{
|
||||
initSDPlaylist(false);
|
||||
if(backupSDStation==0) {
|
||||
store.lastStation = random(1, store.countStation);
|
||||
backupSDStation = store.lastStation;
|
||||
@@ -160,12 +181,13 @@ void Config::initPlaylistMode(){
|
||||
}else{
|
||||
store.play_mode=PM_WEB;
|
||||
}
|
||||
if(store.play_mode==PM_WEB && !emptyFS) initPlaylist();
|
||||
if(getMode()==PM_WEB && !emptyFS) initPlaylist();
|
||||
|
||||
if (store.lastStation == 0 && store.countStation > 0) {
|
||||
store.lastStation = store.play_mode==PM_WEB?1:random(1, store.countStation);
|
||||
save();
|
||||
store.lastStation = getMode()==PM_WEB?1:random(1, store.countStation);
|
||||
//save();
|
||||
}
|
||||
save();
|
||||
_bootDone = true;
|
||||
loadStation(store.lastStation);
|
||||
}
|
||||
@@ -310,8 +332,8 @@ uint16_t Config::getTimezoneOffset() {
|
||||
void Config::save() {
|
||||
uint16_t ls = store.lastStation;
|
||||
uint8_t pm = store.play_mode;
|
||||
if(store.play_mode==PM_SDCARD) store.lastStation = backupLastStation;
|
||||
if(store.play_mode==PM_WEB) backupLastStation = store.lastStation;
|
||||
if(getMode()==PM_SDCARD) store.lastStation = backupLastStation;
|
||||
if(getMode()==PM_WEB) backupLastStation = store.lastStation;
|
||||
bitWrite(store.play_mode, 2, sdSnuffle);
|
||||
eepromWrite(EEPROM_START, store);
|
||||
store.lastStation = ls;
|
||||
@@ -322,10 +344,10 @@ 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
|
||||
if(SDC_CS==255) return;
|
||||
if(!SDinit) {
|
||||
_mountSD();
|
||||
@@ -335,17 +357,17 @@ void Config::changeMode(int newmode){
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(store.play_mode==PM_SDCARD) store.lastStation = config.backupLastStation;
|
||||
if(getMode()==PM_SDCARD) store.lastStation = config.backupLastStation;
|
||||
if(newmode<0){
|
||||
store.play_mode++;
|
||||
if(store.play_mode > MAX_PLAY_MODE){
|
||||
if(getMode() > MAX_PLAY_MODE){
|
||||
store.play_mode=0;
|
||||
}
|
||||
}else{
|
||||
store.play_mode=(playMode_e)newmode;
|
||||
}
|
||||
save();
|
||||
if(store.play_mode==PM_SDCARD && _cardStatus!=CS_MOUNTED){
|
||||
if(getMode()==PM_SDCARD && _cardStatus!=CS_MOUNTED){
|
||||
display.putRequest(NEWMODE, SDCHANGE);
|
||||
while(display.mode()!=SDCHANGE)
|
||||
delay(10);
|
||||
@@ -360,6 +382,7 @@ void Config::changeMode(int newmode){
|
||||
netserver.requestOnChange(GETMODE, 0);
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
display.putRequest(NEWSTATION);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IR_PIN!=255
|
||||
@@ -475,12 +498,12 @@ bool Config::checkNoMedia(const char* path){
|
||||
char nomedia[BUFLEN]= {0};
|
||||
strlcat(nomedia, path, BUFLEN);
|
||||
strlcat(nomedia, "/.nomedia", BUFLEN);
|
||||
SDL(); bool nm = SD.exists(nomedia); SDU();
|
||||
sdog.takeMutex(); bool nm = SD.exists(nomedia); sdog.giveMutex();
|
||||
return nm;
|
||||
}
|
||||
|
||||
void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels){
|
||||
SDL(); File root = SD.open(dirname); SDU();
|
||||
sdog.takeMutex(); File root = SD.open(dirname); sdog.giveMutex();
|
||||
if(!root){
|
||||
Serial.println("##[ERROR]#\tFailed to open directory");
|
||||
return;
|
||||
@@ -490,28 +513,34 @@ void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8
|
||||
return;
|
||||
}
|
||||
|
||||
SDL(); File file = root.openNextFile(); SDU();
|
||||
sdog.takeMutex(); File file = root.openNextFile(); sdog.giveMutex();
|
||||
uint32_t pos = 0;
|
||||
//vTaskDelay(5);
|
||||
while(file){
|
||||
|
||||
if(file.isDirectory()){
|
||||
if(levels && !checkNoMedia(file.path())){
|
||||
listSD(plSDfile, plSDindex, file.path(), levels -1);
|
||||
sdog.takeMutex();
|
||||
bool fid = file.isDirectory();
|
||||
const char * fp = file.path();
|
||||
const char * fn = file.name();
|
||||
sdog.giveMutex();
|
||||
if(fid){
|
||||
if(levels && !checkNoMedia(fp)){
|
||||
listSD(plSDfile, plSDindex, fp, levels -1);
|
||||
}
|
||||
} else {
|
||||
if(endsWith(strlwr((char*)file.name()), ".mp3") || endsWith(file.name(), ".m4a") || endsWith(file.name(), ".aac") || endsWith(file.name(), ".wav") || endsWith(file.name(), ".flac")){
|
||||
if(endsWith(strlwr((char*)fn), ".mp3") || endsWith(fn, ".m4a") || endsWith(fn, ".aac") || endsWith(fn, ".wav") || endsWith(fn, ".flac")){
|
||||
pos = plSDfile.position();
|
||||
plSDfile.print(file.name()); plSDfile.print("\t"); plSDfile.print(file.path()); plSDfile.print("\t"); plSDfile.println(0);
|
||||
plSDfile.print(fn); plSDfile.print("\t"); plSDfile.print(fp); plSDfile.print("\t"); plSDfile.println(0);
|
||||
plSDindex.write((byte *) &pos, 4);
|
||||
}
|
||||
}
|
||||
SDL(); file = root.openNextFile(); SDU();
|
||||
sdog.takeMutex(); file = root.openNextFile(); sdog.giveMutex();
|
||||
}
|
||||
}
|
||||
|
||||
void Config::indexSDPlaylist() {
|
||||
mountSDbusy = true;
|
||||
if(SPIFFS.exists(PLAYLIST_SD_PATH)) SPIFFS.remove(PLAYLIST_SD_PATH);
|
||||
if(SPIFFS.exists(INDEX_SD_PATH)) SPIFFS.remove(INDEX_SD_PATH);
|
||||
File playlist = SPIFFS.open(PLAYLIST_SD_PATH, "w");
|
||||
if (!playlist) {
|
||||
mountSDbusy = false;
|
||||
@@ -519,19 +548,24 @@ void Config::indexSDPlaylist() {
|
||||
}
|
||||
File index = SPIFFS.open(INDEX_SD_PATH, "w");
|
||||
listSD(playlist, index, "/", 2);
|
||||
index.flush();
|
||||
index.close();
|
||||
playlist.flush();
|
||||
playlist.close();
|
||||
delay(50);
|
||||
mountSDbusy = false;
|
||||
}
|
||||
|
||||
void Config::initSDPlaylist() {
|
||||
void Config::initSDPlaylist(bool doIndex) {
|
||||
store.countStation = 0;
|
||||
indexSDPlaylist();
|
||||
if(doIndex) indexSDPlaylist();
|
||||
if (SPIFFS.exists(INDEX_SD_PATH)) {
|
||||
File index = SPIFFS.open(INDEX_SD_PATH, "r");
|
||||
store.countStation = index.size() / 4;
|
||||
if(doIndex){
|
||||
store.lastStation = random(1, store.countStation);
|
||||
backupSDStation = store.lastStation;
|
||||
}
|
||||
index.close();
|
||||
save();
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#endif
|
||||
#define BOOTLOG( ... ) { char buf[120]; sprintf( buf, __VA_ARGS__ ) ; Serial.print("##[BOOT]#\t"); Serial.println(buf); }
|
||||
#define EVERY_MS(x) static uint32_t tmr; bool flag = millis() - tmr >= (x); if (flag) tmr += (x); if (flag)
|
||||
#define REAL_PLAYL store.play_mode==PM_WEB?PLAYLIST_PATH:PLAYLIST_SD_PATH
|
||||
#define REAL_INDEX store.play_mode==PM_WEB?INDEX_PATH:INDEX_SD_PATH
|
||||
#define REAL_PLAYL getMode()==PM_WEB?PLAYLIST_PATH:PLAYLIST_SD_PATH
|
||||
#define REAL_INDEX getMode()==PM_WEB?INDEX_PATH:INDEX_SD_PATH
|
||||
|
||||
#define MAX_PLAY_MODE 1
|
||||
enum playMode_e : uint8_t { PM_WEB=0, PM_SDCARD=1 };
|
||||
@@ -194,7 +194,7 @@ class Config {
|
||||
void setBitrateFormat(BitrateFormat fmt) { configFmt = fmt; }
|
||||
void initPlaylist();
|
||||
void indexPlaylist();
|
||||
void initSDPlaylist();
|
||||
void initSDPlaylist(bool doIndex = true);
|
||||
void indexSDPlaylist();
|
||||
uint8_t fillPlMenu(int from, uint8_t count, bool fromNextion=false);
|
||||
char * stationByNum(uint16_t num);
|
||||
@@ -208,9 +208,12 @@ class Config {
|
||||
void doSleepW();
|
||||
void setSnuffle(bool sn);
|
||||
void changeMode(int newmode=-1);
|
||||
uint8_t getMode() { return store.play_mode & 0b11; }
|
||||
void initPlaylistMode();
|
||||
void checkSD();
|
||||
cardStatus_e getSDStatus(){ return _cardStatus; };
|
||||
void clearCardStatus() { if(_cardStatus!=CS_NONE) _cardStatus=CS_NONE; }
|
||||
bool spiffsCleanup();
|
||||
private:
|
||||
template <class T> int eepromWrite(int ee, const T& value);
|
||||
template <class T> int eepromRead(int ee, T& value);
|
||||
|
||||
@@ -166,13 +166,17 @@ size_t NetServer::chunkedHtmlPageCallback(uint8_t* buffer, size_t maxLen, size_t
|
||||
return canread;
|
||||
}
|
||||
|
||||
void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request, const char * path, bool gzip) {
|
||||
void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request, const char * path, bool doproc) {
|
||||
memset(chunkedPathBuffer, 0, sizeof(chunkedPathBuffer));
|
||||
strlcpy(chunkedPathBuffer, path, sizeof(chunkedPathBuffer)-1);
|
||||
AsyncWebServerResponse *response = request->beginChunkedResponse(contentType, chunkedHtmlPageCallback, processor);
|
||||
xSemaphoreTake(player.playmutex, portMAX_DELAY);
|
||||
AsyncWebServerResponse *response;
|
||||
if(doproc)
|
||||
response = request->beginChunkedResponse(contentType, chunkedHtmlPageCallback, processor);
|
||||
else
|
||||
response = request->beginChunkedResponse(contentType, chunkedHtmlPageCallback);
|
||||
//xSemaphoreTake(player.playmutex, portMAX_DELAY);
|
||||
request->send(response);
|
||||
xSemaphoreGive(player.playmutex);
|
||||
//xSemaphoreGive(player.playmutex);
|
||||
}
|
||||
|
||||
#ifndef DSP_NOT_FLIPPED
|
||||
@@ -200,11 +204,11 @@ void NetServer::processQueue(){
|
||||
switch (request.type) {
|
||||
case PLAYLIST: getPlaylist(clientId); break;
|
||||
case PLAYLISTSAVED: {
|
||||
if(config.store.play_mode==PM_SDCARD) {
|
||||
if(config.getMode()==PM_SDCARD) {
|
||||
// config.indexSDPlaylist();
|
||||
config.initSDPlaylist();
|
||||
}
|
||||
if(config.store.play_mode==PM_WEB){
|
||||
if(config.getMode()==PM_WEB){
|
||||
config.indexPlaylist();
|
||||
config.initPlaylist();
|
||||
}
|
||||
@@ -242,7 +246,7 @@ void NetServer::processQueue(){
|
||||
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 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.getMode()==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;
|
||||
@@ -263,7 +267,7 @@ void NetServer::processQueue(){
|
||||
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 GETPLAYERMODE: sprintf (wsbuf, "{\"playermode\": \"%s\"}", config.getMode()==PM_SDCARD?"modesd":"modeweb"); break;
|
||||
case CHANGEMODE: config.changeMode(newConfigMode); return; break;
|
||||
default: break;
|
||||
}
|
||||
@@ -541,8 +545,8 @@ 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){
|
||||
//return;
|
||||
if (config.getMode()==PM_SDCARD){
|
||||
config.sdResumePos = 0;
|
||||
if(!player.isRunning()){
|
||||
player.setResumeFilePos(atoi(val)-player.sd_min);
|
||||
@@ -626,41 +630,42 @@ void NetServer::getPlaylist(uint8_t clientId) {
|
||||
if (clientId == 0) { websocket.textAll(buf); } else { websocket.text(clientId, buf); }
|
||||
}
|
||||
|
||||
int NetServer::_readPlaylistLine(File &file, char * line, size_t size){
|
||||
int bytesRead = file.readBytesUntil('\n', line, size);
|
||||
if(bytesRead>0){
|
||||
line[bytesRead] = 0;
|
||||
if(line[bytesRead-1]=='\r') line[bytesRead-1]=0;
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
bool NetServer::importPlaylist() {
|
||||
if(config.store.play_mode==PM_SDCARD) return false;
|
||||
if(config.getMode()==PM_SDCARD) return false;
|
||||
File tempfile = SPIFFS.open(TMP_PATH, "r");
|
||||
if (!tempfile) {
|
||||
return false;
|
||||
}
|
||||
char sName[BUFLEN], sUrl[BUFLEN];
|
||||
char sName[BUFLEN], sUrl[BUFLEN], linePl[BUFLEN*3];;
|
||||
int sOvol;
|
||||
String line = tempfile.readStringUntil('\n');
|
||||
if (config.parseCSV(line.c_str(), sName, sUrl, sOvol)) {
|
||||
File playlistfile = SPIFFS.open(PLAYLIST_PATH, "w");
|
||||
playlistfile.println(line);
|
||||
while (tempfile.available()) {
|
||||
line = tempfile.readStringUntil('\n');
|
||||
if (config.parseCSV(line.c_str(), sName, sUrl, sOvol)) {
|
||||
playlistfile.println(line);
|
||||
}
|
||||
}
|
||||
playlistfile.close();
|
||||
_readPlaylistLine(tempfile, linePl, sizeof(linePl)-1);
|
||||
if (config.parseCSV(linePl, sName, sUrl, sOvol)) {
|
||||
tempfile.close();
|
||||
SPIFFS.remove(TMP_PATH);
|
||||
SPIFFS.rename(TMP_PATH, PLAYLIST_PATH);
|
||||
requestOnChange(PLAYLISTSAVED, 0);
|
||||
return true;
|
||||
}
|
||||
if (config.parseJSON(line.c_str(), sName, sUrl, sOvol)) {
|
||||
if (config.parseJSON(linePl, sName, sUrl, sOvol)) {
|
||||
File playlistfile = SPIFFS.open(PLAYLIST_PATH, "w");
|
||||
String wline = String(sName) + "\t" + String(sUrl) + "\t" + String(sOvol);
|
||||
playlistfile.println(wline);
|
||||
snprintf(linePl, sizeof(linePl)-1, "%s\t%s\t%d", sName, sUrl, 0);
|
||||
playlistfile.println(linePl);
|
||||
while (tempfile.available()) {
|
||||
line = tempfile.readStringUntil('\n');
|
||||
if (config.parseJSON(line.c_str(), sName, sUrl, sOvol)) {
|
||||
wline = String(sName) + "\t" + String(sUrl) + "\t" + String(sOvol);
|
||||
playlistfile.println(wline);
|
||||
_readPlaylistLine(tempfile, linePl, sizeof(linePl)-1);
|
||||
if (config.parseJSON(linePl, sName, sUrl, sOvol)) {
|
||||
snprintf(linePl, sizeof(linePl)-1, "%s\t%s\t%d", sName, sUrl, 0);
|
||||
playlistfile.println(linePl);
|
||||
}
|
||||
}
|
||||
playlistfile.flush();
|
||||
playlistfile.close();
|
||||
tempfile.close();
|
||||
SPIFFS.remove(TMP_PATH);
|
||||
@@ -684,26 +689,26 @@ 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(config.store.play_mode==PM_SDCARD) {
|
||||
return "modescard";
|
||||
}else{
|
||||
return "modeweb";
|
||||
}
|
||||
}*/
|
||||
return String();
|
||||
}
|
||||
|
||||
int freeSpace;
|
||||
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
if (!index) {
|
||||
//String spath = "/www/";
|
||||
//if(filename=="playlist.csv" || filename=="wifi.csv") spath = "/data/";
|
||||
//request->_tempFile = SPIFFS.open(config.emptyFS?spath + filename:TMP_PATH , "w");
|
||||
if(filename!="tempwifi.csv"){
|
||||
if(SPIFFS.exists(PLAYLIST_PATH)) SPIFFS.remove(PLAYLIST_PATH);
|
||||
if(SPIFFS.exists(INDEX_PATH)) SPIFFS.remove(INDEX_PATH);
|
||||
if(SPIFFS.exists(PLAYLIST_SD_PATH)) SPIFFS.remove(PLAYLIST_PATH);
|
||||
if(SPIFFS.exists(INDEX_SD_PATH)) SPIFFS.remove(INDEX_PATH);
|
||||
config.clearCardStatus();
|
||||
}
|
||||
freeSpace = (float)SPIFFS.totalBytes()/100*68-SPIFFS.usedBytes();
|
||||
request->_tempFile = SPIFFS.open(TMP_PATH , "w");
|
||||
}
|
||||
if (len) {
|
||||
if(freeSpace>index+len){
|
||||
request->_tempFile.write(data, len);
|
||||
//TODO check index+len size
|
||||
}
|
||||
}
|
||||
if (final) {
|
||||
request->_tempFile.close();
|
||||
@@ -744,10 +749,10 @@ void handleHTTPArgs(AsyncWebServerRequest * request) {
|
||||
#ifdef MQTT_ROOT_TOPIC
|
||||
if (strcmp(request->url().c_str(), PLAYLIST_PATH) == 0) while (mqttplaylistblock) vTaskDelay(5);
|
||||
#endif
|
||||
if(strcmp(request->url().c_str(), PLAYLIST_PATH) == 0 && config.store.play_mode==PM_SDCARD){
|
||||
netserver.chunkedHtmlPage("application/octet-stream", request, PLAYLIST_SD_PATH);
|
||||
if(strcmp(request->url().c_str(), PLAYLIST_PATH) == 0 && config.getMode()==PM_SDCARD){
|
||||
netserver.chunkedHtmlPage("application/octet-stream", request, PLAYLIST_SD_PATH, false);
|
||||
}else{
|
||||
netserver.chunkedHtmlPage("application/octet-stream", request, request->url().c_str());
|
||||
netserver.chunkedHtmlPage("application/octet-stream", request, request->url().c_str(), false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -797,6 +802,7 @@ void handleHTTPArgs(AsyncWebServerRequest * request) {
|
||||
int id = atoi(p->value().c_str());
|
||||
if (id < 1) id = 1;
|
||||
if (id > config.store.countStation) id = config.store.countStation;
|
||||
config.sdResumePos = 0;
|
||||
player.sendCommand({PR_PLAY, id});
|
||||
commandFound=true;
|
||||
DBGVB("[%s] play=%d", __func__, id);
|
||||
@@ -840,6 +846,17 @@ void handleHTTPArgs(AsyncWebServerRequest * request) {
|
||||
commandFound=true;
|
||||
}
|
||||
}
|
||||
if (request->hasArg("clearspiffs")) {
|
||||
if(config.spiffsCleanup()){
|
||||
config.store.play_mode = PM_WEB;
|
||||
config.save();
|
||||
request->redirect("/");
|
||||
ESP.restart();
|
||||
}else{
|
||||
request->send(200);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (request->params() > 0) {
|
||||
request->send(commandFound?200:404);
|
||||
return;
|
||||
|
||||
@@ -60,7 +60,7 @@ class NetServer {
|
||||
void requestOnChange(requestType_e request, uint8_t clientId);
|
||||
void setRSSI(int val) { rssi = val; };
|
||||
int getRSSI() { return rssi; };
|
||||
void chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request, const char * path, bool gzip = false);
|
||||
void chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request, const char * path, bool doproc = true);
|
||||
void onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t clientId);
|
||||
bool irRecordEnable;
|
||||
#if IR_PIN!=255
|
||||
@@ -77,6 +77,7 @@ class NetServer {
|
||||
static void beginUpload(AsyncWebServerRequest *request);
|
||||
static void beginUpdate(AsyncWebServerRequest *request);
|
||||
void processQueue();
|
||||
int _readPlaylistLine(File &file, char * line, size_t size);
|
||||
};
|
||||
|
||||
extern NetServer netserver;
|
||||
|
||||
@@ -42,12 +42,14 @@ void ticks() {
|
||||
mktime(&network.timeinfo);
|
||||
display.putRequest(CLOCK);
|
||||
}
|
||||
if(player.isRunning() && config.store.play_mode==PM_SDCARD) netserver.requestOnChange(SDPOS, 0);
|
||||
if(player.isRunning() && config.getMode()==PM_SDCARD) netserver.requestOnChange(SDPOS, 0);
|
||||
if(divrssi) {
|
||||
netserver.setRSSI(WiFi.RSSI());
|
||||
netserver.requestOnChange(NRSSI, 0);
|
||||
display.putRequest(DSPRSSI, netserver.getRSSI());
|
||||
#if SDC_CS!=255
|
||||
if(!config.mountSDbusy) player.sendCommand({PR_CHECKSD, 0});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef options_h
|
||||
#define options_h
|
||||
|
||||
#define YOVERSION "0.9.201"
|
||||
#define YOVERSION "0.9.220"
|
||||
|
||||
/*******************************************************
|
||||
DO NOT EDIT THIS FILE.
|
||||
|
||||
@@ -89,7 +89,7 @@ void Player::setError(const char *e){
|
||||
}
|
||||
|
||||
void Player::_stop(bool alreadyStopped){
|
||||
if(config.store.play_mode==PM_SDCARD && !alreadyStopped) config.sdResumePos = player.getFilePos();
|
||||
if(config.getMode()==PM_SDCARD && !alreadyStopped) config.sdResumePos = player.getFilePos();
|
||||
_status = STOPPED;
|
||||
setOutputPins(false);
|
||||
if(!hasError()) config.setTitle((display.mode()==LOST || display.mode()==UPDATING)?"":const_PlStopped);
|
||||
@@ -175,7 +175,7 @@ void Player::_play(uint16_t stationId) {
|
||||
config.setDspOn(1);
|
||||
display.putRequest(PSTOP);
|
||||
setOutputPins(false);
|
||||
config.setTitle(config.store.play_mode==PM_WEB?const_PlConnect:"");
|
||||
config.setTitle(config.getMode()==PM_WEB?const_PlConnect:"");
|
||||
config.station.bitrate=0;
|
||||
config.setBitrateFormat(BF_UNCNOWN);
|
||||
config.loadStation(stationId);
|
||||
@@ -187,14 +187,17 @@ void Player::_play(uint16_t stationId) {
|
||||
netserver.loop();
|
||||
config.setSmartStart(0);
|
||||
bool isConnected = false;
|
||||
if(config.store.play_mode==PM_SDCARD && SDC_CS!=255)
|
||||
if(config.getMode()==PM_SDCARD && SDC_CS!=255)
|
||||
isConnected=connecttoFS(SD,config.station.url,config.sdResumePos==0?_resumeFilePos:config.sdResumePos-player.sd_min);
|
||||
else config.store.play_mode=PM_WEB;
|
||||
if(config.store.play_mode==PM_WEB) isConnected=connecttohost(config.station.url);
|
||||
else {
|
||||
config.store.play_mode=PM_WEB;
|
||||
config.save();
|
||||
}
|
||||
if(config.getMode()==PM_WEB) isConnected=connecttohost(config.station.url);
|
||||
if(isConnected){
|
||||
//if (config.store.play_mode==PM_WEB?connecttohost(config.station.url):connecttoFS(SD,config.station.url,config.sdResumePos==0?_resumeFilePos:config.sdResumePos-player.sd_min)) {
|
||||
_status = PLAYING;
|
||||
if(config.store.play_mode==PM_SDCARD) {
|
||||
if(config.getMode()==PM_SDCARD) {
|
||||
config.sdResumePos = 0;
|
||||
config.backupSDStation = stationId;
|
||||
}
|
||||
@@ -238,14 +241,14 @@ void Player::browseUrl(){
|
||||
#endif
|
||||
|
||||
void Player::prev() {
|
||||
if(config.store.play_mode==PM_WEB || !config.sdSnuffle){
|
||||
if(config.getMode()==PM_WEB || !config.sdSnuffle){
|
||||
if (config.store.lastStation == 1) config.store.lastStation = config.store.countStation; else config.store.lastStation--;
|
||||
}
|
||||
sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}
|
||||
|
||||
void Player::next() {
|
||||
if(config.store.play_mode==PM_WEB || !config.sdSnuffle){
|
||||
if(config.getMode()==PM_WEB || !config.sdSnuffle){
|
||||
if (config.store.lastStation == config.store.countStation) config.store.lastStation = 1; else config.store.lastStation++;
|
||||
}else{
|
||||
config.store.lastStation = random(1, config.store.countStation);
|
||||
|
||||
37
yoRadio/src/core/spidog.cpp
Normal file
37
yoRadio/src/core/spidog.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "spidog.h"
|
||||
|
||||
SPIDog sdog;
|
||||
|
||||
SPIDog::SPIDog() {
|
||||
_busy = false;
|
||||
}
|
||||
|
||||
bool SPIDog::begin(){
|
||||
_spiMutex = xSemaphoreCreateMutex();
|
||||
return (_spiMutex != NULL);
|
||||
}
|
||||
|
||||
bool SPIDog::takeMutex(){
|
||||
if(_spiMutex == NULL) {
|
||||
return false;
|
||||
}
|
||||
if(xSemaphoreTake(_spiMutex, SDOG_PORT_DELAY) == pdTRUE){
|
||||
_busy = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SPIDog::giveMutex(){
|
||||
if(_spiMutex != NULL) xSemaphoreGive(_spiMutex);
|
||||
_busy = false;
|
||||
}
|
||||
|
||||
bool SPIDog::breakMutex(uint8_t ticks){
|
||||
if(!_busy){
|
||||
giveMutex();
|
||||
vTaskDelay(ticks);
|
||||
return takeMutex();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
28
yoRadio/src/core/spidog.h
Normal file
28
yoRadio/src/core/spidog.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef spidog_h
|
||||
#define spidog_h
|
||||
#include <Arduino.h>
|
||||
#include "options.h"
|
||||
|
||||
#ifndef SDOG_PORT_DELAY
|
||||
#define SDOG_PORT_DELAY portMAX_DELAY
|
||||
#endif
|
||||
|
||||
class SPIDog {
|
||||
private:
|
||||
SemaphoreHandle_t _spiMutex=NULL;
|
||||
bool _busy;
|
||||
public:
|
||||
SPIDog();
|
||||
~SPIDog(){}
|
||||
bool begin();
|
||||
bool takeMutex();
|
||||
void giveMutex();
|
||||
bool breakMutex(uint8_t ticks=5);
|
||||
bool busy() { return _busy; }
|
||||
bool tm() { return takeMutex(); }
|
||||
void gm() { giveMutex(); }
|
||||
};
|
||||
|
||||
extern SPIDog sdog;
|
||||
|
||||
#endif
|
||||
@@ -14,7 +14,7 @@
|
||||
#define MAX_WIDTH DSP_WIDTH-TFT_FRAMEWDT*2
|
||||
|
||||
#if BITRATE_FULL
|
||||
#define TITLE_FIX 24
|
||||
#define TITLE_FIX 28
|
||||
#else
|
||||
#define TITLE_FIX 0
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "displayGC9106.h"
|
||||
#include "fonts/bootlogo40.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#define DEF_SPI_FREQ 24000000 /* 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)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
#if DSP_HSPI
|
||||
DspCore::DspCore(): Adafruit_GC9106Ex(&SPI2, TFT_DC, TFT_CS, TFT_RST) {}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "displayGC9A01A.h"
|
||||
//#include <SPI.h>
|
||||
#include "fonts/bootlogo.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#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)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
#if DSP_HSPI
|
||||
DspCore::DspCore(): Adafruit_GC9A01A(&SPI2, TFT_CS, TFT_DC, TFT_RST) {}
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
#include "displayILI9225.h"
|
||||
#include <SPI.h>
|
||||
#include "fonts/bootlogo.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
#include "../core/spidog.h"
|
||||
|
||||
extern unsigned char yofont5x7[];
|
||||
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)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
DspCore::DspCore(): TFT_22_ILI9225(TFT_RST, TFT_DC, TFT_CS, 0) {}
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#include "displayILI9341.h"
|
||||
#include "fonts/bootlogo.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
|
||||
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
#if DSP_HSPI
|
||||
DspCore::DspCore(): Adafruit_ILI9341(&SPI2, TFT_DC, TFT_CS, TFT_RST) {}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "displayILI9488.h"
|
||||
//#include <SPI.h>
|
||||
#include "fonts/bootlogo.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#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)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
#if DSP_HSPI
|
||||
DspCore::DspCore(): ILI9486_SPI(&SPI2, TFT_CS, TFT_DC, TFT_RST) {}
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
#include "displayN5110.h"
|
||||
#include <Wire.h>
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
#define LOGO_WIDTH 21
|
||||
#define LOGO_HEIGHT 28
|
||||
|
||||
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
|
||||
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
const unsigned char logo [] PROGMEM=
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#if DSP_MODEL==DSP_SSD1305 || DSP_MODEL==DSP_SSD1305I2C
|
||||
|
||||
#include "displaySSD1305.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#define LOGO_WIDTH 21
|
||||
#define LOGO_HEIGHT 32
|
||||
|
||||
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY); digitalWrite(TFT_CS, LOW)
|
||||
#define GIVE_MUTEX() digitalWrite(TFT_CS, HIGH); if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
|
||||
#define TAKE_MUTEX() sdog.takeMutex(); digitalWrite(TFT_CS, LOW)
|
||||
#define GIVE_MUTEX() digitalWrite(TFT_CS, HIGH); sdog.giveMutex()
|
||||
|
||||
#ifndef DEF_SPI_FREQ
|
||||
#define DEF_SPI_FREQ 8000000UL /* set it to 0 for system default */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "displayST7735.h"
|
||||
#include "fonts/bootlogo40.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#define DEF_SPI_FREQ 26000000UL /* 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)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
#if DSP_HSPI
|
||||
DspCore::DspCore(): Adafruit_ST7735(&SPI2, TFT_CS, TFT_DC, TFT_RST) {}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "displayST7789.h"
|
||||
//#include <SPI.h>
|
||||
#include "fonts/bootlogo.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#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)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
#if DSP_HSPI
|
||||
DspCore::DspCore(): Adafruit_ST7789(&SPI2, TFT_CS, TFT_DC, TFT_RST) {}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "displayST7796.h"
|
||||
//#include <SPI.h>
|
||||
#include "fonts/bootlogo.h"
|
||||
#include "../core/player.h"
|
||||
#include "../core/spidog.h"
|
||||
#include "../core/config.h"
|
||||
#include "../core/network.h"
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#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)
|
||||
#define TAKE_MUTEX() sdog.takeMutex()
|
||||
#define GIVE_MUTEX() sdog.giveMutex()
|
||||
|
||||
#if DSP_HSPI
|
||||
DspCore::DspCore(): Adafruit_ST7796S_kbv(&SPI2, TFT_DC, TFT_CS, TFT_RST) {}
|
||||
@@ -102,7 +102,7 @@ void DspCore::_clockSeconds(){
|
||||
|
||||
void DspCore::_clockDate(){
|
||||
if(_olddateleft>0)
|
||||
dsp.fillRect(_olddateleft, clockTop+10, _olddatewidth, CHARHEIGHT, config.theme.background);
|
||||
dsp.fillRect(_olddateleft, clockTop+14, _olddatewidth, CHARHEIGHT*2, config.theme.background);
|
||||
setTextColor(config.theme.date, config.theme.background);
|
||||
setCursor(_dateleft, clockTop+15);
|
||||
setTextSize(2);
|
||||
|
||||
@@ -56,7 +56,7 @@ void setup() {
|
||||
#ifdef MQTT_ROOT_TOPIC
|
||||
mqttInit();
|
||||
#endif
|
||||
if (config.store.play_mode==PM_SDCARD) player.initHeaders(config.station.url);
|
||||
if (config.getMode()==PM_SDCARD) player.initHeaders(config.station.url);
|
||||
player.lockOutput=false;
|
||||
if (config.store.smartstart == 1) player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user