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;