This commit is contained in:
e2002
2022-12-13 15:44:00 +03:00
parent 616fc1be01
commit 6c9b2651e3
6 changed files with 128 additions and 6 deletions

View File

@@ -72,6 +72,10 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
//#define ENC_HALFQUARD true /* Experiment with it */ //#define ENC_HALFQUARD true /* Experiment with it */
/******************************************/ /******************************************/
/* SDCARD */
//#define SDC_SPI 18, 19, 23 /* SDCARD SPI pins (SCK, MISO, MOSI) */
//#define SDC_CS 255 /* SDCARD CS pin */
/* ENCODER2 */ /* ENCODER2 */
//#define ENC2_BTNL 255 /* Left rotation */ //#define ENC2_BTNL 255 /* Left rotation */
//#define ENC2_BTNB 255 /* Encoder button */ //#define ENC2_BTNB 255 /* Encoder button */

View File

@@ -1,6 +1,6 @@
#include "config.h" #include "config.h"
#include <EEPROM.h> #include <EEPROM.h>
#include <SPIFFS.h> //#include <SPIFFS.h>
#include "display.h" #include "display.h"
#include "player.h" #include "player.h"
@@ -9,6 +9,7 @@ Config config;
#if DSP_HSPI || TS_HSPI || VS_HSPI #if DSP_HSPI || TS_HSPI || VS_HSPI
SPIClass SPI2(HSPI); SPIClass SPI2(HSPI);
#endif #endif
SPIClass SDSPI(VSPI);
void u8fix(char *src){ void u8fix(char *src){
char last = src[strlen(src)-1]; char last = src[strlen(src)-1];
@@ -22,13 +23,28 @@ void Config::init() {
#endif #endif
eepromRead(EEPROM_START, store); eepromRead(EEPROM_START, store);
if (store.config_set != 4262) setDefaults(); if (store.config_set != 4262) setDefaults();
if(store.play_mode==80) store.play_mode=PM_WEB;
//if (!SPIFFS.begin(false, "/spiffs", 30)) { //if (!SPIFFS.begin(false, "/spiffs", 30)) {
if (!SPIFFS.begin(false)) { if (!SPIFFS.begin(false)) {
return; return;
} }
loadTheme(); loadTheme();
ssidsCount = 0; ssidsCount = 0;
initPlaylist(); if(SDC_CS!=255 && store.play_mode==/*PM_SDCARD*/PM_WEB){
pinMode(SDC_CS, OUTPUT); digitalWrite(SDC_CS, HIGH);
SDSPI.begin(SDC_SPI);
SDSPI.setFrequency(1000000);
if(!SD.begin(SDC_CS)){
store.play_mode=PM_WEB;
Serial.println("##[ERROR]#\tCard Mount Failed");
}else{
initSDPlaylist();
}
}
if(store.play_mode==PM_WEB) initPlaylist();
if (store.lastStation == 0 && store.countStation > 0) { if (store.lastStation == 0 && store.countStation > 0) {
store.lastStation = 1; store.lastStation = 1;
save(); save();
@@ -138,7 +154,7 @@ void Config::setDefaults() {
strlcpy(store.weatherkey,"", 64); strlcpy(store.weatherkey,"", 64);
store.volsteps = 1; store.volsteps = 1;
store.encacc = 200; store.encacc = 200;
store.irto = 80; store.play_mode = 0;
store.irtlp = 35; store.irtlp = 35;
store.btnpullup = true; store.btnpullup = true;
store.btnlongpress = 200; store.btnlongpress = 200;
@@ -268,6 +284,88 @@ 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
p -= slen;
if (p < base) return false;
return (strncmp(p, str, slen) == 0);
}
void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels){
File root = SD.open(dirname);
if(!root){
Serial.println("Failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
uint32_t pos = 0;
while(file){
if(file.isDirectory()){
// Serial.print(" DIR : ");
// Serial.println(file.name());
if(levels){
listSD(plSDfile, plSDindex, file.path(), levels -1);
}
} else {
// Serial.print(" FILE: ");
// Serial.print(file.name());
// Serial.print(" SIZE: ");
// Serial.println(file.size());
if(endsWith(file.name(), ".mp3") || endsWith(file.name(), ".m4a") || endsWith(file.name(), ".aac") || endsWith(file.name(), ".wav") || endsWith(file.name(), ".flac")){
pos = plSDfile.position();
plSDfile.print(file.name()); plSDfile.print("\t"); plSDfile.print(file.path()); plSDfile.print("\t"); plSDfile.println(0);
plSDindex.write((byte *) &pos, 4);
Serial.print(" plSDfile.position:\t");
Serial.println(pos);
}
}
file = root.openNextFile();
}
}
void Config::indexSDPlaylist() {
File playlist = SPIFFS.open(PLAYLIST_SD_PATH, "w");
if (!playlist) {
return;
}
// char sName[BUFLEN], sUrl[BUFLEN];
// int sOvol;
File index = SPIFFS.open(INDEX_SD_PATH, "w");
listSD(playlist, index, "/", 2);
/* while (playlist.available()) {
uint32_t pos = playlist.position();
if (parseCSV(playlist.readStringUntil('\n').c_str(), sName, sUrl, sOvol)) {
index.write((byte *) &pos, 4);
}
}*/
index.close();
playlist.close();
}
void Config::initSDPlaylist() {
store.countStation = 0;
indexSDPlaylist();
if (SPIFFS.exists(INDEX_SD_PATH)) {
File index = SD.open(INDEX_SD_PATH, "r");
store.countStation = index.size() / 4;
index.close();
save();
}
}
void Config::loadStation(uint16_t ls) { void Config::loadStation(uint16_t ls) {
char sName[BUFLEN], sUrl[BUFLEN]; char sName[BUFLEN], sUrl[BUFLEN];
int sOvol; int sOvol;

View File

@@ -3,6 +3,8 @@
#include "Arduino.h" #include "Arduino.h"
#include <Ticker.h> #include <Ticker.h>
#include <SPI.h> #include <SPI.h>
#include <SPIFFS.h>
#include <SD.h>
#include "options.h" #include "options.h"
#define EEPROM_SIZE 768 #define EEPROM_SIZE 768
@@ -15,6 +17,9 @@
#define TMP_PATH "/data/tmpfile.txt" #define TMP_PATH "/data/tmpfile.txt"
#define INDEX_PATH "/data/index.dat" #define INDEX_PATH "/data/index.dat"
#define PLAYLIST_SD_PATH "/data/playlistsd.csv"
#define INDEX_SD_PATH "/data/indexsd.dat"
#ifdef DEBUG_V #ifdef DEBUG_V
#define DBGH() { Serial.printf("[%s:%s:%d] Heap: %d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__, xPortGetFreeHeapSize()); } #define DBGH() { Serial.printf("[%s:%s:%d] Heap: %d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__, xPortGetFreeHeapSize()); }
#define DBGVB( ... ) { char buf[200]; sprintf( buf, __VA_ARGS__ ) ; Serial.print("[DEBUG]\t"); Serial.println(buf); } #define DBGVB( ... ) { char buf[200]; sprintf( buf, __VA_ARGS__ ) ; Serial.print("[DEBUG]\t"); Serial.println(buf); }
@@ -90,7 +95,7 @@ struct config_t
char weatherkey[64]; char weatherkey[64];
uint8_t volsteps; uint8_t volsteps;
uint16_t encacc; uint16_t encacc;
uint8_t irto; uint8_t play_mode; //0 WEB, 1 SD
uint8_t irtlp; uint8_t irtlp;
bool btnpullup; bool btnpullup;
uint16_t btnlongpress; uint16_t btnlongpress;
@@ -169,6 +174,9 @@ class Config {
void setSmartStart(byte ss); void setSmartStart(byte ss);
void initPlaylist(); void initPlaylist();
void indexPlaylist(); void indexPlaylist();
void listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels);
void initSDPlaylist();
void indexSDPlaylist();
void fillPlMenu(char plmenu[][40], int from, byte count, bool removeNum = false); void fillPlMenu(char plmenu[][40], int from, byte count, bool removeNum = false);
void setTimezone(int8_t tzh, int8_t tzm); void setTimezone(int8_t tzh, int8_t tzm);
void setTimezoneOffset(uint16_t tzo); void setTimezoneOffset(uint16_t tzo);

View File

@@ -54,6 +54,8 @@ bool NetServer::begin() {
webserver.on("/", HTTP_ANY, handleHTTPArgs); webserver.on("/", HTTP_ANY, handleHTTPArgs);
webserver.on(PLAYLIST_PATH, HTTP_GET, handleHTTPArgs); webserver.on(PLAYLIST_PATH, HTTP_GET, handleHTTPArgs);
webserver.on(INDEX_PATH, HTTP_GET, handleHTTPArgs); webserver.on(INDEX_PATH, HTTP_GET, handleHTTPArgs);
webserver.on(PLAYLIST_SD_PATH, HTTP_GET, handleHTTPArgs);
webserver.on(INDEX_SD_PATH, HTTP_GET, handleHTTPArgs);
webserver.on(SSIDS_PATH, HTTP_GET, handleHTTPArgs); webserver.on(SSIDS_PATH, HTTP_GET, handleHTTPArgs);
webserver.on("/upload", HTTP_POST, beginUpload, handleUpload); webserver.on("/upload", HTTP_POST, beginUpload, handleUpload);
webserver.on("/update", HTTP_GET, handleHTTPArgs); webserver.on("/update", HTTP_GET, handleHTTPArgs);
@@ -630,7 +632,7 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
void handleHTTPArgs(AsyncWebServerRequest * request) { void handleHTTPArgs(AsyncWebServerRequest * request) {
if (request->method() == HTTP_GET) { if (request->method() == HTTP_GET) {
DBGVB("[%s] client ip=%s request of %s", __func__, request->client()->remoteIP().toString().c_str(), request->url().c_str()); DBGVB("[%s] client ip=%s request of %s", __func__, request->client()->remoteIP().toString().c_str(), request->url().c_str());
if (strcmp(request->url().c_str(), PLAYLIST_PATH) == 0 || strcmp(request->url().c_str(), SSIDS_PATH) == 0 || strcmp(request->url().c_str(), INDEX_PATH) == 0 || strcmp(request->url().c_str(), TMP_PATH) == 0) { if (strcmp(request->url().c_str(), PLAYLIST_PATH) == 0 || strcmp(request->url().c_str(), SSIDS_PATH) == 0 || strcmp(request->url().c_str(), INDEX_PATH) == 0 || strcmp(request->url().c_str(), TMP_PATH) == 0 || strcmp(request->url().c_str(), PLAYLIST_SD_PATH) == 0 || strcmp(request->url().c_str(), INDEX_SD_PATH) == 0) {
#ifdef MQTT_HOST #ifdef MQTT_HOST
if (strcmp(request->url().c_str(), PLAYLIST_PATH) == 0) while (mqttplaylistblock) vTaskDelay(5); if (strcmp(request->url().c_str(), PLAYLIST_PATH) == 0) while (mqttplaylistblock) vTaskDelay(5);
#endif #endif

View File

@@ -1,7 +1,7 @@
#ifndef options_h #ifndef options_h
#define options_h #define options_h
#define YOVERSION "0.8.173" #define YOVERSION "0.9.000"
/******************************************************* /*******************************************************
DO NOT EDIT THIS FILE. DO NOT EDIT THIS FILE.
@@ -114,6 +114,14 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
#define I2S_LRC 25 // WSEL Left Right Clock #define I2S_LRC 25 // WSEL Left Right Clock
#endif #endif
/* SDCARD */
#ifndef SDC_SPI
#define SDC_SPI 18, 19, 23 // SDCARD SPI pins (SCK, MISO, MOSI)
#endif
#ifndef SDC_CS
#define SDC_CS 255 // SDCARD CS pin
#endif
/* ENCODER */ /* ENCODER */
#ifndef ENC_BTNL #ifndef ENC_BTNL
#define ENC_BTNL 255 #define ENC_BTNL 255

View File

@@ -9,6 +9,8 @@
#endif #endif
enum audioMode_e { PLAYING, STOPPED }; enum audioMode_e { PLAYING, STOPPED };
enum playMode_e : uint8_t { PM_WEB=0, PM_SDCARD=1 };
struct audiorequest_t struct audiorequest_t
{ {
uint16_t station; uint16_t station;