Files
yoradio/yoRadio/src/core/sdmanager.cpp
2025-08-26 10:04:12 +03:00

140 lines
3.7 KiB
C++

#include "options.h"
#if SDC_CS!=255
#include <Arduino.h>
#include <SPI.h>
#include <SD.h>
#include "vfs_api.h"
#include "sd_diskio.h"
//#define USE_SD
#include "config.h"
#include "sdmanager.h"
#include "display.h"
#include "player.h"
#if defined(SD_SPIPINS) || SD_HSPI
SPIClass SDSPI(HOOPSENb);
#define SDREALSPI SDSPI
#else
#define SDREALSPI SPI
#endif
#ifndef SDSPISPEED
#define SDSPISPEED 20000000
#endif
SDManager sdman(FSImplPtr(new VFSImpl()));
bool SDManager::start(){
ready = begin(SDC_CS, SDREALSPI, SDSPISPEED);
vTaskDelay(10);
if(!ready) ready = begin(SDC_CS, SDREALSPI, SDSPISPEED);
vTaskDelay(20);
if(!ready) ready = begin(SDC_CS, SDREALSPI, SDSPISPEED);
vTaskDelay(50);
if(!ready) ready = begin(SDC_CS, SDREALSPI, SDSPISPEED);
return ready;
}
void SDManager::stop(){
end();
ready = false;
}
#include "diskio_impl.h"
bool SDManager::cardPresent() {
if(!ready) return false;
if(sectorSize()<1) {
return false;
}
uint8_t buff[sectorSize()] = { 0 };
bool bread = readRAW(buff, 1);
if(sectorSize()>0 && !bread) return false;
return bread;
}
bool SDManager::_checkNoMedia(const char* path){
if (path[strlen(path) - 1] == '/')
snprintf(config.tmpBuf, sizeof(config.tmpBuf), "%s%s", path, ".nomedia");
else
snprintf(config.tmpBuf, sizeof(config.tmpBuf), "%s/%s", path, ".nomedia");
bool nm = exists(config.tmpBuf);
return nm;
}
bool SDManager::_endsWith (const char* base, const char* str) {
int slen = strlen(str) - 1;
const char *p = base + strlen(base) - 1;
while(p > base && isspace(*p)) p--;
p -= slen;
if (p < base) return false;
return (strncmp(p, str, slen) == 0);
}
void SDManager::listSD(File &plSDfile, File &plSDindex, const char* dirname, uint8_t levels) {
File root = sdman.open(dirname);
if (!root) {
Serial.println("##[ERROR]#\tFailed to open directory");
return;
}
if (!root.isDirectory()) {
Serial.println("##[ERROR]#\tNot a directory");
return;
}
uint32_t pos = 0;
char* filePath;
while (true) {
vTaskDelay(2);
player.loop();
bool isDir;
String fileName = root.getNextFileName(&isDir);
if (fileName.isEmpty()) break;
filePath = (char*)malloc(fileName.length() + 1);
if (filePath == NULL) {
Serial.println("Memory allocation failed");
break;
}
strcpy(filePath, fileName.c_str());
const char* fn = strrchr(filePath, '/') + 1;
if (isDir) {
if (levels && !_checkNoMedia(filePath)) {
listSD(plSDfile, plSDindex, filePath, levels - 1);
}
} else {
if (_endsWith(strlwr((char*)fn), ".mp3") || _endsWith(fn, ".m4a") || _endsWith(fn, ".aac") ||
_endsWith(fn, ".wav") || _endsWith(fn, ".flac")) {
pos = plSDfile.position();
plSDfile.printf("%s\t%s\t0\n", fn, filePath);
plSDindex.write((uint8_t*)&pos, 4);
Serial.print(".");
if(display.mode()==SDCHANGE) display.putRequest(SDFILEINDEX, _sdFCount+1);
_sdFCount++;
if (_sdFCount % 64 == 0) Serial.println();
}
}
free(filePath);
}
root.close();
}
void SDManager::indexSDPlaylist() {
_sdFCount = 0;
if(exists(PLAYLIST_SD_PATH)) remove(PLAYLIST_SD_PATH);
if(exists(INDEX_SD_PATH)) remove(INDEX_SD_PATH);
File playlist = open(PLAYLIST_SD_PATH, "w", true);
if (!playlist) {
return;
}
File index = open(INDEX_SD_PATH, "w", true);
listSD(playlist, index, "/", SD_MAX_LEVELS);
index.flush();
index.close();
playlist.flush();
playlist.close();
Serial.println();
delay(50);
}
#endif