mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-09-25 22:23:37 +00:00
124 lines
3.1 KiB
C++
124 lines
3.1 KiB
C++
// Copyright (c) 2024 microReticulum contributors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include "SDAccess.h"
|
|
|
|
#ifdef ARDUINO
|
|
|
|
#include <microReticulum/Log.h>
|
|
|
|
using namespace RNS;
|
|
|
|
namespace Hardware {
|
|
namespace TDeck {
|
|
|
|
SemaphoreHandle_t SDAccess::_spi_mutex = nullptr;
|
|
bool SDAccess::_ready = false;
|
|
|
|
bool SDAccess::init(SemaphoreHandle_t mutex) {
|
|
if (_ready) return true;
|
|
if (mutex == nullptr) {
|
|
Serial.println("[SDAccess] ERROR: null mutex");
|
|
return false;
|
|
}
|
|
|
|
_spi_mutex = mutex;
|
|
|
|
// Drive ALL SPI CS lines high to deselect other devices on the bus.
|
|
pinMode(Pin::DISPLAY_CS, OUTPUT);
|
|
digitalWrite(Pin::DISPLAY_CS, HIGH);
|
|
pinMode(Radio::LORA_CS, OUTPUT);
|
|
digitalWrite(Radio::LORA_CS, HIGH);
|
|
pinMode(SDCard::CS, OUTPUT);
|
|
digitalWrite(SDCard::CS, HIGH);
|
|
|
|
// Acquire mutex for SD.begin()
|
|
if (xSemaphoreTake(_spi_mutex, pdMS_TO_TICKS(2000)) != pdTRUE) {
|
|
Serial.println("[SDAccess] Failed to acquire SPI mutex for init");
|
|
return false;
|
|
}
|
|
|
|
// SD card init: use global SPI (FSPI) before Display claims HSPI
|
|
SPI.begin(Pin::DISPLAY_SCK, Radio::SPI_MISO, Pin::DISPLAY_MOSI);
|
|
|
|
// Never format unknown or damaged media. A failed mount is reported and
|
|
// existing card contents remain untouched for explicit recovery.
|
|
bool ok = SD.begin(SDCard::CS, SPI, SD_SPI_FREQ, "/sd", 5, false);
|
|
|
|
xSemaphoreGive(_spi_mutex);
|
|
|
|
if (!ok) {
|
|
Serial.println("[SDAccess] SD card mount failed (no card?)");
|
|
return false;
|
|
}
|
|
|
|
uint8_t cardType = SD.cardType();
|
|
if (cardType == CARD_NONE) {
|
|
Serial.println("[SDAccess] No SD card detected");
|
|
return false;
|
|
}
|
|
|
|
_ready = true;
|
|
|
|
const char* type_str = "UNKNOWN";
|
|
switch (cardType) {
|
|
case CARD_MMC: type_str = "MMC"; break;
|
|
case CARD_SD: type_str = "SD"; break;
|
|
case CARD_SDHC: type_str = "SDHC"; break;
|
|
default: break;
|
|
}
|
|
Serial.printf("[SDAccess] Card type: %s, size: %lluMB\n",
|
|
type_str, SD.cardSize() / (1024 * 1024));
|
|
|
|
return true;
|
|
}
|
|
|
|
int SDAccess::read_file(const char* path, uint8_t* buf, size_t max_len) {
|
|
if (!_ready || !_spi_mutex) return -1;
|
|
|
|
if (xSemaphoreTake(_spi_mutex, pdMS_TO_TICKS(500)) != pdTRUE) {
|
|
return -1;
|
|
}
|
|
|
|
File f = SD.open(path, FILE_READ);
|
|
if (!f) {
|
|
xSemaphoreGive(_spi_mutex);
|
|
return -1;
|
|
}
|
|
|
|
int bytes_read = f.read(buf, max_len);
|
|
f.close();
|
|
|
|
xSemaphoreGive(_spi_mutex);
|
|
return bytes_read;
|
|
}
|
|
|
|
bool SDAccess::file_exists(const char* path) {
|
|
if (!_ready || !_spi_mutex) return false;
|
|
|
|
if (xSemaphoreTake(_spi_mutex, pdMS_TO_TICKS(500)) != pdTRUE) {
|
|
return false;
|
|
}
|
|
|
|
bool exists = SD.exists(path);
|
|
|
|
xSemaphoreGive(_spi_mutex);
|
|
return exists;
|
|
}
|
|
|
|
bool SDAccess::acquire_bus(uint32_t timeout_ms) {
|
|
if (!_spi_mutex) return false;
|
|
return xSemaphoreTake(_spi_mutex, pdMS_TO_TICKS(timeout_ms)) == pdTRUE;
|
|
}
|
|
|
|
void SDAccess::release_bus() {
|
|
if (_spi_mutex) {
|
|
xSemaphoreGive(_spi_mutex);
|
|
}
|
|
}
|
|
|
|
} // namespace TDeck
|
|
} // namespace Hardware
|
|
|
|
#endif // ARDUINO
|