| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- #include "ArchiveStorage.h"
- #include <MeshCore.h>
- #ifndef ARCHIVE_DEBUG
- #if defined(MQTT_DEBUG) && MQTT_DEBUG
- #define ARCHIVE_DEBUG 1
- #else
- #define ARCHIVE_DEBUG 0
- #endif
- #endif
- #if ARCHIVE_DEBUG
- #define ARCHIVE_LOG(fmt, ...) Serial.printf("[ARCHIVE] " fmt "\n", ##__VA_ARGS__)
- #else
- #define ARCHIVE_LOG(...) do { } while (0)
- #endif
- namespace {
- #if defined(ESP32)
- const char* cardTypeName(uint8_t type) {
- switch (type) {
- case CARD_MMC:
- return "mmc";
- case CARD_SD:
- return "sdsc";
- case CARD_SDHC:
- return "sdhc";
- default:
- return "unknown";
- }
- }
- #endif
- } // namespace
- #if defined(ESP32)
- SPIClass* getBoardSharedArchiveSPI() __attribute__((weak));
- #endif
- ArchiveStorage::ArchiveStorage()
- : _attempted(false), _mounted(false), _mount_failed(false), _supported(false), _card_type(0), _spi_bus(HSPI),
- _cs_pin(0xFF), _sck_pin(0xFF),
- _miso_pin(0xFF), _mosi_pin(0xFF), _card_size_bytes(0), _total_bytes(0), _used_bytes(0)
- #if defined(ESP32)
- , _spi(nullptr), _owns_spi(false)
- #endif
- {
- }
- namespace {
- bool mountArchiveSd(SPIClass* spi,
- uint8_t spi_bus,
- uint8_t cs_pin,
- uint8_t sck_pin,
- uint8_t miso_pin,
- uint8_t mosi_pin) {
- if (spi == nullptr) {
- return false;
- }
- #if defined(P_BOARD_IMU_CS)
- pinMode(P_BOARD_IMU_CS, OUTPUT);
- digitalWrite(P_BOARD_IMU_CS, HIGH);
- #endif
- pinMode(cs_pin, OUTPUT);
- digitalWrite(cs_pin, HIGH);
- spi->begin(sck_pin, miso_pin, mosi_pin, cs_pin);
- return SD.begin(cs_pin, *spi, 10000000U);
- }
- } // namespace
- void ArchiveStorage::begin() {
- if (_attempted) {
- return;
- }
- _attempted = true;
- #if defined(ESP32)
- _supported = resolvePins();
- if (!_supported) {
- ARCHIVE_LOG("unsupported: no SD pin mapping");
- return;
- }
- ARCHIVE_LOG("init bus=%u cs=%u sck=%u miso=%u mosi=%u",
- static_cast<unsigned>(_spi_bus),
- static_cast<unsigned>(_cs_pin),
- static_cast<unsigned>(_sck_pin),
- static_cast<unsigned>(_miso_pin),
- static_cast<unsigned>(_mosi_pin));
- _spi = getBoardSharedArchiveSPI();
- _owns_spi = (_spi == nullptr);
- if (_spi == nullptr) {
- _spi = new SPIClass(_spi_bus);
- if (_spi == nullptr) {
- _mount_failed = true;
- ARCHIVE_LOG("mount failed: SPI alloc failed");
- return;
- }
- }
- if (!mountArchiveSd(_spi, _spi_bus, _cs_pin, _sck_pin, _miso_pin, _mosi_pin)) {
- _mount_failed = true;
- ARCHIVE_LOG("mount failed bus=%u cs=%u sck=%u miso=%u mosi=%u",
- static_cast<unsigned>(_spi_bus),
- static_cast<unsigned>(_cs_pin),
- static_cast<unsigned>(_sck_pin),
- static_cast<unsigned>(_miso_pin),
- static_cast<unsigned>(_mosi_pin));
- return;
- }
- _mounted = true;
- if (!SD.exists(getFsStatsPath())) {
- SD.mkdir(getFsStatsPath());
- }
- refreshCardInfo();
- ARCHIVE_LOG("mounted type=%s card=%llu total=%llu used=%llu path=%s",
- getCardTypeName(),
- static_cast<unsigned long long>(_card_size_bytes),
- static_cast<unsigned long long>(_total_bytes),
- static_cast<unsigned long long>(_used_bytes),
- getLogicalStatsPath());
- #else
- _supported = false;
- #endif
- }
- bool ArchiveStorage::recover() {
- #if defined(ESP32)
- if (!_supported || _spi == nullptr) {
- return false;
- }
- ARCHIVE_LOG("recover begin bus=%u cs=%u", static_cast<unsigned>(_spi_bus), static_cast<unsigned>(_cs_pin));
- SD.end();
- if (_owns_spi) {
- _spi->end();
- }
- _mounted = false;
- _mount_failed = false;
- _card_size_bytes = 0;
- _total_bytes = 0;
- _used_bytes = 0;
- if (!mountArchiveSd(_spi, _spi_bus, _cs_pin, _sck_pin, _miso_pin, _mosi_pin)) {
- _mount_failed = true;
- ARCHIVE_LOG("recover failed bus=%u cs=%u", static_cast<unsigned>(_spi_bus), static_cast<unsigned>(_cs_pin));
- return false;
- }
- _mounted = true;
- if (!SD.exists(getFsStatsPath())) {
- SD.mkdir(getFsStatsPath());
- }
- refreshCardInfo();
- ARCHIVE_LOG("recover mounted type=%s card=%llu total=%llu used=%llu path=%s",
- getCardTypeName(),
- static_cast<unsigned long long>(_card_size_bytes),
- static_cast<unsigned long long>(_total_bytes),
- static_cast<unsigned long long>(_used_bytes),
- getLogicalStatsPath());
- return true;
- #else
- return false;
- #endif
- }
- bool ArchiveStorage::isSupported() const {
- return _supported;
- }
- FILESYSTEM* ArchiveStorage::getFS() {
- #if defined(ESP32)
- return _mounted ? &SD : nullptr;
- #else
- return nullptr;
- #endif
- }
- const char* ArchiveStorage::getCardTypeName() const {
- #if defined(ESP32)
- if (!_mounted) {
- return "unavailable";
- }
- return cardTypeName(_card_type);
- #else
- return "unsupported";
- #endif
- }
- #if defined(ESP32)
- bool ArchiveStorage::resolvePins() {
- #if defined(P_BOARD_SPI_SCK) && defined(P_BOARD_SPI_MISO) && defined(P_BOARD_SPI_MOSI) && defined(P_BOARD_SPI_CS)
- _sck_pin = static_cast<uint8_t>(P_BOARD_SPI_SCK);
- _miso_pin = static_cast<uint8_t>(P_BOARD_SPI_MISO);
- _mosi_pin = static_cast<uint8_t>(P_BOARD_SPI_MOSI);
- _cs_pin = static_cast<uint8_t>(P_BOARD_SPI_CS);
- #if defined(TBEAM_SUPREME_SX1262) && defined(FSPI)
- _spi_bus = FSPI;
- #endif
- return true;
- #elif defined(TBEAM_SUPREME_SX1262)
- // T-Beam S3 Supreme SD/IMU shared SPI bus pins.
- _sck_pin = 36;
- _miso_pin = 37;
- _mosi_pin = 35;
- _cs_pin = 47;
- #if defined(FSPI)
- _spi_bus = FSPI;
- #endif
- return true;
- #elif defined(TBEAM_1W)
- // T-Beam 1W microSD shares the board SPI pins but uses its own chip select.
- _sck_pin = 13;
- _miso_pin = 12;
- _mosi_pin = 11;
- _cs_pin = 10;
- #if defined(FSPI)
- _spi_bus = FSPI;
- #endif
- return true;
- #elif defined(HAS_SDCARD) && defined(SDCARD_CS)
- _cs_pin = static_cast<uint8_t>(SDCARD_CS);
- #if defined(SPI_SCK) && defined(SPI_MISO) && defined(SPI_MOSI)
- _sck_pin = static_cast<uint8_t>(SPI_SCK);
- _miso_pin = static_cast<uint8_t>(SPI_MISO);
- _mosi_pin = static_cast<uint8_t>(SPI_MOSI);
- return true;
- #elif defined(P_LORA_SCLK) && defined(P_LORA_MISO) && defined(P_LORA_MOSI)
- _sck_pin = static_cast<uint8_t>(P_LORA_SCLK);
- _miso_pin = static_cast<uint8_t>(P_LORA_MISO);
- _mosi_pin = static_cast<uint8_t>(P_LORA_MOSI);
- return true;
- #endif
- #endif
- return false;
- }
- void ArchiveStorage::refreshCardInfo() {
- if (!_mounted) {
- _card_type = 0;
- _card_size_bytes = 0;
- _total_bytes = 0;
- _used_bytes = 0;
- return;
- }
- if (_card_type == 0) {
- _card_type = SD.cardType();
- }
- _card_size_bytes = SD.cardSize();
- _total_bytes = SD.totalBytes();
- _used_bytes = SD.usedBytes();
- if (_total_bytes == 0) {
- _total_bytes = _card_size_bytes;
- }
- }
- #endif
|