From 7e7792aa51e8f597a67c893bd2db85fb0dcfbf26 Mon Sep 17 00:00:00 2001 From: Woutvstk <119763111+Woutvstk@users.noreply.github.com> Date: Sat, 29 Mar 2025 13:15:21 +0100 Subject: [PATCH] Changed SD library for nrf52 and got S&F working (#6382) - Changed library from deprecated arduino SD library to wrapper of SdFat library - Fixed some bugs in the S&F code for SD card storage Now the S&F functionality works on nrf52 (tested on rak4631 with RAK15002) --- src/FSCommon.cpp | 21 +++++++++++---------- src/modules/Modules.cpp | 2 +- src/modules/StoreForwardModule.cpp | 12 +++++++++--- variants/rak4631/platformio.ini | 2 +- variants/rak4631/variant.h | 6 ++++++ 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp index 818f9fe31..68afebb3d 100644 --- a/src/FSCommon.cpp +++ b/src/FSCommon.cpp @@ -32,8 +32,7 @@ SPIClass SDHandler = SPIClass(VSPI); #ifndef SD_SPI_FREQUENCY #define SD_SPI_FREQUENCY 4000000U #endif -#endif // HAS_SDCARD - +#endif // HAS_SDCARD #if defined(ARCH_STM32WL) @@ -342,9 +341,11 @@ void setupSDCard() #if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) #if (defined(ARCH_ESP32)) SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI); +#elif (defined(ARCH_NRF52)) + SDHandler.begin(); #endif - if (!SD.begin(SDCARD_CS, SDHandlerr, SD_SPI_FREQUENCY)) { // param SDHandler only used for esp32 + if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) { LOG_DEBUG("No SD_MMC card detected"); return; } @@ -353,23 +354,23 @@ void setupSDCard() LOG_DEBUG("No SD_MMC card attached"); return; } - LOG_DEBUG("SD_MMC Card Type: "); if (cardType == CARD_MMC) { - LOG_DEBUG("MMC"); + LOG_DEBUG("SD_MMC Card Type: MMC"); } else if (cardType == CARD_SD) { - LOG_DEBUG("SDSC"); + LOG_DEBUG("SD_MMC Card Type: SDSC"); } else if (cardType == CARD_SDHC) { - LOG_DEBUG("SDHC"); + LOG_DEBUG("SD_MMC Card Type: SDHC"); } else { - LOG_DEBUG("UNKNOWN"); + LOG_DEBUG("SD_MMC Card Type: UNKNOWN"); } uint64_t cardSize = SD.cardSize() / (1024 * 1024); LOG_DEBUG("SD Card Size: %lu MB", (uint32_t)cardSize); LOG_DEBUG("Total space: %lu MB", (uint32_t)(SD.totalBytes() / (1024 * 1024))); -#if (defined(ARCH_ESP32)) // not implemented in arduino sd library + LOG_INFO("Now scanning free clusters on SD card"); + delay(100); // let serial print the above statement properly LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024))); -#endif + #endif #endif } \ No newline at end of file diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 93b8d9826..8a4ac7722 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -219,7 +219,7 @@ void setupModules() paxcounterModule = new PaxcounterModule(); #endif #endif -#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) +#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD) #if !MESHTASTIC_EXCLUDE_STOREFORWARD storeForwardModule = new StoreForwardModule(); #endif diff --git a/src/modules/StoreForwardModule.cpp b/src/modules/StoreForwardModule.cpp index b981f175a..994d08cfc 100644 --- a/src/modules/StoreForwardModule.cpp +++ b/src/modules/StoreForwardModule.cpp @@ -107,6 +107,7 @@ void StoreForwardModule::populateSDCard() } this->storageType = StorageType::ST_SDCARD; uint32_t numberOfPackets = (this->records ? this->records : (((SD.totalBytes() / 3) * 2) / sizeof(PacketHistoryStruct))); + this->records = numberOfPackets; // only allocate space for one temp copy this->packetHistory = (PacketHistoryStruct *)malloc(sizeof(PacketHistoryStruct)); LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets); @@ -174,9 +175,13 @@ uint32_t StoreForwardModule::getNumAvailablePackets(NodeNum dest, uint32_t last_ spiLock->lock(); auto handler = SD.open("/storeforward/" + String(i), FILE_READ); if (handler) { - handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct)); + if (handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct)) != + sizeof(PacketHistoryStruct)) { + LOG_ERROR("SD card reading error"); + } handler.close(); if (this->packetHistory[0].time && (this->packetHistory[0].time > last_time)) { + // Client is only interested in packets not from itself and only in broadcast packets or packets towards it. if (this->packetHistory[0].from != dest && (this->packetHistory[0].to == NODENUM_BROADCAST || this->packetHistory[0].to == dest)) { @@ -191,6 +196,7 @@ uint32_t StoreForwardModule::getNumAvailablePackets(NodeNum dest, uint32_t last_ LOG_ERROR("S&F: Unknown storage type"); } } + return count; } @@ -267,8 +273,8 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp) this->packetHistory[0].payload_size = p.payload.size; memcpy(this->packetHistory[0].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN); spiLock->lock(); - auto handler = SD.open("/storeforward/" + String(this->packetHistoryTotalCount), FILE_WRITE); - handler.write((uint8_t *)&this->packetHistory, sizeof(PacketHistoryStruct)); + auto handler = SD.open("/storeforward/" + String(this->packetHistoryTotalCount), FILE_WRITE, true); + handler.write((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct)); handler.close(); spiLock->unlock(); #endif diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index c423264fe..474de8bed 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -20,7 +20,7 @@ lib_deps = https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2 rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 https://github.com/RAKWireless/RAK12034-BMX160.git#dcead07ffa267d3c906e9ca4a1330ab989e957e2 - https://github.com/Woutvstk/arduino_SD.git#909c2a4a14f5b053bb69958709f0c874aa358c38 ;library to acces SD card + https://github.com/Woutvstk/SdFat_wrapper25.git#6f8f48d56c15cbeac753560dfeede4a487f81f4c ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index ac8130943..67551bfcc 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -138,6 +138,12 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SPI_MISO PIN_SPI1_MISO #define SDCARD_CS (26) +// Some settings for the SdFat library to optimize flash usage +#define SDFAT_FILE_TYPE 1 // only support FAT16/FAT32, not exFAT +#define CHECK_FLASH_PROGRAMMING \ + 0 // this reduces flash usage but may cause higher power usage when sd card is idle TODO:Check if power usage is higher +#define MAINTAIN_FREE_CLUSTER_COUNT 1 // maintain free cluster count + /* * eink display pins */