diff --git a/.vscode/settings.json b/.vscode/settings.json index b663fa5da..74ea618b4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,14 @@ "files.associations": { "limits": "c", "type_traits": "c", - "vector": "cpp" + "vector": "cpp", + "array": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "span": "cpp" }, "C_Cpp.dimInactiveRegions": false, "dotnet.defaultSolution": "disable", diff --git a/platformio.ini b/platformio.ini index 216f48e4c..243b13f0e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -296,7 +296,6 @@ extends = common:esp32 board = adafruit_qtpy_esp32 board_build.partitions = default_8MB.csv board_build.filesystem = littlefs -build_type = debug build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32 ; Adafruit QT Py ESP32-C3 @@ -306,6 +305,7 @@ board = adafruit_qtpy_esp32c3 build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32C3 board_build.filesystem = littlefs board_build.partitions = min_spiffs.csv +upload_port = /dev/cu.usbserial-120 ; Adafruit QT Py ESP32-S2 [env:adafruit_qtpy_esp32s2] diff --git a/src/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp index e99c69822..13df118f0 100644 --- a/src/Wippersnapper_V2.cpp +++ b/src/Wippersnapper_V2.cpp @@ -68,9 +68,6 @@ Wippersnapper_V2::Wippersnapper_V2() { // Initialize model classes WsV2.sensorModel = new SensorModel(); - // SD Card - WsV2._sdCardV2 = new ws_sdcard(); - // Initialize controller classes WsV2.digital_io_controller = new DigitalIOController(); WsV2.analogio_controller = new AnalogIOController(); @@ -106,12 +103,18 @@ void Wippersnapper_V2::provisionV2() { // Determine if app is in SDLogger mode #ifdef USE_TINYUSB - _fileSystemV2->GetSDCSPin(); - #else + _fileSystemV2->GetSDCSPin(); + #elif defined(USE_LITTLEFS) _littleFSV2->GetSDCSPin(); #endif - if (WsV2._sdCardV2->InitSDCard()) + WsV2._sdCardV2 = new ws_sdcard(); + if (WsV2._sdCardV2->isSDCardInitialized()) { + haltErrorV2("GOOD: passed sd cspin check", WS_LED_STATUS_KAT); return; + } else { + // We are hitting against this at 4:16pm 12/16/2021 + haltErrorV2("ERROR: failed sd cspin check", WS_LED_STATUS_MQTT_CONNECTING); + } #ifdef USE_DISPLAY // Initialize the display diff --git a/src/Wippersnapper_demo.ino b/src/Wippersnapper_demo.ino index ec0d68458..c4a452aa6 100644 --- a/src/Wippersnapper_demo.ino +++ b/src/Wippersnapper_demo.ino @@ -26,12 +26,11 @@ Wippersnapper_Manager manager; void setup() { // NOTE: Provisioning must occur prior to serial init.h + Serial.begin(115200); + while (!Serial) delay(10); manager.checkAPIVersion(API_PIN); manager.provision(); - Serial.begin(115200); - while (!Serial) delay(10); - Serial.println("Adafruit Wippersnapper API Manager Demo"); Serial.print("Running Wippersnapper API Version: "); Serial.println(manager.getAPIVersion()); diff --git a/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.cpp b/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.cpp index 97684f9da..9144e4a47 100644 --- a/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.cpp +++ b/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.cpp @@ -17,8 +17,7 @@ defined(ARDUINO_ADAFRUIT_ITSYBITSY_ESP32) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2) || \ defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) || \ - defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) || \ - defined(ARDUINO_ESP32_DEV) || \ + defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) || defined(ARDUINO_ESP32_DEV) || \ defined(ESP32_DEV) #include "WipperSnapper_LittleFS_V2.h" @@ -31,8 +30,8 @@ WipperSnapper_LittleFS_V2::WipperSnapper_LittleFS_V2() { // Attempt to initialize filesystem if (!LittleFS.begin()) { - setStatusLEDColor(RED); - fsHalt("ERROR: Failure initializing LittleFS!"); + fsHalt("ERROR: Failure initializing LittleFS!", + WS_LED_STATUS_WAITING_FOR_REG_MSG); } } @@ -145,8 +144,9 @@ void WipperSnapper_LittleFS_V2::parseSecrets() { Error message to print to serial console. */ /**************************************************************************/ -void WipperSnapper_LittleFS_V2::fsHalt(String msg) { - statusLEDSolid(WS_LED_STATUS_FS_WRITE); +void WipperSnapper_LittleFS_V2::fsHalt(String msg, + ws_led_status_t status_state) { + statusLEDSolid(status_state); while (1) { WS_DEBUG_PRINTLN("Fatal Error: Halted execution!"); WS_DEBUG_PRINTLN(msg.c_str()); @@ -167,6 +167,7 @@ void WipperSnapper_LittleFS_V2::GetSDCSPin() { File file_cfg = LittleFS.open("/config.json"); if (!file_cfg) WsV2.pin_sd_cs = 255; + error = deserializeJson(WsV2._config_doc, file_cfg); if (error) { file_cfg.close(); diff --git a/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.h b/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.h index 1557b11a8..cf4ec4458 100644 --- a/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.h +++ b/src/provisioning/littlefs/WipperSnapper_LittleFS_V2.h @@ -16,7 +16,6 @@ #define WIPPERSNAPPER_LITTLEFS_V2_H #include "Wippersnapper_V2.h" -#include #include // forward decl. @@ -32,7 +31,8 @@ class WipperSnapper_LittleFS_V2 { WipperSnapper_LittleFS_V2(); ~WipperSnapper_LittleFS_V2(); void parseSecrets(); - void fsHalt(String msg); + void fsHalt(String msg, + ws_led_status_t status_state = WS_LED_STATUS_ERROR_RUNTIME); void GetSDCSPin(); }; extern Wippersnapper_V2 WsV2; diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index 2717bda45..c6cf93a71 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -19,10 +19,25 @@ @brief Constructs an instance of the Wippersnapper SD card class. */ /**************************************************************************/ -ws_sdcard::ws_sdcard() { +ws_sdcard::ws_sdcard() + : _sd_spi_cfg(WsV2.pin_sd_cs, DEDICATED_SPI, SPI_SD_CLOCK) { is_mode_offline = false; _use_test_data = false; _sz_cur_log_file = 0; + + if (WsV2.pin_sd_cs == PIN_SD_CS_ERROR) + is_mode_offline = false; + + if (!_sd.begin(_sd_spi_cfg)) { + WS_DEBUG_PRINTLN( + "SD initialization failed.\nDo not reformat the card!\nIs the card " + "correctly inserted?\nIs there a wiring/soldering problem\n"); + is_mode_offline = false; + } else { + // Card initialized - calculate file limits + is_mode_offline = true; + calculateFileLimits(); + } } /**************************************************************************/ @@ -37,45 +52,26 @@ ws_sdcard::~ws_sdcard() { } } -/**************************************************************************/ -/*! - @brief Attempts to initialize the SD card and filesystem. - @returns True if the SD card was successfully initialized, False - otherwise. -*/ -/**************************************************************************/ -bool ws_sdcard::InitSDCard() { - is_mode_offline = false; - csd_t csd; - if (WsV2.pin_sd_cs == PIN_SD_CS_ERROR) - return is_mode_offline; - - if (!_sd.begin(WsV2.pin_sd_cs)) { - WS_DEBUG_PRINTLN( - "SD initialization failed.\nDo not reformat the card!\nIs the card " - "correctly inserted?\nIs there a wiring/soldering problem\n"); - return is_mode_offline; - } - +void ws_sdcard::calculateFileLimits() { // Calculate the maximum number of log files that can be stored on the SD card + csd_t csd; if (!_sd.card()->readCSD(&csd)) { WS_DEBUG_PRINTLN("ERROR: Could not read sdcard information"); - return is_mode_offline; + return; } + // get the complete sdcard capacity in bytes _sd_capacity = (uint64_t)512 * csd.capacity(); // account for 3-5% fatfs overhead utilization size_t sd_capacity_usable = _sd_capacity * (1 - 0.05); - // proportionally set sz of each log file to 10% of the SD card's usable capacity + // proportionally set sz of each log file to 10% of the SD card's usable + // capacity _max_sz_log_file = sd_capacity_usable / 10; // Regardless of sd card size, cap log files to 512MB if (_max_sz_log_file > MAX_SZ_LOG_FILE) { _max_sz_log_file = MAX_SZ_LOG_FILE; } _sd_max_num_log_files = sd_capacity_usable / _max_sz_log_file; - - is_mode_offline = true; - return is_mode_offline; } /**************************************************************************/ diff --git a/src/provisioning/sdcard/ws_sdcard.h b/src/provisioning/sdcard/ws_sdcard.h index 1be51f812..f86c1b3ed 100644 --- a/src/provisioning/sdcard/ws_sdcard.h +++ b/src/provisioning/sdcard/ws_sdcard.h @@ -20,9 +20,18 @@ #include "Wippersnapper_V2.h" #include "sdios.h" -#define SD_FAT_TYPE 3 ///< SdFat type (3 = SdFs) +#if defined(ARDUINO_FEATHER_ESP32) || \ + defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2) +#define SPI_SD_CLOCK \ + SD_SCK_MHZ(25) ///< For ESP32/Pico silicon rev 3.0, we clock at 25MHz +#else +#define SPI_SD_CLOCK SD_SCK_MHZ(50) ///< Default SPI clock speed +#endif + +#define SD_FAT_TYPE 3 ///< SD type (3 = FAT16/FAT32 and exFAT) #define PIN_SD_CS_ERROR 255 ///< Error code for invalid SD card CS pin -#define UNKNOWN_VALUE "unknown" ///< Unknown JSON field value +#define UNKNOWN_VALUE "unknown" ///< Default unknown JSON field value #define MAX_SZ_LOG_FILE (512 * 1024 * 1024) ///< Maximum log file size, in Bytes // forward decl. @@ -38,7 +47,8 @@ class ws_sdcard { public: ws_sdcard(); ~ws_sdcard(); - bool InitSDCard(); + void calculateFileLimits(); + bool isSDCardInitialized() { return is_mode_offline; } bool parseConfigFile(); bool CreateNewLogFile(); bool isModeOffline() { return is_mode_offline; } @@ -82,6 +92,7 @@ class ws_sdcard { bool AddSignalMessageToSharedBuffer( wippersnapper_signal_BrokerToDevice &msg_signal); + SdSpiConfig _sd_spi_cfg; ///< SPI configuration for the SD card SdFat _sd; ///< SD object from Adafruit SDFat library size_t _sd_capacity; ///< Capacity of the SD card, in Bytes size_t _sz_cur_log_file; ///< Size of the current log file, in Bytes