From 8908c6e7242aea07aee1b755fc30de8130d56da8 Mon Sep 17 00:00:00 2001 From: Andrejchrcek Date: Fri, 27 Feb 2026 20:14:02 +0100 Subject: [PATCH] Fix WS28xx stability, DDP buffer limit, and LittleFS initial format 1. Change RMT idle level to LOW for proper WS281x reset 2. Increase WS2811 timing T0H from 300ns to 400ns to improve signal stability over long cables 3. Increase OM_MAX_NUM_CHANNELS from 3000 to 4500 to support up to 4500 pixels for DDP 4. Enable auto-formatting in LittleFS initialization to fix boot loop on fresh ESP32 firmware --- include/output/OutputMgr.hpp | 396 ++-- include/output/OutputWS2811.hpp | 115 +- src/FileMgr.cpp | 3882 +++++++++++++++---------------- src/output/OutputWS2811Rmt.cpp | 2 +- 4 files changed, 2145 insertions(+), 2250 deletions(-) diff --git a/include/output/OutputMgr.hpp b/include/output/OutputMgr.hpp index 12ceeca34..d86bd9d4e 100644 --- a/include/output/OutputMgr.hpp +++ b/include/output/OutputMgr.hpp @@ -1,209 +1,231 @@ #pragma once /* -* OutputMgr.hpp - Output Management class -* -* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2026 Shelby Merrick -* http://www.forkineye.com -* -* This program is provided free for you to use in any way that you wish, -* subject to the laws and regulations where you are using it. Due diligence -* is strongly suggested before using this code. Please give credit where due. -* -* The Author makes no warranty of any kind, express or implied, with regard -* to this program or the documentation contained in this document. The -* Author shall not be liable in any event for incidental or consequential -* damages in connection with, or arising out of, the furnishing, performance -* or use of these programs. -* -* This is a factory class used to manage the output port. It creates and deletes -* the output channel functionality as needed to support any new configurations -* that get sent from from the WebPage. -* -*/ + * OutputMgr.hpp - Output Management class + * + * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver + * Copyright (c) 2021, 2026 Shelby Merrick + * http://www.forkineye.com + * + * This program is provided free for you to use in any way that you wish, + * subject to the laws and regulations where you are using it. Due diligence + * is strongly suggested before using this code. Please give credit where due. + * + * The Author makes no warranty of any kind, express or implied, with regard + * to this program or the documentation contained in this document. The + * Author shall not be liable in any event for incidental or consequential + * damages in connection with, or arising out of, the furnishing, performance + * or use of these programs. + * + * This is a factory class used to manage the output port. It creates and + * deletes the output channel functionality as needed to support any new + * configurations that get sent from from the WebPage. + * + */ #include "ESPixelStick.h" +#include "FileMgr.hpp" #include "OutputMgrPortDefs.hpp" #include "memdebug.h" -#include "FileMgr.hpp" #include -class c_OutputCommon; ///< forward declaration to the pure virtual output class that will be defined later. + +class c_OutputCommon; ///< forward declaration to the pure virtual output class + ///< that will be defined later. #ifdef UART_LAST -# define NUM_UARTS UART_LAST +#define NUM_UARTS UART_LAST #else -# define NUM_UARTS 0 +#define NUM_UARTS 0 #endif -class c_OutputMgr -{ +class c_OutputMgr { private: - #ifdef ARDUINO_ARCH_ESP8266 - #define OM_MAX_NUM_CHANNELS (1200 * 3) - #else // ARDUINO_ARCH_ESP32 - #define OM_MAX_NUM_CHANNELS (3000 * 3) - #endif // !def ARDUINO_ARCH_ESP32 +#ifdef ARDUINO_ARCH_ESP8266 +#define OM_MAX_NUM_CHANNELS (1200 * 3) +#else // ARDUINO_ARCH_ESP32 +#define OM_MAX_NUM_CHANNELS (4500 * 3) +#endif // !def ARDUINO_ARCH_ESP32 public: - c_OutputMgr (); - virtual ~c_OutputMgr (); - - void Begin (); ///< set up the operating environment based on the current config (or defaults) - void Poll (); ///< Call from loop(), renders output data - void ScheduleLoadConfig () {ConfigLoadNeeded = now();} - void LoadConfig (); ///< Read the current configuration data from nvram - void GetConfig (byte * Response, uint32_t maxlen); - void GetConfig (String & Response); - void SetConfig (const char * NewConfig); ///< Save the current configuration data to nvram - void SetConfig (ArduinoJson::JsonDocument & NewConfig); ///< Save the current configuration data to nvram - void GetStatus (JsonObject & jsonStatus); -// void GetPortCounts (uint16_t& PixelCount, uint16_t& SerialCount) {PixelCount = uint16_t(OutputPortId_End); SerialCount = uint16_t(NUM_UARTS); } - uint8_t* GetBufferAddress () { return pOutputBuffer; } ///< Get the address of the buffer into which the E1.31 handler will stuff data - uint32_t GetBufferUsedSize () { return UsedBufferSize; } ///< Get the size (in intensities) of the buffer into which the E1.31 handler will stuff data - uint32_t GetBufferSize () { return uint32_t(OM_MAX_NUM_CHANNELS); } ///< Get the size (in intensities) of the buffer into which the E1.31 handler will stuff data - void DeleteConfig () { FileMgr.DeleteFlashFile (ConfigFileName); } - void PauseOutputs (bool NewState); - void GetDriverName (String & Name) { Name = "OutputMgr"; } - void WriteChannelData (uint32_t StartChannelId, uint32_t ChannelCount, uint8_t * pData); - void ReadChannelData (uint32_t StartChannelId, uint32_t ChannelCount, uint8_t *pTargetData); - void ClearBuffer (); - void TaskPoll (); - void RelayUpdate (uint8_t RelayId, String & NewValue, String & Response); - void ClearStatistics (void); - uint8_t GetNumPorts () {return NumOutputPorts;} - - // do NOT insert into the middle of this list. Always add new types to the end of the list - enum e_OutputProtocolType - { - OutputProtocol_Disabled = 0, - - #ifdef SUPPORT_OutputProtocol_WS2811 - OutputProtocol_WS2811 = 1, - #endif // def SUPPORT_OutputProtocol_WS2811 - - #ifdef SUPPORT_OutputProtocol_GECE - OutputProtocol_GECE = 2, - #endif // def SUPPORT_OutputProtocol_GECE - - #ifdef SUPPORT_OutputProtocol_DMX - OutputProtocol_DMX = 3, - #endif // def SUPPORT_OutputProtocol_DMX - - #ifdef SUPPORT_OutputProtocol_Renard - OutputProtocol_Renard = 4, - #endif // def SUPPORT_OutputProtocol_Renard - - #ifdef SUPPORT_OutputProtocol_Serial - OutputProtocol_Serial = 5, - #endif // def SUPPORT_OutputProtocol_Serial - - #ifdef SUPPORT_OutputProtocol_Relay - OutputProtocol_Relay = 6, - #endif // def SUPPORT_OutputProtocol_Relay - - #ifdef SUPPORT_OutputProtocol_Servo_PCA9685 - OutputProtocol_Servo_PCA9685 = 7, - #endif // def SUPPORT_OutputProtocol_Servo_PCA9685 - - #ifdef SUPPORT_OutputProtocol_UCS1903 - OutputProtocol_UCS1903 = 8, - #endif // def SUPPORT_OutputProtocol_UCS1903 - - #ifdef SUPPORT_OutputProtocol_TM1814 - OutputProtocol_TM1814 = 9, - #endif // def SUPPORT_OutputProtocol_TM1814 - - #ifdef SUPPORT_OutputProtocol_WS2801 - OutputProtocol_WS2801 = 10, - #endif // def SUPPORT_OutputProtocol_WS2801 - - #ifdef SUPPORT_OutputProtocol_APA102 - OutputProtocol_APA102 = 11, - #endif // def SUPPORT_OutputProtocol_APA102 - - #ifdef SUPPORT_OutputProtocol_GS8208 - OutputProtocol_GS8208 = 12, - #endif // def SUPPORT_OutputProtocol_GS8208 - - #ifdef SUPPORT_OutputProtocol_UCS8903 - OutputProtocol_UCS8903 = 13, - #endif // def SUPPORT_OutputProtocol_UCS8903 - - #ifdef SUPPORT_OutputProtocol_TLS3001 - OutputType_TLS3001 = 14, - #endif // def SUPPORT_OutputProtocol_TLS3001 - - #ifdef SUPPORT_OutputProtocol_GRINCH - OutputProtocol_GRINCH = 15, - #endif // def SUPPORT_OutputProtocol_GRINCH - - #ifdef SUPPORT_OutputProtocol_FireGod - OutputProtocol_FireGod = 16, - #endif // def SUPPORT_OutputProtocol_FireGod - - // Add new types here - }; - uint32_t OutputType_End = uint32_t(-1); - - // must be 16 byte aligned. Determined by upshifting the max size of all drivers - #define OutputDriverMemorySize 1200 - uint32_t GetDriverSize() {return OutputDriverMemorySize;} + c_OutputMgr(); + virtual ~c_OutputMgr(); + + void Begin(); ///< set up the operating environment based on the current + ///< config (or defaults) + void Poll(); ///< Call from loop(), renders output data + void ScheduleLoadConfig() { ConfigLoadNeeded = now(); } + void LoadConfig(); ///< Read the current configuration data from nvram + void GetConfig(byte *Response, uint32_t maxlen); + void GetConfig(String &Response); + void SetConfig( + const char *NewConfig); ///< Save the current configuration data to nvram + void + SetConfig(ArduinoJson::JsonDocument + &NewConfig); ///< Save the current configuration data to nvram + void GetStatus(JsonObject &jsonStatus); + // void GetPortCounts (uint16_t& PixelCount, uint16_t& + // SerialCount) {PixelCount = uint16_t(OutputPortId_End); SerialCount = + // uint16_t(NUM_UARTS); } + uint8_t *GetBufferAddress() { + return pOutputBuffer; + } ///< Get the address of the buffer into which the E1.31 handler will stuff + ///< data + uint32_t GetBufferUsedSize() { + return UsedBufferSize; + } ///< Get the size (in intensities) of the buffer into which the E1.31 + ///< handler will stuff data + uint32_t GetBufferSize() { + return uint32_t(OM_MAX_NUM_CHANNELS); + } ///< Get the size (in intensities) of the buffer into which the E1.31 + ///< handler will stuff data + void DeleteConfig() { FileMgr.DeleteFlashFile(ConfigFileName); } + void PauseOutputs(bool NewState); + void GetDriverName(String &Name) { Name = "OutputMgr"; } + void WriteChannelData(uint32_t StartChannelId, uint32_t ChannelCount, + uint8_t *pData); + void ReadChannelData(uint32_t StartChannelId, uint32_t ChannelCount, + uint8_t *pTargetData); + void ClearBuffer(); + void TaskPoll(); + void RelayUpdate(uint8_t RelayId, String &NewValue, String &Response); + void ClearStatistics(void); + uint8_t GetNumPorts() { return NumOutputPorts; } + + // do NOT insert into the middle of this list. Always add new types to the end + // of the list + enum e_OutputProtocolType { + OutputProtocol_Disabled = 0, + +#ifdef SUPPORT_OutputProtocol_WS2811 + OutputProtocol_WS2811 = 1, +#endif // def SUPPORT_OutputProtocol_WS2811 + +#ifdef SUPPORT_OutputProtocol_GECE + OutputProtocol_GECE = 2, +#endif // def SUPPORT_OutputProtocol_GECE + +#ifdef SUPPORT_OutputProtocol_DMX + OutputProtocol_DMX = 3, +#endif // def SUPPORT_OutputProtocol_DMX + +#ifdef SUPPORT_OutputProtocol_Renard + OutputProtocol_Renard = 4, +#endif // def SUPPORT_OutputProtocol_Renard + +#ifdef SUPPORT_OutputProtocol_Serial + OutputProtocol_Serial = 5, +#endif // def SUPPORT_OutputProtocol_Serial + +#ifdef SUPPORT_OutputProtocol_Relay + OutputProtocol_Relay = 6, +#endif // def SUPPORT_OutputProtocol_Relay + +#ifdef SUPPORT_OutputProtocol_Servo_PCA9685 + OutputProtocol_Servo_PCA9685 = 7, +#endif // def SUPPORT_OutputProtocol_Servo_PCA9685 + +#ifdef SUPPORT_OutputProtocol_UCS1903 + OutputProtocol_UCS1903 = 8, +#endif // def SUPPORT_OutputProtocol_UCS1903 + +#ifdef SUPPORT_OutputProtocol_TM1814 + OutputProtocol_TM1814 = 9, +#endif // def SUPPORT_OutputProtocol_TM1814 + +#ifdef SUPPORT_OutputProtocol_WS2801 + OutputProtocol_WS2801 = 10, +#endif // def SUPPORT_OutputProtocol_WS2801 + +#ifdef SUPPORT_OutputProtocol_APA102 + OutputProtocol_APA102 = 11, +#endif // def SUPPORT_OutputProtocol_APA102 + +#ifdef SUPPORT_OutputProtocol_GS8208 + OutputProtocol_GS8208 = 12, +#endif // def SUPPORT_OutputProtocol_GS8208 + +#ifdef SUPPORT_OutputProtocol_UCS8903 + OutputProtocol_UCS8903 = 13, +#endif // def SUPPORT_OutputProtocol_UCS8903 + +#ifdef SUPPORT_OutputProtocol_TLS3001 + OutputType_TLS3001 = 14, +#endif // def SUPPORT_OutputProtocol_TLS3001 + +#ifdef SUPPORT_OutputProtocol_GRINCH + OutputProtocol_GRINCH = 15, +#endif // def SUPPORT_OutputProtocol_GRINCH + +#ifdef SUPPORT_OutputProtocol_FireGod + OutputProtocol_FireGod = 16, +#endif // def SUPPORT_OutputProtocol_FireGod + + // Add new types here + }; + uint32_t OutputType_End = uint32_t(-1); + +// must be 16 byte aligned. Determined by upshifting the max size of all drivers +#define OutputDriverMemorySize 1200 + uint32_t GetDriverSize() { return OutputDriverMemorySize; } + private: - struct alignas(16) DriverInfo_t - { - byte OutputDriver[OutputDriverMemorySize]; - uint32_t OutputBufferStartingOffset = 0; - uint32_t OutputBufferDataSize = 0; - uint32_t OutputBufferEndOffset = 0; - - uint32_t OutputChannelStartingOffset = 0; - uint32_t OutputChannelSize = 0; - uint32_t OutputChannelEndOffset = 0; - - OM_OutputPortDefinition_t PortDefinition; - uint8_t DriverId = -1; - bool OutputDriverInUse = false; - }; - - // pointer(s) to the current active output drivers - DriverInfo_t *pOutputChannelDrivers = nullptr; - uint8_t NumOutputPorts = 0; - uint32_t SizeOfTable = 0; - - // configuration parameter names for the channel manager within the config file - #define NO_CONFIG_NEEDED time_t(-1) - bool HasBeenInitialized = false; - time_t ConfigLoadNeeded = NO_CONFIG_NEEDED; - bool ConfigInProgress = false; - bool OutputIsPaused = false; - bool BuildingNewConfig = false; - - bool ProcessJsonConfig (JsonDocument & jsonConfig); - void CreateJsonConfig (JsonObject & jsonConfig); - void UpdateDisplayBufferReferences (void); - void InstantiateNewOutputChannel(DriverInfo_t &ChannelIndex, e_OutputProtocolType NewChannelType, bool StartDriver = true); - void CreateNewConfig(); - void SetSerialUart(); - bool FindJsonChannelConfig (JsonDocument& jsonConfig, OM_PortId_t PortId, e_OutputProtocolType Type, JsonObject& ChanConfig); - bool SetPortDefnitionDefaults(DriverInfo_t & CurrentOutput, e_OutputProtocolType TargetProtocolType); - - String ConfigFileName; - - uint8_t *pOutputBuffer = nullptr; - uint32_t UsedBufferSize = 0; - - #ifndef DEFAULT_CONSOLE_TX_GPIO - #define DEFAULT_CONSOLE_TX_GPIO gpio_num_t::GPIO_NUM_1 - #define DEFAULT_CONSOLE_RX_GPIO gpio_num_t::GPIO_NUM_3 - #endif // ndef DEFAULT_CONSOLE_TX_GPIO - - gpio_num_t ConsoleTxGpio = DEFAULT_CONSOLE_TX_GPIO; - gpio_num_t ConsoleRxGpio = DEFAULT_CONSOLE_RX_GPIO; + struct alignas(16) DriverInfo_t { + byte OutputDriver[OutputDriverMemorySize]; + uint32_t OutputBufferStartingOffset = 0; + uint32_t OutputBufferDataSize = 0; + uint32_t OutputBufferEndOffset = 0; + + uint32_t OutputChannelStartingOffset = 0; + uint32_t OutputChannelSize = 0; + uint32_t OutputChannelEndOffset = 0; + + OM_OutputPortDefinition_t PortDefinition; + uint8_t DriverId = -1; + bool OutputDriverInUse = false; + }; + + // pointer(s) to the current active output drivers + DriverInfo_t *pOutputChannelDrivers = nullptr; + uint8_t NumOutputPorts = 0; + uint32_t SizeOfTable = 0; + +// configuration parameter names for the channel manager within the config file +#define NO_CONFIG_NEEDED time_t(-1) + bool HasBeenInitialized = false; + time_t ConfigLoadNeeded = NO_CONFIG_NEEDED; + bool ConfigInProgress = false; + bool OutputIsPaused = false; + bool BuildingNewConfig = false; + + bool ProcessJsonConfig(JsonDocument &jsonConfig); + void CreateJsonConfig(JsonObject &jsonConfig); + void UpdateDisplayBufferReferences(void); + void InstantiateNewOutputChannel(DriverInfo_t &ChannelIndex, + e_OutputProtocolType NewChannelType, + bool StartDriver = true); + void CreateNewConfig(); + void SetSerialUart(); + bool FindJsonChannelConfig(JsonDocument &jsonConfig, OM_PortId_t PortId, + e_OutputProtocolType Type, JsonObject &ChanConfig); + bool SetPortDefnitionDefaults(DriverInfo_t &CurrentOutput, + e_OutputProtocolType TargetProtocolType); + + String ConfigFileName; + + uint8_t *pOutputBuffer = nullptr; + uint32_t UsedBufferSize = 0; + +#ifndef DEFAULT_CONSOLE_TX_GPIO +#define DEFAULT_CONSOLE_TX_GPIO gpio_num_t::GPIO_NUM_1 +#define DEFAULT_CONSOLE_RX_GPIO gpio_num_t::GPIO_NUM_3 +#endif // ndef DEFAULT_CONSOLE_TX_GPIO + + gpio_num_t ConsoleTxGpio = DEFAULT_CONSOLE_TX_GPIO; + gpio_num_t ConsoleRxGpio = DEFAULT_CONSOLE_RX_GPIO; #if defined(ARDUINO_ARCH_ESP32) - TaskHandle_t myTaskHandle = NULL; - // uint32_t PollCount = 0; + TaskHandle_t myTaskHandle = NULL; + // uint32_t PollCount = 0; #endif // defined(ARDUINO_ARCH_ESP32) }; // c_OutputMgr diff --git a/include/output/OutputWS2811.hpp b/include/output/OutputWS2811.hpp index 1abb46898..fe4564d06 100644 --- a/include/output/OutputWS2811.hpp +++ b/include/output/OutputWS2811.hpp @@ -1,74 +1,83 @@ #pragma once /* -* OutputWS2811.h - WS2811 driver code for ESPixelStick -* -* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2024 Shelby Merrick -* http://www.forkineye.com -* -* This program is provided free for you to use in any way that you wish, -* subject to the laws and regulations where you are using it. Due diligence -* is strongly suggested before using this code. Please give credit where due. -* -* The Author makes no warranty of any kind, express or implied, with regard -* to this program or the documentation contained in this document. The -* Author shall not be liable in any event for incidental or consequential -* damages in connection with, or arising out of, the furnishing, performance -* or use of these programs. -* -* This is a derived class that converts data in the output buffer into -* pixel intensities and then transmits them through the configured serial -* interface. -* -*/ + * OutputWS2811.h - WS2811 driver code for ESPixelStick + * + * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver + * Copyright (c) 2015, 2024 Shelby Merrick + * http://www.forkineye.com + * + * This program is provided free for you to use in any way that you wish, + * subject to the laws and regulations where you are using it. Due diligence + * is strongly suggested before using this code. Please give credit where due. + * + * The Author makes no warranty of any kind, express or implied, with regard + * to this program or the documentation contained in this document. The + * Author shall not be liable in any event for incidental or consequential + * damages in connection with, or arising out of, the furnishing, performance + * or use of these programs. + * + * This is a derived class that converts data in the output buffer into + * pixel intensities and then transmits them through the configured serial + * interface. + * + */ #include "OutputPixel.hpp" #if defined(SUPPORT_OutputProtocol_WS2811) #ifdef ARDUINO_ARCH_ESP32 -# include +#include #endif -class c_OutputWS2811 : public c_OutputPixel -{ +class c_OutputWS2811 : public c_OutputPixel { public: - // These functions are inherited from c_OutputCommon - c_OutputWS2811 (OM_OutputPortDefinition_t & OutputPortDefinition, - c_OutputMgr::e_OutputProtocolType outputType); - virtual ~c_OutputWS2811 (); + // These functions are inherited from c_OutputCommon + c_OutputWS2811(OM_OutputPortDefinition_t &OutputPortDefinition, + c_OutputMgr::e_OutputProtocolType outputType); + virtual ~c_OutputWS2811(); - // functions to be provided by the derived class - virtual void Begin (); - virtual bool SetConfig (ArduinoJson::JsonObject & jsonConfig); ///< Set a new config in the driver - virtual void GetConfig (ArduinoJson::JsonObject & jsonConfig); ///< Get the current config used by the driver - virtual void GetStatus (ArduinoJson::JsonObject & jsonStatus); - void GetDriverName (String & sDriverName) { sDriverName = CN_WS2811; } + // functions to be provided by the derived class + virtual void Begin(); + virtual bool SetConfig( + ArduinoJson::JsonObject &jsonConfig); ///< Set a new config in the driver + virtual void + GetConfig(ArduinoJson::JsonObject + &jsonConfig); ///< Get the current config used by the driver + virtual void GetStatus(ArduinoJson::JsonObject &jsonStatus); + void GetDriverName(String &sDriverName) { sDriverName = CN_WS2811; } protected: - -#define WS2811_PIXEL_DATA_RATE 800000.0 // 800Khz -#define WS2811_PIXEL_NS_BIT_TOTAL ( (1.0 / WS2811_PIXEL_DATA_RATE) * NanoSecondsInASecond) +#define WS2811_PIXEL_DATA_RATE 800000.0 // 800Khz +#define WS2811_PIXEL_NS_BIT_TOTAL \ + ((1.0 / WS2811_PIXEL_DATA_RATE) * NanoSecondsInASecond) #ifdef ARDUINO_ARCH_ESP32 - // values have been adjusted to work with seed pixels. -// #define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // = 312 on logic analyzer 220ns - 380ns per datasheet -// #define WS2811_PIXEL_NS_BIT_0_LOW 945.0 // = 937 on logic analyzer 580ns - 1.6us per datasheet -// #define WS2811_PIXEL_NS_BIT_1_HIGH 975.0 // = 937 on logic analyzer 580ns - 1.6us per datasheet -// #define WS2811_PIXEL_NS_BIT_1_LOW 300.0 // = 312 on logic analyzer 220ns - 380ns per datasheet - #define WS2811_PIXEL_NS_BIT_0_HIGH 300.0 // 220ns - 380ns per datasheet - #define WS2811_PIXEL_NS_BIT_0_LOW (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH) - #define WS2811_PIXEL_NS_BIT_1_HIGH WS2811_PIXEL_NS_BIT_0_LOW - #define WS2811_PIXEL_NS_BIT_1_LOW WS2811_PIXEL_NS_BIT_0_HIGH + // values have been adjusted to work with seed pixels. + // #define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // = 312 on logic analyzer + // 220ns - 380ns per datasheet #define WS2811_PIXEL_NS_BIT_0_LOW 945.0 // = + // 937 on logic analyzer 580ns - 1.6us per datasheet #define + // WS2811_PIXEL_NS_BIT_1_HIGH 975.0 // = 937 on logic analyzer 580ns + // - 1.6us per datasheet #define WS2811_PIXEL_NS_BIT_1_LOW 300.0 // = + // 312 on logic analyzer 220ns - 380ns per datasheet +#define WS2811_PIXEL_NS_BIT_0_HIGH \ + 400.0 // 220ns - 380ns per datasheet (increased for stability) +#define WS2811_PIXEL_NS_BIT_0_LOW \ + (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH) +#define WS2811_PIXEL_NS_BIT_1_HIGH WS2811_PIXEL_NS_BIT_0_LOW +#define WS2811_PIXEL_NS_BIT_1_LOW WS2811_PIXEL_NS_BIT_0_HIGH #else - #define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // 220ns - 380ns per datasheet - #define WS2811_PIXEL_NS_BIT_0_LOW (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH) - #define WS2811_PIXEL_NS_BIT_1_HIGH 975.0 // 580ns - 1.6us per datasheet - #define WS2811_PIXEL_NS_BIT_1_LOW (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_1_HIGH) +#define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // 220ns - 380ns per datasheet +#define WS2811_PIXEL_NS_BIT_0_LOW \ + (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH) +#define WS2811_PIXEL_NS_BIT_1_HIGH 975.0 // 580ns - 1.6us per datasheet +#define WS2811_PIXEL_NS_BIT_1_LOW \ + (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_1_HIGH) #endif // ARDUINO_ARCH_ESP32 -#define WS2811_PIXEL_IDLE_TIME_US 350.0 // 350us per datasheet -#define WS2811_PIXEL_IDLE_TIME_NS WS2811_PIXEL_IDLE_TIME_US * NanoSecondsInAMicroSecond +#define WS2811_PIXEL_IDLE_TIME_US 350.0 // 350us per datasheet +#define WS2811_PIXEL_IDLE_TIME_NS \ + WS2811_PIXEL_IDLE_TIME_US *NanoSecondsInAMicroSecond -#define WS2811_PIXEL_BITS_PER_INTENSITY 8 +#define WS2811_PIXEL_BITS_PER_INTENSITY 8 }; // c_OutputWS2811 diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp index 3d31a1a54..fb96dd12e 100644 --- a/src/FileMgr.cpp +++ b/src/FileMgr.cpp @@ -1,31 +1,32 @@ /* -* FileMgr.cpp - Output Management class -* -* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2025 Shelby Merrick -* http://www.forkineye.com -* -* This program is provided free for you to use in any way that you wish, -* subject to the laws and regulations where you are using it. Due diligence -* is strongly suggested before using this code. Please give credit where due. -* -* The Author makes no warranty of any kind, express or implied, with regard -* to this program or the documentation contained in this document. The -* Author shall not be liable in any event for incidental or consequential -* damages in connection with, or arising out of, the furnishing, performance -* or use of these programs. -* -*/ + * FileMgr.cpp - Output Management class + * + * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver + * Copyright (c) 2021, 2025 Shelby Merrick + * http://www.forkineye.com + * + * This program is provided free for you to use in any way that you wish, + * subject to the laws and regulations where you are using it. Due diligence + * is strongly suggested before using this code. Please give credit where due. + * + * The Author makes no warranty of any kind, express or implied, with regard + * to this program or the documentation contained in this document. The + * Author shall not be liable in any event for incidental or consequential + * damages in connection with, or arising out of, the furnishing, performance + * or use of these programs. + * + */ #include "ESPixelStick.h" #include #include #include "FileMgr.hpp" +#include "UnzipFiles.hpp" +#include "input/InputMgr.hpp" #include "network/NetworkMgr.hpp" #include "output/OutputMgr.hpp" -#include "input/InputMgr.hpp" -#include "UnzipFiles.hpp" + SdFs sd; const int8_t DISABLE_CS_PIN = -1; @@ -34,97 +35,88 @@ const int8_t DISABLE_CS_PIN = -1; #define SD_CONFIG SdioConfig(FIFO_SDIO) #elif ENABLE_DEDICATED_SPI #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(16)) -#else // HAS_SDIO_CLASS +#else // HAS_SDIO_CLASS #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SD_SCK_MHZ(16)) -#endif // HAS_SDIO_CLASS +#endif // HAS_SDIO_CLASS #ifdef SIMULATE_SD -char XlateFileMode[3] = { CN_r[0], CN_w[0], CN_w[0] }; +char XlateFileMode[3] = {CN_r[0], CN_w[0], CN_w[0]}; #else -oflag_t XlateFileMode[3] = { O_READ , O_WRITE | O_CREAT, O_WRITE | O_APPEND }; +oflag_t XlateFileMode[3] = {O_READ, O_WRITE | O_CREAT, O_WRITE | O_APPEND}; #endif // def SIMULATE_SD #ifdef SUPPORT_FTP #include -FtpServer ftpSrv; +FtpServer ftpSrv; //----------------------------------------------------------------------------- -void ftp_callback(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace) -{ - FeedWDT(); - switch (ftpOperation) - { - case FTP_CONNECT: - { - InputMgr.SetOperationalState(false); - LOG_PORT.println(F("FTP: Connected!")); - break; - } - - case FTP_DISCONNECT: - { - InputMgr.SetOperationalState(true); - LOG_PORT.println(F("FTP: Disconnected!")); - break; - } - - case FTP_FREE_SPACE_CHANGE: - { - FileMgr.BuildFseqList(false); - LOG_PORT.printf("FTP: Free space change, free %u of %u! Rebuilding FSEQ file list\n", freeSpace, totalSpace); - break; - } - - default: - { - LOG_PORT.println(F("FTP: unknown callback!")); - break; - } - } +void ftp_callback(FtpOperation ftpOperation, unsigned int freeSpace, + unsigned int totalSpace) { + FeedWDT(); + switch (ftpOperation) { + case FTP_CONNECT: { + InputMgr.SetOperationalState(false); + LOG_PORT.println(F("FTP: Connected!")); + break; + } + + case FTP_DISCONNECT: { + InputMgr.SetOperationalState(true); + LOG_PORT.println(F("FTP: Disconnected!")); + break; + } + + case FTP_FREE_SPACE_CHANGE: { + FileMgr.BuildFseqList(false); + LOG_PORT.printf( + "FTP: Free space change, free %u of %u! Rebuilding FSEQ file list\n", + freeSpace, totalSpace); + break; + } + + default: { + LOG_PORT.println(F("FTP: unknown callback!")); + break; + } + } }; //----------------------------------------------------------------------------- -void ftp_transferCallback(FtpTransferOperation ftpOperation, const char* name, unsigned int transferredSize) -{ - FeedWDT(); - switch (ftpOperation) - { - case FTP_UPLOAD_START: - { - LOG_PORT.println(String(F("FTP: Start Uploading '")) + name + "'"); - // size_t free = heap_caps_get_largest_free_block(0x1800); - // LOG_PORT.printf("heap: 0x%x\n", free); - break; - } - - case FTP_UPLOAD: - { - // LOG_PORT.printf("FTP: Upload of file %s byte %u\n", name, transferredSize); - // size_t free = heap_caps_get_largest_free_block(0x1800); - // LOG_PORT.printf("heap: 0x%x\n", free); - break; - } - - case FTP_TRANSFER_STOP: - { - LOG_PORT.println(String(F("FTP: Done Uploading '")) + name + "'"); - // size_t free = heap_caps_get_largest_free_block(0x1800); - // LOG_PORT.printf("heap: 0x%x\n", free); - break; - } - - case FTP_TRANSFER_ERROR: - { - LOG_PORT.println(String(F("FTP: Error Uploading '")) + name + "'"); - break; - } - - default: - { - LOG_PORT.println(F("FTP: Unknown Transfer Callback!")); - break; - } - } +void ftp_transferCallback(FtpTransferOperation ftpOperation, const char *name, + unsigned int transferredSize) { + FeedWDT(); + switch (ftpOperation) { + case FTP_UPLOAD_START: { + LOG_PORT.println(String(F("FTP: Start Uploading '")) + name + "'"); + // size_t free = heap_caps_get_largest_free_block(0x1800); + // LOG_PORT.printf("heap: 0x%x\n", free); + break; + } + + case FTP_UPLOAD: { + // LOG_PORT.printf("FTP: Upload of file %s byte %u\n", name, + // transferredSize); size_t free = heap_caps_get_largest_free_block(0x1800); + // LOG_PORT.printf("heap: 0x%x\n", free); + break; + } + + case FTP_TRANSFER_STOP: { + LOG_PORT.println(String(F("FTP: Done Uploading '")) + name + "'"); + // size_t free = heap_caps_get_largest_free_block(0x1800); + // LOG_PORT.printf("heap: 0x%x\n", free); + break; + } + + case FTP_TRANSFER_ERROR: { + LOG_PORT.println(String(F("FTP: Error Uploading '")) + name + "'"); + break; + } + + default: { + LOG_PORT.println(F("FTP: Unknown Transfer Callback!")); + break; + } + } /* FTP_UPLOAD_START = 0, * FTP_UPLOAD = 1, @@ -145,472 +137,442 @@ void ftp_transferCallback(FtpTransferOperation ftpOperation, const char* name, u //----------------------------------------------------------------------------- ///< Start up the driver and put it into a safe mode -c_FileMgr::c_FileMgr () -{ +c_FileMgr::c_FileMgr() { #ifdef ARDUINO_ARCH_ESP32 - SdAccessSemaphore = xSemaphoreCreateBinary(); - UnLockSd(); + SdAccessSemaphore = xSemaphoreCreateBinary(); + UnLockSd(); #endif // def ARDUINO_ARCH_ESP32 - fsUploadFileName.reserve(256); - InitSdFileList (); + fsUploadFileName.reserve(256); + InitSdFileList(); } // c_FileMgr //----------------------------------------------------------------------------- ///< deallocate any resources and put the output channels into a safe state -c_FileMgr::~c_FileMgr () -{ - // DEBUG_START; +c_FileMgr::~c_FileMgr() { + // DEBUG_START; - // DEBUG_END; + // DEBUG_END; } // ~c_FileMgr //----------------------------------------------------------------------------- ///< Start the module -void c_FileMgr::Begin () -{ - // DEBUG_START; +void c_FileMgr::Begin() { + // DEBUG_START; - do // once - { - if (!LittleFS.begin ()) - { - String msg = String(CN_stars) + F (" Flash file system did not initialize correctly ") + CN_stars; - RequestReboot(msg, 1000, true); - break; - } + do // once + { +#ifdef ARDUINO_ARCH_ESP32 + if (!LittleFS.begin(true)) +#else + if (!LittleFS.begin()) +#endif + { + String msg = String(CN_stars) + + F(" Flash file system did not initialize correctly ") + + CN_stars; + RequestReboot(msg, 1000, true); + break; + } - #ifdef ARDUINO_ARCH_ESP32 - logcon (String (F ("Flash file system initialized. Used = ")) + String (LittleFS.usedBytes ()) + String (F (" out of ")) + String (LittleFS.totalBytes()) ); - #else - logcon (String (F ("Flash file system initialized."))); - #endif // def ARDUINO_ARCH_ESP32 +#ifdef ARDUINO_ARCH_ESP32 + logcon(String(F("Flash file system initialized. Used = ")) + + String(LittleFS.usedBytes()) + String(F(" out of ")) + + String(LittleFS.totalBytes())); +#else + logcon(String(F("Flash file system initialized."))); +#endif // def ARDUINO_ARCH_ESP32 - listDir (LittleFS, String ("/"), 3); + listDir(LittleFS, String("/"), 3); - // StartSdCard(); + // StartSdCard(); - } while (false); + } while (false); - // DEBUG_END; + // DEBUG_END; } // begin //----------------------------------------------------------------------------- -void c_FileMgr::StartSdCard () -{ - // DEBUG_START; - - SetSpiIoPins (); - #ifdef SUPPORT_UNZIP - // DEBUG_V(String("FoundZipFile: ") + String(FoundZipFile)) - if(FoundZipFile) - { - // DEBUG_V("Start Unzipping"); - FeedWDT(); - UnzipFiles * Unzipper = new UnzipFiles(); - Unzipper->Run(); - delete Unzipper; - String Reason = F("Requesting reboot after unzipping files"); - RequestReboot(Reason, 1, true); - } - #endif // def SUPPORT_UNZIP - - // DEBUG_END; +void c_FileMgr::StartSdCard() { + // DEBUG_START; + + SetSpiIoPins(); +#ifdef SUPPORT_UNZIP + // DEBUG_V(String("FoundZipFile: ") + String(FoundZipFile)) + if (FoundZipFile) { + // DEBUG_V("Start Unzipping"); + FeedWDT(); + UnzipFiles *Unzipper = new UnzipFiles(); + Unzipper->Run(); + delete Unzipper; + String Reason = F("Requesting reboot after unzipping files"); + RequestReboot(Reason, 1, true); + } +#endif // def SUPPORT_UNZIP + + // DEBUG_END; } // StartSdCard //----------------------------------------------------------------------------- // Cause the FTP operation to get re-established. -void c_FileMgr::UpdateFtp() -{ - // DEBUG_START; +void c_FileMgr::UpdateFtp() { + // DEBUG_START; - NetworkStateChanged(NetworkMgr.IsConnected()); + NetworkStateChanged(NetworkMgr.IsConnected()); - // DEBUG_END; + // DEBUG_END; } // UpdateFtp //----------------------------------------------------------------------------- -void c_FileMgr::NetworkStateChanged (bool NewState) -{ - // DEBUG_START; +void c_FileMgr::NetworkStateChanged(bool NewState) { + // DEBUG_START; #ifdef SUPPORT_FTP - // DEBUG_V("Disable FTP"); - ftpSrv.end(); - - // DEBUG_V(String(" NewState: ") + String(NewState)); - // DEBUG_V(String("SdCardInstalled: ") + String(SdCardInstalled)); - // DEBUG_V(String(" FtpEnabled: ") + String(FtpEnabled)); - if(NewState && SdCardInstalled && FtpEnabled) - { - logcon("Starting FTP server."); - ftpSrv.setCallback(ftp_callback); - ftpSrv.setTransferCallback(ftp_transferCallback); - ftpSrv.begin(FtpUserName, FtpPassword, WelcomeString); - } - else - { - // DEBUG_V("Not starting FTP service"); - } + // DEBUG_V("Disable FTP"); + ftpSrv.end(); + + // DEBUG_V(String(" NewState: ") + String(NewState)); + // DEBUG_V(String("SdCardInstalled: ") + String(SdCardInstalled)); + // DEBUG_V(String(" FtpEnabled: ") + String(FtpEnabled)); + if (NewState && SdCardInstalled && FtpEnabled) { + logcon("Starting FTP server."); + ftpSrv.setCallback(ftp_callback); + ftpSrv.setTransferCallback(ftp_transferCallback); + ftpSrv.begin(FtpUserName, FtpPassword, WelcomeString); + } else { + // DEBUG_V("Not starting FTP service"); + } #endif // def SUPPORT_FTP - // DEBUG_END; + // DEBUG_END; } // NetworkStateChanged //----------------------------------------------------------------------------- -void c_FileMgr::Poll() - { - // xDEBUG_START; +void c_FileMgr::Poll() { + // xDEBUG_START; #ifdef SUPPORT_FTP - if(FtpEnabled) - { - FeedWDT(); - ftpSrv.handleFTP(); - } + if (FtpEnabled) { + FeedWDT(); + ftpSrv.handleFTP(); + } #endif // def SUPPORT_FTP - // xDEBUG_END; - } // Poll + // xDEBUG_END; +} // Poll //----------------------------------------------------------------------------- -bool c_FileMgr::SetConfig (JsonObject & json) -{ - // DEBUG_START; - - bool ConfigChanged = false; - bool SpiConfigChanged = false; - JsonObject JsonDeviceConfig = json[(char*)CN_device].as(); - if (JsonDeviceConfig) - { - // PrettyPrint (JsonDeviceConfig, "c_FileMgr"); - - // DEBUG_V("miso_pin: " + String(miso_pin)); - // DEBUG_V("mosi_pin: " + String(mosi_pin)); - // DEBUG_V(" clk_pin: " + String(clk_pin)); - // DEBUG_V(" cs_pin: " + String(cs_pin)); - // DEBUG_V(" Speed: " + String(MaxSdSpeed)); - - SpiConfigChanged |= setFromJSON (miso_pin, JsonDeviceConfig, CN_miso_pin); - SpiConfigChanged |= setFromJSON (mosi_pin, JsonDeviceConfig, CN_mosi_pin); - SpiConfigChanged |= setFromJSON (clk_pin, JsonDeviceConfig, CN_clock_pin); - SpiConfigChanged |= setFromJSON (cs_pin, JsonDeviceConfig, CN_cs_pin); - SpiConfigChanged |= setFromJSON (MaxSdSpeed, JsonDeviceConfig, CN_sdspeed); - - ConfigChanged |= setFromJSON (FtpUserName, JsonDeviceConfig, CN_user); - ConfigChanged |= setFromJSON (FtpPassword, JsonDeviceConfig, CN_password); - ConfigChanged |= setFromJSON (FtpEnabled, JsonDeviceConfig, CN_enabled); - - #ifdef DEFAULT_SD_POWER_PIN - ConfigChanged |= setFromJSON (sd_pwr_pin, JsonDeviceConfig, CN_sd_pwr_pin); - ConfigChanged |= setFromJSON (sd_pwr_on, JsonDeviceConfig, CN_sd_pwr_on); - ConfigChanged |= setFromJSON (sd_pwr_dly, JsonDeviceConfig, CN_sd_pwr_dly); - #endif // def DEFAULT_SD_POWER_PIN - - // DEBUG_V("miso_pin: " + String(miso_pin)); - // DEBUG_V("mosi_pin: " + String(mosi_pin)); - // DEBUG_V(" clk_pin: " + String(clk_pin)); - // DEBUG_V(" cs_pin: " + String(cs_pin)); - // DEBUG_V(" Speed: " + String(MaxSdSpeed)); - - // DEBUG_V("ConfigChanged: " + String(ConfigChanged)); - } - else - { - logcon (F ("No File Manager settings found.")); - } +bool c_FileMgr::SetConfig(JsonObject &json) { + // DEBUG_START; + + bool ConfigChanged = false; + bool SpiConfigChanged = false; + JsonObject JsonDeviceConfig = json[(char *)CN_device].as(); + if (JsonDeviceConfig) { + // PrettyPrint (JsonDeviceConfig, "c_FileMgr"); + + // DEBUG_V("miso_pin: " + String(miso_pin)); + // DEBUG_V("mosi_pin: " + String(mosi_pin)); + // DEBUG_V(" clk_pin: " + String(clk_pin)); + // DEBUG_V(" cs_pin: " + String(cs_pin)); + // DEBUG_V(" Speed: " + String(MaxSdSpeed)); + + SpiConfigChanged |= setFromJSON(miso_pin, JsonDeviceConfig, CN_miso_pin); + SpiConfigChanged |= setFromJSON(mosi_pin, JsonDeviceConfig, CN_mosi_pin); + SpiConfigChanged |= setFromJSON(clk_pin, JsonDeviceConfig, CN_clock_pin); + SpiConfigChanged |= setFromJSON(cs_pin, JsonDeviceConfig, CN_cs_pin); + SpiConfigChanged |= setFromJSON(MaxSdSpeed, JsonDeviceConfig, CN_sdspeed); + + ConfigChanged |= setFromJSON(FtpUserName, JsonDeviceConfig, CN_user); + ConfigChanged |= setFromJSON(FtpPassword, JsonDeviceConfig, CN_password); + ConfigChanged |= setFromJSON(FtpEnabled, JsonDeviceConfig, CN_enabled); - // DEBUG_V (String ("ConfigChanged: ") + String (ConfigChanged)); - // DEBUG_V (String ("SpiConfigChanged: ") + String (SpiConfigChanged)); +#ifdef DEFAULT_SD_POWER_PIN + ConfigChanged |= setFromJSON(sd_pwr_pin, JsonDeviceConfig, CN_sd_pwr_pin); + ConfigChanged |= setFromJSON(sd_pwr_on, JsonDeviceConfig, CN_sd_pwr_on); + ConfigChanged |= setFromJSON(sd_pwr_dly, JsonDeviceConfig, CN_sd_pwr_dly); +#endif // def DEFAULT_SD_POWER_PIN - if(IsBooting) - { - // DEBUG_V("We are booting"); - StartSdCard (); - SpiConfigChanged = false; - } + // DEBUG_V("miso_pin: " + String(miso_pin)); + // DEBUG_V("mosi_pin: " + String(mosi_pin)); + // DEBUG_V(" clk_pin: " + String(clk_pin)); + // DEBUG_V(" cs_pin: " + String(cs_pin)); + // DEBUG_V(" Speed: " + String(MaxSdSpeed)); - else if (SpiConfigChanged) - { - String msg = "SD Card gpio change requires reboot"; - RequestReboot(msg,1000); - } + // DEBUG_V("ConfigChanged: " + String(ConfigChanged)); + } else { + logcon(F("No File Manager settings found.")); + } - if (ConfigChanged) - { - NetworkStateChanged(NetworkMgr.IsConnected()); - } + // DEBUG_V (String ("ConfigChanged: ") + String (ConfigChanged)); + // DEBUG_V (String ("SpiConfigChanged: ") + String (SpiConfigChanged)); - // DEBUG_END; + if (IsBooting) { + // DEBUG_V("We are booting"); + StartSdCard(); + SpiConfigChanged = false; + } - return ConfigChanged || SpiConfigChanged; + else if (SpiConfigChanged) { + String msg = "SD Card gpio change requires reboot"; + RequestReboot(msg, 1000); + } + + if (ConfigChanged) { + NetworkStateChanged(NetworkMgr.IsConnected()); + } + + // DEBUG_END; + + return ConfigChanged || SpiConfigChanged; } // SetConfig //----------------------------------------------------------------------------- -void c_FileMgr::GetConfig (JsonObject& json) -{ - // DEBUG_START; +void c_FileMgr::GetConfig(JsonObject &json) { + // DEBUG_START; - JsonWrite(json, CN_miso_pin, miso_pin); - JsonWrite(json, CN_mosi_pin, mosi_pin); - JsonWrite(json, CN_clock_pin, clk_pin); - JsonWrite(json, CN_cs_pin, cs_pin); - JsonWrite(json, CN_sdspeed, MaxSdSpeed); + JsonWrite(json, CN_miso_pin, miso_pin); + JsonWrite(json, CN_mosi_pin, mosi_pin); + JsonWrite(json, CN_clock_pin, clk_pin); + JsonWrite(json, CN_cs_pin, cs_pin); + JsonWrite(json, CN_sdspeed, MaxSdSpeed); - JsonWrite(json, CN_user, FtpUserName); - JsonWrite(json, CN_password, FtpPassword); - JsonWrite(json, CN_enabled, FtpEnabled); + JsonWrite(json, CN_user, FtpUserName); + JsonWrite(json, CN_password, FtpPassword); + JsonWrite(json, CN_enabled, FtpEnabled); - #ifdef DEFAULT_SD_POWER_PIN - JsonWrite(json, CN_sd_pwr_pin, sd_pwr_pin); - JsonWrite(json, CN_sd_pwr_on, sd_pwr_on); - JsonWrite(json, CN_sd_pwr_dly, sd_pwr_dly); - #endif // def DEFAULT_SD_POWER_PIN +#ifdef DEFAULT_SD_POWER_PIN + JsonWrite(json, CN_sd_pwr_pin, sd_pwr_pin); + JsonWrite(json, CN_sd_pwr_on, sd_pwr_on); + JsonWrite(json, CN_sd_pwr_dly, sd_pwr_dly); +#endif // def DEFAULT_SD_POWER_PIN - // DEBUG_END; + // DEBUG_END; } // GetConfig //----------------------------------------------------------------------------- -void c_FileMgr::GetStatus (JsonObject& json) -{ - // DEBUG_START; +void c_FileMgr::GetStatus(JsonObject &json) { + // DEBUG_START; #ifdef ARDUINO_ARCH_ESP32 - json[F ("size")] = LittleFS.totalBytes (); - json[F ("used")] = LittleFS.usedBytes (); + json[F("size")] = LittleFS.totalBytes(); + json[F("used")] = LittleFS.usedBytes(); #endif // def ARDUINO_ARCH_ESP32 - // DEBUG_END; + // DEBUG_END; } // GetConfig //------------------------------------------------------------------------------ // Call back for file timestamps. Only called for file create and sync(). -void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10) -{ - // LOG_PORT.println("DateTime Start"); - - tmElements_t tm; - breakTime(now(), tm); - - // LOG_PORT.println(String("time_t:") + String(now())); - // LOG_PORT.println(String("Year Raw:") + String(tm.Year)); - // LOG_PORT.println(String("Year Adj:") + String(tm.Year + 1970)); - // LOG_PORT.println(String("Month:") + String(tm.Month)); - // LOG_PORT.println(String("Day:") + String(tm.Day)); - - // Return date using FS_DATE macro to format fields. - *date = FS_DATE(tm.Year+1970, tm.Month, tm.Day); - // LOG_PORT.println(String("date:") + String(*date)); - - // Return time using FS_TIME macro to format fields. - *time = FS_TIME(tm.Hour, tm.Minute, tm.Second); - // LOG_PORT.println(String("time:") + String(*time)); - - // Return low time bits in units of 10 ms, 0 <= ms10 <= 199. - *ms10 = 0; - // LOG_PORT.println("DateTime End"); +void dateTime(uint16_t *date, uint16_t *time, uint8_t *ms10) { + // LOG_PORT.println("DateTime Start"); + + tmElements_t tm; + breakTime(now(), tm); + + // LOG_PORT.println(String("time_t:") + String(now())); + // LOG_PORT.println(String("Year Raw:") + String(tm.Year)); + // LOG_PORT.println(String("Year Adj:") + String(tm.Year + 1970)); + // LOG_PORT.println(String("Month:") + String(tm.Month)); + // LOG_PORT.println(String("Day:") + String(tm.Day)); + + // Return date using FS_DATE macro to format fields. + *date = FS_DATE(tm.Year + 1970, tm.Month, tm.Day); + // LOG_PORT.println(String("date:") + String(*date)); + + // Return time using FS_TIME macro to format fields. + *time = FS_TIME(tm.Hour, tm.Minute, tm.Second); + // LOG_PORT.println(String("time:") + String(*time)); + + // Return low time bits in units of 10 ms, 0 <= ms10 <= 199. + *ms10 = 0; + // LOG_PORT.println("DateTime End"); } //----------------------------------------------------------------------------- -void c_FileMgr::SetSpiIoPins () -{ - // DEBUG_START; +void c_FileMgr::SetSpiIoPins() { + // DEBUG_START; #if defined ARDUINO_ARCH_ESP8266 - ESP.wdtDisable(); + ESP.wdtDisable(); #endif // def ARDUINO_ARCH_ESP8266 -#if defined (SIMULATE_SD) - if(!ESP_SDFS.exists(CN_slashsd)) - { - ESP_SDFS.mkdir(CN_slashsd); - } +#if defined(SIMULATE_SD) + if (!ESP_SDFS.exists(CN_slashsd)) { + ESP_SDFS.mkdir(CN_slashsd); + } - SdCardInstalled = true; - SetSdSpeed(); - BuildFseqList(true); + SdCardInstalled = true; + SetSdSpeed(); + BuildFseqList(true); -#elif defined (SUPPORT_SD) || defined(SUPPORT_SD_MMC) - if (SdCardInstalled) - { - // DEBUG_V("Terminate current SD session"); - ESP_SD.end (); - } - #ifdef DEFAULT_SD_POWER_PIN - PowerCycleSdCard(); - #endif // def DEFAULT_SD_POWER_PIN +#elif defined(SUPPORT_SD) || defined(SUPPORT_SD_MMC) + if (SdCardInstalled) { + // DEBUG_V("Terminate current SD session"); + ESP_SD.end(); + } +#ifdef DEFAULT_SD_POWER_PIN + PowerCycleSdCard(); +#endif // def DEFAULT_SD_POWER_PIN - FsDateTime::setCallback(dateTime); + FsDateTime::setCallback(dateTime); #ifdef ARDUINO_ARCH_ESP32 - // DEBUG_V(); - try + // DEBUG_V(); + try #endif // def ARDUINO_ARCH_ESP32 - { + { #ifdef SIMULATE_SD -#elif defined (SUPPORT_SD_MMC) - // DEBUG_V (String (" Data 0: ") + String (SD_CARD_DATA_0)); - // DEBUG_V (String (" Data 1: ") + String (SD_CARD_DATA_1)); - // DEBUG_V (String (" Data 2: ") + String (SD_CARD_DATA_2)); - // DEBUG_V (String (" Data 3: ") + String (SD_CARD_DATA_3)); - - pinMode(SD_CARD_DATA_0, PULLUP); - pinMode(SD_CARD_DATA_1, PULLUP); - pinMode(SD_CARD_DATA_2, PULLUP); - pinMode(SD_CARD_DATA_3, PULLUP); - - if(!ESP_SD.begin()) +#elif defined(SUPPORT_SD_MMC) + // DEBUG_V (String (" Data 0: ") + String (SD_CARD_DATA_0)); + // DEBUG_V (String (" Data 1: ") + String (SD_CARD_DATA_1)); + // DEBUG_V (String (" Data 2: ") + String (SD_CARD_DATA_2)); + // DEBUG_V (String (" Data 3: ") + String (SD_CARD_DATA_3)); + + pinMode(SD_CARD_DATA_0, PULLUP); + pinMode(SD_CARD_DATA_1, PULLUP); + pinMode(SD_CARD_DATA_2, PULLUP); + pinMode(SD_CARD_DATA_3, PULLUP); + + if (!ESP_SD.begin()) #else // ifndef SUPPORT_SD_MMC -# ifdef ARDUINO_ARCH_ESP32 - // DEBUG_V (String ("miso_pin: ") + String (miso_pin)); - // DEBUG_V (String ("mosi_pin: ") + String (mosi_pin)); - // DEBUG_V (String (" clk_pin: ") + String (clk_pin)); - // DEBUG_V (String (" cs_pin: ") + String (cs_pin)); - - // DEBUG_V(); - SPI.end (); - // DEBUG_V(); - pinMode(cs_pin, OUTPUT); - // DEBUG_V(); -# ifdef USE_MISO_PULLUP - // DEBUG_V("USE_MISO_PULLUP"); - // on some hardware MISO is missing a required pull-up resistor, use internal pull-up. - ResetGpio(gpio_num_t(mosi_pin)); - pinMode(miso_pin, INPUT_PULLUP); -# else - // DEBUG_V(); - pinMode(miso_pin, INPUT); - // DEBUG_V(); -# endif // def USE_MISO_PULLUP - // DEBUG_V(); - SPI.begin (clk_pin, miso_pin, mosi_pin, cs_pin); // uses HSPI by default -# else // ESP8266 - SPI.end (); - SPI.begin (); -# endif // ! ARDUINO_ARCH_ESP32 - // DEBUG_V(); - if (!ESP_SD.begin (SdSpiConfig(cs_pin, SHARED_SPI, SD_SCK_MHZ(16)))) -#endif // !def SUPPORT_SD_MMC - { - // DEBUG_V(); - // logcon(String(F("No SD card installed"))); - SdCardInstalled = false; - // DEBUG_V(); - if(nullptr == ESP_SD.card()) - { - logcon(F("SD 'Card' setup failed.")); - } - else if (ESP_SD.card()->errorCode()) - { - logcon(String(F("SD Card Error: initialization failed - code: ")) + String(ESP_SD.card()->errorCode())); - // DEBUG_V(String(F("SD Card initialization failed - data: ")) + String(ESP_SD.card()->errorData())); - // printSdErrorText(&LOG_PORT, ESP_SD.card()->errorCode()); LOG_PORT.println(""); - } - else if (ESP_SD.vol()->fatType() == 0) - { - logcon(F("SD Card Error: Can't find a valid FAT16/FAT32 partition.")); - } - else - { - logcon(F("SD Card Error: Can't determine SD Card error type")); - } - } - else - { - // DEBUG_V("SdCardInstalled = true"); - SdCardInstalled = true; - // DEBUG_V(); - SetSdSpeed (); +#ifdef ARDUINO_ARCH_ESP32 + // DEBUG_V (String ("miso_pin: ") + String (miso_pin)); + // DEBUG_V (String ("mosi_pin: ") + String (mosi_pin)); + // DEBUG_V (String (" clk_pin: ") + String (clk_pin)); + // DEBUG_V (String (" cs_pin: ") + String (cs_pin)); - // DEBUG_V(String("SdCardSize: ") + int64String(SdCardSize)); + // DEBUG_V(); + SPI.end(); + // DEBUG_V(); + pinMode(cs_pin, OUTPUT); + // DEBUG_V(); +#ifdef USE_MISO_PULLUP + // DEBUG_V("USE_MISO_PULLUP"); + // on some hardware MISO is missing a required pull-up resistor, use + // internal pull-up. + ResetGpio(gpio_num_t(mosi_pin)); + pinMode(miso_pin, INPUT_PULLUP); +#else + // DEBUG_V(); + pinMode(miso_pin, INPUT); + // DEBUG_V(); +#endif // def USE_MISO_PULLUP + // DEBUG_V(); + SPI.begin(clk_pin, miso_pin, mosi_pin, cs_pin); // uses HSPI by default +#else // ESP8266 + SPI.end(); + SPI.begin(); +#endif // ! ARDUINO_ARCH_ESP32 + // DEBUG_V(); + if (!ESP_SD.begin(SdSpiConfig(cs_pin, SHARED_SPI, SD_SCK_MHZ(16)))) +#endif // !def SUPPORT_SD_MMC + { + // DEBUG_V(); + // logcon(String(F("No SD card installed"))); + SdCardInstalled = false; + // DEBUG_V(); + if (nullptr == ESP_SD.card()) { + logcon(F("SD 'Card' setup failed.")); + } else if (ESP_SD.card()->errorCode()) { + logcon(String(F("SD Card Error: initialization failed - code: ")) + + String(ESP_SD.card()->errorCode())); + // DEBUG_V(String(F("SD Card initialization failed - data: ")) + + // String(ESP_SD.card()->errorData())); printSdErrorText(&LOG_PORT, + // ESP_SD.card()->errorCode()); LOG_PORT.println(""); + } else if (ESP_SD.vol()->fatType() == 0) { + logcon(F("SD Card Error: Can't find a valid FAT16/FAT32 partition.")); + } else { + logcon(F("SD Card Error: Can't determine SD Card error type")); + } + } + else { + // DEBUG_V("SdCardInstalled = true"); + SdCardInstalled = true; + // DEBUG_V(); + SetSdSpeed(); - DescribeSdCardToUser (); - // DEBUG_V(); - } + // DEBUG_V(String("SdCardSize: ") + int64String(SdCardSize)); - // DEBUG_V(); - BuildFseqList(true); - // DEBUG_V(); + DescribeSdCardToUser(); + // DEBUG_V(); } + + // DEBUG_V(); + BuildFseqList(true); + // DEBUG_V(); + } #ifdef ARDUINO_ARCH_ESP32 - catch (const std::exception &e) - { - logcon (String (F ("ERROR: Could not init the SD Card: "))+ e.what()); - SdCardInstalled = false; - } + catch (const std::exception &e) { + logcon(String(F("ERROR: Could not init the SD Card: ")) + e.what()); + SdCardInstalled = false; + } #endif // def ARDUINO_ARCH_ESP32 - // SdFile::dateTimeCallback(dateTime); + // SdFile::dateTimeCallback(dateTime); -#else // no sd defined - SdCardInstalled = false; +#else // no sd defined + SdCardInstalled = false; #endif // defined (SUPPORT_SD) || defined(SUPPORT_SD_MMC) #ifdef ARDUINO_ARCH_ESP8266 - ESP.wdtEnable(uint32_t(0)); + ESP.wdtEnable(uint32_t(0)); #endif // def ARDUINO_ARCH_ESP8266 - // DEBUG_END; + // DEBUG_END; } // SetSpiIoPins //----------------------------------------------------------------------------- -void c_FileMgr::SetSdSpeed () -{ - // DEBUG_START; +void c_FileMgr::SetSdSpeed() { + // DEBUG_START; #ifdef SIMULATE_SD - SdCardSize = ESP_SD.totalBytes(); -#elif defined (SUPPORT_SD) || defined(SUPPORT_SD_MMC) - if (SdCardInstalled) - { - // DEBUG_V(); - csd_t csd; - uint8_t tran_speed = 0; - - CSD MyCsd; - // DEBUG_V(); - ESP_SD.card()->readCSD(&csd); - memcpy (&MyCsd, &csd.csd[0], sizeof(csd.csd)); - // DEBUG_V(String("TRAN Speed: 0x") + String(MyCsd.Decode_0.tran_speed,HEX)); - tran_speed = MyCsd.Decode_0.tran_speed; - uint32_t FinalTranSpeedMHz = MaxSdSpeed; - - switch(tran_speed) - { - case 0x32: - { - FinalTranSpeedMHz = 25; - break; - } - case 0x5A: - { - FinalTranSpeedMHz = 50; - break; - } - case 0x0B: - { - FinalTranSpeedMHz = 100; - break; - } - case 0x2B: - { - FinalTranSpeedMHz = 200; - break; - } - default: - { - FinalTranSpeedMHz = 25; - } - } - // DEBUG_V(); - FinalTranSpeedMHz = min(FinalTranSpeedMHz, MaxSdSpeed); - SPI.setFrequency(FinalTranSpeedMHz * 1024 * 1024); - logcon(String("Set SD speed to ") + String(FinalTranSpeedMHz) + "Mhz"); + SdCardSize = ESP_SD.totalBytes(); +#elif defined(SUPPORT_SD) || defined(SUPPORT_SD_MMC) + if (SdCardInstalled) { + // DEBUG_V(); + csd_t csd; + uint8_t tran_speed = 0; - SdCardSize =1024 *1024 * 0.000512 * csd.capacity(); - // DEBUG_V(String("SdCardSize: ") + int64String(SdCardSize)); + CSD MyCsd; + // DEBUG_V(); + ESP_SD.card()->readCSD(&csd); + memcpy(&MyCsd, &csd.csd[0], sizeof(csd.csd)); + // DEBUG_V(String("TRAN Speed: 0x") + + // String(MyCsd.Decode_0.tran_speed,HEX)); + tran_speed = MyCsd.Decode_0.tran_speed; + uint32_t FinalTranSpeedMHz = MaxSdSpeed; + + switch (tran_speed) { + case 0x32: { + FinalTranSpeedMHz = 25; + break; + } + case 0x5A: { + FinalTranSpeedMHz = 50; + break; + } + case 0x0B: { + FinalTranSpeedMHz = 100; + break; + } + case 0x2B: { + FinalTranSpeedMHz = 200; + break; } + default: { + FinalTranSpeedMHz = 25; + } + } + // DEBUG_V(); + FinalTranSpeedMHz = min(FinalTranSpeedMHz, MaxSdSpeed); + SPI.setFrequency(FinalTranSpeedMHz * 1024 * 1024); + logcon(String("Set SD speed to ") + String(FinalTranSpeedMHz) + "Mhz"); + + SdCardSize = 1024 * 1024 * 0.000512 * csd.capacity(); + // DEBUG_V(String("SdCardSize: ") + int64String(SdCardSize)); + } #endif // defined (SUPPORT_SD) || defined(SUPPORT_SD_MMC) - // DEBUG_END; + // DEBUG_END; } // SetSdSpeed @@ -620,1074 +582,1015 @@ void c_FileMgr::SetSdSpeed () to appear to not be installed. A power cycle fixes the issue. Clocking the bus also causes any incomplete transaction to get cleared. */ -void c_FileMgr::ResetSdCard() -{ - // DEBUG_START; +void c_FileMgr::ResetSdCard() { + // DEBUG_START; #ifndef SIMULATE_SD - // send 0xff bytes until we get 0xff back - byte ResetValue = 0x00; - digitalWrite(cs_pin, LOW); - SPI.beginTransaction(SPISettings()); - // DEBUG_V(); - uint32_t retry = 2000; - while((0xff != ResetValue) && (--retry)) - { - delay(1); - ResetValue = SPI.transfer(0xff); - } - SPI.endTransaction(); - digitalWrite(cs_pin, HIGH); + // send 0xff bytes until we get 0xff back + byte ResetValue = 0x00; + digitalWrite(cs_pin, LOW); + SPI.beginTransaction(SPISettings()); + // DEBUG_V(); + uint32_t retry = 2000; + while ((0xff != ResetValue) && (--retry)) { + delay(1); + ResetValue = SPI.transfer(0xff); + } + SPI.endTransaction(); + digitalWrite(cs_pin, HIGH); #endif // ndef SIMULATE_SD - // DEBUG_END; + // DEBUG_END; } // ResetSdCard //----------------------------------------------------------------------------- -void c_FileMgr::DeleteFlashFile (String FileName) -{ - // DEBUG_START; +void c_FileMgr::DeleteFlashFile(String FileName) { + // DEBUG_START; - ConnrectFilename(FileName); + ConnrectFilename(FileName); - if(LittleFS.exists(FileName)) { LittleFS.remove (FileName); } + if (LittleFS.exists(FileName)) { + LittleFS.remove(FileName); + } - if(!FileName.equals(CN_fseqfilelist)) - { - BuildFseqList(false); - } + if (!FileName.equals(CN_fseqfilelist)) { + BuildFseqList(false); + } - // DEBUG_END; + // DEBUG_END; } // DeleteConfigFile //----------------------------------------------------------------------------- -void c_FileMgr::RenameFlashFile (String OldName, String NewName) -{ - // DEBUG_START; +void c_FileMgr::RenameFlashFile(String OldName, String NewName) { + // DEBUG_START; - ConnrectFilename(OldName); - ConnrectFilename(NewName); + ConnrectFilename(OldName); + ConnrectFilename(NewName); - // DEBUG_V(String("OldName: ") + OldName); - // DEBUG_V(String("NewName: ") + NewName); + // DEBUG_V(String("OldName: ") + OldName); + // DEBUG_V(String("NewName: ") + NewName); - DeleteFlashFile(NewName); - if(!LittleFS.rename(OldName, NewName)) - { - logcon(String(CN_stars) + F("Could not rename '") + OldName + F("' to '") + NewName + F("'") + CN_stars); - } + DeleteFlashFile(NewName); + if (!LittleFS.rename(OldName, NewName)) { + logcon(String(CN_stars) + F("Could not rename '") + OldName + F("' to '") + + NewName + F("'") + CN_stars); + } - // DEBUG_END; + // DEBUG_END; } // RenameFlashFile //----------------------------------------------------------------------------- -void c_FileMgr::listDir (fs::FS& fs, String dirname, uint8_t levels) -{ - // DEBUG_START; - std::vector ListOfSubDirectories; - do // once - { - logcon (String (F ("Listing directory: ")) + dirname); - - File root = fs.open (dirname, CN_r); - if (!root) - { - logcon (String (CN_stars) + F ("failed to open directory: ") + dirname + CN_stars); - break; - } +void c_FileMgr::listDir(fs::FS &fs, String dirname, uint8_t levels) { + // DEBUG_START; + std::vector ListOfSubDirectories; + do // once + { + logcon(String(F("Listing directory: ")) + dirname); + + File root = fs.open(dirname, CN_r); + if (!root) { + logcon(String(CN_stars) + F("failed to open directory: ") + dirname + + CN_stars); + break; + } - if (!root.isDirectory ()) - { - logcon (String (F ("Is not a directory: ")) + dirname); - break; - } + if (!root.isDirectory()) { + logcon(String(F("Is not a directory: ")) + dirname); + break; + } - File MyFile = root.openNextFile (); + File MyFile = root.openNextFile(); - while (MyFile) - { - if (MyFile.isDirectory ()) - { - ListOfSubDirectories.push_back(MyFile.name()); - } - else - { - logcon ("'" + String (MyFile.name ()) + "': \t'" + String (MyFile.size ()) + "'"); - } - MyFile = root.openNextFile (); - } + while (MyFile) { + if (MyFile.isDirectory()) { + ListOfSubDirectories.push_back(MyFile.name()); + } else { + logcon("'" + String(MyFile.name()) + "': \t'" + String(MyFile.size()) + + "'"); + } + MyFile = root.openNextFile(); + } - for(auto & CurrentSubDir : ListOfSubDirectories) - { - if (levels) - { - listDir (fs, dirname + "/" + CurrentSubDir, levels - 1); - } - } - } while (false); + for (auto &CurrentSubDir : ListOfSubDirectories) { + if (levels) { + listDir(fs, dirname + "/" + CurrentSubDir, levels - 1); + } + } + } while (false); } // listDir //----------------------------------------------------------------------------- -bool c_FileMgr::LoadFlashFile (const String& FileName, DeserializationHandler Handler) -{ - // DEBUG_START; +bool c_FileMgr::LoadFlashFile(const String &FileName, + DeserializationHandler Handler) { + // DEBUG_START; - bool retval = false; + bool retval = false; - do // once - { - String CfgFileMessagePrefix = String (CN_Configuration_File_colon) + "'" + FileName + "' "; + do // once + { + String CfgFileMessagePrefix = + String(CN_Configuration_File_colon) + "'" + FileName + "' "; - // DEBUG_V ("allocate the JSON Doc"); -/* - String RawFileData; - if (false == ReadConfigFile (FileName, RawFileData)) - { - logcon (String(CN_stars) + CfgFileMessagePrefix + F ("Could not read file.") + CN_stars); - break; - } - logcon(RawFileData); -*/ - // DEBUG_V(); - fs::File file = LittleFS.open (FileName.c_str (), CN_r); - // DEBUG_V(); - if (!file) - { - logcon (String (CN_stars) + CfgFileMessagePrefix + String (F (" Could not open file for reading ")) + CN_stars); - break; - } + // DEBUG_V ("allocate the JSON Doc"); + /* + String RawFileData; + if (false == ReadConfigFile (FileName, RawFileData)) + { + logcon (String(CN_stars) + CfgFileMessagePrefix + F ("Could not + read file.") + CN_stars); break; + } + logcon(RawFileData); + */ + // DEBUG_V(); + fs::File file = LittleFS.open(FileName.c_str(), CN_r); + // DEBUG_V(); + if (!file) { + logcon(String(CN_stars) + CfgFileMessagePrefix + + String(F(" Could not open file for reading ")) + CN_stars); + break; + } - JsonDocument jsonDoc; - jsonDoc.to(); - - // DEBUG_V ("Convert File to JSON document"); - DeserializationError error = deserializeJson (jsonDoc, file); - file.close (); - - // DEBUG_V ("Error Check"); - if (error) - { - // logcon (CN_Heap_colon + String (ESP.getMaxFreeBlockSize ())); - logcon (String(CN_stars) + CfgFileMessagePrefix + String (F ("Deserialzation Error. Error code = ")) + error.c_str () + CN_stars); - // logcon (CN_plussigns + RawFileData + CN_minussigns); - // DEBUG_V (String (" heap: ") + String (ESP.getFreeHeap ())); - // xDEBUG_V (String (" getMaxFreeBlockSize: ") + String (ESP.getMaxFreeBlockSize ())); - // xDEBUG_V (String (" file.size: ") + String (file.size ())); - break; - } + JsonDocument jsonDoc; + jsonDoc.to(); + + // DEBUG_V ("Convert File to JSON document"); + DeserializationError error = deserializeJson(jsonDoc, file); + file.close(); + + // DEBUG_V ("Error Check"); + if (error) { + // logcon (CN_Heap_colon + String (ESP.getMaxFreeBlockSize ())); + logcon(String(CN_stars) + CfgFileMessagePrefix + + String(F("Deserialzation Error. Error code = ")) + error.c_str() + + CN_stars); + // logcon (CN_plussigns + RawFileData + CN_minussigns); + // DEBUG_V (String (" heap: ") + String (ESP.getFreeHeap + // ())); + // xDEBUG_V (String (" getMaxFreeBlockSize: ") + String + // (ESP.getMaxFreeBlockSize ())); + // xDEBUG_V (String (" file.size: ") + String (file.size ())); + break; + } - // DEBUG_V (); - logcon (CfgFileMessagePrefix + String (F ("loaded."))); + // DEBUG_V (); + logcon(CfgFileMessagePrefix + String(F("loaded."))); - // DEBUG_V (); - Handler (jsonDoc); + // DEBUG_V (); + Handler(jsonDoc); - // DEBUG_V(); - retval = true; + // DEBUG_V(); + retval = true; - } while (false); + } while (false); - // DEBUG_END; - return retval; + // DEBUG_END; + return retval; } // LoadFlashFile //----------------------------------------------------------------------------- -bool c_FileMgr::SaveFlashFile (const String& FileName, String& FileData) -{ - // DEBUG_START; +bool c_FileMgr::SaveFlashFile(const String &FileName, String &FileData) { + // DEBUG_START; - bool Response = SaveFlashFile (FileName, FileData.c_str ()); + bool Response = SaveFlashFile(FileName, FileData.c_str()); - // DEBUG_END; - return Response; + // DEBUG_END; + return Response; } // SaveConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::SaveFlashFile (const String& FileName, const char * FileData) -{ - // DEBUG_START; - - bool Response = false; - String CfgFileMessagePrefix = String (CN_Configuration_File_colon) + "'" + FileName + "' "; - // DEBUG_V (FileData); - - fs::File file = LittleFS.open (FileName.c_str (), CN_w); - if (!file) - { - logcon (String (CN_stars) + CfgFileMessagePrefix + String (F ("Could not open file for writing..")) + CN_stars); - } - else - { - file.seek (0, SeekSet); - file.print (FileData); - file.close (); +bool c_FileMgr::SaveFlashFile(const String &FileName, const char *FileData) { + // DEBUG_START; + + bool Response = false; + String CfgFileMessagePrefix = + String(CN_Configuration_File_colon) + "'" + FileName + "' "; + // DEBUG_V (FileData); + + fs::File file = LittleFS.open(FileName.c_str(), CN_w); + if (!file) { + logcon(String(CN_stars) + CfgFileMessagePrefix + + String(F("Could not open file for writing..")) + CN_stars); + } else { + file.seek(0, SeekSet); + file.print(FileData); + file.close(); + + file = LittleFS.open(FileName.c_str(), CN_r); + logcon(CfgFileMessagePrefix + String(F("saved ")) + String(file.size()) + + F(" bytes.")); + file.close(); + + Response = true; + } + + // DEBUG_END; + return Response; +} // SaveConfigFile - file = LittleFS.open (FileName.c_str (), CN_r); - logcon (CfgFileMessagePrefix + String (F ("saved ")) + String (file.size ()) + F (" bytes.")); - file.close (); +//----------------------------------------------------------------------------- +bool c_FileMgr::SaveFlashFile(const String &FileName, JsonDocument &FileData) { + // DEBUG_START; + bool Response = false; - Response = true; - } + String CfgFileMessagePrefix = + String(CN_Configuration_File_colon) + "'" + FileName + "' "; + // DEBUG_V(String("CfgFileMessagePrefix: ") + CfgFileMessagePrefix); - // DEBUG_END; - return Response; -} // SaveConfigFile + // serializeJson(FileData, LOG_PORT); + // DEBUG_V(""); -//----------------------------------------------------------------------------- -bool c_FileMgr::SaveFlashFile(const String &FileName, JsonDocument &FileData) -{ - // DEBUG_START; - bool Response = false; + // delay(100); + // DEBUG_V(""); - String CfgFileMessagePrefix = String(CN_Configuration_File_colon) + "'" + FileName + "' "; - // DEBUG_V(String("CfgFileMessagePrefix: ") + CfgFileMessagePrefix); + fs::File file = LittleFS.open(FileName.c_str(), CN_w); + // DEBUG_V(""); - // serializeJson(FileData, LOG_PORT); + if (!file) { + logcon(String(CN_stars) + CfgFileMessagePrefix + + String(F("Could not open file for writing..")) + CN_stars); + } else { // DEBUG_V(""); - - // delay(100); + file.seek(0, SeekSet); // DEBUG_V(""); - fs::File file = LittleFS.open(FileName.c_str(), CN_w); + size_t NumBytesSaved = serializeJson(FileData, file); // DEBUG_V(""); - if (!file) - { - logcon(String(CN_stars) + CfgFileMessagePrefix + String(F("Could not open file for writing..")) + CN_stars); - } - else - { - // DEBUG_V(""); - file.seek(0, SeekSet); - // DEBUG_V(""); - - size_t NumBytesSaved = serializeJson(FileData, file); - // DEBUG_V(""); - - file.close(); + file.close(); - logcon(CfgFileMessagePrefix + String(F("saved ")) + String(NumBytesSaved) + F(" bytes.")); + logcon(CfgFileMessagePrefix + String(F("saved ")) + String(NumBytesSaved) + + F(" bytes.")); - Response = true; - } + Response = true; + } - // DEBUG_END; + // DEBUG_END; - return Response; + return Response; } // SaveConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::SaveFlashFile(const String & FileName, uint32_t index, uint8_t *data, uint32_t len, bool final) -{ - // DEBUG_START; - bool Response = false; - - String CfgFileMessagePrefix = String(CN_Configuration_File_colon) + "'" + FileName + "' "; - // DEBUG_V(String("CfgFileMessagePrefix: ") + CfgFileMessagePrefix); - // DEBUG_V(String(" FileName: ") + FileName); - // DEBUG_V(String(" index: ") + String(index)); - // DEBUG_V(String(" len: ") + String(len)); - // DEBUG_V(String(" final: ") + String(final)); - - fs::File file; - - if(0 == index) - { - file = LittleFS.open(FileName.c_str(), CN_w); - } - else - { - file = LittleFS.open(FileName.c_str(), "a"); - } +bool c_FileMgr::SaveFlashFile(const String &FileName, uint32_t index, + uint8_t *data, uint32_t len, bool final) { + // DEBUG_START; + bool Response = false; + + String CfgFileMessagePrefix = + String(CN_Configuration_File_colon) + "'" + FileName + "' "; + // DEBUG_V(String("CfgFileMessagePrefix: ") + CfgFileMessagePrefix); + // DEBUG_V(String(" FileName: ") + FileName); + // DEBUG_V(String(" index: ") + String(index)); + // DEBUG_V(String(" len: ") + String(len)); + // DEBUG_V(String(" final: ") + String(final)); + + fs::File file; + + if (0 == index) { + file = LittleFS.open(FileName.c_str(), CN_w); + } else { + file = LittleFS.open(FileName.c_str(), "a"); + } + // DEBUG_V(""); + + if (!file) { + logcon(String(CN_stars) + CfgFileMessagePrefix + + String(F("Could not open file for writing..")) + CN_stars); + } else { + // DEBUG_V(""); + file.seek(int(index), SeekMode::SeekSet); // DEBUG_V(""); - if (!file) - { - logcon(String(CN_stars) + CfgFileMessagePrefix + String(F("Could not open file for writing..")) + CN_stars); - } - else - { - // DEBUG_V(""); - file.seek(int(index), SeekMode::SeekSet); - // DEBUG_V(""); - - size_t NumBytesSaved = file.write(data, size_t(len)); - // DEBUG_V(""); + size_t NumBytesSaved = file.write(data, size_t(len)); + // DEBUG_V(""); - file.close(); + file.close(); - logcon(CfgFileMessagePrefix + String(F("saved ")) + String(NumBytesSaved) + F(" bytes.")); + logcon(CfgFileMessagePrefix + String(F("saved ")) + String(NumBytesSaved) + + F(" bytes.")); - Response = true; - } + Response = true; + } - // DEBUG_END; + // DEBUG_END; - return Response; + return Response; } // SaveConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadFlashFile (const String& FileName, String& FileData) -{ - // DEBUG_START; - - bool GotFileData = false; - String CfgFileMessagePrefix = String (CN_Configuration_File_colon) + "'" + FileName + "' "; - - // DEBUG_V (String("File '") + FileName + "' is being opened."); - fs::File file = LittleFS.open (FileName.c_str (), CN_r); - if (file) - { - // Suppress this for now, may add it back later - //logcon (CfgFileMessagePrefix + String (F ("reading ")) + String (file.size()) + F (" bytes.")); - - // DEBUG_V (String("File '") + FileName + "' is open."); - file.seek (0, SeekSet); - FileData = file.readString (); - file.close (); - GotFileData = true; +bool c_FileMgr::ReadFlashFile(const String &FileName, String &FileData) { + // DEBUG_START; + + bool GotFileData = false; + String CfgFileMessagePrefix = + String(CN_Configuration_File_colon) + "'" + FileName + "' "; + + // DEBUG_V (String("File '") + FileName + "' is being opened."); + fs::File file = LittleFS.open(FileName.c_str(), CN_r); + if (file) { + // Suppress this for now, may add it back later + // logcon (CfgFileMessagePrefix + String (F ("reading ")) + String + // (file.size()) + F (" bytes.")); + + // DEBUG_V (String("File '") + FileName + "' is open."); + file.seek(0, SeekSet); + FileData = file.readString(); + file.close(); + GotFileData = true; - // DEBUG_V (FileData); - } - else - { - logcon (String (CN_stars) + CN_Configuration_File_colon + "'" + FileName + F ("' not found.") + CN_stars); - } + // DEBUG_V (FileData); + } else { + logcon(String(CN_stars) + CN_Configuration_File_colon + "'" + FileName + + F("' not found.") + CN_stars); + } - // DEBUG_END; - return GotFileData; + // DEBUG_END; + return GotFileData; } // ReadConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadFlashFile (const String& FileName, JsonDocument & FileData) -{ - // DEBUG_START; - bool GotFileData = false; - - do // once - { - String RawFileData; - if (false == ReadFlashFile (FileName, RawFileData)) - { - // DEBUG_V ("Failed to read file"); - break; - } +bool c_FileMgr::ReadFlashFile(const String &FileName, JsonDocument &FileData) { + // DEBUG_START; + bool GotFileData = false; + + do // once + { + String RawFileData; + if (false == ReadFlashFile(FileName, RawFileData)) { + // DEBUG_V ("Failed to read file"); + break; + } - // did we actually get any data - if (0 == RawFileData.length ()) - { - // DEBUG_V ("File is empty"); - // nope, no data - GotFileData = false; - break; - } + // did we actually get any data + if (0 == RawFileData.length()) { + // DEBUG_V ("File is empty"); + // nope, no data + GotFileData = false; + break; + } - // DEBUG_V ("Convert File to JSON document"); - DeserializationError error = deserializeJson (FileData, (const String)RawFileData); - - // DEBUG_V ("Error Check"); - if (error) - { - String CfgFileMessagePrefix = String (CN_Configuration_File_colon) + "'" + FileName + "' "; - logcon (CN_Heap_colon + String (ESP.getFreeHeap ())); - logcon (CfgFileMessagePrefix + String (F ("Deserialzation Error. Error code = ")) + error.c_str ()); - logcon (CN_plussigns + RawFileData + CN_minussigns); - break; - } + // DEBUG_V ("Convert File to JSON document"); + DeserializationError error = + deserializeJson(FileData, (const String)RawFileData); + + // DEBUG_V ("Error Check"); + if (error) { + String CfgFileMessagePrefix = + String(CN_Configuration_File_colon) + "'" + FileName + "' "; + logcon(CN_Heap_colon + String(ESP.getFreeHeap())); + logcon(CfgFileMessagePrefix + + String(F("Deserialzation Error. Error code = ")) + error.c_str()); + logcon(CN_plussigns + RawFileData + CN_minussigns); + break; + } - // DEBUG_V ("Got config data"); - GotFileData = true; + // DEBUG_V ("Got config data"); + GotFileData = true; - } while (false); + } while (false); - // DEBUG_END; - return GotFileData; + // DEBUG_END; + return GotFileData; } // ReadConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadFlashFile (const String & FileName, byte * FileData, size_t maxlen) -{ - // DEBUG_START; - bool GotFileData = false; +bool c_FileMgr::ReadFlashFile(const String &FileName, byte *FileData, + size_t maxlen) { + // DEBUG_START; + bool GotFileData = false; - do // once - { - // DEBUG_V (String("File '") + FileName + "' is being opened."); - fs::File file = LittleFS.open (FileName.c_str (), CN_r); - if (!file) - { - logcon (String (CN_stars) + CN_Configuration_File_colon + "'" + FileName + F ("' not found.") + CN_stars); - break; - } + do // once + { + // DEBUG_V (String("File '") + FileName + "' is being opened."); + fs::File file = LittleFS.open(FileName.c_str(), CN_r); + if (!file) { + logcon(String(CN_stars) + CN_Configuration_File_colon + "'" + FileName + + F("' not found.") + CN_stars); + break; + } - if (file.size() >= maxlen) - { - logcon (String (CN_stars) + CN_Configuration_File_colon + "'" + FileName + F ("' too large for buffer. ") + CN_stars); - file.close (); - break; - } + if (file.size() >= maxlen) { + logcon(String(CN_stars) + CN_Configuration_File_colon + "'" + FileName + + F("' too large for buffer. ") + CN_stars); + file.close(); + break; + } - // Suppress this for now, may add it back later - // Done at interrupt level. Cant use Strings - // LOG_PORT.print (FileName); - // LOG_PORT.print (" reading "); - // LOG_PORT.print (file.size ()); - // LOG_PORT.println (" bytes."); + // Suppress this for now, may add it back later + // Done at interrupt level. Cant use Strings + // LOG_PORT.print (FileName); + // LOG_PORT.print (" reading "); + // LOG_PORT.print (file.size ()); + // LOG_PORT.println (" bytes."); - // DEBUG_V (String("File '") + FileName + "' is open."); - file.seek (0, SeekSet); - file.read (FileData, file.size()); - file.close (); + // DEBUG_V (String("File '") + FileName + "' is open."); + file.seek(0, SeekSet); + file.read(FileData, file.size()); + file.close(); - GotFileData = true; + GotFileData = true; - // DEBUG_V (FileData); + // DEBUG_V (FileData); - } while (false); + } while (false); - // DEBUG_END; - return GotFileData; + // DEBUG_END; + return GotFileData; } // ReadConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::FlashFileExists (const String & FileName) -{ - return LittleFS.exists (FileName.c_str ()); +bool c_FileMgr::FlashFileExists(const String &FileName) { + return LittleFS.exists(FileName.c_str()); } // FlashFileExists //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void c_FileMgr::InitSdFileList () -{ - // DEBUG_START; +void c_FileMgr::InitSdFileList() { + // DEBUG_START; - int index = 0; - for (auto& currentFileListEntry : FileList) - { - currentFileListEntry.Filename.reserve(256); - currentFileListEntry.handle = INVALID_FILE_HANDLE; - currentFileListEntry.entryId = index++; - } + int index = 0; + for (auto ¤tFileListEntry : FileList) { + currentFileListEntry.Filename.reserve(256); + currentFileListEntry.handle = INVALID_FILE_HANDLE; + currentFileListEntry.entryId = index++; + } - // DEBUG_END; + // DEBUG_END; } // InitFileList //----------------------------------------------------------------------------- -int c_FileMgr::FileListFindSdFileHandle (FileId HandleToFind) -{ - // DEBUG_START; - - int response = -1; - // DEBUG_V (String ("HandleToFind: ") + String (HandleToFind)); - - if(INVALID_FILE_HANDLE != HandleToFind) - { - for (auto & currentFileListEntry : FileList) - { - // DEBUG_V (String ("currentFileListEntry.handle: ") + String (currentFileListEntry.handle)); - // DEBUG_V (String ("currentFileListEntry.entryId: ") + String (currentFileListEntry.entryId)); - - if (currentFileListEntry.handle == HandleToFind) - { - response = currentFileListEntry.entryId; - break; - } - } +int c_FileMgr::FileListFindSdFileHandle(FileId HandleToFind) { + // DEBUG_START; + + int response = -1; + // DEBUG_V (String ("HandleToFind: ") + String (HandleToFind)); + + if (INVALID_FILE_HANDLE != HandleToFind) { + for (auto ¤tFileListEntry : FileList) { + // DEBUG_V (String ("currentFileListEntry.handle: ") + String + // (currentFileListEntry.handle)); DEBUG_V (String + // ("currentFileListEntry.entryId: ") + String + // (currentFileListEntry.entryId)); + + if (currentFileListEntry.handle == HandleToFind) { + response = currentFileListEntry.entryId; + break; + } } + } - // DEBUG_END; + // DEBUG_END; - return response; + return response; } // FileListFindSdFileHandle //----------------------------------------------------------------------------- -c_FileMgr::FileId c_FileMgr::CreateSdFileHandle () -{ - // DEBUG_START; - - FileId response = INVALID_FILE_HANDLE; - FileId FileHandle = millis (); - - // create a unique handle - while (-1 != FileListFindSdFileHandle (FileHandle)) - { - ++FileHandle; +c_FileMgr::FileId c_FileMgr::CreateSdFileHandle() { + // DEBUG_START; + + FileId response = INVALID_FILE_HANDLE; + FileId FileHandle = millis(); + + // create a unique handle + while (-1 != FileListFindSdFileHandle(FileHandle)) { + ++FileHandle; + } + + // find an empty slot + for (auto ¤tFileListEntry : FileList) { + if (currentFileListEntry.handle == INVALID_FILE_HANDLE) { + currentFileListEntry.handle = FileHandle; + response = FileHandle; + // DEBUG_V(String("handle: ") + currentFileListEntry.handle); + break; } + } - // find an empty slot - for (auto & currentFileListEntry : FileList) - { - if (currentFileListEntry.handle == INVALID_FILE_HANDLE) - { - currentFileListEntry.handle = FileHandle; - response = FileHandle; - // DEBUG_V(String("handle: ") + currentFileListEntry.handle); - break; - } - } - - if (INVALID_FILE_HANDLE == response) - { - logcon (String (CN_stars) + F (" Could not allocate another file handle ") + CN_stars); - } - // DEBUG_V (String ("FileHandle: ") + String (FileHandle)); + if (INVALID_FILE_HANDLE == response) { + logcon(String(CN_stars) + F(" Could not allocate another file handle ") + + CN_stars); + } + // DEBUG_V (String ("FileHandle: ") + String (FileHandle)); - // DEBUG_END; + // DEBUG_END; - return response; + return response; } // CreateFileHandle //----------------------------------------------------------------------------- -void c_FileMgr::DeleteSdFile (const String & FileName) -{ - // DEBUG_START; +void c_FileMgr::DeleteSdFile(const String &FileName) { + // DEBUG_START; #ifdef SIMULATE_SD - String NewFilename = String(CN_slashsdslash) + FileName; - DeleteFlashFile(NewFilename); + String NewFilename = String(CN_slashsdslash) + FileName; + DeleteFlashFile(NewFilename); #else + LockSd(); + bool FileExists = ESP_SD.exists(FileName); + UnLockSd(); + if (FileExists) { + // DEBUG_V (String ("Deleting '") + FileName + "'"); LockSd(); - bool FileExists = ESP_SD.exists (FileName); + ESP_SD.remove(FileName); UnLockSd(); - if (FileExists) - { - // DEBUG_V (String ("Deleting '") + FileName + "'"); - LockSd(); - ESP_SD.remove (FileName); - UnLockSd(); - } + } #endif // def SIMULATE_SD - BuildFseqList(false); + BuildFseqList(false); - // DEBUG_END; + // DEBUG_END; } // DeleteSdFile //----------------------------------------------------------------------------- -void c_FileMgr::DescribeSdCardToUser () -{ - // DEBUG_START; - - logcon (String (F ("SD Card Size: ")) + int64String (SdCardSize) + "Bytes"); -/* - // DEBUG_V("Open Root"); - FsFile root; - ESP_SD.chdir(); - root.open("/", O_READ); - printDirectory (root, 0); - root.close(); - // DEBUG_V("Close Root"); -*/ - // DEBUG_END; +void c_FileMgr::DescribeSdCardToUser() { + // DEBUG_START; + + logcon(String(F("SD Card Size: ")) + int64String(SdCardSize) + "Bytes"); + /* + // DEBUG_V("Open Root"); + FsFile root; + ESP_SD.chdir(); + root.open("/", O_READ); + printDirectory (root, 0); + root.close(); + // DEBUG_V("Close Root"); + */ + // DEBUG_END; } // DescribeSdCardToUser //----------------------------------------------------------------------------- -void c_FileMgr::GetListOfSdFiles (std::vector & Response) -{ - // DEBUG_START; - - char entryName[256]; - - Response.clear(); - LockSd(); - do // once - { - if (false == SdCardIsInstalled ()) - { - // DEBUG_V("No SD Card installed"); - break; - } +void c_FileMgr::GetListOfSdFiles(std::vector &Response) { + // DEBUG_START; + + char entryName[256]; + + Response.clear(); + LockSd(); + do // once + { + if (false == SdCardIsInstalled()) { + // DEBUG_V("No SD Card installed"); + break; + } #ifdef SIMULATE_SD - File root = ESP_SD.open (CN_slashsd, CN_r); - if (!root) - { - logcon (String (CN_stars) + F ("failed to open directory: ") + CN_slashsd + CN_stars); - break; - } + File root = ESP_SD.open(CN_slashsd, CN_r); + if (!root) { + logcon(String(CN_stars) + F("failed to open directory: ") + CN_slashsd + + CN_stars); + break; + } - if (!root.isDirectory ()) - { - logcon (String (F ("Is not a directory: ")) + CN_slashsd); - break; - } + if (!root.isDirectory()) { + logcon(String(F("Is not a directory: ")) + CN_slashsd); + break; + } - File MyFile = root.openNextFile (); + File MyFile = root.openNextFile(); - while (MyFile) - { - if(MyFile.isDirectory()) - { - // not a file we are looking for - continue; - } + while (MyFile) { + if (MyFile.isDirectory()) { + // not a file we are looking for + continue; + } - String EntryName = String (MyFile.name()); - EntryName = EntryName.substring ((('/' == EntryName[0]) ? 1 : 0)); - // DEBUG_V ("EntryName: '" + EntryName + "'"); - // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); + String EntryName = String(MyFile.name()); + EntryName = EntryName.substring((('/' == EntryName[0]) ? 1 : 0)); + // DEBUG_V ("EntryName: '" + EntryName + "'"); + // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); - if ((!EntryName.isEmpty ()) && - (0 != MyFile.size ()) - ) - { - // DEBUG_V ("Adding File: '" + EntryName + "'"); - Response.push_back(EntryName); - logcon ("'" + EntryName + "': \t'" + String (MyFile.size ()) + "'"); - } + if ((!EntryName.isEmpty()) && (0 != MyFile.size())) { + // DEBUG_V ("Adding File: '" + EntryName + "'"); + Response.push_back(EntryName); + logcon("'" + EntryName + "': \t'" + String(MyFile.size()) + "'"); + } - MyFile = root.openNextFile (); - } + MyFile = root.openNextFile(); + } #else - FsFile Entry; - FsFile dir; - ESP_SD.chdir(); // Set to sd root - if(!dir.open ("/", O_READ)) - { - logcon("ERROR:GetListOfSdFiles: Could not open root dir"); - break; - } - - while (Entry.openNext (&dir, O_READ)) - { - if(!Entry.isFile() || Entry.isHidden()) - { - // not a file we are looking for - continue; - } - - memset(entryName, 0x0, sizeof(entryName)); - Entry.getName(entryName, sizeof(entryName)-1); - String EntryName = String (entryName); - EntryName = EntryName.substring ((('/' == EntryName[0]) ? 1 : 0)); - // DEBUG_V ("EntryName: '" + EntryName + "'"); - // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); - - if ((!EntryName.isEmpty ()) && - (!EntryName.equals(String (F ("System Volume Information")))) && - (0 != Entry.size ()) - ) - { - // DEBUG_V ("Adding File: '" + EntryName + "'"); - Response.push_back(EntryName); - } + FsFile Entry; + FsFile dir; + ESP_SD.chdir(); // Set to sd root + if (!dir.open("/", O_READ)) { + logcon("ERROR:GetListOfSdFiles: Could not open root dir"); + break; + } - Entry.close (); - } + while (Entry.openNext(&dir, O_READ)) { + if (!Entry.isFile() || Entry.isHidden()) { + // not a file we are looking for + continue; + } + + memset(entryName, 0x0, sizeof(entryName)); + Entry.getName(entryName, sizeof(entryName) - 1); + String EntryName = String(entryName); + EntryName = EntryName.substring((('/' == EntryName[0]) ? 1 : 0)); + // DEBUG_V ("EntryName: '" + EntryName + "'"); + // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); + + if ((!EntryName.isEmpty()) && + (!EntryName.equals(String(F("System Volume Information")))) && + (0 != Entry.size())) { + // DEBUG_V ("Adding File: '" + EntryName + "'"); + Response.push_back(EntryName); + } + + Entry.close(); + } - dir.close(); + dir.close(); #endif // ndef SUPPORT_SD - } while (false); - UnLockSd(); + } while (false); + UnLockSd(); - // DEBUG_END; + // DEBUG_END; } // GetListOfSdFiles //----------------------------------------------------------------------------- -void c_FileMgr::printDirectory (FsFile & dir, int numTabs) -{ - // DEBUG_START; - - char entryName[256]; - FsFile Entry; - String tabs = emptyString; - tabs.reserve(2 * (numTabs + 1)); - for (uint8_t i = 0; i < numTabs; i++) - { - tabs = tabs + " "; - } - - while (Entry.openNext(&dir, O_READ)) - { - FeedWDT(); +void c_FileMgr::printDirectory(FsFile &dir, int numTabs) { + // DEBUG_START; + + char entryName[256]; + FsFile Entry; + String tabs = emptyString; + tabs.reserve(2 * (numTabs + 1)); + for (uint8_t i = 0; i < numTabs; i++) { + tabs = tabs + " "; + } + + while (Entry.openNext(&dir, O_READ)) { + FeedWDT(); - memset(entryName, 0x0, sizeof(entryName)); - Entry.getName(entryName, sizeof(entryName)-1); - // DEBUG_V(String("entryName: '") + String(entryName) + "'"); + memset(entryName, 0x0, sizeof(entryName)); + Entry.getName(entryName, sizeof(entryName) - 1); + // DEBUG_V(String("entryName: '") + String(entryName) + "'"); - if (Entry.isDirectory ()) - { - logcon (tabs + F ("> ") + entryName); - printDirectory (dir, numTabs + 1); - Entry.close(); - continue; - } + if (Entry.isDirectory()) { + logcon(tabs + F("> ") + entryName); + printDirectory(dir, numTabs + 1); + Entry.close(); + continue; + } - if(!Entry.isHidden()) - { - // files have sizes, directories do not - logcon (tabs + entryName + F (" - ") + int64String(Entry.size ())); - } - Entry.close(); + if (!Entry.isHidden()) { + // files have sizes, directories do not + logcon(tabs + entryName + F(" - ") + int64String(Entry.size())); } + Entry.close(); + } - // DEBUG_END; + // DEBUG_END; } // printDirectory //----------------------------------------------------------------------------- -void c_FileMgr::SaveSdFile (const String & FileName, String & FileData) -{ - // DEBUG_START; +void c_FileMgr::SaveSdFile(const String &FileName, String &FileData) { + // DEBUG_START; - do // once - { - FileId FileHandle = INVALID_FILE_HANDLE; - if (false == OpenSdFile (FileName, FileMode::FileWrite, FileHandle, -1)) - { - logcon (String (F ("Could not open '")) + FileName + F ("' for writting.")); - break; - } + do // once + { + FileId FileHandle = INVALID_FILE_HANDLE; + if (false == OpenSdFile(FileName, FileMode::FileWrite, FileHandle, -1)) { + logcon(String(F("Could not open '")) + FileName + F("' for writting.")); + break; + } - int WriteCount = WriteSdFile (FileHandle, (byte*)FileData.c_str (), (uint64_t)FileData.length ()); - logcon (String (F ("Wrote '")) + FileName + F ("' ") + String(WriteCount)); + int WriteCount = WriteSdFile(FileHandle, (byte *)FileData.c_str(), + (uint64_t)FileData.length()); + logcon(String(F("Wrote '")) + FileName + F("' ") + String(WriteCount)); - // DEBUG_FILE_HANDLE (FileHandle); - CloseSdFile (FileHandle); + // DEBUG_FILE_HANDLE (FileHandle); + CloseSdFile(FileHandle); - } while (false); + } while (false); - // DEBUG_END; + // DEBUG_END; } // SaveSdFile //----------------------------------------------------------------------------- -void c_FileMgr::SaveSdFile (const String & FileName, JsonVariant & FileData) -{ - // DEBUG_START; - String Temp; - serializeJson (FileData, Temp); - SaveSdFile (FileName, Temp); - // DEBUG_END; +void c_FileMgr::SaveSdFile(const String &FileName, JsonVariant &FileData) { + // DEBUG_START; + String Temp; + serializeJson(FileData, Temp); + SaveSdFile(FileName, Temp); + // DEBUG_END; } // SaveSdFile //----------------------------------------------------------------------------- -bool c_FileMgr::OpenSdFile (const String & _FileName, FileMode Mode, FileId & FileHandle, int FileListIndex) -{ - // DEBUG_START; - // DEBUG_V(String("Mode: ") + String(Mode)); - - bool FileIsOpen = false; - #ifdef SIMULATE_SD - String FileName = String(CN_slashsdslash) + _FileName; - #else - String FileName = _FileName; - #endif - do // once - { - if (!SdCardInstalled) - { - // no SD card is installed - FileHandle = INVALID_FILE_HANDLE; - break; - } - - // DEBUG_V (); - - // DEBUG_V (String("FileName: '") + FileName + "'"); - - if (FileMode::FileRead == Mode) - { - // DEBUG_V (String("Read mode")); - if (false == ESP_SD.exists (FileName)) - { - logcon (String (F ("ERROR: Cannot find '")) + FileName + F ("' for reading. File does not exist.")); - break; - } - } - // DEBUG_V ("File Exists"); - - // do we have a pre defined index? - if(-1 == FileListIndex) - { - // DEBUG_V("No predefined File Handle"); - FileHandle = CreateSdFileHandle (); - // DEBUG_V (String("FileHandle: ") + String(FileHandle)); +bool c_FileMgr::OpenSdFile(const String &_FileName, FileMode Mode, + FileId &FileHandle, int FileListIndex) { + // DEBUG_START; + // DEBUG_V(String("Mode: ") + String(Mode)); - FileListIndex = FileListFindSdFileHandle (FileHandle); - // DEBUG_V(String("Using lookup File Index: ") + String(FileListIndex)); - } - else - { - // DEBUG_V(String("Using predefined File Index: ") + String(FileListIndex)); - FileHandle = FileList[FileListIndex].handle; - } + bool FileIsOpen = false; +#ifdef SIMULATE_SD + String FileName = String(CN_slashsdslash) + _FileName; +#else + String FileName = _FileName; +#endif + do // once + { + if (!SdCardInstalled) { + // no SD card is installed + FileHandle = INVALID_FILE_HANDLE; + break; + } - // DEBUG_V("did we get an index"); - if (-1 != FileListIndex) - { - // DEBUG_V(String("Valid FileListIndex: ") + String(FileListIndex)); - FileList[FileListIndex].Filename = FileName; - // DEBUG_V(String("Got file handle: ") + String(FileHandle)); - LockSd(); - #ifdef SIMULATE_SD - FileList[FileListIndex].fsFile = ESP_SDFS.open (FileName, &XlateFileMode[Mode]); - FileList[FileListIndex].IsOpen = true; - #else - FileList[FileListIndex].IsOpen = FileList[FileListIndex].fsFile.open(FileList[FileListIndex].Filename.c_str(), XlateFileMode[Mode]); - #endif // def SIMULATE_SD - UnLockSd(); - - // DEBUG_V(String("ReadWrite: ") + String(XlateFileMode[Mode])); - // xDEBUG_V(String("File Size: ") + String64(FileList[FileListIndex].fsFile.size())); - FileList[FileListIndex].mode = Mode; - - // DEBUG_V("Open return"); - if (!FileList[FileListIndex].IsOpen) - { - logcon(String(F("ERROR: Could not open '")) + FileName + F("'.")); - // release the file list entry - // DEBUG_FILE_HANDLE (FileHandle); - FileList[FileListIndex].IsOpen = false; - CloseSdFile(FileHandle); - break; - } - // DEBUG_V(""); + // DEBUG_V (); - LockSd(); - FileList[FileListIndex].size = FileList[FileListIndex].fsFile.size(); - UnLockSd(); - // DEBUG_V(String(FileList[FileListIndex].Filename) + " - " + String(FileList[FileListIndex].size)); + // DEBUG_V (String("FileName: '") + FileName + "'"); - if (FileMode::FileWrite == Mode) - { - // DEBUG_V ("Write Mode"); - LockSd(); - FileList[FileListIndex].fsFile.seek (0); - UnLockSd(); - } - // DEBUG_V (); + if (FileMode::FileRead == Mode) { + // DEBUG_V (String("Read mode")); + if (false == ESP_SD.exists(FileName)) { + logcon(String(F("ERROR: Cannot find '")) + FileName + + F("' for reading. File does not exist.")); + break; + } + } + // DEBUG_V ("File Exists"); + + // do we have a pre defined index? + if (-1 == FileListIndex) { + // DEBUG_V("No predefined File Handle"); + FileHandle = CreateSdFileHandle(); + // DEBUG_V (String("FileHandle: ") + String(FileHandle)); + + FileListIndex = FileListFindSdFileHandle(FileHandle); + // DEBUG_V(String("Using lookup File Index: ") + String(FileListIndex)); + } else { + // DEBUG_V(String("Using predefined File Index: ") + + // String(FileListIndex)); + FileHandle = FileList[FileListIndex].handle; + } - FileIsOpen = true; - // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); - } - else - { - // DEBUG_V("Could not get a file list index"); - } + // DEBUG_V("did we get an index"); + if (-1 != FileListIndex) { + // DEBUG_V(String("Valid FileListIndex: ") + String(FileListIndex)); + FileList[FileListIndex].Filename = FileName; + // DEBUG_V(String("Got file handle: ") + String(FileHandle)); + LockSd(); +#ifdef SIMULATE_SD + FileList[FileListIndex].fsFile = + ESP_SDFS.open(FileName, &XlateFileMode[Mode]); + FileList[FileListIndex].IsOpen = true; +#else + FileList[FileListIndex].IsOpen = FileList[FileListIndex].fsFile.open( + FileList[FileListIndex].Filename.c_str(), XlateFileMode[Mode]); +#endif // def SIMULATE_SD + UnLockSd(); + + // DEBUG_V(String("ReadWrite: ") + String(XlateFileMode[Mode])); + // xDEBUG_V(String("File Size: ") + + // String64(FileList[FileListIndex].fsFile.size())); + FileList[FileListIndex].mode = Mode; + + // DEBUG_V("Open return"); + if (!FileList[FileListIndex].IsOpen) { + logcon(String(F("ERROR: Could not open '")) + FileName + F("'.")); + // release the file list entry + // DEBUG_FILE_HANDLE (FileHandle); + FileList[FileListIndex].IsOpen = false; + CloseSdFile(FileHandle); + break; + } + // DEBUG_V(""); + + LockSd(); + FileList[FileListIndex].size = FileList[FileListIndex].fsFile.size(); + UnLockSd(); + // DEBUG_V(String(FileList[FileListIndex].Filename) + " - " + + // String(FileList[FileListIndex].size)); + + if (FileMode::FileWrite == Mode) { + // DEBUG_V ("Write Mode"); + LockSd(); + FileList[FileListIndex].fsFile.seek(0); + UnLockSd(); + } + // DEBUG_V (); + + FileIsOpen = true; + // DEBUG_V (String ("File.Handle: ") + String + // (FileList[FileListIndex].handle)); + } else { + // DEBUG_V("Could not get a file list index"); + } - } while (false); + } while (false); - // DEBUG_END; - return FileIsOpen; + // DEBUG_END; + return FileIsOpen; } // OpenSdFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadSdFile (const String & FileName, String & FileData) -{ - // DEBUG_START; +bool c_FileMgr::ReadSdFile(const String &FileName, String &FileData) { + // DEBUG_START; - bool GotFileData = false; - FileId FileHandle = INVALID_FILE_HANDLE; + bool GotFileData = false; + FileId FileHandle = INVALID_FILE_HANDLE; - // DEBUG_V (String("File '") + FileName + "' is being opened."); - if (true == OpenSdFile (FileName, FileMode::FileRead, FileHandle, -1)) - { - // DEBUG_V (String("File '") + FileName + "' is open."); - int FileListIndex; - if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - LockSd(); - FileList[FileListIndex].fsFile.seek (0); - FileData = FileList[FileListIndex].fsFile.readString (); - UnLockSd(); - } + // DEBUG_V (String("File '") + FileName + "' is being opened."); + if (true == OpenSdFile(FileName, FileMode::FileRead, FileHandle, -1)) { + // DEBUG_V (String("File '") + FileName + "' is open."); + int FileListIndex; + if (-1 != (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + LockSd(); + FileList[FileListIndex].fsFile.seek(0); + FileData = FileList[FileListIndex].fsFile.readString(); + UnLockSd(); + } - // DEBUG_FILE_HANDLE (FileHandle); - CloseSdFile (FileHandle); - GotFileData = (0 != FileData.length()); + // DEBUG_FILE_HANDLE (FileHandle); + CloseSdFile(FileHandle); + GotFileData = (0 != FileData.length()); - // DEBUG_V (FileData); - } - else - { - // DEBUG_FILE_HANDLE (FileHandle); - CloseSdFile (FileHandle); - logcon (String (F ("SD file: '")) + FileName + String (F ("' not found."))); - } + // DEBUG_V (FileData); + } else { + // DEBUG_FILE_HANDLE (FileHandle); + CloseSdFile(FileHandle); + logcon(String(F("SD file: '")) + FileName + String(F("' not found."))); + } - // DEBUG_END; - return GotFileData; + // DEBUG_END; + return GotFileData; } // ReadSdFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadSdFile (const String & FileName, JsonDocument & FileData) -{ - // DEBUG_START; +bool c_FileMgr::ReadSdFile(const String &FileName, JsonDocument &FileData) { + // DEBUG_START; - bool GotFileData = false; - FileId FileHandle = INVALID_FILE_HANDLE; + bool GotFileData = false; + FileId FileHandle = INVALID_FILE_HANDLE; - // DEBUG_V (String("File '") + FileName + "' is being opened."); - if (true == OpenSdFile (FileName, FileMode::FileRead, FileHandle, -1)) - { - // DEBUG_V (String("File '") + FileName + "' is open."); - int FileListIndex; - if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - LockSd(); - FileList[FileListIndex].fsFile.seek (0); - String RawFileData = FileList[FileListIndex].fsFile.readString (); - UnLockSd(); - - // DEBUG_V ("Convert File to JSON document"); - DeserializationError error = deserializeJson (FileData, RawFileData); - - // DEBUG_V ("Error Check"); - if (error) - { - String CfgFileMessagePrefix = String (CN_Configuration_File_colon) + "'" + FileName + "' "; - logcon (CN_Heap_colon + String (ESP.getFreeHeap ())); - logcon (CfgFileMessagePrefix + String (F ("Deserialzation Error. Error code = ")) + error.c_str ()); - logcon (CN_plussigns + RawFileData + CN_minussigns); - } - else - { - GotFileData = true; - } - } - // DEBUG_FILE_HANDLE (FileHandle); - CloseSdFile(FileHandle); - } - else - { - logcon (String (F ("SD file: '")) + FileName + String (F ("' not found."))); + // DEBUG_V (String("File '") + FileName + "' is being opened."); + if (true == OpenSdFile(FileName, FileMode::FileRead, FileHandle, -1)) { + // DEBUG_V (String("File '") + FileName + "' is open."); + int FileListIndex; + if (-1 != (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + LockSd(); + FileList[FileListIndex].fsFile.seek(0); + String RawFileData = FileList[FileListIndex].fsFile.readString(); + UnLockSd(); + + // DEBUG_V ("Convert File to JSON document"); + DeserializationError error = deserializeJson(FileData, RawFileData); + + // DEBUG_V ("Error Check"); + if (error) { + String CfgFileMessagePrefix = + String(CN_Configuration_File_colon) + "'" + FileName + "' "; + logcon(CN_Heap_colon + String(ESP.getFreeHeap())); + logcon(CfgFileMessagePrefix + + String(F("Deserialzation Error. Error code = ")) + + error.c_str()); + logcon(CN_plussigns + RawFileData + CN_minussigns); + } else { + GotFileData = true; + } } + // DEBUG_FILE_HANDLE (FileHandle); + CloseSdFile(FileHandle); + } else { + logcon(String(F("SD file: '")) + FileName + String(F("' not found."))); + } - // DEBUG_END; - return GotFileData; + // DEBUG_END; + return GotFileData; } // ReadSdFile //----------------------------------------------------------------------------- -uint64_t c_FileMgr::ReadSdFile (const FileId& FileHandle, byte* FileData, uint64_t NumBytesToRead, uint64_t StartingPosition) -{ - // DEBUG_START; - - uint64_t response = 0; - - // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); - // DEBUG_V (String (" NumBytesToRead: ") + String (NumBytesToRead)); - // DEBUG_V (String (" StartingPosition: ") + String (StartingPosition)); - - int FileListIndex; - if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - uint64_t BytesRemaining = uint64_t(FileList[FileListIndex].size - StartingPosition); - uint64_t ActualBytesToRead = min(NumBytesToRead, BytesRemaining); - // DEBUG_V(String(" BytesRemaining: ") + String(BytesRemaining)); - // DEBUG_V(String("ActualBytesToRead: ") + String(ActualBytesToRead)); - LockSd(); - FileList[FileListIndex].fsFile.seek(StartingPosition); - #ifdef SIMULATE_SD - response = FileList[FileListIndex].fsFile.readBytes((char*)FileData, ActualBytesToRead); - #else - response = FileList[FileListIndex].fsFile.readBytes(FileData, ActualBytesToRead); - #endif // def SIMULATE_SD - UnLockSd(); - // DEBUG_V(String(" response: ") + String64(response)); - } - else - { - logcon (String (F ("ReadSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); - } +uint64_t c_FileMgr::ReadSdFile(const FileId &FileHandle, byte *FileData, + uint64_t NumBytesToRead, + uint64_t StartingPosition) { + // DEBUG_START; + + uint64_t response = 0; + + // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); + // DEBUG_V (String (" NumBytesToRead: ") + String (NumBytesToRead)); + // DEBUG_V (String (" StartingPosition: ") + String (StartingPosition)); + + int FileListIndex; + if (-1 != (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + uint64_t BytesRemaining = + uint64_t(FileList[FileListIndex].size - StartingPosition); + uint64_t ActualBytesToRead = min(NumBytesToRead, BytesRemaining); + // DEBUG_V(String(" BytesRemaining: ") + String(BytesRemaining)); + // DEBUG_V(String("ActualBytesToRead: ") + String(ActualBytesToRead)); + LockSd(); + FileList[FileListIndex].fsFile.seek(StartingPosition); +#ifdef SIMULATE_SD + response = FileList[FileListIndex].fsFile.readBytes((char *)FileData, + ActualBytesToRead); +#else + response = + FileList[FileListIndex].fsFile.readBytes(FileData, ActualBytesToRead); +#endif // def SIMULATE_SD + UnLockSd(); + // DEBUG_V(String(" response: ") + String64(response)); + } else { + logcon(String(F("ReadSdFile::ERROR::Invalid File Handle: ")) + + String(FileHandle)); + } - // DEBUG_END; - return response; + // DEBUG_END; + return response; } // ReadSdFile //----------------------------------------------------------------------------- -void c_FileMgr::CloseSdFile (FileId& FileHandle) -{ - // DEBUG_START; - // DEBUG_V(String(" FileHandle: ") + String(FileHandle)); +void c_FileMgr::CloseSdFile(FileId &FileHandle) { + // DEBUG_START; + // DEBUG_V(String(" FileHandle: ") + String(FileHandle)); - int FileListIndex; - if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - // DEBUG_V("Close the file"); - LockSd(); - FileList[FileListIndex].fsFile.close (); - UnLockSd(); + int FileListIndex; + if (-1 != (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + // DEBUG_V("Close the file"); + LockSd(); + FileList[FileListIndex].fsFile.close(); + UnLockSd(); - FileList[FileListIndex].IsOpen = false; - FileList[FileListIndex].handle = INVALID_FILE_HANDLE; + FileList[FileListIndex].IsOpen = false; + FileList[FileListIndex].handle = INVALID_FILE_HANDLE; - if (nullptr != FileList[FileListIndex].buffer.DataBuffer) - { - if(FileList[FileListIndex].buffer.DataBuffer != OutputMgr.GetBufferAddress()) - { - // only free the buffer if it is not malloc'd - free(FileList[FileListIndex].buffer.DataBuffer); - } - } - FileList[FileListIndex].buffer.DataBuffer = nullptr; - FileList[FileListIndex].buffer.size = 0; - FileList[FileListIndex].buffer.offset = 0; - } - else - { - logcon (String (F ("CloseSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); + if (nullptr != FileList[FileListIndex].buffer.DataBuffer) { + if (FileList[FileListIndex].buffer.DataBuffer != + OutputMgr.GetBufferAddress()) { + // only free the buffer if it is not malloc'd + free(FileList[FileListIndex].buffer.DataBuffer); + } } + FileList[FileListIndex].buffer.DataBuffer = nullptr; + FileList[FileListIndex].buffer.size = 0; + FileList[FileListIndex].buffer.offset = 0; + } else { + logcon(String(F("CloseSdFile::ERROR::Invalid File Handle: ")) + + String(FileHandle)); + } - FileHandle = INVALID_FILE_HANDLE; + FileHandle = INVALID_FILE_HANDLE; - // DEBUG_END; + // DEBUG_END; } // CloseSdFile //----------------------------------------------------------------------------- -uint64_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, uint64_t NumBytesToWrite) -{ - // DEBUG_START; +uint64_t c_FileMgr::WriteSdFile(const FileId &FileHandle, byte *FileData, + uint64_t NumBytesToWrite) { + // DEBUG_START; - uint64_t NumBytesWritten = 0; - do // once - { - int FileListIndex; - // DEBUG_V (String("Bytes to write: ") + String(NumBytesToWrite)); - if (-1 == (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - // DEBUG_V (String("FileHandle: ") + String(FileHandle)); - logcon (String (F ("WriteSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); - break; - } + uint64_t NumBytesWritten = 0; + do // once + { + int FileListIndex; + // DEBUG_V (String("Bytes to write: ") + String(NumBytesToWrite)); + if (-1 == (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + // DEBUG_V (String("FileHandle: ") + String(FileHandle)); + logcon(String(F("WriteSdFile::ERROR::Invalid File Handle: ")) + + String(FileHandle)); + break; + } - // DEBUG_V (String("FileListIndex: ") + String(FileListIndex)); - delay(10); - FeedWDT(); - LockSd(); - // DEBUG_V(); - NumBytesWritten = FileList[FileListIndex].fsFile.write((uint8_t*)FileData, NumBytesToWrite); - // DEBUG_V(); - FileList[FileListIndex].fsFile.flush(); - // DEBUG_V(); - UnLockSd(); - FeedWDT(); - delay(10); - // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); - // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); - - if(NumBytesWritten != NumBytesToWrite) - { - logcon(String(F("ERROR: SD Write failed. Tried writting ")) + String(NumBytesToWrite) + F(" bytes. Actually wrote ") + String(NumBytesWritten) + F(" bytes.")); - NumBytesWritten = 0; - break; - } - } while(false); + // DEBUG_V (String("FileListIndex: ") + String(FileListIndex)); + delay(10); + FeedWDT(); + LockSd(); + // DEBUG_V(); + NumBytesWritten = FileList[FileListIndex].fsFile.write((uint8_t *)FileData, + NumBytesToWrite); + // DEBUG_V(); + FileList[FileListIndex].fsFile.flush(); + // DEBUG_V(); + UnLockSd(); + FeedWDT(); + delay(10); + // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); + // DEBUG_V (String ("File.Handle: ") + String + // (FileList[FileListIndex].handle)); + + if (NumBytesWritten != NumBytesToWrite) { + logcon(String(F("ERROR: SD Write failed. Tried writting ")) + + String(NumBytesToWrite) + F(" bytes. Actually wrote ") + + String(NumBytesWritten) + F(" bytes.")); + NumBytesWritten = 0; + break; + } + } while (false); - // DEBUG_END; - return NumBytesWritten; + // DEBUG_END; + return NumBytesWritten; } // WriteSdFile @@ -1696,834 +1599,795 @@ uint64_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, uint6 Specialized function that buffers data until the buffer is full and then writes out the buffer as a single operation. */ -uint64_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, uint64_t NumBytesInSourceBuffer) -{ - // DEBUG_START; - - uint64_t NumBytesWrittenToDestBuffer = 0; - bool ForceWriteToSD = (0 == NumBytesInSourceBuffer); - do // once - { - int FileListIndex; - // DEBUG_V (String(" NumBytesInSourceBuffer: ") + String(NumBytesInSourceBuffer)); - // DEBUG_V (String(" ForceWriteToSD: ") + String(ForceWriteToSD)); - if (-1 == (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - logcon (String (F ("WriteSdFileBuf::ERROR::Invalid File Handle: ")) + String (FileHandle)); - break; - } - - // are we using a buffer in front of the SD card? - if(nullptr == FileList[FileListIndex].buffer.DataBuffer) - { - delay(10); - FeedWDT(); - - // DEBUG_V("Not using buffers"); - LockSd(); - NumBytesWrittenToDestBuffer = FileList[FileListIndex].fsFile.write(FileData, NumBytesInSourceBuffer); - FileList[FileListIndex].fsFile.flush(); - UnLockSd(); - - delay(20); - FeedWDT(); - } - else // buffered mode - { - // DEBUG_V("Using buffers"); - // DEBUG_V(String(" NumBytesInSourceBuffer: ") + String(NumBytesInSourceBuffer)); - uint64_t SpaceRemaining = FileList[FileListIndex].buffer.size - FileList[FileListIndex].buffer.offset; - // DEBUG_V(String(" SpaceRemaining: ") + String(SpaceRemaining)); - - if(ForceWriteToSD || - (NumBytesInSourceBuffer && - (SpaceRemaining < NumBytesInSourceBuffer))) - { - // DEBUG_V("Write out the buffer"); - // delay(20); - // DEBUG_V(String(" BytesToBeWrittenToSD: ") + String(FileList[FileListIndex].buffer.offset)); - FeedWDT(); - LockSd(); - uint64_t WroteToSdSize = FileList[FileListIndex].fsFile.write(FileList[FileListIndex].buffer.DataBuffer, FileList[FileListIndex].buffer.offset); - FileList[FileListIndex].fsFile.flush(); - UnLockSd(); - delay(30); - FeedWDT(); - // DEBUG_V(String(" offset: ") + String(FileList[FileListIndex].buffer.offset)); - // DEBUG_V(String(" WroteToSdSize: ") + String(WroteToSdSize)); - if(FileList[FileListIndex].buffer.offset != WroteToSdSize) - { - logcon (String("WriteSdFileBuf:ERROR:SD Write Failed. Tried to write: ") + - String(FileList[FileListIndex].buffer.offset) + - " bytes. Actually wrote: " + String(WroteToSdSize)) - NumBytesWrittenToDestBuffer = 0; - break; - } // end write failed - // reset the buffer - FileList[FileListIndex].buffer.offset = 0; - // DEBUG_V(String(" New offset: ") + String(FileList[FileListIndex].buffer.offset)); - ForceWriteToSD = false; - } +uint64_t c_FileMgr::WriteSdFileBuf(const FileId &FileHandle, byte *FileData, + uint64_t NumBytesInSourceBuffer) { + // DEBUG_START; + + uint64_t NumBytesWrittenToDestBuffer = 0; + bool ForceWriteToSD = (0 == NumBytesInSourceBuffer); + do // once + { + int FileListIndex; + // DEBUG_V (String(" NumBytesInSourceBuffer: ") + + // String(NumBytesInSourceBuffer)); DEBUG_V (String(" ForceWriteToSD: ") + + // String(ForceWriteToSD)); + if (-1 == (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + logcon(String(F("WriteSdFileBuf::ERROR::Invalid File Handle: ")) + + String(FileHandle)); + break; + } - if(NumBytesInSourceBuffer) - { - // DEBUG_V(String(" Writing ") + String(NumBytesInSourceBuffer) + " bytes to the buffer"); - // DEBUG_V(String(" offset: ") + String(FileList[FileListIndex].buffer.offset)); - memcpy(&(FileList[FileListIndex].buffer.DataBuffer[FileList[FileListIndex].buffer.offset]), FileData, NumBytesInSourceBuffer); - - FileList[FileListIndex].buffer.offset += NumBytesInSourceBuffer; - NumBytesWrittenToDestBuffer += NumBytesInSourceBuffer; - NumBytesInSourceBuffer -= NumBytesInSourceBuffer; - // DEBUG_V(String("NumBytesWrittenToDestBuffer: ") + String(NumBytesWrittenToDestBuffer)); - // DEBUG_V(String(" NumBytesInSourceBuffer: ") + String(NumBytesInSourceBuffer)); - // DEBUG_V(String(" New offset: ") + String(FileList[FileListIndex].buffer.offset)); - - }; // End write to buffer - } - // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); - // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); + // are we using a buffer in front of the SD card? + if (nullptr == FileList[FileListIndex].buffer.DataBuffer) { + delay(10); + FeedWDT(); + + // DEBUG_V("Not using buffers"); + LockSd(); + NumBytesWrittenToDestBuffer = FileList[FileListIndex].fsFile.write( + FileData, NumBytesInSourceBuffer); + FileList[FileListIndex].fsFile.flush(); + UnLockSd(); + + delay(20); + FeedWDT(); + } else // buffered mode + { + // DEBUG_V("Using buffers"); + // DEBUG_V(String(" NumBytesInSourceBuffer: ") + + // String(NumBytesInSourceBuffer)); + uint64_t SpaceRemaining = FileList[FileListIndex].buffer.size - + FileList[FileListIndex].buffer.offset; + // DEBUG_V(String(" SpaceRemaining: ") + + // String(SpaceRemaining)); + + if (ForceWriteToSD || (NumBytesInSourceBuffer && + (SpaceRemaining < NumBytesInSourceBuffer))) { + // DEBUG_V("Write out the buffer"); + // delay(20); + // DEBUG_V(String(" BytesToBeWrittenToSD: ") + + // String(FileList[FileListIndex].buffer.offset)); + FeedWDT(); + LockSd(); + uint64_t WroteToSdSize = FileList[FileListIndex].fsFile.write( + FileList[FileListIndex].buffer.DataBuffer, + FileList[FileListIndex].buffer.offset); + FileList[FileListIndex].fsFile.flush(); + UnLockSd(); + delay(30); + FeedWDT(); + // DEBUG_V(String(" offset: ") + + // String(FileList[FileListIndex].buffer.offset)); DEBUG_V(String(" + // WroteToSdSize: ") + String(WroteToSdSize)); + if (FileList[FileListIndex].buffer.offset != WroteToSdSize) { + logcon( + String("WriteSdFileBuf:ERROR:SD Write Failed. Tried to write: ") + + String(FileList[FileListIndex].buffer.offset) + + " bytes. Actually wrote: " + String(WroteToSdSize)) + NumBytesWrittenToDestBuffer = 0; + break; + } // end write failed + // reset the buffer + FileList[FileListIndex].buffer.offset = 0; + // DEBUG_V(String(" New offset: ") + + // String(FileList[FileListIndex].buffer.offset)); + ForceWriteToSD = false; + } + + if (NumBytesInSourceBuffer) { + // DEBUG_V(String(" Writing ") + + // String(NumBytesInSourceBuffer) + " bytes to the buffer"); + // DEBUG_V(String(" offset: ") + + // String(FileList[FileListIndex].buffer.offset)); + memcpy(&(FileList[FileListIndex] + .buffer.DataBuffer[FileList[FileListIndex].buffer.offset]), + FileData, NumBytesInSourceBuffer); + + FileList[FileListIndex].buffer.offset += NumBytesInSourceBuffer; + NumBytesWrittenToDestBuffer += NumBytesInSourceBuffer; + NumBytesInSourceBuffer -= NumBytesInSourceBuffer; + // DEBUG_V(String("NumBytesWrittenToDestBuffer: ") + + // String(NumBytesWrittenToDestBuffer)); DEBUG_V(String(" + // NumBytesInSourceBuffer: ") + String(NumBytesInSourceBuffer)); + // DEBUG_V(String(" New offset: ") + + // String(FileList[FileListIndex].buffer.offset)); + + }; // End write to buffer + } + // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); + // DEBUG_V (String ("File.Handle: ") + String + // (FileList[FileListIndex].handle)); - } while(false); + } while (false); - // DEBUG_END; - return NumBytesWrittenToDestBuffer; + // DEBUG_END; + return NumBytesWrittenToDestBuffer; } // WriteSdFile //----------------------------------------------------------------------------- -uint64_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, uint64_t NumBytesToWrite, uint64_t StartingPosition) -{ - // DEBUG_START; - uint64_t response = 0; - int FileListIndex; - if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - // DEBUG_V (String (" NumBytesToWrite: ") + String (NumBytesToWrite)); - // DEBUG_V (String ("StartingPosition: ") + String (StartingPosition)); - // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); - // DEBUG_V (String (" File.Handle: ") + String (FileList[FileListIndex].handle)); - LockSd(); - FileList[FileListIndex].fsFile.seek (StartingPosition); - UnLockSd(); - response = WriteSdFile (FileHandle, FileData, NumBytesToWrite, true); - } - else - { - logcon (String (F ("WriteSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); - } +uint64_t c_FileMgr::WriteSdFile(const FileId &FileHandle, byte *FileData, + uint64_t NumBytesToWrite, + uint64_t StartingPosition) { + // DEBUG_START; + uint64_t response = 0; + int FileListIndex; + if (-1 != (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + // DEBUG_V (String (" NumBytesToWrite: ") + String (NumBytesToWrite)); + // DEBUG_V (String ("StartingPosition: ") + String (StartingPosition)); + // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); + // DEBUG_V (String (" File.Handle: ") + String + // (FileList[FileListIndex].handle)); + LockSd(); + FileList[FileListIndex].fsFile.seek(StartingPosition); + UnLockSd(); + response = WriteSdFile(FileHandle, FileData, NumBytesToWrite, true); + } else { + logcon(String(F("WriteSdFile::ERROR::Invalid File Handle: ")) + + String(FileHandle)); + } - // DEBUG_END; - return response; + // DEBUG_END; + return response; } // WriteSdFile //----------------------------------------------------------------------------- -uint64_t c_FileMgr::GetSdFileSize (const String& FileName) -{ - // DEBUG_START; - uint64_t response = 0; - FileId Handle = INVALID_FILE_HANDLE; - if(OpenSdFile (FileName, FileMode::FileRead, Handle, -1)) - { - response = GetSdFileSize(Handle); - // DEBUG_FILE_HANDLE (Handle); - CloseSdFile(Handle); - } - else - { - logcon(String(F("Could not open '")) + FileName + F("' to check size.")); - } - // DEBUG_END; - return response; +uint64_t c_FileMgr::GetSdFileSize(const String &FileName) { + // DEBUG_START; + uint64_t response = 0; + FileId Handle = INVALID_FILE_HANDLE; + if (OpenSdFile(FileName, FileMode::FileRead, Handle, -1)) { + response = GetSdFileSize(Handle); + // DEBUG_FILE_HANDLE (Handle); + CloseSdFile(Handle); + } else { + logcon(String(F("Could not open '")) + FileName + F("' to check size.")); + } + // DEBUG_END; + return response; } // GetSdFileSize //----------------------------------------------------------------------------- -uint64_t c_FileMgr::GetSdFileSize (const FileId& FileHandle) -{ - // DEBUG_START; +uint64_t c_FileMgr::GetSdFileSize(const FileId &FileHandle) { + // DEBUG_START; - uint64_t response = 0; - int FileListIndex; - if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - LockSd(); - response = FileList[FileListIndex].fsFile.size (); - UnLockSd(); - } - else - { - logcon (String (F ("GetSdFileSize::ERROR::Invalid File Handle: ")) + String (FileHandle)); - } - // DEBUG_V(String("response: ") + int64String(response)); + uint64_t response = 0; + int FileListIndex; + if (-1 != (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + LockSd(); + response = FileList[FileListIndex].fsFile.size(); + UnLockSd(); + } else { + logcon(String(F("GetSdFileSize::ERROR::Invalid File Handle: ")) + + String(FileHandle)); + } + // DEBUG_V(String("response: ") + int64String(response)); - // DEBUG_END; - return response; + // DEBUG_END; + return response; } // GetSdFileSize //----------------------------------------------------------------------------- -void c_FileMgr::RenameSdFile(const String & OldName, const String & NewName) -{ - // DEBUG_START; - // DEBUG_V(String("OldName: '") + OldName + "'"); - // DEBUG_V(String("NewName: '") + NewName + "'"); +void c_FileMgr::RenameSdFile(const String &OldName, const String &NewName) { + // DEBUG_START; + // DEBUG_V(String("OldName: '") + OldName + "'"); + // DEBUG_V(String("NewName: '") + NewName + "'"); #ifdef SIMULATE_SD - RenameFlashFile(String(CN_slashsdslash) + OldName, String(CN_slashsdslash) + NewName); + RenameFlashFile(String(CN_slashsdslash) + OldName, + String(CN_slashsdslash) + NewName); #else - LockSd(); - // only do this in the root dir - ESP_SD.chdir(); - // rename does not work if the target already exists - ESP_SD.remove(NewName); - if(!ESP_SD.rename(OldName, NewName)) - { - logcon(String(CN_stars) + F("Could not rename '") + OldName + F("' to '") + NewName + F("'") + CN_stars); - } - UnLockSd(); + LockSd(); + // only do this in the root dir + ESP_SD.chdir(); + // rename does not work if the target already exists + ESP_SD.remove(NewName); + if (!ESP_SD.rename(OldName, NewName)) { + logcon(String(CN_stars) + F("Could not rename '") + OldName + F("' to '") + + NewName + F("'") + CN_stars); + } + UnLockSd(); #endif // ndef SIMULATE_SD - // DEBUG_END; + // DEBUG_END; } // RenameSdFile //----------------------------------------------------------------------------- -void c_FileMgr::BuildFseqList(bool DisplayFileNames) -{ - // DEBUG_START; - - char entryName [256]; - do // once - { - if(!SdCardIsInstalled()) - { - // DEBUG_V("No SD card installed."); - BuildDefaultFseqList(); - break; - } +void c_FileMgr::BuildFseqList(bool DisplayFileNames) { + // DEBUG_START; + + char entryName[256]; + do // once + { + if (!SdCardIsInstalled()) { + // DEBUG_V("No SD card installed."); + BuildDefaultFseqList(); + break; + } - FeedWDT(); + FeedWDT(); - JsonDocument jsonDoc; - jsonDoc.to(); + JsonDocument jsonDoc; + jsonDoc.to(); - JsonWrite(jsonDoc, "totalBytes", SdCardSize); - JsonArray jsonDocFileList = jsonDoc["files"].to (); + JsonWrite(jsonDoc, "totalBytes", SdCardSize); + JsonArray jsonDocFileList = jsonDoc["files"].to(); - uint32_t FileIndex = 0; - uint64_t usedBytes = 0; - uint32_t numFiles = 0; + uint32_t FileIndex = 0; + uint64_t usedBytes = 0; + uint32_t numFiles = 0; - LockSd(); + LockSd(); #ifdef SIMULATE_SD - JsonWrite(jsonDoc, "usedBytes", ESP_SD.usedBytes()); - File InputDir = ESP_SD.open (CN_slashsd, CN_r); + JsonWrite(jsonDoc, "usedBytes", ESP_SD.usedBytes()); + File InputDir = ESP_SD.open(CN_slashsd, CN_r); #else - ESP_SD.chdir(); - FsFile InputDir = ESP_SD.open ("/", O_READ); - ESP_SD.chdir(); + ESP_SD.chdir(); + FsFile InputDir = ESP_SD.open("/", O_READ); + ESP_SD.chdir(); #endif // ndef SIMULATE_SD - if(!InputDir) - { - UnLockSd(); - logcon(F("ERROR: Could not open SD card for Reading FSEQ List.")); - break; - } + if (!InputDir) { + UnLockSd(); + logcon(F("ERROR: Could not open SD card for Reading FSEQ List.")); + break; + } - // DEBUG_V(String("InputDir Name: ") + String(InputDir.name())); + // DEBUG_V(String("InputDir Name: ") + String(InputDir.name())); #ifdef SIMULATE_SD - String CurrentEntryName = InputDir.getNextFileName(); - while (!CurrentEntryName.isEmpty()) - { - // DEBUG_V("Process a file entry"); - // DEBUG_V(String("CurrentEntryName: ") + CurrentEntryName); - - FeedWDT(); - - File CurrentEntry = ESP_SD.open(CurrentEntryName, CN_r); - if(CurrentEntry.isDirectory()) - { - // DEBUG_V("Skip embedded directory and hidden files"); - CurrentEntry.close(); - continue; - } - - String EntryName = String (CurrentEntry.name()); - // DEBUG_V ( "EntryName: " + EntryName); - // DEBUG_V (" EntryName.length(): " + String(EntryName.length ())); - // DEBUG_V ("CurrentEntry.size(): " + String(CurrentEntry.size ())); - - if ((!EntryName.isEmpty ()) && (0 != CurrentEntry.size ())) - { - FoundZipFile |= IsCompressed(EntryName); - - usedBytes += CurrentEntry.size (); - ++numFiles; - - if(DisplayFileNames) - { - logcon (String(F("SD File: '")) + EntryName + "' " + String(CurrentEntry.size ())); - } - uint16_t Date; - uint16_t Time; - // CurrentEntry.getCreateDateTime (&Date, &Time); - // DEBUG_V(String("Date: ") + String(Date)); - // DEBUG_V(String("Year: ") + String(FS_YEAR(Date))); - // DEBUG_V(String("Day: ") + String(FS_DAY(Date))); - // DEBUG_V(String("Month: ") + String(FS_MONTH(Date))); - - // DEBUG_V(String("Time: ") + String(Time)); - // DEBUG_V(String("Hours: ") + String(FS_HOUR(Time))); - // DEBUG_V(String("Minutes: ") + String(FS_MINUTE(Time))); - // DEBUG_V(String("Seconds: ") + String(FS_SECOND(Time))); - - tmElements_t tm; - tm.Year = FS_YEAR(Date) - 1970; - tm.Month = FS_MONTH(Date); - tm.Day = FS_DAY(Date); - tm.Hour = FS_HOUR(Time); - tm.Minute = FS_MINUTE(Time); - tm.Second = FS_SECOND(Time); - - // DEBUG_V(String("tm: ") + String(time_t(makeTime(tm)))); - jsonDocFileList[FileIndex]["name"] = EntryName; - jsonDocFileList[FileIndex]["date"] = makeTime(tm); - jsonDocFileList[FileIndex]["length"] = CurrentEntry.size (); - ++FileIndex; - } - else - { - // DEBUG_V("Skipping File"); - } - CurrentEntry.close(); - CurrentEntryName = InputDir.getNextFileName (); - - } // end while true - #else - FsFile CurrentEntry; - while (CurrentEntry.openNext (&InputDir, O_READ)) - { - // DEBUG_V("Process a file entry"); - FeedWDT(); - - if(CurrentEntry.isDirectory() || CurrentEntry.isHidden()) - { - // DEBUG_V("Skip embedded directory and hidden files"); - CurrentEntry.close(); - continue; - } - - memset(entryName, 0x0, sizeof(entryName)); - CurrentEntry.getName (entryName, sizeof(entryName)-1); - String EntryName = String (entryName); - // DEBUG_V ( "EntryName: " + EntryName); - // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); - // DEBUG_V (" entry.size(): " + int64String(CurrentEntry.size ())); - - if ((!EntryName.isEmpty ()) && - (0 != CurrentEntry.size ()) - ) - { - FoundZipFile |= IsCompressed(EntryName); - - usedBytes += CurrentEntry.size (); - ++numFiles; - - if(DisplayFileNames) - { - logcon (String(F("SD File: '")) + EntryName + "' " + String(CurrentEntry.size ())); - } - uint16_t Date; - uint16_t Time; - CurrentEntry.getCreateDateTime (&Date, &Time); - // DEBUG_V(String("Date: ") + String(Date)); - // DEBUG_V(String("Year: ") + String(FS_YEAR(Date))); - // DEBUG_V(String("Day: ") + String(FS_DAY(Date))); - // DEBUG_V(String("Month: ") + String(FS_MONTH(Date))); - - // DEBUG_V(String("Time: ") + String(Time)); - // DEBUG_V(String("Hours: ") + String(FS_HOUR(Time))); - // DEBUG_V(String("Minutes: ") + String(FS_MINUTE(Time))); - // DEBUG_V(String("Seconds: ") + String(FS_SECOND(Time))); - - tmElements_t tm; - tm.Year = FS_YEAR(Date) - 1970; - tm.Month = FS_MONTH(Date); - tm.Day = FS_DAY(Date); - tm.Hour = FS_HOUR(Time); - tm.Minute = FS_MINUTE(Time); - tm.Second = FS_SECOND(Time); - - // DEBUG_V(String("tm: ") + String(time_t(makeTime(tm)))); - jsonDocFileList[FileIndex]["name"] = EntryName; - jsonDocFileList[FileIndex]["date"] = makeTime(tm); - jsonDocFileList[FileIndex]["length"] = CurrentEntry.size (); - ++FileIndex; - } - else - { - // DEBUG_V("Skipping File"); - } - CurrentEntry.close(); - } // end while true - - JsonWrite(jsonDoc, "usedBytes", usedBytes); + String CurrentEntryName = InputDir.getNextFileName(); + while (!CurrentEntryName.isEmpty()) { + // DEBUG_V("Process a file entry"); + // DEBUG_V(String("CurrentEntryName: ") + CurrentEntryName); + + FeedWDT(); + + File CurrentEntry = ESP_SD.open(CurrentEntryName, CN_r); + if (CurrentEntry.isDirectory()) { + // DEBUG_V("Skip embedded directory and hidden files"); + CurrentEntry.close(); + continue; + } + + String EntryName = String(CurrentEntry.name()); + // DEBUG_V ( "EntryName: " + EntryName); + // DEBUG_V (" EntryName.length(): " + String(EntryName.length ())); + // DEBUG_V ("CurrentEntry.size(): " + String(CurrentEntry.size ())); + + if ((!EntryName.isEmpty()) && (0 != CurrentEntry.size())) { + FoundZipFile |= IsCompressed(EntryName); + + usedBytes += CurrentEntry.size(); + ++numFiles; + + if (DisplayFileNames) { + logcon(String(F("SD File: '")) + EntryName + "' " + + String(CurrentEntry.size())); + } + uint16_t Date; + uint16_t Time; + // CurrentEntry.getCreateDateTime (&Date, &Time); + // DEBUG_V(String("Date: ") + String(Date)); + // DEBUG_V(String("Year: ") + String(FS_YEAR(Date))); + // DEBUG_V(String("Day: ") + String(FS_DAY(Date))); + // DEBUG_V(String("Month: ") + String(FS_MONTH(Date))); + + // DEBUG_V(String("Time: ") + String(Time)); + // DEBUG_V(String("Hours: ") + String(FS_HOUR(Time))); + // DEBUG_V(String("Minutes: ") + String(FS_MINUTE(Time))); + // DEBUG_V(String("Seconds: ") + String(FS_SECOND(Time))); + + tmElements_t tm; + tm.Year = FS_YEAR(Date) - 1970; + tm.Month = FS_MONTH(Date); + tm.Day = FS_DAY(Date); + tm.Hour = FS_HOUR(Time); + tm.Minute = FS_MINUTE(Time); + tm.Second = FS_SECOND(Time); + + // DEBUG_V(String("tm: ") + String(time_t(makeTime(tm)))); + jsonDocFileList[FileIndex]["name"] = EntryName; + jsonDocFileList[FileIndex]["date"] = makeTime(tm); + jsonDocFileList[FileIndex]["length"] = CurrentEntry.size(); + ++FileIndex; + } else { + // DEBUG_V("Skipping File"); + } + CurrentEntry.close(); + CurrentEntryName = InputDir.getNextFileName(); + + } // end while true +#else + FsFile CurrentEntry; + while (CurrentEntry.openNext(&InputDir, O_READ)) { + // DEBUG_V("Process a file entry"); + FeedWDT(); + + if (CurrentEntry.isDirectory() || CurrentEntry.isHidden()) { + // DEBUG_V("Skip embedded directory and hidden files"); + CurrentEntry.close(); + continue; + } + + memset(entryName, 0x0, sizeof(entryName)); + CurrentEntry.getName(entryName, sizeof(entryName) - 1); + String EntryName = String(entryName); + // DEBUG_V ( "EntryName: " + EntryName); + // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); + // DEBUG_V (" entry.size(): " + int64String(CurrentEntry.size ())); + + if ((!EntryName.isEmpty()) && (0 != CurrentEntry.size())) { + FoundZipFile |= IsCompressed(EntryName); + + usedBytes += CurrentEntry.size(); + ++numFiles; + + if (DisplayFileNames) { + logcon(String(F("SD File: '")) + EntryName + "' " + + String(CurrentEntry.size())); + } + uint16_t Date; + uint16_t Time; + CurrentEntry.getCreateDateTime(&Date, &Time); + // DEBUG_V(String("Date: ") + String(Date)); + // DEBUG_V(String("Year: ") + String(FS_YEAR(Date))); + // DEBUG_V(String("Day: ") + String(FS_DAY(Date))); + // DEBUG_V(String("Month: ") + String(FS_MONTH(Date))); + + // DEBUG_V(String("Time: ") + String(Time)); + // DEBUG_V(String("Hours: ") + String(FS_HOUR(Time))); + // DEBUG_V(String("Minutes: ") + String(FS_MINUTE(Time))); + // DEBUG_V(String("Seconds: ") + String(FS_SECOND(Time))); + + tmElements_t tm; + tm.Year = FS_YEAR(Date) - 1970; + tm.Month = FS_MONTH(Date); + tm.Day = FS_DAY(Date); + tm.Hour = FS_HOUR(Time); + tm.Minute = FS_MINUTE(Time); + tm.Second = FS_SECOND(Time); + + // DEBUG_V(String("tm: ") + String(time_t(makeTime(tm)))); + jsonDocFileList[FileIndex]["name"] = EntryName; + jsonDocFileList[FileIndex]["date"] = makeTime(tm); + jsonDocFileList[FileIndex]["length"] = CurrentEntry.size(); + ++FileIndex; + } else { + // DEBUG_V("Skipping File"); + } + CurrentEntry.close(); + } // end while true + + JsonWrite(jsonDoc, "usedBytes", usedBytes); - #endif // ndef SIMULATE_SD +#endif // ndef SIMULATE_SD - InputDir.close(); - UnLockSd(); + InputDir.close(); + UnLockSd(); - // close the array and add the descriptive data - JsonWrite(jsonDoc, "numFiles", numFiles); - JsonWrite(jsonDoc, "SdCardPresent", true); - // PrettyPrint (jsonDoc, String ("FSEQ File List")); - SaveFlashFile(String(CN_fseqfilelist) + F(".json"), jsonDoc); - } while(false); + // close the array and add the descriptive data + JsonWrite(jsonDoc, "numFiles", numFiles); + JsonWrite(jsonDoc, "SdCardPresent", true); + // PrettyPrint (jsonDoc, String ("FSEQ File List")); + SaveFlashFile(String(CN_fseqfilelist) + F(".json"), jsonDoc); + } while (false); - // String Temp; - // ReadFlashFile(FSEQFILELIST, Temp); - // xDEBUG_V(Temp); + // String Temp; + // ReadFlashFile(FSEQFILELIST, Temp); + // xDEBUG_V(Temp); - // DEBUG_END; + // DEBUG_END; } // BuildFseqList //----------------------------------------------------------------------------- -void c_FileMgr::FindFirstZipFile(String &FileName) -{ - // DEBUG_START; - char entryName [256]; - - do // once - { - if(!SdCardIsInstalled()) - { - // DEBUG_V("No SD card installed."); - break; - } +void c_FileMgr::FindFirstZipFile(String &FileName) { + // DEBUG_START; + char entryName[256]; + + do // once + { + if (!SdCardIsInstalled()) { + // DEBUG_V("No SD card installed."); + break; + } - FeedWDT(); - LockSd(); + FeedWDT(); + LockSd(); #ifdef SIMULATE_SD - File InputFile; - InputFile = ESP_SD.open(CN_slashsd, CN_r); - if(!InputFile) + File InputFile; + InputFile = ESP_SD.open(CN_slashsd, CN_r); + if (!InputFile) #else - FsFile InputFile; - ESP_SD.chdir(); - if(!InputFile.open ("/", O_READ)) + FsFile InputFile; + ESP_SD.chdir(); + if (!InputFile.open("/", O_READ)) #endif // ndef SIMULATE_SD - { - UnLockSd(); - logcon(F("ERROR: Could not open SD card for Reading FSEQ List.")); - break; - } - - // open output file, erase old data - #ifdef SIMULATE_SD - - File CurrentEntry = InputFile.openNextFile(); - while (CurrentEntry) - { - // DEBUG_V("Process a file entry"); - FeedWDT(); - - if(CurrentEntry.isDirectory()) - { - // DEBUG_V("Skip embedded directory and hidden files"); - CurrentEntry.close(); - continue; - } - - String EntryName = String (CurrentEntry.name()); - // DEBUG_V ( "EntryName: " + EntryName); - // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); - // DEBUG_V (String(" entry.size(): ") + int64String(CurrentEntry.size ())); + { + UnLockSd(); + logcon(F("ERROR: Could not open SD card for Reading FSEQ List.")); + break; + } - // is this a zipped file? - if(IsCompressed(EntryName)) - { - FileName = EntryName; - CurrentEntry.close(); - // InputFile.close(); - break; - } - else - { - // DEBUG_V("Skipping File"); - } - CurrentEntry.close(); - CurrentEntry = InputFile.openNextFile(); - } // end while true - #else - ESP_SD.chdir(); - - FsFile CurrentEntry; - while (CurrentEntry.openNext (&InputFile, O_READ)) - { - // DEBUG_V("Process a file entry"); - FeedWDT(); - - if(CurrentEntry.isDirectory() || CurrentEntry.isHidden()) - { - // DEBUG_V("Skip embedded directory and hidden files"); - CurrentEntry.close(); - continue; - } +// open output file, erase old data +#ifdef SIMULATE_SD - memset(entryName, 0x0, sizeof(entryName)); - CurrentEntry.getName (entryName, sizeof(entryName)-1); - String EntryName = String (entryName); - // DEBUG_V ( "EntryName: " + EntryName); - // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); - // DEBUG_V (" entry.size(): " + int64String(CurrentEntry.size ())); + File CurrentEntry = InputFile.openNextFile(); + while (CurrentEntry) { + // DEBUG_V("Process a file entry"); + FeedWDT(); + + if (CurrentEntry.isDirectory()) { + // DEBUG_V("Skip embedded directory and hidden files"); + CurrentEntry.close(); + continue; + } + + String EntryName = String(CurrentEntry.name()); + // DEBUG_V ( "EntryName: " + EntryName); + // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); + // DEBUG_V (String(" entry.size(): ") + int64String(CurrentEntry.size + // ())); + + // is this a zipped file? + if (IsCompressed(EntryName)) { + FileName = EntryName; + CurrentEntry.close(); + // InputFile.close(); + break; + } else { + // DEBUG_V("Skipping File"); + } + CurrentEntry.close(); + CurrentEntry = InputFile.openNextFile(); + } // end while true +#else + ESP_SD.chdir(); - // is this a zipped file? - if(IsCompressed(EntryName)) - { - FileName = EntryName; - CurrentEntry.close(); - InputFile.close(); - break; - } - else - { - // DEBUG_V("Skipping File"); - } - CurrentEntry.close(); - } // end while true + FsFile CurrentEntry; + while (CurrentEntry.openNext(&InputFile, O_READ)) { + // DEBUG_V("Process a file entry"); + FeedWDT(); + + if (CurrentEntry.isDirectory() || CurrentEntry.isHidden()) { + // DEBUG_V("Skip embedded directory and hidden files"); + CurrentEntry.close(); + continue; + } + + memset(entryName, 0x0, sizeof(entryName)); + CurrentEntry.getName(entryName, sizeof(entryName) - 1); + String EntryName = String(entryName); + // DEBUG_V ( "EntryName: " + EntryName); + // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); + // DEBUG_V (" entry.size(): " + int64String(CurrentEntry.size ())); + + // is this a zipped file? + if (IsCompressed(EntryName)) { + FileName = EntryName; + CurrentEntry.close(); + InputFile.close(); + break; + } else { + // DEBUG_V("Skipping File"); + } + CurrentEntry.close(); + } // end while true - #endif // ndef SIMULATE_SD +#endif // ndef SIMULATE_SD - InputFile.close(); - UnLockSd(); - } while(false); + InputFile.close(); + UnLockSd(); + } while (false); - // DEBUG_END; + // DEBUG_END; } // FindFirstZipFile //----------------------------------------------------------------------------- -bool c_FileMgr::handleFileUpload ( - const String & filename, - size_t index, - uint8_t* data, - size_t len, - bool final, - uint32_t totalLen) -{ - // DEBUG_START; - bool response = false; - - // try to keep a reboot from causing a corrupted file - // DelayReboot(10000); - - // DEBUG_V (String ("filename: ") + filename); - // DEBUG_V (String (" index: ") + String (index)); - // DEBUG_V (String (" len: ") + String (len)); - // DEBUG_V (String (" final: ") + String (final)); - // DEBUG_V (String (" total: ") + String (totalLen)); - - do // once - { - FeedWDT(); - if ((0 == index)) - { - // DEBUG_V("New File"); - handleFileUploadNewFile (filename); - expectedIndex = 0; - // LOG_PORT.println("."); - } +bool c_FileMgr::handleFileUpload(const String &filename, size_t index, + uint8_t *data, size_t len, bool final, + uint32_t totalLen) { + // DEBUG_START; + bool response = false; + + // try to keep a reboot from causing a corrupted file + // DelayReboot(10000); + + // DEBUG_V (String ("filename: ") + filename); + // DEBUG_V (String (" index: ") + String (index)); + // DEBUG_V (String (" len: ") + String (len)); + // DEBUG_V (String (" final: ") + String (final)); + // DEBUG_V (String (" total: ") + String (totalLen)); + + do // once + { + FeedWDT(); + if ((0 == index)) { + // DEBUG_V("New File"); + handleFileUploadNewFile(filename); + expectedIndex = 0; + // LOG_PORT.println("."); + } - if (index != expectedIndex) - { - if(fsUploadFileHandle != INVALID_FILE_HANDLE) - { - logcon (String(F("ERROR: Expected index: ")) + String(expectedIndex) + F(" does not match actual index: ") + String(index)); - - // DEBUG_FILE_HANDLE (fsUploadFileHandle); - // DEBUG_V(String("fsUploadFileName: ") + fsUploadFileName); - CloseSdFile (fsUploadFileHandle); - // DEBUG_V(String("fsUploadFileName: ") + fsUploadFileName); - DeleteSdFile (fsUploadFileName); - delay(100); - BuildFseqList(false); - expectedIndex = 0; - fsUploadFileName.clear(); - } - break; - } + if (index != expectedIndex) { + if (fsUploadFileHandle != INVALID_FILE_HANDLE) { + logcon(String(F("ERROR: Expected index: ")) + String(expectedIndex) + + F(" does not match actual index: ") + String(index)); + + // DEBUG_FILE_HANDLE (fsUploadFileHandle); + // DEBUG_V(String("fsUploadFileName: ") + fsUploadFileName); + CloseSdFile(fsUploadFileHandle); + // DEBUG_V(String("fsUploadFileName: ") + fsUploadFileName); + DeleteSdFile(fsUploadFileName); + delay(100); + BuildFseqList(false); + expectedIndex = 0; + fsUploadFileName.clear(); + } + break; + } - // DEBUG_V (String ("fsUploadFileName: ") + String (fsUploadFileName)); + // DEBUG_V (String ("fsUploadFileName: ") + String (fsUploadFileName)); - // update the next expected chunk id - expectedIndex = index + len; - size_t bytesWritten = 0; + // update the next expected chunk id + expectedIndex = index + len; + size_t bytesWritten = 0; - if (len) - { - // Write data - // DEBUG_V ("UploadWrite: " + String (len) + String (" bytes")); - bytesWritten = WriteSdFileBuf (fsUploadFileHandle, data, len); - // DEBUG_V (String ("Writing bytes: ") + String (index)); + if (len) { + // Write data + // DEBUG_V ("UploadWrite: " + String (len) + String (" bytes")); + bytesWritten = WriteSdFileBuf(fsUploadFileHandle, data, len); + // DEBUG_V (String ("Writing bytes: ") + String (index)); #ifdef ARDUINO_ARCH_ESP32 - LOG_PORT.println(String("\033[Fprogress: ") + String(expectedIndex) + ", heap: " + String(heap_caps_get_largest_free_block(0x1800))); + LOG_PORT.println( + String("\033[Fprogress: ") + String(expectedIndex) + + ", heap: " + String(heap_caps_get_largest_free_block(0x1800))); #else - LOG_PORT.println(String("\033[Fprogress: ") + String(expectedIndex) + ", heap: " + String(ESP.getFreeHeap ())); + LOG_PORT.println(String("\033[Fprogress: ") + String(expectedIndex) + + ", heap: " + String(ESP.getFreeHeap())); #endif // def ARDUINO_ARCH_ESP32 - LOG_PORT.flush(); - } - // PauseSdFile(fsUploadFile); - - if(len != bytesWritten) - { - // DEBUG_V("Write failed. Stop transfer"); - // DEBUG_FILE_HANDLE (fsUploadFileHandle); - CloseSdFile(fsUploadFileHandle); - DeleteSdFile (fsUploadFileName); - expectedIndex = 0; - fsUploadFileName.clear(); - break; - } - response = true; - } while(false); - - if ((true == final) && (fsUploadFileHandle != INVALID_FILE_HANDLE)) - { - // DEBUG_V(String("fsUploadFileName: ") + String(fsUploadFileName)); - // cause the remainder in the buffer to be written. - WriteSdFileBuf (fsUploadFileHandle, data, 0); - uint32_t uploadTime = (uint32_t)(millis() - fsUploadStartTime) / 1000; - FeedWDT(); - // DEBUG_FILE_HANDLE (fsUploadFileHandle); - CloseSdFile (fsUploadFileHandle); - - logcon (String (F ("Upload File: '")) + fsUploadFileName + - F ("' Done (") + String (uploadTime) + - F ("s). Received: ") + String(expectedIndex) + - F(" Bytes out of ") + String(totalLen) + - F(" bytes. FileLen: ") + GetSdFileSize(filename)); - - FeedWDT(); - expectedIndex = 0; - - delay(100); - BuildFseqList(false); - - OutputMgr.ClearBuffer(); - OutputMgr.PauseOutputs(false); - InputMgr.SetOperationalState(false); + LOG_PORT.flush(); + } + // PauseSdFile(fsUploadFile); + + if (len != bytesWritten) { + // DEBUG_V("Write failed. Stop transfer"); + // DEBUG_FILE_HANDLE (fsUploadFileHandle); + CloseSdFile(fsUploadFileHandle); + DeleteSdFile(fsUploadFileName); + expectedIndex = 0; + fsUploadFileName.clear(); + break; + } + response = true; + } while (false); - // DEBUG_V(String("Expected: ") + String(totalLen)); - // DEBUG_V(String(" Got: ") + String(GetSdFileSize(fsUploadFileName))); - if(IsCompressed(fsUploadFileName)) - { - // String reason = F("Reboot after receiving a compressed file"); - // RequestReboot(reason, 100000); - } + if ((true == final) && (fsUploadFileHandle != INVALID_FILE_HANDLE)) { + // DEBUG_V(String("fsUploadFileName: ") + String(fsUploadFileName)); + // cause the remainder in the buffer to be written. + WriteSdFileBuf(fsUploadFileHandle, data, 0); + uint32_t uploadTime = (uint32_t)(millis() - fsUploadStartTime) / 1000; + FeedWDT(); + // DEBUG_FILE_HANDLE (fsUploadFileHandle); + CloseSdFile(fsUploadFileHandle); - fsUploadFileName.clear(); - } + logcon(String(F("Upload File: '")) + fsUploadFileName + F("' Done (") + + String(uploadTime) + F("s). Received: ") + String(expectedIndex) + + F(" Bytes out of ") + String(totalLen) + F(" bytes. FileLen: ") + + GetSdFileSize(filename)); - // DEBUG_END; - return response; -} // handleFileUpload + FeedWDT(); + expectedIndex = 0; -//----------------------------------------------------------------------------- -void c_FileMgr::handleFileUploadNewFile (const String & filename) -{ - // DEBUG_START; - // DEBUG_V ("UploadStart: " + filename); + delay(100); + BuildFseqList(false); - fsUploadStartTime = millis(); - // DEBUG_V(String("filename: ") + String(filename)); + OutputMgr.ClearBuffer(); + OutputMgr.PauseOutputs(false); + InputMgr.SetOperationalState(false); - // are we terminating the previous download? - if (!fsUploadFileName.isEmpty()) - { - logcon (String (F ("Aborting Previous File Upload For: '")) + fsUploadFileName + String (F ("'"))); - // DEBUG_FILE_HANDLE (fsUploadFileHandle); - CloseSdFile (fsUploadFileHandle); + // DEBUG_V(String("Expected: ") + String(totalLen)); + // DEBUG_V(String(" Got: ") + String(GetSdFileSize(fsUploadFileName))); + if (IsCompressed(fsUploadFileName)) { + // String reason = F("Reboot after receiving a compressed file"); + // RequestReboot(reason, 100000); } - // Set up to receive a file fsUploadFileName.clear(); - fsUploadFileName = filename; - - logcon (String (F ("Upload File: '")) + fsUploadFileName + String (F ("' Started"))); - - DeleteSdFile (fsUploadFileName); + } - // Open the file for writing - // DEBUG_V(String("fsUploadFileName: ") + String(fsUploadFileName)); - OpenSdFile (fsUploadFileName, FileMode::FileWrite, fsUploadFileHandle, -1 /*first access*/); - int FileListIndex; - if (-1 == (FileListIndex = FileListFindSdFileHandle (fsUploadFileHandle))) - { - logcon (String (F ("WriteSdFileBuf::ERROR::Invalid File Handle: ")) + String (fsUploadFileHandle)); - } - else - { - // DEBUG_V("Use the output buffer as a data buffer"); - FileList[FileListIndex].buffer.offset = 0; - FileList[FileListIndex].buffer.size = min(uint32_t(OutputMgr.GetBufferSize() & ~(SD_BLOCK_SIZE - 1)), uint32_t(MAX_SD_BUFFER_SIZE)); - FileList[FileListIndex].buffer.DataBuffer = OutputMgr.GetBufferAddress(); - OutputMgr.PauseOutputs(true); - InputMgr.SetOperationalState(false); - OutputMgr.ClearBuffer(); - // DEBUG_V(String("Buffer Size: ") + String(FileList[FileListIndex].buffer.size)); - } + // DEBUG_END; + return response; +} // handleFileUpload - // DEBUG_END; +//----------------------------------------------------------------------------- +void c_FileMgr::handleFileUploadNewFile(const String &filename) { + // DEBUG_START; + // DEBUG_V ("UploadStart: " + filename); + + fsUploadStartTime = millis(); + // DEBUG_V(String("filename: ") + String(filename)); + + // are we terminating the previous download? + if (!fsUploadFileName.isEmpty()) { + logcon(String(F("Aborting Previous File Upload For: '")) + + fsUploadFileName + String(F("'"))); + // DEBUG_FILE_HANDLE (fsUploadFileHandle); + CloseSdFile(fsUploadFileHandle); + } + + // Set up to receive a file + fsUploadFileName.clear(); + fsUploadFileName = filename; + + logcon(String(F("Upload File: '")) + fsUploadFileName + + String(F("' Started"))); + + DeleteSdFile(fsUploadFileName); + + // Open the file for writing + // DEBUG_V(String("fsUploadFileName: ") + String(fsUploadFileName)); + OpenSdFile(fsUploadFileName, FileMode::FileWrite, fsUploadFileHandle, + -1 /*first access*/); + int FileListIndex; + if (-1 == (FileListIndex = FileListFindSdFileHandle(fsUploadFileHandle))) { + logcon(String(F("WriteSdFileBuf::ERROR::Invalid File Handle: ")) + + String(fsUploadFileHandle)); + } else { + // DEBUG_V("Use the output buffer as a data buffer"); + FileList[FileListIndex].buffer.offset = 0; + FileList[FileListIndex].buffer.size = + min(uint32_t(OutputMgr.GetBufferSize() & ~(SD_BLOCK_SIZE - 1)), + uint32_t(MAX_SD_BUFFER_SIZE)); + FileList[FileListIndex].buffer.DataBuffer = OutputMgr.GetBufferAddress(); + OutputMgr.PauseOutputs(true); + InputMgr.SetOperationalState(false); + OutputMgr.ClearBuffer(); + // DEBUG_V(String("Buffer Size: ") + + // String(FileList[FileListIndex].buffer.size)); + } + + // DEBUG_END; } // handleFileUploadNewFile //----------------------------------------------------------------------------- -void c_FileMgr::BuildDefaultFseqList () -{ - // DEBUG_START; +void c_FileMgr::BuildDefaultFseqList() { + // DEBUG_START; - JsonDocument jsonDoc; - jsonDoc.to(); - JsonWrite(jsonDoc, "SdCardPresent", false); - JsonWrite(jsonDoc, "totalBytes", 0); - JsonWrite(jsonDoc, "usedBytes", 0); - JsonWrite(jsonDoc, "numFiles", 0); - jsonDoc["files"].to (); - SaveFlashFile(String(CN_fseqfilelist) + F(".json"), jsonDoc); + JsonDocument jsonDoc; + jsonDoc.to(); + JsonWrite(jsonDoc, "SdCardPresent", false); + JsonWrite(jsonDoc, "totalBytes", 0); + JsonWrite(jsonDoc, "usedBytes", 0); + JsonWrite(jsonDoc, "numFiles", 0); + jsonDoc["files"].to(); + SaveFlashFile(String(CN_fseqfilelist) + F(".json"), jsonDoc); - // DEBUG_END; + // DEBUG_END; - return; + return; } // BuildDefaultFseqList //----------------------------------------------------------------------------- -bool c_FileMgr::SeekSdFile(const FileId & FileHandle, uint64_t position, SeekMode Mode) -{ - // DEBUG_START; - - // DEBUG_V(String("FileHandle: ") + String(FileHandle)); - // DEBUG_V(String(" position: ") + String(position)); - // DEBUG_V(String(" Mode: ") + String(uint32_t(Mode))); - - bool response = false; - int FileListIndex; - do // once - { - if (-1 == (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - logcon (String (F ("SeekSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); - break; - } +bool c_FileMgr::SeekSdFile(const FileId &FileHandle, uint64_t position, + SeekMode Mode) { + // DEBUG_START; + + // DEBUG_V(String("FileHandle: ") + String(FileHandle)); + // DEBUG_V(String(" position: ") + String(position)); + // DEBUG_V(String(" Mode: ") + String(uint32_t(Mode))); + + bool response = false; + int FileListIndex; + do // once + { + if (-1 == (FileListIndex = FileListFindSdFileHandle(FileHandle))) { + logcon(String(F("SeekSdFile::ERROR::Invalid File Handle: ")) + + String(FileHandle)); + break; + } - LockSd(); - switch(Mode) - { - case SeekMode::SeekSet: - { - response = FileList[FileListIndex].fsFile.seek (position); - break; - } - case SeekMode::SeekEnd: - { - uint64_t EndPosition = FileList[FileListIndex].fsFile.size(); - response = FileList[FileListIndex].fsFile.seek (EndPosition - position); - break; - } - case SeekMode::SeekCur: - { - uint64_t CurrentPosition = FileList[FileListIndex].fsFile.position(); - response = FileList[FileListIndex].fsFile.seek (CurrentPosition + position); - break; - } - default: - { - logcon("Procedural error. Cannot set seek value"); - break; - } - } // end switch mode - UnLockSd(); - } while(false); + LockSd(); + switch (Mode) { + case SeekMode::SeekSet: { + response = FileList[FileListIndex].fsFile.seek(position); + break; + } + case SeekMode::SeekEnd: { + uint64_t EndPosition = FileList[FileListIndex].fsFile.size(); + response = FileList[FileListIndex].fsFile.seek(EndPosition - position); + break; + } + case SeekMode::SeekCur: { + uint64_t CurrentPosition = FileList[FileListIndex].fsFile.position(); + response = + FileList[FileListIndex].fsFile.seek(CurrentPosition + position); + break; + } + default: { + logcon("Procedural error. Cannot set seek value"); + break; + } + } // end switch mode + UnLockSd(); + } while (false); - // DEBUG_END; - return response; + // DEBUG_END; + return response; } // SeekSdFile //----------------------------------------------------------------------------- -void c_FileMgr::LockSd() -{ - // DEBUG_START; +void c_FileMgr::LockSd() { + // DEBUG_START; #ifdef ARDUINO_ARCH_ESP32 - xSemaphoreTake( SdAccessSemaphore, TickType_t(-1) ); + xSemaphoreTake(SdAccessSemaphore, TickType_t(-1)); #endif // def ARDUINO_ARCH_ESP32 - // DEBUG_END; + // DEBUG_END; } // LockSd //----------------------------------------------------------------------------- -void c_FileMgr::UnLockSd() -{ - // DEBUG_START; +void c_FileMgr::UnLockSd() { + // DEBUG_START; #ifdef ARDUINO_ARCH_ESP32 - xSemaphoreGive( SdAccessSemaphore ); + xSemaphoreGive(SdAccessSemaphore); #endif // def ARDUINO_ARCH_ESP32 - // DEBUG_END; + // DEBUG_END; } // UnLockSd //----------------------------------------------------------------------------- -void c_FileMgr::AbortSdFileUpload() -{ - // DEBUG_START; +void c_FileMgr::AbortSdFileUpload() { + // DEBUG_START; - if(fsUploadFileHandle != INVALID_FILE_HANDLE) - { - // DEBUG_FILE_HANDLE (fsUploadFileHandle); - CloseSdFile(fsUploadFileHandle); - } + if (fsUploadFileHandle != INVALID_FILE_HANDLE) { + // DEBUG_FILE_HANDLE (fsUploadFileHandle); + CloseSdFile(fsUploadFileHandle); + } - // DEBUG_END; + // DEBUG_END; } // AbortSdFileUpload //----------------------------------------------------------------------------- -bool c_FileMgr::IsCompressed(String FileName) -{ - // DEBUG_START; - bool Response = false; - - // DEBUG_V(String("FileName: ") + FileName); - FileName.toLowerCase(); - Response = ((-1 != FileName.indexOf(F(".zip"))) || (-1 != FileName.indexOf(F(".xlz")))); - // DEBUG_V(String("Response: ") + String(Response)); - - // DEBUG_END; - return Response; +bool c_FileMgr::IsCompressed(String FileName) { + // DEBUG_START; + bool Response = false; + + // DEBUG_V(String("FileName: ") + FileName); + FileName.toLowerCase(); + Response = ((-1 != FileName.indexOf(F(".zip"))) || + (-1 != FileName.indexOf(F(".xlz")))); + // DEBUG_V(String("Response: ") + String(Response)); + + // DEBUG_END; + return Response; } // IsCompressed //----------------------------------------------------------------------------- -void c_FileMgr::GetSdInfo(SdInfo & Response) -{ - Response.MaxSize = SdCardSize; - // TODO Response.Used = ESP_SD..usedBytes(); - Response.Available = SdCardSize - Response.Used; +void c_FileMgr::GetSdInfo(SdInfo &Response) { + Response.MaxSize = SdCardSize; + // TODO Response.Used = ESP_SD..usedBytes(); + Response.Available = SdCardSize - Response.Used; } // GetSdInfo #ifdef DEFAULT_SD_POWER_PIN //----------------------------------------------------------------------------- -void c_FileMgr::PowerCycleSdCard() -{ - // DEBUG_START; +void c_FileMgr::PowerCycleSdCard() { + // DEBUG_START; - pinMode(sd_pwr_pin, OUTPUT); - digitalWrite(sd_pwr_pin, !sd_pwr_on); - delay(sd_pwr_dly); - digitalWrite(sd_pwr_pin, sd_pwr_on); + pinMode(sd_pwr_pin, OUTPUT); + digitalWrite(sd_pwr_pin, !sd_pwr_on); + delay(sd_pwr_dly); + digitalWrite(sd_pwr_pin, sd_pwr_on); - // DEBUG_END; + // DEBUG_END; } #endif // def DEFAULT_SD_POWER_PIN diff --git a/src/output/OutputWS2811Rmt.cpp b/src/output/OutputWS2811Rmt.cpp index 82e1e70ff..a202fc2b0 100644 --- a/src/output/OutputWS2811Rmt.cpp +++ b/src/output/OutputWS2811Rmt.cpp @@ -104,7 +104,7 @@ bool c_OutputWS2811Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig) c_OutputRmt::OutputRmtConfig_t OutputRmtConfig; OutputRmtConfig.RmtChannelId = rmt_channel_t(OutputPortDefinition.PortId); OutputRmtConfig.DataPin = gpio_num_t(OutputPortDefinition.gpios.data); - OutputRmtConfig.idle_level = rmt_idle_level_t::RMT_IDLE_LEVEL_HIGH; + OutputRmtConfig.idle_level = rmt_idle_level_t::RMT_IDLE_LEVEL_LOW; OutputRmtConfig.pPixelDataSource = this; OutputRmtConfig.NumFrameStartBits = 0; OutputRmtConfig.CitrdsArray = ConvertIntensityToRmtDataStream;