mirror of
https://git.mirrors.martin98.com/https://github.com/luc-github/ESP3D.git
synced 2025-07-28 02:31:59 +08:00
Idf 5.1.4/Arduino 3.0.4 porting for esp32 (#1046)
* Update WebSocket library * Update SSDP library * Update TFT_eSPI library * Update EspLuaEngine library * Update SDFat library * Change to pioarduino * Make ESP3DMessageFIFO and ESP3DMessage more thread safe * Fix sanity checks for BT * Add some C6 support * Refactor ethernet code * Split Ethernet Sta / WiFi sta ESP Commands and settings * Simplify wait and wdtFeed code * Set C3 with 4MB by default in platformio.ini * Apply Disable brown out only on ESP32 to avoid crash e.g:ESP32S3 * Add missing entries in platformio.ini
This commit is contained in:
parent
8deab1f06c
commit
93312ff8b5
2
.github/ci/install-esp32.sh
vendored
2
.github/ci/install-esp32.sh
vendored
@ -12,7 +12,7 @@ echo "Clone esp32 core"
|
|||||||
cd $HOME/arduino_ide/hardware
|
cd $HOME/arduino_ide/hardware
|
||||||
mkdir esp32
|
mkdir esp32
|
||||||
cd esp32
|
cd esp32
|
||||||
git clone -b 2.0.8 https://github.com/espressif/arduino-esp32.git esp32
|
git clone -b 3.0.4 https://github.com/espressif/arduino-esp32.git esp32
|
||||||
cd esp32
|
cd esp32
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
cd tools
|
cd tools
|
||||||
|
8
.github/ci/prepare-libs.sh
vendored
8
.github/ci/prepare-libs.sh
vendored
@ -6,13 +6,13 @@ shopt -s globstar
|
|||||||
ls $HOME
|
ls $HOME
|
||||||
# Make sure we are inside the github workspace
|
# Make sure we are inside the github workspace
|
||||||
cd $GITHUB_WORKSPACE
|
cd $GITHUB_WORKSPACE
|
||||||
cp -r ./libraries/ESP32SSDP-1.2.1 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/ESP32SSDP-2.0.2 $HOME/arduino_ide/libraries/
|
||||||
cp -r ./libraries/arduinoWebSockets-2.3.6 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/arduinoWebSockets-2.5.2 $HOME/arduino_ide/libraries/
|
||||||
cp -r ./libraries/DHT_sensor_library_for_ESPx-1.0.6 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/DHT_sensor_library_for_ESPx-1.0.6 $HOME/arduino_ide/libraries/
|
||||||
cp -r ./libraries/esp8266-oled-ssd1306-4.3.0 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/esp8266-oled-ssd1306-4.3.0 $HOME/arduino_ide/libraries/
|
||||||
cp -r ./libraries/TFT_eSPI-2.4.72 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/TFT_eSPI-2.5.43 $HOME/arduino_ide/libraries/
|
||||||
cp -r ./libraries/lvgl-8.2.0 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/lvgl-8.2.0 $HOME/arduino_ide/libraries/
|
||||||
cp -r ./libraries/EspLuaEngine-1.0.1 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/EspLuaEngine-1.0.2 $HOME/arduino_ide/libraries/
|
||||||
cp -r ./libraries/BMx280MI-1.2.0 $HOME/arduino_ide/libraries/
|
cp -r ./libraries/BMx280MI-1.2.0 $HOME/arduino_ide/libraries/
|
||||||
#TODO add SDFat libraries according version and target
|
#TODO add SDFat libraries according version and target
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
|
|
||||||
cd %~dp0esp3d
|
|
||||||
astyle --recursive --style=otbs *.h *.cpp *.ino
|
|
||||||
del /S *.ori
|
|
||||||
dir
|
|
||||||
cd ..
|
|
||||||
pause
|
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
cd `dirname "$0"`
|
|
||||||
cd esp3d
|
|
||||||
astyle --recursive --style=otbs '*.h' '*.cpp' '*.ino'
|
|
||||||
rm -r -v *.ori
|
|
||||||
cd ..
|
|
||||||
read -p "Press any key to continue ..."
|
|
@ -44,6 +44,24 @@ AP_IP = 192.168.0.1
|
|||||||
#AP channel 1~14
|
#AP channel 1~14
|
||||||
AP_channel = 11
|
AP_channel = 11
|
||||||
|
|
||||||
|
#Ethernet STA IP Mode DHCP / STATIC
|
||||||
|
ETH_STA_IP_mode = DHCP
|
||||||
|
|
||||||
|
#Ethernet STA static IP
|
||||||
|
ETH_STA_IP = 192.168.0.2
|
||||||
|
|
||||||
|
#Ethernet STA static gateway
|
||||||
|
ETH_STA_GW = 192.168.0.1
|
||||||
|
|
||||||
|
#Ethernet STA static mask
|
||||||
|
ETH_STA_MSK = 255.255.255.0
|
||||||
|
|
||||||
|
#Ethernet STA static dns
|
||||||
|
ETH_STA_DNS = 192.168.0.1
|
||||||
|
|
||||||
|
#Ethernet fallback mode BT, OFF
|
||||||
|
eth_sta_fallback = OFF
|
||||||
|
|
||||||
[services]
|
[services]
|
||||||
#Active or not Serial Bridge Yes / No
|
#Active or not Serial Bridge Yes / No
|
||||||
Serial_Bridge_active = Yes
|
Serial_Bridge_active = Yes
|
||||||
|
@ -119,7 +119,7 @@
|
|||||||
/* Use Ethernet
|
/* Use Ethernet
|
||||||
* Enable ethernet communications
|
* Enable ethernet communications
|
||||||
*/
|
*/
|
||||||
// #define ETH_FEATURE
|
//#define ETH_FEATURE
|
||||||
|
|
||||||
// Ethernet type (Check ETH.h eth_phy_type_t)
|
// Ethernet type (Check ETH.h eth_phy_type_t)
|
||||||
// TYPE_ETH_PHY_LAN8720
|
// TYPE_ETH_PHY_LAN8720
|
||||||
@ -136,20 +136,20 @@
|
|||||||
// MODE_ETH_CLOCK_GPIO0_OUT
|
// MODE_ETH_CLOCK_GPIO0_OUT
|
||||||
// MODE_ETH_CLOCK_GPIO16_OUT
|
// MODE_ETH_CLOCK_GPIO16_OUT
|
||||||
// MODE_ETH_CLOCK_GPIO17_OUT
|
// MODE_ETH_CLOCK_GPIO17_OUT
|
||||||
#define ESP3D_ETH_CLK_MODE MODE_ETH_CLOCK_GPIO17_OUT
|
#define ESP3D_ETH_CLK_MODE MODE_ETH_CLOCK_GPIO0_IN
|
||||||
|
|
||||||
// Pins of ethernet board
|
// Pins of ethernet board
|
||||||
#define ESP3D_ETH_PHY_POWER_PIN 12
|
#define ESP3D_ETH_PHY_POWER_PIN 16
|
||||||
// #define ESP3D_ETH_PHY_MDC_PIN 23
|
#define ESP3D_ETH_PHY_MDC_PIN 23
|
||||||
// #define ESP3D_ETH_PHY_MDIO_PIN 18
|
#define ESP3D_ETH_PHY_MDIO_PIN 18
|
||||||
|
|
||||||
// Address of ethernet board
|
// Address of ethernet board
|
||||||
// #define ESP3D_ETH_PHY_ADDR 0
|
#define ESP3D_ETH_PHY_ADDR 1
|
||||||
|
|
||||||
/* Use Bluetooth
|
/* Use Bluetooth
|
||||||
* Enable serial bluetooth communications
|
* Enable serial bluetooth communications
|
||||||
*/
|
*/
|
||||||
// #define BLUETOOTH_FEATURE
|
//#define BLUETOOTH_FEATURE
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
*
|
*
|
||||||
@ -283,14 +283,15 @@
|
|||||||
* ESP_SHARED_SD //Printer SD Card is also connected to ESP3D
|
* ESP_SHARED_SD //Printer SD Card is also connected to ESP3D
|
||||||
* Does your system has SD card and how it is connected to your ESP3D
|
* Does your system has SD card and how it is connected to your ESP3D
|
||||||
*/
|
*/
|
||||||
// #define SD_DEVICE_CONNECTION ESP_SHARED_SD
|
//#define SD_DEVICE_CONNECTION ESP_DIRECT_SD
|
||||||
|
|
||||||
/* SD card library
|
/* SD card library
|
||||||
* ESP_SD_NATIVE //esp32 / esp8266
|
* ESP_SD_NATIVE //esp32 / esp8266
|
||||||
* ESP_SDIO //esp32 only
|
* ESP_SDIO //esp32 only
|
||||||
* ESP_SDFAT2 //esp8266 / esp32
|
* ESP_SDFAT2 //esp8266 / esp32
|
||||||
*/
|
*/
|
||||||
// #define SD_DEVICE ESP_SD_NATIVE
|
//#define SD_DEVICE ESP_SDFAT2
|
||||||
|
|
||||||
|
|
||||||
// #define SD_CARD_TYPE ESP_FYSETC_WIFI_PRO_SDCARD
|
// #define SD_CARD_TYPE ESP_FYSETC_WIFI_PRO_SDCARD
|
||||||
|
|
||||||
@ -299,7 +300,7 @@
|
|||||||
* SD_ONE_BIT_MODE
|
* SD_ONE_BIT_MODE
|
||||||
* SD_FOUR_BIT_MODE
|
* SD_FOUR_BIT_MODE
|
||||||
*/
|
*/
|
||||||
// #define SDIO_BIT_MODE SD_ONE_BIT_MODE
|
//#define SDIO_BIT_MODE SD_ONE_BIT_MODE
|
||||||
|
|
||||||
/* Enable date/time on files
|
/* Enable date/time on files
|
||||||
* Set date/time on files using SNTP or last webui connection
|
* Set date/time on files using SNTP or last webui connection
|
||||||
@ -335,7 +336,13 @@
|
|||||||
/* SD card CS pin
|
/* SD card CS pin
|
||||||
* The pin used to select SD card in SPI mode
|
* The pin used to select SD card in SPI mode
|
||||||
*/
|
*/
|
||||||
// #define ESP_SD_CS_PIN 5
|
//#define ESP_SD_CS_PIN 21
|
||||||
|
//#define ESP_SD_MISO_PIN 8
|
||||||
|
//#define ESP_SD_MOSI_PIN 9
|
||||||
|
//#define ESP_SD_SCK_PIN 7
|
||||||
|
//#define ESP_SDIO_CMD_PIN 38
|
||||||
|
//#define ESP_SDIO_D0_PIN 40
|
||||||
|
//#define ESP_SDIO_CLK_PIN 39
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
*
|
*
|
||||||
@ -383,7 +390,7 @@
|
|||||||
* The pin used to reset ESP3D setting if set to low for more than 1 second at
|
* The pin used to reset ESP3D setting if set to low for more than 1 second at
|
||||||
* start
|
* start
|
||||||
*/
|
*/
|
||||||
#define ESP3D_RESET_PIN 0
|
//#define ESP3D_RESET_PIN 0
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
*
|
*
|
||||||
@ -505,9 +512,10 @@
|
|||||||
* CAMERA_MODEL_ESP32S2_CAM_BOARD
|
* CAMERA_MODEL_ESP32S2_CAM_BOARD
|
||||||
* CAMERA_MODEL_ESP32S3_CAM_LCD
|
* CAMERA_MODEL_ESP32S3_CAM_LCD
|
||||||
* CAMERA_MODEL_ESP32S3_EYE
|
* CAMERA_MODEL_ESP32S3_EYE
|
||||||
|
* CAMERA_MODEL_XIAO_ESP32S3
|
||||||
* Camera connected to ESP board, only ones with PSRAM are supported
|
* Camera connected to ESP board, only ones with PSRAM are supported
|
||||||
*/
|
*/
|
||||||
// #define CAMERA_DEVICE CAMERA_MODEL_AI_THINKER
|
// #define CAMERA_DEVICE CAMERA_MODEL_XIAO_ESP32S3
|
||||||
|
|
||||||
/* Flip vertically
|
/* Flip vertically
|
||||||
* Flip camera vertically
|
* Flip camera vertically
|
||||||
@ -621,9 +629,9 @@
|
|||||||
// LOG_OUTPUT_SERIAL2
|
// LOG_OUTPUT_SERIAL2
|
||||||
// LOG_OUTPUT_TELNET
|
// LOG_OUTPUT_TELNET
|
||||||
// LOG_OUTPUT_WEBSOCKET
|
// LOG_OUTPUT_WEBSOCKET
|
||||||
// #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
|
//#define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
|
||||||
|
|
||||||
// #define ESP3D_DEBUG_LEVEL LOG_LEVEL_DEBUG
|
//#define ESP3D_DEBUG_LEVEL LOG_LEVEL_DEBUG
|
||||||
|
|
||||||
#ifdef ESP_LOG_FEATURE
|
#ifdef ESP_LOG_FEATURE
|
||||||
#define LOG_ESP3D_BAUDRATE 115200
|
#define LOG_ESP3D_BAUDRATE 115200
|
||||||
|
@ -26,15 +26,11 @@ const char* help[] = {
|
|||||||
"[ESP100](SSID) - display/set STA SSID",
|
"[ESP100](SSID) - display/set STA SSID",
|
||||||
"[ESP101](Password) - set STA password",
|
"[ESP101](Password) - set STA password",
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
"[ESP102](Mode) - display/set STA IP mode (DHCP/STATIC)",
|
"[ESP102](Mode) - display/set STA IP mode (DHCP/STATIC)",
|
||||||
"[ESP103](IP=xxxx MSK=xxxx GW=xxxx) - display/set STA IP/Mask/GW",
|
"[ESP103](IP=xxxx MSK=xxxx GW=xxxx) - display/set STA IP/Mask/GW",
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE
|
|
||||||
#if defined(WIFI_FEATURE) || defined(BLUETOOTH_FEATURE) || defined(ETH_FEATURE)
|
|
||||||
"[ESP104](State) - display/set sta fallback mode which can be BT, SETUP, "
|
"[ESP104](State) - display/set sta fallback mode which can be BT, SETUP, "
|
||||||
"OFF",
|
"OFF",
|
||||||
#endif // WIFI_FEATURE || BLUETOOTH_FEATURE || ETH_FEATURE
|
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
"[ESP105](SSID) - display/set AP SSID",
|
"[ESP105](SSID) - display/set AP SSID",
|
||||||
"[ESP106](Password) - set AP password",
|
"[ESP106](Password) - set AP password",
|
||||||
"[ESP107](IP) - display/set AP IP",
|
"[ESP107](IP) - display/set AP IP",
|
||||||
@ -53,6 +49,11 @@ const char* help[] = {
|
|||||||
"[ESP115](State) - display/set immediate Network state which can be ON, "
|
"[ESP115](State) - display/set immediate Network state which can be ON, "
|
||||||
"OFF",
|
"OFF",
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE || BT_FEATURE
|
#endif // WIFI_FEATURE || ETH_FEATURE || BT_FEATURE
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
"[ESP116](Mode) - display/set ETH STA IP mode (DHCP/STATIC)",
|
||||||
|
"[ESP117](IP=xxxx MSK=xxxx GW=xxxx) - display/set ETH STA IP/Mask/GW",
|
||||||
|
"[ESP118](State) - display/set eth sta fallback mode which can be BT, Off",
|
||||||
|
#endif // ETH_FEATURE
|
||||||
#if defined(HTTP_FEATURE)
|
#if defined(HTTP_FEATURE)
|
||||||
"[ESP120](State) - display/set HTTP state which can be ON, OFF",
|
"[ESP120](State) - display/set HTTP state which can be ON, OFF",
|
||||||
"[ESP121](Port) - display/set HTTP port ",
|
"[ESP121](Port) - display/set HTTP port ",
|
||||||
@ -196,13 +197,9 @@ const uint cmdlist[] = {
|
|||||||
#if defined(WIFI_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
100, 101,
|
100, 101,
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
102, 103,
|
102, 103,
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE
|
|
||||||
#if defined(WIFI_FEATURE) || defined(BLUETOOTH_FEATURE) || defined(ETH_FEATURE)
|
|
||||||
104,
|
104,
|
||||||
#endif // WIFI_FEATURE || BLUETOOTH_FEATURE || ETH_FEATURE
|
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
105, 106, 107, 108,
|
105, 106, 107, 108,
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(WIFI_FEATURE) || defined(BLUETOOTH_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE) || defined(BLUETOOTH_FEATURE) || defined(ETH_FEATURE)
|
||||||
@ -214,6 +211,9 @@ const uint cmdlist[] = {
|
|||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BT_FEATURE)
|
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BT_FEATURE)
|
||||||
112, 114, 115,
|
112, 114, 115,
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE || BT_FEATURE
|
#endif // WIFI_FEATURE || ETH_FEATURE || BT_FEATURE
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
116, 117, 118,
|
||||||
|
#endif // ETH_FEATURE
|
||||||
#if defined(HTTP_FEATURE)
|
#if defined(HTTP_FEATURE)
|
||||||
120, 121,
|
120, 121,
|
||||||
#endif // HTTP_FEATURE
|
#endif // HTTP_FEATURE
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "../../include/esp3d_config.h"
|
#include "../../include/esp3d_config.h"
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
#include "../../modules/network/netconfig.h"
|
#include "../../modules/network/netconfig.h"
|
||||||
#include "../esp3d_commands.h"
|
#include "../esp3d_commands.h"
|
||||||
#include "../esp3d_settings.h"
|
#include "../esp3d_settings.h"
|
||||||
@ -26,9 +26,6 @@
|
|||||||
#if defined(WIFI_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
#include "../../modules/wifi/wificonfig.h"
|
#include "../../modules/wifi/wificonfig.h"
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(ETH_FEATURE)
|
|
||||||
#include "../../modules/ethernet/ethconfig.h"
|
|
||||||
#endif // ETH_FEATURE
|
|
||||||
#include "../../modules/authentication/authentication_service.h"
|
#include "../../modules/authentication/authentication_service.h"
|
||||||
#define COMMAND_ID 102
|
#define COMMAND_ID 102
|
||||||
// Change STA IP mode (DHCP/STATIC)
|
// Change STA IP mode (DHCP/STATIC)
|
||||||
@ -97,4 +94,4 @@ void ESP3DCommands::ESP102(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "../../include/esp3d_config.h"
|
#include "../../include/esp3d_config.h"
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
#include "../../modules/network/netconfig.h"
|
#include "../../modules/network/netconfig.h"
|
||||||
#include "../esp3d_commands.h"
|
#include "../esp3d_commands.h"
|
||||||
#include "../esp3d_settings.h"
|
#include "../esp3d_settings.h"
|
||||||
@ -26,9 +26,6 @@
|
|||||||
#if defined(WIFI_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
#include "../../modules/wifi/wificonfig.h"
|
#include "../../modules/wifi/wificonfig.h"
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(ETH_FEATURE)
|
|
||||||
#include "../../modules/ethernet/ethconfig.h"
|
|
||||||
#endif // ETH_FEATURE
|
|
||||||
#include "../../modules/authentication/authentication_service.h"
|
#include "../../modules/authentication/authentication_service.h"
|
||||||
#define COMMAND_ID 103
|
#define COMMAND_ID 103
|
||||||
// Change STA IP/Mask/GW
|
// Change STA IP/Mask/GW
|
||||||
@ -121,4 +118,4 @@ void ESP3DCommands::ESP103(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "../../include/esp3d_config.h"
|
#include "../../include/esp3d_config.h"
|
||||||
#if defined(WIFI_FEATURE) || defined(BLUETOOTH_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
#include "../../modules/authentication/authentication_service.h"
|
#include "../../modules/authentication/authentication_service.h"
|
||||||
#include "../../modules/network/netconfig.h"
|
#include "../../modules/network/netconfig.h"
|
||||||
#include "../esp3d_commands.h"
|
#include "../esp3d_commands.h"
|
||||||
@ -54,11 +54,6 @@ void ESP3DCommands::ESP104(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
ok_msg = "BT";
|
ok_msg = "BT";
|
||||||
} else
|
} else
|
||||||
#endif // BLUETOOTH_FEATURE
|
#endif // BLUETOOTH_FEATURE
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
if (byteValue == (uint8_t)ESP_AP_SETUP) {
|
|
||||||
ok_msg = "CONFIG";
|
|
||||||
} else
|
|
||||||
#endif // WIFI_FEATURE
|
|
||||||
if (byteValue == (uint8_t)ESP_NO_NETWORK) {
|
if (byteValue == (uint8_t)ESP_NO_NETWORK) {
|
||||||
ok_msg = "OFF";
|
ok_msg = "OFF";
|
||||||
} else {
|
} else {
|
||||||
@ -76,11 +71,6 @@ void ESP3DCommands::ESP104(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
byteValue = (uint8_t)ESP_BT;
|
byteValue = (uint8_t)ESP_BT;
|
||||||
} else
|
} else
|
||||||
#endif // BLUETOOTH_FEATURE
|
#endif // BLUETOOTH_FEATURE
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
if (tmpstr == "CONFIG") {
|
|
||||||
byteValue = (uint8_t)ESP_AP_SETUP;
|
|
||||||
} else
|
|
||||||
#endif // WIFI_FEATURE
|
|
||||||
if (tmpstr == "OFF") {
|
if (tmpstr == "OFF") {
|
||||||
byteValue = (uint8_t)ESP_NO_NETWORK;
|
byteValue = (uint8_t)ESP_NO_NETWORK;
|
||||||
} else {
|
} else {
|
||||||
|
94
esp3d/src/core/commands/ESP116.cpp
Normal file
94
esp3d/src/core/commands/ESP116.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
ESP116.cpp - ESP3D command class
|
||||||
|
|
||||||
|
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||||
|
|
||||||
|
This code is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with This code; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#include "../../include/esp3d_config.h"
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
#include "../../modules/network/netconfig.h"
|
||||||
|
#include "../esp3d_commands.h"
|
||||||
|
#include "../esp3d_settings.h"
|
||||||
|
#include "../../modules/ethernet/ethconfig.h"
|
||||||
|
#include "../../modules/authentication/authentication_service.h"
|
||||||
|
#define COMMAND_ID 116
|
||||||
|
// Change ETH STA IP mode (DHCP/STATIC)
|
||||||
|
//[ESP116]<mode>[json=no] [pwd=<admin password>]
|
||||||
|
void ESP3DCommands::ESP116(int cmd_params_pos, ESP3DMessage* msg) {
|
||||||
|
ESP3DClientType target = msg->origin;
|
||||||
|
ESP3DRequest requestId = msg->request_id;
|
||||||
|
(void)requestId;
|
||||||
|
msg->target = target;
|
||||||
|
msg->origin = ESP3DClientType::command;
|
||||||
|
bool hasError = false;
|
||||||
|
String error_msg = "Invalid parameters";
|
||||||
|
String ok_msg = "ok";
|
||||||
|
bool json = hasTag(msg, cmd_params_pos, "json");
|
||||||
|
String tmpstr;
|
||||||
|
uint8_t byteValue = (uint8_t)-1;
|
||||||
|
#if defined(AUTHENTICATION_FEATURE)
|
||||||
|
if (msg->authentication_level == ESP3DAuthenticationLevel::guest) {
|
||||||
|
msg->authentication_level = ESP3DAuthenticationLevel::not_authenticated;
|
||||||
|
dispatchAuthenticationError(msg, COMMAND_ID, json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
tmpstr = get_clean_param(msg, cmd_params_pos);
|
||||||
|
if (tmpstr.length() == 0) {
|
||||||
|
byteValue = ESP3DSettings::readByte(ESP_ETH_STA_IP_MODE);
|
||||||
|
if (byteValue == static_cast<uint8_t>(DHCP_MODE)) {
|
||||||
|
ok_msg = "DHCP";
|
||||||
|
} else if (byteValue == static_cast<uint8_t>(STATIC_IP_MODE)) {
|
||||||
|
ok_msg = "STATIC";
|
||||||
|
} else {
|
||||||
|
ok_msg = "Unknown:" + String(byteValue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#if defined(AUTHENTICATION_FEATURE)
|
||||||
|
if (msg->authentication_level != ESP3DAuthenticationLevel::admin) {
|
||||||
|
dispatchAuthenticationError(msg, COMMAND_ID, json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
if (tmpstr == "DHCP") {
|
||||||
|
byteValue = static_cast<uint8_t>(DHCP_MODE);
|
||||||
|
} else if (tmpstr == "STATIC") {
|
||||||
|
byteValue = static_cast<uint8_t>(STATIC_IP_MODE);
|
||||||
|
} else {
|
||||||
|
byteValue = (uint8_t)-1; // unknow flag so put outof range value
|
||||||
|
}
|
||||||
|
esp3d_log("got %s param for a value of %d, is valid %d", tmpstr.c_str(),
|
||||||
|
byteValue,
|
||||||
|
ESP3DSettings::isValidByteSetting(byteValue, ESP_ETH_STA_IP_MODE));
|
||||||
|
if (ESP3DSettings::isValidByteSetting(byteValue, ESP_ETH_STA_IP_MODE)) {
|
||||||
|
esp3d_log("Value %d is valid", byteValue);
|
||||||
|
if (!ESP3DSettings::writeByte(ESP_ETH_STA_IP_MODE, byteValue)) {
|
||||||
|
hasError = true;
|
||||||
|
error_msg = "Set value failed";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasError = true;
|
||||||
|
error_msg = "Invalid parameter";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dispatchAnswer(msg, COMMAND_ID, json, hasError,
|
||||||
|
hasError ? error_msg.c_str() : ok_msg.c_str())) {
|
||||||
|
esp3d_log_e("Error sending response to clients");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ETH_FEATURE
|
118
esp3d/src/core/commands/ESP117.cpp
Normal file
118
esp3d/src/core/commands/ESP117.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
ESP117.cpp - ESP3D command class
|
||||||
|
|
||||||
|
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||||
|
|
||||||
|
This code is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with This code; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#include "../../include/esp3d_config.h"
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
#include "../../modules/network/netconfig.h"
|
||||||
|
#include "../esp3d_commands.h"
|
||||||
|
#include "../esp3d_settings.h"
|
||||||
|
#include "../../modules/ethernet/ethconfig.h"
|
||||||
|
#include "../../modules/authentication/authentication_service.h"
|
||||||
|
#define COMMAND_ID 117
|
||||||
|
// Change ETH STA IP/Mask/GW
|
||||||
|
//[ESP117]IP=<IP> MSK=<IP> GW=<IP> DNS=<IP> [json=no] [pwd=<admin password>
|
||||||
|
void ESP3DCommands::ESP117(int cmd_params_pos, ESP3DMessage* msg) {
|
||||||
|
ESP3DClientType target = msg->origin;
|
||||||
|
ESP3DRequest requestId = msg->request_id;
|
||||||
|
(void)requestId;
|
||||||
|
msg->target = target;
|
||||||
|
msg->origin = ESP3DClientType::command;
|
||||||
|
bool hasError = false;
|
||||||
|
String error_msg = "Invalid parameters";
|
||||||
|
String ok_msg = "ok";
|
||||||
|
bool json = hasTag(msg, cmd_params_pos, "json");
|
||||||
|
String tmpstr;
|
||||||
|
const char* cmdList[] = {"IP=", "MSK=", "GW=", "DNS="};
|
||||||
|
uint8_t cmdListSize = sizeof(cmdList) / sizeof(char*);
|
||||||
|
const ESP3DSettingIndex settingIndex[] = {
|
||||||
|
ESP_ETH_STA_IP_VALUE, ESP_ETH_STA_MASK_VALUE, ESP_ETH_STA_GATEWAY_VALUE,
|
||||||
|
ESP_ETH_STA_DNS_VALUE};
|
||||||
|
#if defined(AUTHENTICATION_FEATURE)
|
||||||
|
if (msg->authentication_level == ESP3DAuthenticationLevel::guest) {
|
||||||
|
msg->authentication_level = ESP3DAuthenticationLevel::not_authenticated;
|
||||||
|
dispatchAuthenticationError(msg, COMMAND_ID, json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
tmpstr = get_clean_param(msg, cmd_params_pos);
|
||||||
|
if (tmpstr.length() == 0) {
|
||||||
|
if (json) {
|
||||||
|
ok_msg = "{\"ip\":\"";
|
||||||
|
} else {
|
||||||
|
ok_msg = "IP: ";
|
||||||
|
}
|
||||||
|
ok_msg += ESP3DSettings::readIPString(ESP_ETH_STA_IP_VALUE);
|
||||||
|
if (json) {
|
||||||
|
ok_msg += "\",\"gw\":\"";
|
||||||
|
} else {
|
||||||
|
ok_msg += ", GW: ";
|
||||||
|
}
|
||||||
|
ok_msg += ESP3DSettings::readIPString(ESP_ETH_STA_GATEWAY_VALUE);
|
||||||
|
if (json) {
|
||||||
|
ok_msg += "\",\"msk\":\"";
|
||||||
|
} else {
|
||||||
|
ok_msg += ", MSK: ";
|
||||||
|
}
|
||||||
|
ok_msg += ESP3DSettings::readIPString(ESP_ETH_STA_MASK_VALUE);
|
||||||
|
if (json) {
|
||||||
|
ok_msg += "\",\"dns\":\"";
|
||||||
|
} else {
|
||||||
|
ok_msg += ", DNS: ";
|
||||||
|
}
|
||||||
|
ok_msg += ESP3DSettings::readIPString(ESP_ETH_STA_DNS_VALUE);
|
||||||
|
if (json) {
|
||||||
|
ok_msg += "\"}";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#if defined(AUTHENTICATION_FEATURE)
|
||||||
|
if (msg->authentication_level != ESP3DAuthenticationLevel::admin) {
|
||||||
|
dispatchAuthenticationError(msg, COMMAND_ID, json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
bool hasParam = false;
|
||||||
|
for (uint8_t i = 0; i < cmdListSize; i++) {
|
||||||
|
tmpstr = get_param(msg, cmd_params_pos, cmdList[i]);
|
||||||
|
if (tmpstr.length() != 0) {
|
||||||
|
hasParam = true;
|
||||||
|
if (ESP3DSettings::isValidIPStringSetting(tmpstr.c_str(),
|
||||||
|
settingIndex[i])) {
|
||||||
|
esp3d_log("Value %s is valid", tmpstr.c_str());
|
||||||
|
if (!ESP3DSettings::writeIPString(settingIndex[i], tmpstr.c_str())) {
|
||||||
|
hasError = true;
|
||||||
|
error_msg = "Set value failed";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasError = true;
|
||||||
|
error_msg = "Invalid parameter";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasParam && !hasError) {
|
||||||
|
hasError = true;
|
||||||
|
error_msg = "Invalid parameter";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dispatchAnswer(msg, COMMAND_ID, json, hasError,
|
||||||
|
hasError ? error_msg.c_str() : ok_msg.c_str())) {
|
||||||
|
esp3d_log_e("Error sending response to clients");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ETH_FEATURE
|
101
esp3d/src/core/commands/ESP118.cpp
Normal file
101
esp3d/src/core/commands/ESP118.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
ESP118.cpp - ESP3D command class
|
||||||
|
|
||||||
|
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||||
|
|
||||||
|
This code is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with This code; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#include "../../include/esp3d_config.h"
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
#include "../../modules/authentication/authentication_service.h"
|
||||||
|
#include "../../modules/network/netconfig.h"
|
||||||
|
#include "../esp3d_commands.h"
|
||||||
|
#include "../esp3d_settings.h"
|
||||||
|
|
||||||
|
#define COMMAND_ID 118
|
||||||
|
// Set ETH STA fallback mode state at boot which can be BT, WIFI-SETUP, OFF
|
||||||
|
//[ESP118]<state> json=<no> pwd=<admin password>
|
||||||
|
void ESP3DCommands::ESP118(int cmd_params_pos, ESP3DMessage* msg) {
|
||||||
|
ESP3DClientType target = msg->origin;
|
||||||
|
ESP3DRequest requestId = msg->request_id;
|
||||||
|
(void)requestId;
|
||||||
|
msg->target = target;
|
||||||
|
msg->origin = ESP3DClientType::command;
|
||||||
|
bool hasError = false;
|
||||||
|
String error_msg = "Invalid parameters";
|
||||||
|
String ok_msg = "ok";
|
||||||
|
bool json = hasTag(msg, cmd_params_pos, "json");
|
||||||
|
String tmpstr;
|
||||||
|
uint8_t byteValue = (uint8_t)-1;
|
||||||
|
#if defined(AUTHENTICATION_FEATURE)
|
||||||
|
if (msg->authentication_level == ESP3DAuthenticationLevel::guest) {
|
||||||
|
msg->authentication_level = ESP3DAuthenticationLevel::not_authenticated;
|
||||||
|
dispatchAuthenticationError(msg, COMMAND_ID, json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
tmpstr = get_clean_param(msg, cmd_params_pos);
|
||||||
|
if (tmpstr.length() == 0) {
|
||||||
|
byteValue = ESP3DSettings::readByte(ESP_ETH_STA_FALLBACK_MODE);
|
||||||
|
#if defined(BLUETOOTH_FEATURE)
|
||||||
|
if (byteValue == (uint8_t)ESP_BT) {
|
||||||
|
ok_msg = "BT";
|
||||||
|
} else
|
||||||
|
#endif // BLUETOOTH_FEATURE
|
||||||
|
if (byteValue == (uint8_t)ESP_NO_NETWORK) {
|
||||||
|
ok_msg = "OFF";
|
||||||
|
} else {
|
||||||
|
ok_msg = "Unknown";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#if defined(AUTHENTICATION_FEATURE)
|
||||||
|
if (msg->authentication_level != ESP3DAuthenticationLevel::admin) {
|
||||||
|
dispatchAuthenticationError(msg, COMMAND_ID, json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
#if defined(BLUETOOTH_FEATURE)
|
||||||
|
if (tmpstr == "BT") {
|
||||||
|
byteValue = (uint8_t)ESP_BT;
|
||||||
|
} else
|
||||||
|
#endif // BLUETOOTH_FEATURE
|
||||||
|
if (tmpstr == "OFF") {
|
||||||
|
byteValue = (uint8_t)ESP_NO_NETWORK;
|
||||||
|
} else {
|
||||||
|
byteValue = (uint8_t)-1; // unknow flag so put outof range value
|
||||||
|
}
|
||||||
|
esp3d_log(
|
||||||
|
"got %s param for a value of %d, is valid %d", tmpstr.c_str(),
|
||||||
|
byteValue,
|
||||||
|
ESP3DSettings::isValidByteSetting(byteValue, ESP_ETH_STA_FALLBACK_MODE));
|
||||||
|
if (ESP3DSettings::isValidByteSetting(byteValue, ESP_ETH_STA_FALLBACK_MODE)) {
|
||||||
|
esp3d_log("Value %d is valid", byteValue);
|
||||||
|
if (!ESP3DSettings::writeByte(ESP_ETH_STA_FALLBACK_MODE, byteValue)) {
|
||||||
|
hasError = true;
|
||||||
|
error_msg = "Set value failed";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasError = true;
|
||||||
|
error_msg = "Invalid parameter";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dispatchAnswer(msg, COMMAND_ID, json, hasError,
|
||||||
|
hasError ? error_msg.c_str() : ok_msg.c_str())) {
|
||||||
|
esp3d_log_e("Error sending response to clients");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ETH_FEATURE
|
@ -51,23 +51,40 @@ void ESP3DCommands::ESP301(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
#endif // AUTHENTICATION_FEATURE
|
#endif // AUTHENTICATION_FEATURE
|
||||||
tmpstr = get_clean_param(msg, cmd_params_pos);
|
tmpstr = get_clean_param(msg, cmd_params_pos);
|
||||||
if (tmpstr.length() == 0) {
|
if (tmpstr.length() == 0) {
|
||||||
|
String error = esp3d_lua_interpreter.getLastError();
|
||||||
if (!esp3d_lua_interpreter.isScriptRunning()) {
|
if (!esp3d_lua_interpreter.isScriptRunning()) {
|
||||||
if (json) {
|
if (json) {
|
||||||
ok_msg = "{\"status\":\"idle\"}";
|
ok_msg = "{\"status\":\"idle\"";
|
||||||
|
if (error.length() > 0) {
|
||||||
|
ok_msg += ",\"error\":\"" + error + "\"";
|
||||||
|
}
|
||||||
|
ok_msg+="}";
|
||||||
} else {
|
} else {
|
||||||
ok_msg = "idle";
|
ok_msg = "idle";
|
||||||
|
if (error.length() > 0) {
|
||||||
|
ok_msg += ", error: " + error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String status =
|
String status =
|
||||||
esp3d_lua_interpreter.isScriptPaused() ? "paused" : "running";
|
esp3d_lua_interpreter.isScriptPaused() ? "paused" : "running";
|
||||||
|
|
||||||
|
if (error.length() > 0) {
|
||||||
|
status = "error";
|
||||||
|
}
|
||||||
String scriptName = esp3d_lua_interpreter.getCurrentScriptName();
|
String scriptName = esp3d_lua_interpreter.getCurrentScriptName();
|
||||||
String duration = esp3d_string::formatDuration(
|
String duration = esp3d_string::formatDuration(
|
||||||
esp3d_lua_interpreter.getExecutionTime());
|
esp3d_lua_interpreter.getExecutionTime());
|
||||||
if (json) {
|
if (json) {
|
||||||
|
String errorMsg = error.length() > 0 ? ",\"error\":\"" + error + "\"" : "";
|
||||||
ok_msg = "{\"status\":\"" + status + "\",\"script\":\"" + scriptName +
|
ok_msg = "{\"status\":\"" + status + "\",\"script\":\"" + scriptName +
|
||||||
"\",\"duration\":\"" + duration + "\"}";
|
"\",\"duration\":\"" + duration + "\"" + errorMsg + "}";
|
||||||
} else {
|
} else {
|
||||||
ok_msg = status + ", " + scriptName + ", duration " + duration;
|
ok_msg = status;
|
||||||
|
if (error.length() > 0) {
|
||||||
|
ok_msg += ": " + error;
|
||||||
|
}
|
||||||
|
ok_msg += ", " + scriptName + ", duration " + duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -113,7 +130,7 @@ void ESP3DCommands::ESP301(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tmpstr == "ABORT") {
|
} else if (tmpstr == "ABORT") {
|
||||||
esp3d_lua_interpreter.abortCurrentScript();
|
esp3d_lua_interpreter.abortScript();
|
||||||
ok_msg = "Script aborted";
|
ok_msg = "Script aborted";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -91,6 +91,19 @@ const char* FallbackValues[] = {"0"
|
|||||||
#endif // BLUETOOTH_FEATURE
|
#endif // BLUETOOTH_FEATURE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char* EthFallbackValues[] = {"0"
|
||||||
|
#ifdef BLUETOOTH_FEATURE
|
||||||
|
,
|
||||||
|
"3"
|
||||||
|
#endif // BLUETOOTH_FEATURE
|
||||||
|
};
|
||||||
|
const char* EthFallbackLabels[] = {"none"
|
||||||
|
#ifdef BLUETOOTH_FEATURE
|
||||||
|
,
|
||||||
|
"bt"
|
||||||
|
#endif // BLUETOOTH_FEATURE
|
||||||
|
};
|
||||||
|
|
||||||
const char* FirmwareLabels[] = {"Unknown", "Grbl", "Marlin", "Smoothieware",
|
const char* FirmwareLabels[] = {"Unknown", "Grbl", "Marlin", "Smoothieware",
|
||||||
"Repetier"};
|
"Repetier"};
|
||||||
|
|
||||||
@ -204,6 +217,30 @@ void ESP3DCommands::ESP400(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
dispatchSetting(json, "network/network", ESP_BOOT_RADIO_STATE, "radio_boot",
|
dispatchSetting(json, "network/network", ESP_BOOT_RADIO_STATE, "radio_boot",
|
||||||
YesNoValues, YesNoLabels, sizeof(YesNoValues) / sizeof(char*),
|
YesNoValues, YesNoLabels, sizeof(YesNoValues) / sizeof(char*),
|
||||||
-1, -1, -1, NULL, true, target, requestId);
|
-1, -1, -1, NULL, true, target, requestId);
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
// Ethernet STA IP mode
|
||||||
|
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_IP_MODE, "ip mode", IpModeValues,
|
||||||
|
IpModeLabels, sizeof(IpModeLabels) / sizeof(char*), -1, -1,
|
||||||
|
-1, nullptr, true, target, requestId);
|
||||||
|
// Ethernet STA static IP
|
||||||
|
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_IP_VALUE, "ip", nullptr, nullptr,
|
||||||
|
-1, -1, -1, -1, nullptr, true, target, requestId);
|
||||||
|
|
||||||
|
// Ethernet STA static Gateway
|
||||||
|
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_GATEWAY_VALUE, "gw", nullptr,
|
||||||
|
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId);
|
||||||
|
// Ethernet STA static Mask
|
||||||
|
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_MASK_VALUE, "msk", nullptr,
|
||||||
|
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId);
|
||||||
|
// Ethernet STA static DNS
|
||||||
|
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_DNS_VALUE, "DNS", nullptr,
|
||||||
|
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId);
|
||||||
|
// Ethernet Sta fallback mode
|
||||||
|
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_FALLBACK_MODE,
|
||||||
|
"sta fallback mode", EthFallbackValues, EthFallbackLabels,
|
||||||
|
sizeof(EthFallbackValues) / sizeof(char*), -1, -1, -1, nullptr,
|
||||||
|
true, target, requestId);
|
||||||
|
#endif // ETH_FEATURE
|
||||||
#ifdef WIFI_FEATURE
|
#ifdef WIFI_FEATURE
|
||||||
// STA SSID network/sta
|
// STA SSID network/sta
|
||||||
dispatchSetting(json, "network/sta", ESP_STA_SSID, "SSID", nullptr, nullptr,
|
dispatchSetting(json, "network/sta", ESP_STA_SSID, "SSID", nullptr, nullptr,
|
||||||
@ -214,7 +251,7 @@ void ESP3DCommands::ESP400(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
nullptr, 64, 8, 0, -1, nullptr, true, target, requestId);
|
nullptr, 64, 8, 0, -1, nullptr, true, target, requestId);
|
||||||
|
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
// STA IP mode
|
// STA IP mode
|
||||||
dispatchSetting(json, "network/sta", ESP_STA_IP_MODE, "ip mode", IpModeValues,
|
dispatchSetting(json, "network/sta", ESP_STA_IP_MODE, "ip mode", IpModeValues,
|
||||||
IpModeLabels, sizeof(IpModeLabels) / sizeof(char*), -1, -1,
|
IpModeLabels, sizeof(IpModeLabels) / sizeof(char*), -1, -1,
|
||||||
@ -233,15 +270,15 @@ void ESP3DCommands::ESP400(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
dispatchSetting(json, "network/sta", ESP_STA_DNS_VALUE, "DNS", nullptr,
|
dispatchSetting(json, "network/sta", ESP_STA_DNS_VALUE, "DNS", nullptr,
|
||||||
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId);
|
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId);
|
||||||
|
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
|
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BT_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
// Sta fallback mode
|
// Sta fallback mode
|
||||||
dispatchSetting(json, "network/sta", ESP_STA_FALLBACK_MODE,
|
dispatchSetting(json, "network/sta", ESP_STA_FALLBACK_MODE,
|
||||||
"sta fallback mode", FallbackValues, FallbackLabels,
|
"sta fallback mode", FallbackValues, FallbackLabels,
|
||||||
sizeof(FallbackValues) / sizeof(char*), -1, -1, -1, nullptr,
|
sizeof(FallbackValues) / sizeof(char*), -1, -1, -1, nullptr,
|
||||||
true, target, requestId);
|
true, target, requestId);
|
||||||
#endif // WIFI_FEATURE || ETH_FEATURE || BT_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(WIFI_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
// AP SSID network/ap
|
// AP SSID network/ap
|
||||||
dispatchSetting(json, "network/ap", ESP_AP_SSID, "SSID", nullptr, nullptr, 32,
|
dispatchSetting(json, "network/ap", ESP_AP_SSID, "SSID", nullptr, nullptr, 32,
|
||||||
|
@ -157,6 +157,14 @@ void ESP3DCommands::ESP420(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
|
|
||||||
// FW architecture
|
// FW architecture
|
||||||
tmpstr = ESP3DSettings::TargetBoard();
|
tmpstr = ESP3DSettings::TargetBoard();
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
tmpstr = ESP.getChipModel();
|
||||||
|
tmpstr+="-";
|
||||||
|
tmpstr+=ESP.getChipRevision();
|
||||||
|
tmpstr+="-";
|
||||||
|
tmpstr+=ESP.getChipCores();
|
||||||
|
tmpstr+="@";
|
||||||
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
if (!dispatchIdValue(json, "FW arch", tmpstr.c_str(), target, requestId,
|
if (!dispatchIdValue(json, "FW arch", tmpstr.c_str(), target, requestId,
|
||||||
false)) {
|
false)) {
|
||||||
return;
|
return;
|
||||||
@ -389,6 +397,7 @@ void ESP3DCommands::ESP420(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// IP mode
|
// IP mode
|
||||||
|
esp3d_log_d("IP mode %d", NetConfig::isIPModeDHCP(ESP_ETH_STA));
|
||||||
tmpstr = (NetConfig::isIPModeDHCP(ESP_ETH_STA)) ? "dhcp" : "static";
|
tmpstr = (NetConfig::isIPModeDHCP(ESP_ETH_STA)) ? "dhcp" : "static";
|
||||||
if (!dispatchIdValue(json, "ip mode", tmpstr.c_str(), target, requestId,
|
if (!dispatchIdValue(json, "ip mode", tmpstr.c_str(), target, requestId,
|
||||||
false)) {
|
false)) {
|
||||||
@ -418,6 +427,11 @@ void ESP3DCommands::ESP420(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
false)) {
|
false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!dispatchIdValue(json, "ethernet", "OFF", target, requestId,
|
||||||
|
false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // ETH_FEATURE
|
#endif // ETH_FEATURE
|
||||||
#if defined(WIFI_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
|
@ -56,7 +56,7 @@ void ESP3DCommands::ESP710(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
} else {
|
} else {
|
||||||
if (formatfs) {
|
if (formatfs) {
|
||||||
ok_msg = "Starting formating...";
|
ok_msg = "Starting formating...";
|
||||||
endMsg = ESP3DMessageManager::copyMsgInfos(*msg);
|
endMsg = esp3d_message_manager.copyMsgInfos(*msg);
|
||||||
} else {
|
} else {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
error_msg = "Invalid parameter";
|
error_msg = "Invalid parameter";
|
||||||
|
@ -57,7 +57,7 @@ void ESP3DCommands::ESP715(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
if (formatsd) {
|
if (formatsd) {
|
||||||
if (ESP_SD::getState() != ESP_SDCARD_BUSY) {
|
if (ESP_SD::getState() != ESP_SDCARD_BUSY) {
|
||||||
ok_msg = "Starting formating...";
|
ok_msg = "Starting formating...";
|
||||||
endMsg = ESP3DMessageManager::copyMsgInfos(*msg);
|
endMsg = esp3d_message_manager.copyMsgInfos(*msg);
|
||||||
} else {
|
} else {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
error_msg = "SD card busy";
|
error_msg = "SD card busy";
|
||||||
|
@ -49,7 +49,11 @@ void ESP3DCommands::ESP720(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
#endif // AUTHENTICATION_FEATURE
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
|
||||||
ESP3DMessage msgInfo;
|
ESP3DMessage msgInfo;
|
||||||
ESP3DMessageManager::copyMsgInfos(&msgInfo, *msg);
|
esp3d_log("Copy msg infos");
|
||||||
|
if (!esp3d_message_manager.copyMsgInfos(&msgInfo, *msg)) {
|
||||||
|
esp3d_log_e("Error copying msg infos");
|
||||||
|
return;
|
||||||
|
}
|
||||||
tmpstr = get_clean_param(msg, cmd_params_pos);
|
tmpstr = get_clean_param(msg, cmd_params_pos);
|
||||||
|
|
||||||
if (tmpstr.length() == 0) {
|
if (tmpstr.length() == 0) {
|
||||||
@ -104,7 +108,7 @@ void ESP3DCommands::ESP720(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
if (!json) {
|
if (!json) {
|
||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newMsg->type = ESP3DMessageType::core;
|
newMsg->type = ESP3DMessageType::core;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
@ -156,7 +160,7 @@ void ESP3DCommands::ESP720(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
if (!json) {
|
if (!json) {
|
||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newMsg->type = ESP3DMessageType::core;
|
newMsg->type = ESP3DMessageType::core;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
@ -202,7 +206,7 @@ void ESP3DCommands::ESP720(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
newMsg->type = ESP3DMessageType::tail;
|
newMsg->type = ESP3DMessageType::tail;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
esp3d_log_e("Error sending response to clients");
|
esp3d_log_e("Error sending response to clients");
|
||||||
|
@ -49,7 +49,7 @@ void ESP3DCommands::ESP740(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
#endif // AUTHENTICATION_FEATURE
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
|
||||||
ESP3DMessage msgInfo;
|
ESP3DMessage msgInfo;
|
||||||
ESP3DMessageManager::copyMsgInfos(&msgInfo, *msg);
|
esp3d_message_manager.copyMsgInfos(&msgInfo, *msg);
|
||||||
tmpstr = get_clean_param(msg, cmd_params_pos);
|
tmpstr = get_clean_param(msg, cmd_params_pos);
|
||||||
|
|
||||||
if (tmpstr.length() == 0) {
|
if (tmpstr.length() == 0) {
|
||||||
@ -118,7 +118,7 @@ void ESP3DCommands::ESP740(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
if (!json) {
|
if (!json) {
|
||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newMsg->type = ESP3DMessageType::core;
|
newMsg->type = ESP3DMessageType::core;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
@ -170,7 +170,7 @@ void ESP3DCommands::ESP740(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
if (!json) {
|
if (!json) {
|
||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newMsg->type = ESP3DMessageType::core;
|
newMsg->type = ESP3DMessageType::core;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
@ -216,7 +216,7 @@ void ESP3DCommands::ESP740(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
newMsg->type = ESP3DMessageType::tail;
|
newMsg->type = ESP3DMessageType::tail;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
esp3d_log_e("Error sending response to clients");
|
esp3d_log_e("Error sending response to clients");
|
||||||
|
@ -49,7 +49,7 @@ void ESP3DCommands::ESP780(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
#endif // AUTHENTICATION_FEATURE
|
#endif // AUTHENTICATION_FEATURE
|
||||||
|
|
||||||
ESP3DMessage msgInfo;
|
ESP3DMessage msgInfo;
|
||||||
ESP3DMessageManager::copyMsgInfos(&msgInfo, *msg);
|
esp3d_message_manager.copyMsgInfos(&msgInfo, *msg);
|
||||||
tmpstr = get_clean_param(msg, cmd_params_pos);
|
tmpstr = get_clean_param(msg, cmd_params_pos);
|
||||||
|
|
||||||
if (tmpstr.length() == 0) {
|
if (tmpstr.length() == 0) {
|
||||||
@ -105,7 +105,7 @@ void ESP3DCommands::ESP780(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
if (!json) {
|
if (!json) {
|
||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newMsg->type = ESP3DMessageType::core;
|
newMsg->type = ESP3DMessageType::core;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
@ -157,7 +157,7 @@ void ESP3DCommands::ESP780(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
if (!json) {
|
if (!json) {
|
||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newMsg->type = ESP3DMessageType::core;
|
newMsg->type = ESP3DMessageType::core;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
@ -203,7 +203,7 @@ void ESP3DCommands::ESP780(int cmd_params_pos, ESP3DMessage* msg) {
|
|||||||
ok_msg += "\n";
|
ok_msg += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessage* newMsg = ESP3DMessageManager::copyMsgInfos(msgInfo);
|
ESP3DMessage* newMsg = esp3d_message_manager.copyMsgInfos(msgInfo);
|
||||||
newMsg->type = ESP3DMessageType::tail;
|
newMsg->type = ESP3DMessageType::tail;
|
||||||
if (!dispatch(newMsg, ok_msg.c_str())) {
|
if (!dispatch(newMsg, ok_msg.c_str())) {
|
||||||
esp3d_log_e("Error sending response to clients");
|
esp3d_log_e("Error sending response to clients");
|
||||||
|
@ -55,6 +55,9 @@
|
|||||||
#endif // SD_UPDATE_FEATURE
|
#endif // SD_UPDATE_FEATURE
|
||||||
#include "../modules/boot_delay/boot_delay.h"
|
#include "../modules/boot_delay/boot_delay.h"
|
||||||
#include "esp3d_message.h"
|
#include "esp3d_message.h"
|
||||||
|
#ifdef ESP_LUA_INTERPRETER_FEATURE
|
||||||
|
#include "../modules/lua_interpreter/lua_interpreter_service.h"
|
||||||
|
#endif // ESP_LUA_INTERPRETER_FEATURE
|
||||||
|
|
||||||
bool Esp3D::restart = false;
|
bool Esp3D::restart = false;
|
||||||
|
|
||||||
@ -179,6 +182,10 @@ void Esp3D::handle() {
|
|||||||
#if defined(GCODE_HOST_FEATURE)
|
#if defined(GCODE_HOST_FEATURE)
|
||||||
esp3d_gcode_host.handle();
|
esp3d_gcode_host.handle();
|
||||||
#endif // GCODE_HOST_FEATURE
|
#endif // GCODE_HOST_FEATURE
|
||||||
|
|
||||||
|
#ifdef ESP_LUA_INTERPRETER_FEATURE
|
||||||
|
esp3d_lua_interpreter.handle();
|
||||||
|
#endif // ESP_LUA_INTERPRETER_FEATURE
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Esp3D::started() { return _started; }
|
bool Esp3D::started() { return _started; }
|
||||||
|
@ -388,7 +388,7 @@ void ESP3DCommands::execute_internal_command(int cmd, int cmd_params_pos,
|
|||||||
ESP101(cmd_params_pos, msg);
|
ESP101(cmd_params_pos, msg);
|
||||||
break;
|
break;
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
// Change STA IP mode (DHCP/STATIC)
|
// Change STA IP mode (DHCP/STATIC)
|
||||||
//[ESP102]<mode>pwd=<admin password>
|
//[ESP102]<mode>pwd=<admin password>
|
||||||
case 102:
|
case 102:
|
||||||
@ -399,15 +399,11 @@ void ESP3DCommands::execute_internal_command(int cmd, int cmd_params_pos,
|
|||||||
case 103:
|
case 103:
|
||||||
ESP103(cmd_params_pos, msg);
|
ESP103(cmd_params_pos, msg);
|
||||||
break;
|
break;
|
||||||
#endif // WIFI_FEATURE ||ETH_FEATURE
|
|
||||||
#if defined(WIFI_FEATURE) || defined(BLUETOOTH_FEATURE) || defined(ETH_FEATURE)
|
|
||||||
// Set fallback mode which can be BT, WIFI-AP, OFF
|
// Set fallback mode which can be BT, WIFI-AP, OFF
|
||||||
//[ESP104]<state>pwd=<admin password>
|
//[ESP104]<state>pwd=<admin password>
|
||||||
case 104:
|
case 104:
|
||||||
ESP104(cmd_params_pos, msg);
|
ESP104(cmd_params_pos, msg);
|
||||||
break;
|
break;
|
||||||
#endif // WIFI_FEATURE || BLUETOOTH_FEATURE || ETH_FEATURE)
|
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
// AP SSID
|
// AP SSID
|
||||||
//[ESP105]<SSID>[pwd=<admin password>]
|
//[ESP105]<SSID>[pwd=<admin password>]
|
||||||
case 105:
|
case 105:
|
||||||
@ -465,6 +461,24 @@ void ESP3DCommands::execute_internal_command(int cmd, int cmd_params_pos,
|
|||||||
break;
|
break;
|
||||||
#endif // WIFI_FEATURE|| ETH_FEATURE || BT_FEATURE
|
#endif // WIFI_FEATURE|| ETH_FEATURE || BT_FEATURE
|
||||||
|
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
// Change ETH STA IP mode (DHCP/STATIC)
|
||||||
|
//[ESP116]<mode>pwd=<admin password>
|
||||||
|
case 116:
|
||||||
|
ESP102(cmd_params_pos, msg);
|
||||||
|
break;
|
||||||
|
// Change ETH STA IP/Mask/GW
|
||||||
|
//[ESP117]IP=<IP> MSK=<IP> GW=<IP> pwd=<admin password>
|
||||||
|
case 117:
|
||||||
|
ESP117(cmd_params_pos, msg);
|
||||||
|
break;
|
||||||
|
// Set fallback mode which can be BT, OFF
|
||||||
|
//[ESP118]<state>pwd=<admin password>
|
||||||
|
case 118:
|
||||||
|
ESP118(cmd_params_pos, msg);
|
||||||
|
break;
|
||||||
|
#endif // ETH_FEATURE
|
||||||
|
|
||||||
#ifdef HTTP_FEATURE
|
#ifdef HTTP_FEATURE
|
||||||
// Set HTTP state which can be ON, OFF
|
// Set HTTP state which can be ON, OFF
|
||||||
//[ESP120]<state>pwd=<admin password>
|
//[ESP120]<state>pwd=<admin password>
|
||||||
@ -1165,9 +1179,9 @@ void ESP3DCommands::process(ESP3DMessage *msg) {
|
|||||||
esp3d_log("Execute internal command %d", cmdId);
|
esp3d_log("Execute internal command %d", cmdId);
|
||||||
execute_internal_command(cmdId, espcmdpos, msg);
|
execute_internal_command(cmdId, espcmdpos, msg);
|
||||||
} else {
|
} else {
|
||||||
esp3d_log("Dispatch command, len %d, from %d(%s) to %d(%s)", msg->size,
|
/*esp3d_log("Dispatch command, len %d, from %d(%s) to %d(%s)", msg->size,
|
||||||
static_cast<uint8_t>(msg->origin), GETCLIENTSTR(msg->origin),
|
static_cast<uint8_t>(msg->origin), GETCLIENTSTR(msg->origin),
|
||||||
static_cast<uint8_t>(msg->target), GETCLIENTSTR(msg->target));
|
static_cast<uint8_t>(msg->target), GETCLIENTSTR(msg->target));*/
|
||||||
|
|
||||||
// Work around to avoid to dispatch single \n or \r to everyone as it is
|
// Work around to avoid to dispatch single \n or \r to everyone as it is
|
||||||
// part of previous ESP3D command
|
// part of previous ESP3D command
|
||||||
@ -1177,10 +1191,11 @@ void ESP3DCommands::process(ESP3DMessage *msg) {
|
|||||||
lastIsESP3D = false;
|
lastIsESP3D = false;
|
||||||
// delete message
|
// delete message
|
||||||
esp3d_log("Delete message");
|
esp3d_log("Delete message");
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastIsESP3D = false;
|
lastIsESP3D = false;
|
||||||
|
esp3d_log("Dispatch message: %s", msg->data);
|
||||||
dispatch(msg);
|
dispatch(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1206,25 +1221,25 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg, uint8_t *sbuf, size_t len) {
|
|||||||
}
|
}
|
||||||
tmpstr += '\n';
|
tmpstr += '\n';
|
||||||
esp3d_log("update command success: *%s*", tmpstr.c_str());
|
esp3d_log("update command success: *%s*", tmpstr.c_str());
|
||||||
if (!ESP3DMessageManager::setDataContent(msg, (uint8_t *)tmpstr.c_str(),
|
if (!esp3d_message_manager.setDataContent(msg, (uint8_t *)tmpstr.c_str(),
|
||||||
tmpstr.length())) {
|
tmpstr.length())) {
|
||||||
esp3d_log_e("set data content failed");
|
esp3d_log_e("set data content failed");
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
esp3d_log("format command success, no need to update");
|
esp3d_log("format command success, no need to update");
|
||||||
if (!ESP3DMessageManager::setDataContent(msg, sbuf, len)) {
|
if (!esp3d_message_manager.setDataContent(msg, sbuf, len)) {
|
||||||
esp3d_log_e("set data content failed");
|
esp3d_log_e("set data content failed");
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
esp3d_log("not unique or tail message");
|
esp3d_log("not unique or tail message");
|
||||||
if (!ESP3DMessageManager::setDataContent(msg, sbuf, len)) {
|
if (!esp3d_message_manager.setDataContent(msg, sbuf, len)) {
|
||||||
esp3d_log_e("set data content failed");
|
esp3d_log_e("set data content failed");
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1235,7 +1250,7 @@ bool ESP3DCommands::dispatch(uint8_t *sbuf, size_t size, ESP3DClientType target,
|
|||||||
ESP3DRequest requestId, ESP3DMessageType type,
|
ESP3DRequest requestId, ESP3DMessageType type,
|
||||||
ESP3DClientType origin,
|
ESP3DClientType origin,
|
||||||
ESP3DAuthenticationLevel authentication_level) {
|
ESP3DAuthenticationLevel authentication_level) {
|
||||||
ESP3DMessage *newMsgPtr = ESP3DMessageManager::newMsg(origin, target);
|
ESP3DMessage *newMsgPtr = esp3d_message_manager.newMsg(origin, target);
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
newMsgPtr->request_id = requestId;
|
newMsgPtr->request_id = requestId;
|
||||||
newMsgPtr->type = type;
|
newMsgPtr->type = type;
|
||||||
@ -1249,7 +1264,7 @@ bool ESP3DCommands::dispatch(const char *sbuf, ESP3DClientType target,
|
|||||||
ESP3DRequest requestId, ESP3DMessageType type,
|
ESP3DRequest requestId, ESP3DMessageType type,
|
||||||
ESP3DClientType origin,
|
ESP3DClientType origin,
|
||||||
ESP3DAuthenticationLevel authentication_level) {
|
ESP3DAuthenticationLevel authentication_level) {
|
||||||
ESP3DMessage *newMsgPtr = ESP3DMessageManager::newMsg(origin, target);
|
ESP3DMessage *newMsgPtr = esp3d_message_manager.newMsg(origin, target);
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
newMsgPtr->request_id = requestId;
|
newMsgPtr->request_id = requestId;
|
||||||
newMsgPtr->type = type;
|
newMsgPtr->type = type;
|
||||||
@ -1281,7 +1296,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
switch (msg->target) {
|
switch (msg->target) {
|
||||||
case ESP3DClientType::no_client:
|
case ESP3DClientType::no_client:
|
||||||
esp3d_log("No client message");
|
esp3d_log("No client message");
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
break;
|
break;
|
||||||
#if COMMUNICATION_PROTOCOL == RAW_SERIAL
|
#if COMMUNICATION_PROTOCOL == RAW_SERIAL
|
||||||
case ESP3DClientType::serial:
|
case ESP3DClientType::serial:
|
||||||
@ -1303,7 +1318,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
MYSERIAL1.write('\n');
|
MYSERIAL1.write('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESP3DClientType::socket_serial:
|
case ESP3DClientType::socket_serial:
|
||||||
@ -1413,7 +1428,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
tmp.replace("\n", " ");
|
tmp.replace("\n", " ");
|
||||||
tmp.replace("\r", "");
|
tmp.replace("\r", "");
|
||||||
tmp += "\n";
|
tmp += "\n";
|
||||||
if (ESP3DMessageManager::setDataContent(msg, (uint8_t *)tmp.c_str(),
|
if (esp3d_message_manager.setDataContent(msg, (uint8_t *)tmp.c_str(),
|
||||||
tmp.length())) {
|
tmp.length())) {
|
||||||
return dispatch(msg);
|
return dispatch(msg);
|
||||||
}
|
}
|
||||||
@ -1432,7 +1447,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::remote_screen;
|
msg->target = ESP3DClientType::remote_screen;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::remote_screen;
|
copy_msg->target = ESP3DClientType::remote_screen;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1451,7 +1466,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::lua_script;
|
msg->target = ESP3DClientType::lua_script;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::lua_script;
|
copy_msg->target = ESP3DClientType::lua_script;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1471,7 +1486,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->request_id.id = ESP_OUTPUT_STATUS;
|
msg->request_id.id = ESP_OUTPUT_STATUS;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::rendering;
|
copy_msg->target = ESP3DClientType::rendering;
|
||||||
copy_msg->request_id.id = ESP_OUTPUT_STATUS;
|
copy_msg->request_id.id = ESP_OUTPUT_STATUS;
|
||||||
@ -1491,7 +1506,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::echo_serial;
|
msg->target = ESP3DClientType::echo_serial;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::echo_serial;
|
copy_msg->target = ESP3DClientType::echo_serial;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1509,7 +1524,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::serial_bridge;
|
msg->target = ESP3DClientType::serial_bridge;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::serial_bridge;
|
copy_msg->target = ESP3DClientType::serial_bridge;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1528,7 +1543,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::bluetooth;
|
msg->target = ESP3DClientType::bluetooth;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::bluetooth;
|
copy_msg->target = ESP3DClientType::bluetooth;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1547,7 +1562,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::telnet;
|
msg->target = ESP3DClientType::telnet;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::telnet;
|
copy_msg->target = ESP3DClientType::telnet;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1570,7 +1585,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::webui_websocket;
|
msg->target = ESP3DClientType::webui_websocket;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::webui_websocket;
|
copy_msg->target = ESP3DClientType::webui_websocket;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1592,7 +1607,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
msg->target = ESP3DClientType::websocket;
|
msg->target = ESP3DClientType::websocket;
|
||||||
} else {
|
} else {
|
||||||
// duplicate message because current is already pending
|
// duplicate message because current is already pending
|
||||||
ESP3DMessage *copy_msg = ESP3DMessageManager::copyMsg(*msg);
|
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
|
||||||
if (copy_msg) {
|
if (copy_msg) {
|
||||||
copy_msg->target = ESP3DClientType::websocket;
|
copy_msg->target = ESP3DClientType::websocket;
|
||||||
dispatch(copy_msg);
|
dispatch(copy_msg);
|
||||||
@ -1624,7 +1639,7 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
|
|||||||
// clear message
|
// clear message
|
||||||
if (!sendOk) {
|
if (!sendOk) {
|
||||||
esp3d_log_e("Send msg failed");
|
esp3d_log_e("Send msg failed");
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
}
|
}
|
||||||
return sendOk;
|
return sendOk;
|
||||||
}
|
}
|
||||||
|
@ -53,14 +53,10 @@ class ESP3DCommands {
|
|||||||
void ESP100(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP100(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
void ESP101(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP101(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
#endif // WIFI_FEATURE
|
#endif // WIFI_FEATURE
|
||||||
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
void ESP102(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP102(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
void ESP103(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP103(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
#endif // WIFI_FEATURE ||ETH_FEATURE
|
|
||||||
#if defined(WIFI_FEATURE) || defined(BLUETOOTH_FEATURE) || defined(ETH_FEATURE)
|
|
||||||
void ESP104(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP104(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
#endif // WIFI_FEATURE || BLUETOOTH_FEATURE || ETH_FEATURE
|
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
void ESP105(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP105(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
void ESP106(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP106(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
void ESP107(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP107(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
@ -77,6 +73,11 @@ class ESP3DCommands {
|
|||||||
void ESP114(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP114(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
void ESP115(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP115(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
#endif // WIFI_FEATURE || BLUETOOTH_FEATURE || ETH_FEATURE
|
#endif // WIFI_FEATURE || BLUETOOTH_FEATURE || ETH_FEATURE
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
void ESP116(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
|
void ESP117(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
|
void ESP118(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
|
#endif // ETH_FEATURE
|
||||||
#if defined(HTTP_FEATURE)
|
#if defined(HTTP_FEATURE)
|
||||||
void ESP120(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP120(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
void ESP121(int cmd_params_pos, ESP3DMessage* msg);
|
void ESP121(int cmd_params_pos, ESP3DMessage* msg);
|
||||||
|
@ -34,9 +34,13 @@
|
|||||||
#endif // __has_include ("rtc_wdt.h")
|
#endif // __has_include ("rtc_wdt.h")
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
#endif // CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <driver/adc.h>
|
#include <esp_adc/adc_continuous.h>
|
||||||
|
#include <esp_adc/adc_oneshot.h>
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
|
|
||||||
|
#if !CONFIG_IDF_TARGET_ESP32C6
|
||||||
#include <soc/rtc_cntl_reg.h>
|
#include <soc/rtc_cntl_reg.h>
|
||||||
|
#endif // !CONFIG_IDF_TARGET_ESP32C6
|
||||||
|
|
||||||
TaskHandle_t ESP3DHal::xHandle = nullptr;
|
TaskHandle_t ESP3DHal::xHandle = nullptr;
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
@ -135,10 +139,7 @@ void ESP3DHal::analogRange(uint32_t range) {
|
|||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
bool ESP3DHal::begin() {
|
bool ESP3DHal::begin() {
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(CAMERA_DEVICE)
|
checkTWDT();
|
||||||
esp3d_log("Disable brown out");
|
|
||||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector
|
|
||||||
#endif // ARDUINO_ARCH_ESP32 && CAMERA_DEVICE
|
|
||||||
// Clear all wifi state
|
// Clear all wifi state
|
||||||
WiFi.persistent(false);
|
WiFi.persistent(false);
|
||||||
WiFi.disconnect(true);
|
WiFi.disconnect(true);
|
||||||
@ -160,47 +161,61 @@ bool ESP3DHal::begin() {
|
|||||||
// End ESP3D
|
// End ESP3D
|
||||||
void ESP3DHal::end() {}
|
void ESP3DHal::end() {}
|
||||||
|
|
||||||
|
void ESP3DHal::checkTWDT() {
|
||||||
|
// ESP32-C6 Seems not working with esp_task_wdt_reset()
|
||||||
|
// I itinitally though it was wrong initialization of TWDT
|
||||||
|
// doing esp_task_wdt_init() is not working
|
||||||
|
// but esp_task_wdt_reconfigure() is working
|
||||||
|
// unfortunately it is still not working with esp_task_wdt_reset()
|
||||||
|
// so because doing esp_task_wdt_reconfigure and not do not change the
|
||||||
|
// behavior so I comment it for now as note Instead I use vTaskDelay(1) to
|
||||||
|
// feed the WDT and seems ok delay(1) seems also ok
|
||||||
|
/*
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C6
|
||||||
|
//ESP32-C6
|
||||||
|
esp_err_t err = esp_task_wdt_status(NULL);
|
||||||
|
if (err == ESP_ERR_NOT_FOUND) {
|
||||||
|
esp3d_log_e("WDT was never initialized");
|
||||||
|
esp_task_wdt_config_t twdt_config = {
|
||||||
|
.timeout_ms = 2 * 1000,
|
||||||
|
.idle_core_mask = (1 << 0),
|
||||||
|
.trigger_panic = true,
|
||||||
|
};
|
||||||
|
err = esp_task_wdt_reconfigure(&twdt_config);
|
||||||
|
if (err == ESP_ERR_INVALID_STATE) {
|
||||||
|
esp3d_log_e("WDT already initialized");
|
||||||
|
} else if (err != ESP_OK) {
|
||||||
|
esp3d_log_e("WDT cannot be setup");
|
||||||
|
} else {
|
||||||
|
esp3d_log("WDT setup ok");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_IDF_TARGET_ESP32C6
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
// Watchdog feeder
|
// Watchdog feeder
|
||||||
void ESP3DHal::wdtFeed() {
|
void ESP3DHal::wdtFeed() {
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
vTaskDelay(1);
|
||||||
|
return;
|
||||||
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
ESP.wdtFeed();
|
ESP.wdtFeed();
|
||||||
#endif // ARDUINO_ARCH_ESP8266
|
#endif // ARDUINO_ARCH_ESP8266
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
|
||||||
static uint64_t lastYield = 0;
|
|
||||||
uint64_t now = millis();
|
|
||||||
if ((now - lastYield) > 2000) {
|
|
||||||
lastYield = now;
|
|
||||||
vTaskDelay(5); // delay 1 RTOS tick
|
|
||||||
}
|
|
||||||
#if !defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0)
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
// FIXME: not implemented
|
|
||||||
rtc_wdt_feed();
|
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
#endif //! defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0)
|
|
||||||
#ifndef DISABLE_WDT_ESP3DLIB_TASK
|
|
||||||
if (xHandle && esp_task_wdt_status(xHandle) == ESP_OK) {
|
|
||||||
if (esp_task_wdt_reset() != ESP_OK) {
|
|
||||||
esp3d_log_e("WDT Reset failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // DISABLE_WDT_ESP3DLIB_TASK
|
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait function
|
// wait function
|
||||||
void ESP3DHal::wait(uint32_t milliseconds) {
|
void ESP3DHal::wait(uint32_t milliseconds) {
|
||||||
#if defined(ASYNCWEBSERVER)
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
uint32_t timeout = millis();
|
uint32_t timeout = millis();
|
||||||
while ((millis() - timeout) < milliseconds) {
|
while ((millis() - timeout) < milliseconds) {
|
||||||
wdtFeed();
|
wdtFeed();
|
||||||
}
|
}
|
||||||
#else // !(ASYNCWEBSERVER
|
#endif // CONFIG_IDF_TARGET_ESP32
|
||||||
wdtFeed();
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
// before 0 was acceptable, now it seems need to put 5 to have some effect if
|
delay(milliseconds);
|
||||||
// on esp32 core 0
|
#endif // ARDUINO_ARCH_ESP8266
|
||||||
delay(milliseconds < 5 ? 5 : milliseconds);
|
|
||||||
#endif // !ASYNCWEBSERVER
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ESP3DHal::getChipID() {
|
uint16_t ESP3DHal::getChipID() {
|
||||||
|
@ -49,6 +49,7 @@ class ESP3DHal {
|
|||||||
static void analogWriteFreq(uint32_t freq);
|
static void analogWriteFreq(uint32_t freq);
|
||||||
static void analogRange(uint32_t range);
|
static void analogRange(uint32_t range);
|
||||||
static const char * arduinoVersion();
|
static const char * arduinoVersion();
|
||||||
|
static void checkTWDT();
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
static TaskHandle_t xHandle;
|
static TaskHandle_t xHandle;
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
|
@ -24,28 +24,67 @@
|
|||||||
|
|
||||||
ESP3DRequest no_id{.id = 0};
|
ESP3DRequest no_id{.id = 0};
|
||||||
|
|
||||||
|
ESP3DMessageManager esp3d_message_manager;
|
||||||
|
|
||||||
|
ESP3DMessageManager::ESP3DMessageManager() {
|
||||||
|
_mutex = xSemaphoreCreateMutex();
|
||||||
#if defined(ESP_LOG_FEATURE)
|
#if defined(ESP_LOG_FEATURE)
|
||||||
int msg_counting = 0;
|
_msg_counting = 0;
|
||||||
#endif // ESP_LOG_FEATURE
|
#endif // ESP_LOG_FEATURE
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessageManager::~ESP3DMessageManager() { vSemaphoreDelete(_mutex); }
|
||||||
|
|
||||||
bool ESP3DMessageManager::deleteMsg(ESP3DMessage* message) {
|
bool ESP3DMessageManager::deleteMsg(ESP3DMessage* message) {
|
||||||
if (!message) return false;
|
esp3d_log("Delete msg");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
bool result = _deleteMsg(message);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
esp3d_log("Delete msg done");
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP3DMessageManager::_deleteMsg(ESP3DMessage* message) {
|
||||||
|
esp3d_log("_Delete msg");
|
||||||
|
if (!message) {
|
||||||
|
esp3d_log_e("Message is null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (message->data) {
|
if (message->data) {
|
||||||
|
esp3d_log("Free data");
|
||||||
free(message->data);
|
free(message->data);
|
||||||
}
|
}
|
||||||
free(message);
|
free(message);
|
||||||
message = NULL;
|
message = NULL;
|
||||||
#if defined(ESP_LOG_FEATURE)
|
#if defined(ESP_LOG_FEATURE)
|
||||||
esp3d_log("Deletion : Now we have %ld msg", --msg_counting);
|
esp3d_log("Deletion : Now we have %ld msg", --_msg_counting);
|
||||||
#endif // ESP_LOG_FEATURE
|
#endif // ESP_LOG_FEATURE
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessage* ESP3DMessageManager::newMsg() {
|
ESP3DMessage* ESP3DMessageManager::newMsg() {
|
||||||
|
esp3d_log("New msg");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
ESP3DMessage* newMsgPtr = nullptr;
|
||||||
|
newMsgPtr = _newMsg();
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
return newMsgPtr;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessage* ESP3DMessageManager::_newMsg() {
|
||||||
|
esp3d_log("_New msg");
|
||||||
ESP3DMessage* newMsgPtr = (ESP3DMessage*)malloc(sizeof(ESP3DMessage));
|
ESP3DMessage* newMsgPtr = (ESP3DMessage*)malloc(sizeof(ESP3DMessage));
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
#if defined(ESP_LOG_FEATURE)
|
#if defined(ESP_LOG_FEATURE)
|
||||||
esp3d_log("Creation : Now we have %ld msg", ++msg_counting);
|
esp3d_log("Creation : Now we have %ld msg", ++_msg_counting);
|
||||||
#endif // ESP_LOG_FEATURE
|
#endif // ESP_LOG_FEATURE
|
||||||
newMsgPtr->data = nullptr;
|
newMsgPtr->data = nullptr;
|
||||||
newMsgPtr->size = 0;
|
newMsgPtr->size = 0;
|
||||||
@ -57,45 +96,113 @@ ESP3DMessage* ESP3DMessageManager::newMsg() {
|
|||||||
} else {
|
} else {
|
||||||
esp3d_log_e("Out of memory");
|
esp3d_log_e("Out of memory");
|
||||||
}
|
}
|
||||||
|
esp3d_log("Message created");
|
||||||
return newMsgPtr;
|
return newMsgPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessage* ESP3DMessageManager::newMsg(ESP3DRequest requestId) {
|
ESP3DMessage* ESP3DMessageManager::newMsg(ESP3DRequest requestId) {
|
||||||
ESP3DMessage* newMsgPtr = newMsg();
|
esp3d_log("New msg");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
ESP3DMessage* newMsgPtr = nullptr;
|
||||||
|
newMsgPtr = _newMsg(requestId);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
esp3d_log("New msg done");
|
||||||
|
return newMsgPtr;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessage* ESP3DMessageManager::_newMsg(ESP3DRequest requestId) {
|
||||||
|
esp3d_log("_New msg");
|
||||||
|
ESP3DMessage* newMsgPtr = _newMsg();
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
|
esp3d_log("New msg done");
|
||||||
newMsgPtr->origin = ESP3DClientType::command;
|
newMsgPtr->origin = ESP3DClientType::command;
|
||||||
newMsgPtr->request_id = requestId;
|
newMsgPtr->request_id = requestId;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("newMsgPtr is null");
|
||||||
}
|
}
|
||||||
return newMsgPtr;
|
return newMsgPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESP3DMessageManager::copyMsgInfos(ESP3DMessage* newMsgPtr,
|
bool ESP3DMessageManager::copyMsgInfos(ESP3DMessage* newMsgPtr,
|
||||||
ESP3DMessage msg) {
|
ESP3DMessage msg) {
|
||||||
|
esp3d_log("Copy msg infos");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
bool result = _copyMsgInfos(newMsgPtr, msg);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
esp3d_log("Copy msg infos done");
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP3DMessageManager::_copyMsgInfos(ESP3DMessage* newMsgPtr,
|
||||||
|
ESP3DMessage msg) {
|
||||||
|
esp3d_log("_Copy msg infos");
|
||||||
if (!newMsgPtr) {
|
if (!newMsgPtr) {
|
||||||
|
esp3d_log_e("newMsgPtr is null");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
esp3d_log("Copying msg infos");
|
||||||
newMsgPtr->origin = msg.origin;
|
newMsgPtr->origin = msg.origin;
|
||||||
newMsgPtr->target = msg.target;
|
newMsgPtr->target = msg.target;
|
||||||
newMsgPtr->authentication_level = msg.authentication_level;
|
newMsgPtr->authentication_level = msg.authentication_level;
|
||||||
newMsgPtr->request_id = msg.request_id;
|
newMsgPtr->request_id = msg.request_id;
|
||||||
newMsgPtr->type = msg.type;
|
newMsgPtr->type = msg.type;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessage* ESP3DMessageManager::copyMsgInfos(ESP3DMessage msg) {
|
ESP3DMessage* ESP3DMessageManager::copyMsgInfos(ESP3DMessage msg) {
|
||||||
ESP3DMessage* newMsgPtr = newMsg();
|
esp3d_log("Copy msg infos");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
ESP3DMessage* newMsgPtr = _copyMsgInfos(msg);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
esp3d_log("Copy msg infos done");
|
||||||
|
return newMsgPtr;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessage* ESP3DMessageManager::_copyMsgInfos(ESP3DMessage msg) {
|
||||||
|
esp3d_log("_Copy msg infos");
|
||||||
|
ESP3DMessage* newMsgPtr = _newMsg();
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
copyMsgInfos(newMsgPtr, msg);
|
_copyMsgInfos(newMsgPtr, msg);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("newMsg is null");
|
||||||
}
|
}
|
||||||
return newMsgPtr;
|
return newMsgPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessage* ESP3DMessageManager::copyMsg(ESP3DMessage msg) {
|
ESP3DMessage* ESP3DMessageManager::copyMsg(ESP3DMessage msg) {
|
||||||
ESP3DMessage* newMsgPtr = newMsg(msg.origin, msg.target, msg.data, msg.size,
|
esp3d_log("Copy msg");
|
||||||
msg.authentication_level);
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
ESP3DMessage* newMsgPtr = _copyMsg(msg);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
return newMsgPtr;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessage* ESP3DMessageManager::_copyMsg(ESP3DMessage msg) {
|
||||||
|
esp3d_log("_Copy msg");
|
||||||
|
ESP3DMessage* newMsgPtr = _newMsg(msg.origin, msg.target, msg.data, msg.size,
|
||||||
|
msg.authentication_level);
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
newMsgPtr->request_id = msg.request_id;
|
newMsgPtr->request_id = msg.request_id;
|
||||||
newMsgPtr->type = msg.type;
|
newMsgPtr->type = msg.type;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("newMsgPtr is null");
|
||||||
}
|
}
|
||||||
return newMsgPtr;
|
return newMsgPtr;
|
||||||
}
|
}
|
||||||
@ -103,15 +210,36 @@ ESP3DMessage* ESP3DMessageManager::copyMsg(ESP3DMessage msg) {
|
|||||||
ESP3DMessage* ESP3DMessageManager::newMsg(
|
ESP3DMessage* ESP3DMessageManager::newMsg(
|
||||||
ESP3DClientType origin, ESP3DClientType target, const uint8_t* data,
|
ESP3DClientType origin, ESP3DClientType target, const uint8_t* data,
|
||||||
size_t length, ESP3DAuthenticationLevel authentication_level) {
|
size_t length, ESP3DAuthenticationLevel authentication_level) {
|
||||||
ESP3DMessage* newMsgPtr = newMsg(origin, target, authentication_level);
|
esp3d_log("New msg");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
ESP3DMessage* newMsgPtr =
|
||||||
|
_newMsg(origin, target, data, length, authentication_level);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
esp3d_log("New msg done");
|
||||||
|
return newMsgPtr;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessage* ESP3DMessageManager::_newMsg(
|
||||||
|
ESP3DClientType origin, ESP3DClientType target, const uint8_t* data,
|
||||||
|
size_t length, ESP3DAuthenticationLevel authentication_level) {
|
||||||
|
ESP3DMessage* newMsgPtr = _newMsg(origin, target, authentication_level);
|
||||||
|
esp3d_log("_New msg");
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
if (!setDataContent(newMsgPtr, data, length)) {
|
if (!_setDataContent(newMsgPtr, data, length)) {
|
||||||
deleteMsg(newMsgPtr);
|
_deleteMsg(newMsgPtr);
|
||||||
newMsgPtr = nullptr;
|
newMsgPtr = nullptr;
|
||||||
esp3d_log_e("newMsg failed for origin %d, target %d, data %s",
|
esp3d_log_e("newMsg failed for origin %d, target %d, data %s",
|
||||||
(uint8_t)origin, (uint8_t)target,
|
(uint8_t)origin, (uint8_t)target,
|
||||||
data ? (char*)data : "null");
|
data ? (char*)data : "null");
|
||||||
|
} else {
|
||||||
|
esp3d_log("Message created");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("newMsgPtr is null");
|
||||||
}
|
}
|
||||||
return newMsgPtr;
|
return newMsgPtr;
|
||||||
}
|
}
|
||||||
@ -119,17 +247,51 @@ ESP3DMessage* ESP3DMessageManager::newMsg(
|
|||||||
ESP3DMessage* ESP3DMessageManager::newMsg(
|
ESP3DMessage* ESP3DMessageManager::newMsg(
|
||||||
ESP3DClientType origin, ESP3DClientType target,
|
ESP3DClientType origin, ESP3DClientType target,
|
||||||
ESP3DAuthenticationLevel authentication_level) {
|
ESP3DAuthenticationLevel authentication_level) {
|
||||||
ESP3DMessage* newMsgPtr = newMsg();
|
esp3d_log("New msg");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
ESP3DMessage* newMsgPtr = _newMsg(origin, target, authentication_level);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
esp3d_log("New msg done");
|
||||||
|
return newMsgPtr;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessage* ESP3DMessageManager::_newMsg(
|
||||||
|
ESP3DClientType origin, ESP3DClientType target,
|
||||||
|
ESP3DAuthenticationLevel authentication_level) {
|
||||||
|
esp3d_log("_New msg");
|
||||||
|
ESP3DMessage* newMsgPtr = _newMsg();
|
||||||
if (newMsgPtr) {
|
if (newMsgPtr) {
|
||||||
newMsgPtr->origin = origin;
|
newMsgPtr->origin = origin;
|
||||||
newMsgPtr->target = target;
|
newMsgPtr->target = target;
|
||||||
newMsgPtr->authentication_level = authentication_level;
|
newMsgPtr->authentication_level = authentication_level;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("newMsgPtr is null");
|
||||||
}
|
}
|
||||||
|
esp3d_log("_New msg done");
|
||||||
return newMsgPtr;
|
return newMsgPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESP3DMessageManager::setDataContent(ESP3DMessage* msg, const uint8_t* data,
|
bool ESP3DMessageManager::setDataContent(ESP3DMessage* msg, const uint8_t* data,
|
||||||
size_t length) {
|
size_t length) {
|
||||||
|
esp3d_log("Set data content");
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
bool result = _setDataContent(msg, data, length);
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
esp3d_log("Set data content done");
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP3DMessageManager::_setDataContent(ESP3DMessage* msg,
|
||||||
|
const uint8_t* data, size_t length) {
|
||||||
|
esp3d_log("_Set data content");
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
esp3d_log_e("no valid msg container");
|
esp3d_log_e("no valid msg container");
|
||||||
return false;
|
return false;
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
|
|
||||||
#define ESP_STATE_DISCONNECTED 0
|
#define ESP_STATE_DISCONNECTED 0
|
||||||
|
|
||||||
#ifndef _ESP3DOUTPUT_H
|
#pragma once
|
||||||
#define _ESP3DOUTPUT_H
|
|
||||||
|
|
||||||
#include "../include/esp3d_config.h"
|
#include "../include/esp3d_config.h"
|
||||||
|
|
||||||
@ -43,6 +42,23 @@ class WebServer;
|
|||||||
|
|
||||||
#include "../modules/authentication/authentication_level_types.h"
|
#include "../modules/authentication/authentication_level_types.h"
|
||||||
#include "esp3d_client_types.h"
|
#include "esp3d_client_types.h"
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
//To avoid compilation error on ESP8266
|
||||||
|
// and to use many ifdefs
|
||||||
|
#ifndef pdTRUE
|
||||||
|
#define pdTRUE true
|
||||||
|
#define xSemaphoreTake(A, B) true
|
||||||
|
#define xSemaphoreGive(A)
|
||||||
|
#define xSemaphoreCreateMutex(A) 0
|
||||||
|
#define vSemaphoreDelete(A)
|
||||||
|
#define SemaphoreHandle_t void*
|
||||||
|
#endif //pdTRUE
|
||||||
|
#endif //ESP8266
|
||||||
|
|
||||||
enum class ESP3DMessageType : uint8_t { head, core, tail, unique };
|
enum class ESP3DMessageType : uint8_t { head, core, tail, unique };
|
||||||
|
|
||||||
@ -68,21 +84,44 @@ struct ESP3DMessage {
|
|||||||
|
|
||||||
class ESP3DMessageManager final {
|
class ESP3DMessageManager final {
|
||||||
public:
|
public:
|
||||||
static ESP3DMessage *newMsg();
|
ESP3DMessageManager();
|
||||||
static ESP3DMessage *newMsg(ESP3DRequest requestId);
|
~ESP3DMessageManager();
|
||||||
static bool deleteMsg(ESP3DMessage *message);
|
ESP3DMessage *newMsg();
|
||||||
static bool copyMsgInfos(ESP3DMessage *newMsgPtr, ESP3DMessage msg);
|
ESP3DMessage *newMsg(ESP3DRequest requestId);
|
||||||
static ESP3DMessage *copyMsgInfos(ESP3DMessage msg);
|
bool deleteMsg(ESP3DMessage *message);
|
||||||
static ESP3DMessage *copyMsg(ESP3DMessage msg);
|
bool copyMsgInfos(ESP3DMessage *newMsgPtr, ESP3DMessage msg);
|
||||||
static ESP3DMessage *newMsg(ESP3DClientType origin, ESP3DClientType target,
|
ESP3DMessage *copyMsgInfos(ESP3DMessage msg);
|
||||||
const uint8_t *data, size_t length,
|
|
||||||
ESP3DAuthenticationLevel authentication_level =
|
ESP3DMessage *copyMsg(ESP3DMessage msg);
|
||||||
ESP3DAuthenticationLevel::guest);
|
|
||||||
static ESP3DMessage *newMsg(ESP3DClientType origin, ESP3DClientType target,
|
ESP3DMessage *newMsg(ESP3DClientType origin, ESP3DClientType target,
|
||||||
ESP3DAuthenticationLevel authentication_level =
|
const uint8_t *data, size_t length,
|
||||||
ESP3DAuthenticationLevel::guest);
|
ESP3DAuthenticationLevel authentication_level =
|
||||||
static bool setDataContent(ESP3DMessage *msg, const uint8_t *data,
|
ESP3DAuthenticationLevel::guest);
|
||||||
size_t length);
|
ESP3DMessage *newMsg(ESP3DClientType origin, ESP3DClientType target,
|
||||||
|
ESP3DAuthenticationLevel authentication_level =
|
||||||
|
ESP3DAuthenticationLevel::guest);
|
||||||
|
bool setDataContent(ESP3DMessage *msg, const uint8_t *data, size_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _deleteMsg(ESP3DMessage *message);
|
||||||
|
ESP3DMessage *_newMsg();
|
||||||
|
ESP3DMessage *_newMsg(ESP3DRequest requestId);
|
||||||
|
bool _copyMsgInfos(ESP3DMessage *newMsgPtr, ESP3DMessage msg);
|
||||||
|
ESP3DMessage *_copyMsgInfos(ESP3DMessage msg);
|
||||||
|
ESP3DMessage *_copyMsg(ESP3DMessage msg);
|
||||||
|
ESP3DMessage *_newMsg(ESP3DClientType origin, ESP3DClientType target,
|
||||||
|
const uint8_t *data, size_t length,
|
||||||
|
ESP3DAuthenticationLevel authentication_level =
|
||||||
|
ESP3DAuthenticationLevel::guest);
|
||||||
|
ESP3DMessage *_newMsg(ESP3DClientType origin, ESP3DClientType target,
|
||||||
|
ESP3DAuthenticationLevel authentication_level =
|
||||||
|
ESP3DAuthenticationLevel::guest);
|
||||||
|
bool _setDataContent(ESP3DMessage *msg, const uint8_t *data, size_t length);
|
||||||
|
SemaphoreHandle_t _mutex;
|
||||||
|
#if defined(ESP_LOG_FEATURE)
|
||||||
|
int _msg_counting;
|
||||||
|
#endif // ESP_LOG_FEATURE
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_ESP3DOUTPUT_H
|
extern ESP3DMessageManager esp3d_message_manager;
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
esp3d_messageFifo.h - class for handeling message
|
esp3d_messageFifo.h - class for managing messages list, thread safe
|
||||||
|
|
||||||
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||||
|
|
||||||
@ -19,77 +19,149 @@
|
|||||||
*/
|
*/
|
||||||
#if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP8285)
|
#if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP8285)
|
||||||
|
|
||||||
#include "esp3d_message.h"
|
|
||||||
#include "../include/esp3d_config.h"
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#include "../include/esp3d_config.h"
|
||||||
|
#include "esp3d_message.h"
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
// To avoid compilation error on ESP8266
|
||||||
|
// and to use many ifdefs
|
||||||
|
#ifndef pdTRUE
|
||||||
|
#define pdTRUE true
|
||||||
|
#define xSemaphoreTake(A, B) true
|
||||||
|
#define xSemaphoreGive(A)
|
||||||
|
#define xSemaphoreCreateMutex(A) 0
|
||||||
|
#define vSemaphoreDelete(A)
|
||||||
|
#define SemaphoreHandle_t void*
|
||||||
|
#endif // pdTRUE
|
||||||
|
#endif // ESP8266
|
||||||
|
|
||||||
class ESP3DMessageFIFO {
|
class ESP3DMessageFIFO {
|
||||||
public:
|
public:
|
||||||
ESP3DMessageFIFO(size_t maxSize = 5) : maxSize(maxSize) {
|
ESP3DMessageFIFO(size_t maxSize = 5) {
|
||||||
mutex = xSemaphoreCreateMutex();
|
_mutex = xSemaphoreCreateMutex();
|
||||||
}
|
_maxSize = maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
~ESP3DMessageFIFO() {
|
~ESP3DMessageFIFO() {
|
||||||
clear();
|
clear();
|
||||||
vSemaphoreDelete(mutex);
|
vSemaphoreDelete(_mutex);
|
||||||
}
|
}
|
||||||
|
void setId(String id) { _id = id; }
|
||||||
|
String getId() { return _id; }
|
||||||
|
|
||||||
void push(ESP3DMessage* message) {
|
void setMaxSize(size_t maxSize) { _maxSize = maxSize; }
|
||||||
xSemaphoreTake(mutex, portMAX_DELAY);
|
size_t getMaxSize() { return _maxSize; }
|
||||||
if (fifo.size() >= maxSize) {
|
|
||||||
ESP3DMessage* oldestMessage = fifo.front();
|
void push(ESP3DMessage* message) {
|
||||||
fifo.pop();
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
ESP3DMessageManager::deleteMsg(oldestMessage);
|
esp3d_log("push to list [%s] size: %d", _id.c_str(), fifo.size());
|
||||||
|
if (fifo.size() >= _maxSize && _maxSize != 0) {
|
||||||
|
esp3d_log("remove oldest message to make room for new one");
|
||||||
|
ESP3DMessage* oldestMessage = fifo.front();
|
||||||
|
fifo.pop();
|
||||||
|
esp3d_message_manager.deleteMsg(oldestMessage);
|
||||||
|
esp3d_log("oldest message removed, list [%s] size: %d", _id.c_str(),
|
||||||
|
fifo.size());
|
||||||
|
}
|
||||||
|
fifo.push(message);
|
||||||
|
esp3d_log("push to list [%s] size: %d", _id.c_str(), fifo.size());
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("push to list [%s] failed, list size: %d", _id.c_str(),
|
||||||
|
fifo.size());
|
||||||
|
esp3d_log_e("Delete message");
|
||||||
|
esp3d_message_manager.deleteMsg(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP3DMessage* pop() {
|
||||||
|
ESP3DMessage* message = nullptr;
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
if (!fifo.empty()) {
|
||||||
|
esp3d_log("pop from list [%s] size: %d", _id.c_str(), fifo.size());
|
||||||
|
message = fifo.front();
|
||||||
|
fifo.pop();
|
||||||
|
esp3d_log("Now list [%s] size: %d", _id.c_str(), fifo.size());
|
||||||
|
esp3d_log("Message: %s", (const char*)message->data);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("pop from list [%s] failed, list size: %d", _id.c_str(),
|
||||||
|
fifo.size());
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty() {
|
||||||
|
bool empty = true;
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
empty = fifo.empty();
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() {
|
||||||
|
size_t s = 0;
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
s = fifo.size();
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
while (!fifo.empty()) {
|
||||||
|
ESP3DMessage* message = fifo.front();
|
||||||
|
fifo.pop();
|
||||||
|
esp3d_message_manager.deleteMsg(message);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(_mutex);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool applyToEach(std::function<bool(ESP3DMessage*)> fn,
|
||||||
|
bool stopOnFalse = true) {
|
||||||
|
bool result = false;
|
||||||
|
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
result = true;
|
||||||
|
size_t size = fifo.size();
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
ESP3DMessage* message = fifo.front();
|
||||||
|
bool result = fn(message);
|
||||||
|
fifo.pop();
|
||||||
|
if (!result && stopOnFalse) {
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fifo.push(message);
|
}
|
||||||
xSemaphoreGive(mutex);
|
xSemaphoreGive(_mutex);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ESP3DMessage* pop() {
|
private:
|
||||||
ESP3DMessage* message = nullptr;
|
std::queue<ESP3DMessage*> fifo;
|
||||||
xSemaphoreTake(mutex, portMAX_DELAY);
|
SemaphoreHandle_t _mutex;
|
||||||
if (!fifo.empty()) {
|
size_t _maxSize;
|
||||||
message = fifo.front();
|
String _id;
|
||||||
fifo.pop();
|
|
||||||
}
|
|
||||||
xSemaphoreGive(mutex);
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEmpty() {
|
|
||||||
bool empty;
|
|
||||||
xSemaphoreTake(mutex, portMAX_DELAY);
|
|
||||||
empty = fifo.empty();
|
|
||||||
xSemaphoreGive(mutex);
|
|
||||||
return empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() {
|
|
||||||
size_t s;
|
|
||||||
xSemaphoreTake(mutex, portMAX_DELAY);
|
|
||||||
s = fifo.size();
|
|
||||||
xSemaphoreGive(mutex);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
xSemaphoreTake(mutex, portMAX_DELAY);
|
|
||||||
while (!fifo.empty()) {
|
|
||||||
ESP3DMessage* message = fifo.front();
|
|
||||||
fifo.pop();
|
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
|
||||||
}
|
|
||||||
xSemaphoreGive(mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::queue<ESP3DMessage*> fifo;
|
|
||||||
SemaphoreHandle_t mutex;
|
|
||||||
const size_t maxSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP8285)
|
#endif // !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP8285)
|
@ -75,6 +75,12 @@
|
|||||||
#define MIN_SERVER_ADDRESS_LENGTH 0
|
#define MIN_SERVER_ADDRESS_LENGTH 0
|
||||||
|
|
||||||
// default byte values
|
// default byte values
|
||||||
|
#ifdef ETH_FEATURE
|
||||||
|
#define DEFAULT_ETH_STA_FALLBACK_MODE STRING(ESP_NO_NETWORK)
|
||||||
|
#else
|
||||||
|
#define DEFAULT_ETH_STA_FALLBACK_MODE STRING(ESP_NO_NETWORK)
|
||||||
|
#endif // ETH_FEATURE
|
||||||
|
|
||||||
#ifdef WIFI_FEATURE
|
#ifdef WIFI_FEATURE
|
||||||
#define DEFAULT_STA_FALLBACK_MODE STRING(ESP_AP_SETUP)
|
#define DEFAULT_STA_FALLBACK_MODE STRING(ESP_AP_SETUP)
|
||||||
#if defined(STATION_WIFI_SSID) && defined(STATION_WIFI_PASSWORD)
|
#if defined(STATION_WIFI_SSID) && defined(STATION_WIFI_PASSWORD)
|
||||||
@ -192,6 +198,12 @@ uint16_t ESP3DSettingsData[] = {ESP_RADIO_MODE,
|
|||||||
ESP_STA_DNS_VALUE,
|
ESP_STA_DNS_VALUE,
|
||||||
ESP_AP_IP_VALUE,
|
ESP_AP_IP_VALUE,
|
||||||
ESP_STA_IP_MODE,
|
ESP_STA_IP_MODE,
|
||||||
|
ESP_ETH_STA_FALLBACK_MODE,
|
||||||
|
ESP_ETH_STA_IP_VALUE,
|
||||||
|
ESP_ETH_STA_GATEWAY_VALUE,
|
||||||
|
ESP_ETH_STA_MASK_VALUE,
|
||||||
|
ESP_ETH_STA_DNS_VALUE,
|
||||||
|
ESP_ETH_STA_IP_MODE,
|
||||||
ESP_SETTINGS_VERSION,
|
ESP_SETTINGS_VERSION,
|
||||||
ESP_NOTIFICATION_TYPE,
|
ESP_NOTIFICATION_TYPE,
|
||||||
ESP_CALIBRATION,
|
ESP_CALIBRATION,
|
||||||
@ -240,7 +252,6 @@ uint16_t ESP3DSettingsData[] = {ESP_RADIO_MODE,
|
|||||||
ESP_FTP_DATA_PASSIVE_PORT,
|
ESP_FTP_DATA_PASSIVE_PORT,
|
||||||
ESP_WEBDAV_PORT,
|
ESP_WEBDAV_PORT,
|
||||||
ESP_SERIAL_BRIDGE_BAUD
|
ESP_SERIAL_BRIDGE_BAUD
|
||||||
|
|
||||||
};
|
};
|
||||||
#if defined(SD_DEVICE)
|
#if defined(SD_DEVICE)
|
||||||
const uint8_t SupportedSPIDivider[] = {1, 2, 4, 6, 8, 16, 32};
|
const uint8_t SupportedSPIDivider[] = {1, 2, 4, 6, 8, 16, 32};
|
||||||
@ -714,6 +725,8 @@ const char *ESP3DSettings::TargetBoard() {
|
|||||||
#define TYPE_BOARD "ESP32-S3"
|
#define TYPE_BOARD "ESP32-S3"
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#define TYPE_BOARD "ESP32-C3"
|
#define TYPE_BOARD "ESP32-C3"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||||
|
#define TYPE_BOARD "ESP32-C6"
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOARD_HAS_PSRAM
|
#ifdef BOARD_HAS_PSRAM
|
||||||
#define IS_PSRAM " (PSRAM)"
|
#define IS_PSRAM " (PSRAM)"
|
||||||
@ -960,12 +973,19 @@ bool ESP3DSettings::isValidByteSetting(uint8_t value,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef ETH_FEATURE
|
||||||
|
case ESP_ETH_STA_IP_MODE:
|
||||||
|
if (value == DHCP_MODE || value == STATIC_IP_MODE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif // ETH_FEATURE
|
||||||
|
#if defined(WIFI_FEATURE)
|
||||||
case ESP_STA_IP_MODE:
|
case ESP_STA_IP_MODE:
|
||||||
if (value == DHCP_MODE || value == STATIC_IP_MODE) {
|
if (value == DHCP_MODE || value == STATIC_IP_MODE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
case ESP_AP_CHANNEL:
|
case ESP_AP_CHANNEL:
|
||||||
for (uint8_t i = 0; i < SupportedApChannelsSize; i++) {
|
for (uint8_t i = 0; i < SupportedApChannelsSize; i++) {
|
||||||
if (value == SupportedApChannels[i]) {
|
if (value == SupportedApChannels[i]) {
|
||||||
@ -1012,11 +1032,9 @@ bool ESP3DSettings::isValidByteSetting(uint8_t value,
|
|||||||
// 0 means no timeout so it is ok to have 0
|
// 0 means no timeout so it is ok to have 0
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case ESP_STA_FALLBACK_MODE:
|
#ifdef ETH_FEATURE
|
||||||
|
case ESP_ETH_STA_FALLBACK_MODE:
|
||||||
if (value == ESP_NO_NETWORK
|
if (value == ESP_NO_NETWORK
|
||||||
#if defined(WIFI_FEATURE)
|
|
||||||
|| value == ESP_AP_SETUP
|
|
||||||
#endif // WIFI_FEATURE
|
|
||||||
#if defined(BT_FEATURE)
|
#if defined(BT_FEATURE)
|
||||||
|| value == ESP_BT
|
|| value == ESP_BT
|
||||||
#endif // BT_FEATURE
|
#endif // BT_FEATURE
|
||||||
@ -1024,7 +1042,20 @@ bool ESP3DSettings::isValidByteSetting(uint8_t value,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif // ETH_FEATURE
|
||||||
|
#if defined(WIFI_FEATURE)
|
||||||
|
case ESP_STA_FALLBACK_MODE:
|
||||||
|
if (value == ESP_NO_NETWORK
|
||||||
|
|
||||||
|
|| value == ESP_AP_SETUP
|
||||||
|
#if defined(BT_FEATURE)
|
||||||
|
|| value == ESP_BT
|
||||||
|
#endif // BT_FEATURE
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif // WIFI_FEATURE
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1117,8 +1148,10 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
|
|||||||
case ESP_SECURE_SERIAL:
|
case ESP_SECURE_SERIAL:
|
||||||
case ESP_BOOT_RADIO_STATE:
|
case ESP_BOOT_RADIO_STATE:
|
||||||
case ESP_STA_FALLBACK_MODE:
|
case ESP_STA_FALLBACK_MODE:
|
||||||
|
case ESP_ETH_STA_FALLBACK_MODE:
|
||||||
case ESP_SERIAL_BRIDGE_ON:
|
case ESP_SERIAL_BRIDGE_ON:
|
||||||
case ESP_STA_IP_MODE:
|
case ESP_STA_IP_MODE:
|
||||||
|
case ESP_ETH_STA_IP_MODE:
|
||||||
setting.type = ESP3DSettingType::byte_t; // byte
|
setting.type = ESP3DSettingType::byte_t; // byte
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1144,6 +1177,10 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
|
|||||||
case ESP_STA_GATEWAY_VALUE:
|
case ESP_STA_GATEWAY_VALUE:
|
||||||
case ESP_STA_MASK_VALUE:
|
case ESP_STA_MASK_VALUE:
|
||||||
case ESP_STA_DNS_VALUE:
|
case ESP_STA_DNS_VALUE:
|
||||||
|
case ESP_ETH_STA_IP_VALUE:
|
||||||
|
case ESP_ETH_STA_GATEWAY_VALUE:
|
||||||
|
case ESP_ETH_STA_MASK_VALUE:
|
||||||
|
case ESP_ETH_STA_DNS_VALUE:
|
||||||
case ESP_AP_IP_VALUE:
|
case ESP_AP_IP_VALUE:
|
||||||
|
|
||||||
setting.type = ESP3DSettingType::ip_t; // ip = 4 bytes
|
setting.type = ESP3DSettingType::ip_t; // ip = 4 bytes
|
||||||
@ -1197,11 +1234,17 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
|
|||||||
case ESP_WEBDAV_ON:
|
case ESP_WEBDAV_ON:
|
||||||
case ESP_SECURE_SERIAL:
|
case ESP_SECURE_SERIAL:
|
||||||
case ESP_BOOT_RADIO_STATE:
|
case ESP_BOOT_RADIO_STATE:
|
||||||
|
case ESP_ETH_STA_FALLBACK_MODE:
|
||||||
case ESP_STA_FALLBACK_MODE:
|
case ESP_STA_FALLBACK_MODE:
|
||||||
case ESP_SERIAL_BRIDGE_ON:
|
case ESP_SERIAL_BRIDGE_ON:
|
||||||
|
case ESP_ETH_STA_IP_MODE:
|
||||||
case ESP_STA_IP_MODE:
|
case ESP_STA_IP_MODE:
|
||||||
setting.size = 1; // 1 byte
|
setting.size = 1; // 1 byte
|
||||||
break;
|
break;
|
||||||
|
case ESP_ETH_STA_IP_VALUE:
|
||||||
|
case ESP_ETH_STA_GATEWAY_VALUE:
|
||||||
|
case ESP_ETH_STA_MASK_VALUE:
|
||||||
|
case ESP_ETH_STA_DNS_VALUE:
|
||||||
case ESP_STA_IP_VALUE:
|
case ESP_STA_IP_VALUE:
|
||||||
case ESP_STA_GATEWAY_VALUE:
|
case ESP_STA_GATEWAY_VALUE:
|
||||||
case ESP_STA_MASK_VALUE:
|
case ESP_STA_MASK_VALUE:
|
||||||
@ -1278,6 +1321,8 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
|
|||||||
|
|
||||||
// default value of setting in string
|
// default value of setting in string
|
||||||
switch (index) {
|
switch (index) {
|
||||||
|
|
||||||
|
case ESP_ETH_STA_IP_MODE:
|
||||||
case ESP_STA_IP_MODE:
|
case ESP_STA_IP_MODE:
|
||||||
setting.default_val = DEFAULT_STA_IP_MODE;
|
setting.default_val = DEFAULT_STA_IP_MODE;
|
||||||
break;
|
break;
|
||||||
@ -1350,6 +1395,9 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
|
|||||||
case ESP_BOOT_RADIO_STATE:
|
case ESP_BOOT_RADIO_STATE:
|
||||||
setting.default_val = DEFAULT_BOOT_RADIO_STATE;
|
setting.default_val = DEFAULT_BOOT_RADIO_STATE;
|
||||||
break;
|
break;
|
||||||
|
case ESP_ETH_STA_FALLBACK_MODE:
|
||||||
|
setting.default_val = DEFAULT_ETH_STA_FALLBACK_MODE;
|
||||||
|
break;
|
||||||
case ESP_STA_FALLBACK_MODE:
|
case ESP_STA_FALLBACK_MODE:
|
||||||
setting.default_val = DEFAULT_STA_FALLBACK_MODE;
|
setting.default_val = DEFAULT_STA_FALLBACK_MODE;
|
||||||
break;
|
break;
|
||||||
@ -1401,15 +1449,19 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
|
|||||||
case ESP_TIME_ZONE:
|
case ESP_TIME_ZONE:
|
||||||
setting.default_val = DEFAULT_TIME_ZONE;
|
setting.default_val = DEFAULT_TIME_ZONE;
|
||||||
break;
|
break;
|
||||||
|
case ESP_ETH_STA_IP_VALUE:
|
||||||
case ESP_STA_IP_VALUE:
|
case ESP_STA_IP_VALUE:
|
||||||
setting.default_val = DEFAULT_STA_IP_VALUE;
|
setting.default_val = DEFAULT_STA_IP_VALUE;
|
||||||
break;
|
break;
|
||||||
|
case ESP_ETH_STA_GATEWAY_VALUE:
|
||||||
case ESP_STA_GATEWAY_VALUE:
|
case ESP_STA_GATEWAY_VALUE:
|
||||||
setting.default_val = DEFAULT_STA_GATEWAY_VALUE;
|
setting.default_val = DEFAULT_STA_GATEWAY_VALUE;
|
||||||
break;
|
break;
|
||||||
|
case ESP_ETH_STA_MASK_VALUE:
|
||||||
case ESP_STA_MASK_VALUE:
|
case ESP_STA_MASK_VALUE:
|
||||||
setting.default_val = DEFAULT_STA_MASK_VALUE;
|
setting.default_val = DEFAULT_STA_MASK_VALUE;
|
||||||
break;
|
break;
|
||||||
|
case ESP_ETH_STA_DNS_VALUE:
|
||||||
case ESP_STA_DNS_VALUE:
|
case ESP_STA_DNS_VALUE:
|
||||||
setting.default_val = DEFAULT_STA_DNS_VALUE;
|
setting.default_val = DEFAULT_STA_DNS_VALUE;
|
||||||
break;
|
break;
|
||||||
|
@ -119,7 +119,7 @@ typedef uint ESP3DSettingIndex;
|
|||||||
#define ESP_SETUP 1192 // 1 byte = flag
|
#define ESP_SETUP 1192 // 1 byte = flag
|
||||||
// #define FREE 1193 // 1 byte = flag
|
// #define FREE 1193 // 1 byte = flag
|
||||||
// #define FREE 1194 // 1 byte = flag
|
// #define FREE 1194 // 1 byte = flag
|
||||||
// #define FREE 1195 // 1 byte = flag
|
#define ESP_ETH_STA_FALLBACK_MODE 1195 // 1 byte = flag
|
||||||
#define ESP_FTP_CTRL_PORT 1196 // 4 bytes = int
|
#define ESP_FTP_CTRL_PORT 1196 // 4 bytes = int
|
||||||
#define ESP_FTP_DATA_ACTIVE_PORT 1200 // 4 bytes = int
|
#define ESP_FTP_DATA_ACTIVE_PORT 1200 // 4 bytes = int
|
||||||
#define ESP_FTP_DATA_PASSIVE_PORT 1204 // 4 bytes = int
|
#define ESP_FTP_DATA_PASSIVE_PORT 1204 // 4 bytes = int
|
||||||
@ -133,9 +133,13 @@ typedef uint ESP3DSettingIndex;
|
|||||||
#define ESP_BOOT_RADIO_STATE 1221 // 1 byte = flag
|
#define ESP_BOOT_RADIO_STATE 1221 // 1 byte = flag
|
||||||
#define ESP_STA_FALLBACK_MODE 1222 // 1 byte = flag
|
#define ESP_STA_FALLBACK_MODE 1222 // 1 byte = flag
|
||||||
#define ESP_SERIAL_BRIDGE_ON 1223 // 1 byte = flag
|
#define ESP_SERIAL_BRIDGE_ON 1223 // 1 byte = flag
|
||||||
// #define FREE 1224 // 1 byte = flag
|
#define ESP_ETH_STA_IP_MODE 1224 // 1 byte = flag
|
||||||
#define ESP_SERIAL_BRIDGE_BAUD 1225 // 4 bytes= int
|
#define ESP_SERIAL_BRIDGE_BAUD 1225 // 4 bytes= int
|
||||||
#define ESP_TIME_ZONE 1229 // 7 bytes 6+1 = string
|
#define ESP_TIME_ZONE 1229 // 7 bytes 6+1 = string
|
||||||
|
#define ESP_ETH_STA_IP_VALUE 1237 // 4 bytes xxx.xxx.xxx.xxx
|
||||||
|
#define ESP_ETH_STA_MASK_VALUE 1240 // 4 bytes xxx.xxx.xxx.xxx
|
||||||
|
#define ESP_ETH_STA_GATEWAY_VALUE 1244 // 4 bytes xxx.xxx.xxx.xxx
|
||||||
|
#define ESP_ETH_STA_DNS_VALUE 1248 // 4 bytes xxx.xxx.xxx.xxx
|
||||||
|
|
||||||
// Hidden password
|
// Hidden password
|
||||||
#define HIDDEN_PASSWORD "********"
|
#define HIDDEN_PASSWORD "********"
|
||||||
@ -313,14 +317,36 @@ typedef uint ESP3DSettingIndex;
|
|||||||
#define MODE_ETH_CLOCK_GPIO16_OUT 2
|
#define MODE_ETH_CLOCK_GPIO16_OUT 2
|
||||||
#define MODE_ETH_CLOCK_GPIO17_OUT 3
|
#define MODE_ETH_CLOCK_GPIO17_OUT 3
|
||||||
|
|
||||||
// Ethernet type (Check ETH.h eth_phy_type_t)
|
// Ethernet type (Check ETH.h eth_phy_type_t because it enum with #ifdef CONFIG_....)
|
||||||
#define TYPE_ETH_PHY_LAN8720 0
|
#define TYPE_ETH_PHY_LAN8720 0
|
||||||
#define TYPE_ETH_PHY_TLK110 1
|
#define TYPE_ETH_PHY_TLK110 1
|
||||||
#define TYPE_ETH_PHY_RTL8201 2
|
#define TYPE_ETH_PHY_RTL8201 2
|
||||||
#define TYPE_ETH_PHY_DP83848 3
|
#define TYPE_ETH_PHY_DP83848 3
|
||||||
#define TYPE_ETH_PHY_DM9051 4
|
#define TYPE_ETH_PHY_KSZ8041 4
|
||||||
#define TYPE_ETH_PHY_KSZ8041 5
|
#define TYPE_ETH_PHY_KSZ8081 5
|
||||||
#define TYPE_ETH_PHY_KSZ8081 6
|
#define TYPE_ETH_PHY_DM9051 6
|
||||||
|
#define TYPE_ETH_PHY_W5500 7
|
||||||
|
#define TYPE_ETH_PHY_KSZ8851 8
|
||||||
|
|
||||||
|
//SPI pis for ethernet
|
||||||
|
#ifndef ETH_PHY_CS
|
||||||
|
#define ETH_PHY_CS 15
|
||||||
|
#endif // ETH_PHY_CS
|
||||||
|
#ifndef ETH_PHY_IRQ
|
||||||
|
#define ETH_PHY_IRQ 4
|
||||||
|
#endif // ETH_PHY_IRQ
|
||||||
|
#ifndef ETH_PHY_RST
|
||||||
|
#define ETH_PHY_RST 5
|
||||||
|
#endif // ETH_PHY_RST
|
||||||
|
#ifndef ETH_SPI_SCK
|
||||||
|
#define ETH_SPI_SCK 14
|
||||||
|
#endif // ETH_SPI_SCK
|
||||||
|
#ifndef ETH_SPI_MISO
|
||||||
|
#define ETH_SPI_MISO 12
|
||||||
|
#endif // ETH_SPI_MISO
|
||||||
|
#ifndef ETH_SPI_MOSI
|
||||||
|
#define ETH_SPI_MOSI 13
|
||||||
|
#endif // ETH_SPI_MOSI
|
||||||
|
|
||||||
// Host path
|
// Host path
|
||||||
#define ESP3D_HOST_PATH "/"
|
#define ESP3D_HOST_PATH "/"
|
||||||
|
@ -77,8 +77,8 @@
|
|||||||
/**************************
|
/**************************
|
||||||
* Bluetooth
|
* Bluetooth
|
||||||
* ***********************/
|
* ***********************/
|
||||||
#if defined(BLUETOOTH_FEATURE) && defined(ARDUINO_ARCH_ESP8266)
|
#if (defined(BLUETOOTH_FEATURE) && !defined(ARDUINO_ARCH_ESP32)) || (defined(BLUETOOTH_FEATURE) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)))
|
||||||
#error Bluetooth is not available in ESP8266
|
#error Bluetooth is only available for ESP32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#ifdef BLUETOOTH_FEATURE
|
#ifdef BLUETOOTH_FEATURE
|
||||||
#include "../../core/esp3d_commands.h"
|
#include "../../core/esp3d_commands.h"
|
||||||
#include "../../core/esp3d_settings.h"
|
#include "../../core/esp3d_settings.h"
|
||||||
#include "../../esp3d_string.h"
|
#include "../../core/esp3d_string.h"
|
||||||
#include "../network/netconfig.h"
|
#include "../network/netconfig.h"
|
||||||
#include "BT_service.h"
|
#include "BT_service.h"
|
||||||
#include "BluetoothSerial.h"
|
#include "BluetoothSerial.h"
|
||||||
@ -192,7 +192,7 @@ ESP3DAuthenticationLevel BTService::getAuthentication() { return _auth; }
|
|||||||
void BTService::flushbuffer() {
|
void BTService::flushbuffer() {
|
||||||
_buffer[_buffer_size] = 0x0;
|
_buffer[_buffer_size] = 0x0;
|
||||||
// dispatch command
|
// dispatch command
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::bluetooth, esp3d_commands.getOutputClient(), _buffer,
|
ESP3DClientType::bluetooth, esp3d_commands.getOutputClient(), _buffer,
|
||||||
_buffer_size, _auth);
|
_buffer_size, _auth);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
@ -288,7 +288,7 @@ bool BTService::dispatch(ESP3DMessage *message) {
|
|||||||
if (sentcnt != message->size) {
|
if (sentcnt != message->size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,8 +242,10 @@ int Camera::command(const char *param, const char *value) {
|
|||||||
|
|
||||||
bool Camera::initHardware() {
|
bool Camera::initHardware() {
|
||||||
_initialised = false;
|
_initialised = false;
|
||||||
|
#if !(CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6)
|
||||||
esp3d_log("Disable brown out");
|
esp3d_log("Disable brown out");
|
||||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector
|
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector
|
||||||
|
#endif // !(CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6)
|
||||||
stopHardware();
|
stopHardware();
|
||||||
camera_config_t config;
|
camera_config_t config;
|
||||||
config.ledc_channel = LEDC_CHANNEL_0;
|
config.ledc_channel = LEDC_CHANNEL_0;
|
||||||
|
@ -52,7 +52,7 @@ bool Display::dispatch(ESP3DMessage* message) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -29,62 +29,39 @@
|
|||||||
#endif // ARDUINO_ARCH_ESP8266
|
#endif // ARDUINO_ARCH_ESP8266
|
||||||
#include "../../core/esp3d_commands.h"
|
#include "../../core/esp3d_commands.h"
|
||||||
#include "../../core/esp3d_settings.h"
|
#include "../../core/esp3d_settings.h"
|
||||||
|
#include "../../core/esp3d_string.h"
|
||||||
#include "../network/netconfig.h"
|
#include "../network/netconfig.h"
|
||||||
#include "ethconfig.h"
|
#include "ethconfig.h"
|
||||||
|
|
||||||
|
#if defined(GCODE_HOST_FEATURE)
|
||||||
|
#include "../gcode_host/gcode_host.h"
|
||||||
|
#endif // GCODE_HOST_FEATURE
|
||||||
|
|
||||||
bool EthConfig::_started = false;
|
bool EthConfig::_started = false;
|
||||||
bool EthConfig::_connected = false;
|
bool EthConfig::_connected = false;
|
||||||
|
uint8_t EthConfig::_ipMode = DHCP_MODE;
|
||||||
const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0};
|
const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0};
|
||||||
|
|
||||||
bool EthConfig::StartSTA() {
|
bool EthConfig::StartSTA() {
|
||||||
bool res = true;
|
bool res = true;
|
||||||
if ((ESP3DSettings::readByte(ESP_STA_IP_MODE) != DHCP_MODE)) {
|
if (_ipMode == STATIC_IP_MODE) {
|
||||||
int32_t IP = ESP3DSettings::read_IP(ESP_STA_IP_VALUE);
|
int32_t IP = ESP3DSettings::read_IP(ESP_ETH_STA_IP_VALUE);
|
||||||
int32_t GW = ESP3DSettings::read_IP(ESP_STA_GATEWAY_VALUE);
|
int32_t GW = ESP3DSettings::read_IP(ESP_ETH_STA_GATEWAY_VALUE);
|
||||||
int32_t MK = ESP3DSettings::read_IP(ESP_STA_MASK_VALUE);
|
int32_t MK = ESP3DSettings::read_IP(ESP_ETH_STA_MASK_VALUE);
|
||||||
int32_t DNS = ESP3DSettings::read_IP(ESP_STA_DNS_VALUE);
|
int32_t DNS = ESP3DSettings::read_IP(ESP_ETH_STA_DNS_VALUE);
|
||||||
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
|
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
|
||||||
res = ETH.config(ip, gateway, mask, dns);
|
res = ETH.config(ip, gateway, mask, dns);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/*bool EthConfig::StartSRV()
|
|
||||||
{
|
|
||||||
bool res = true;
|
|
||||||
//static IP
|
|
||||||
int32_t IP = ESP3DSettings::read_IP(ESP_AP_IP_VALUE);
|
|
||||||
IPAddress ip(IP), mask(DEFAULT_AP_MASK_VALUE), gateway(IP);
|
|
||||||
if (!ETH.config(ip, gateway,mask)) {
|
|
||||||
res = false;
|
|
||||||
esp3d_log_e("Set static IP error");
|
|
||||||
}
|
|
||||||
//start DHCP server
|
|
||||||
if(res) {
|
|
||||||
dhcps_lease_t lease;
|
|
||||||
lease.enable = true;
|
|
||||||
lease.start_ip.addr = static_cast<uint32_t>(IP) + (1 << 24);
|
|
||||||
lease.end_ip.addr = static_cast<uint32_t>(IP) + (11 << 24);
|
|
||||||
tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_ETH);
|
|
||||||
tcpip_adapter_dhcps_option(
|
|
||||||
(tcpip_adapter_option_mode_t)TCPIP_ADAPTER_OP_SET,
|
|
||||||
(tcpip_adapter_option_id_t)REQUESTED_IP_ADDRESS,
|
|
||||||
(void*)&lease, sizeof(dhcps_lease_t)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_ETH) != ESP_OK){
|
bool EthConfig::linkUp() { return _connected; }
|
||||||
res = false;
|
|
||||||
esp3d_log_e("Start DHCP server failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
bool EthConfig::linkUp() {
|
uint8_t EthConfig::ipMode(bool fromsettings) {
|
||||||
#if defined(ESP_IDF_VERSION_MAJOR)
|
if (fromsettings) {
|
||||||
// patch for https://github.com/espressif/arduino-esp32/issues/6105
|
_ipMode = (ESP3DSettings::readByte(ESP_ETH_STA_IP_MODE) != DHCP_MODE);
|
||||||
return _connected;
|
}
|
||||||
#else
|
return _ipMode;
|
||||||
return ETH.linkUp();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,9 +69,33 @@ bool EthConfig::linkUp() {
|
|||||||
*/
|
*/
|
||||||
bool EthConfig::begin(int8_t& espMode) {
|
bool EthConfig::begin(int8_t& espMode) {
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
ipMode(true);
|
||||||
end();
|
end();
|
||||||
_started = ETH.begin();
|
if (ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_LAN8720) {
|
||||||
|
esp3d_log_d("ETH PHY Type %d", ESP3D_ETH_PHY_TYPE);
|
||||||
|
_started = ETH.begin();
|
||||||
|
} else {
|
||||||
|
if (ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_TLK110 ||
|
||||||
|
ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_RTL8201 ||
|
||||||
|
ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_DP83848 ||
|
||||||
|
ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_KSZ8041 ||
|
||||||
|
ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_KSZ8081) {
|
||||||
|
esp3d_log_d("ETH PHY Type %d", ESP3D_ETH_PHY_TYPE);
|
||||||
|
_started = ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_POWER,
|
||||||
|
ETH_PHY_MDC, ETH_PHY_MDIO, ETH_CLK_MODE);
|
||||||
|
} else {
|
||||||
|
if (ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_W5500) {
|
||||||
|
esp3d_log_d("ETH spi PHY Type %d", ESP3D_ETH_PHY_TYPE);
|
||||||
|
SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI);
|
||||||
|
_started = ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS,
|
||||||
|
ETH_PHY_IRQ, ETH_PHY_RST, SPI);
|
||||||
|
} else {
|
||||||
|
esp3d_log("Ethernet PHY type not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_started) {
|
if (_started) {
|
||||||
if (ESP3DSettings::isVerboseBoot()) {
|
if (ESP3DSettings::isVerboseBoot()) {
|
||||||
esp3d_commands.dispatch("Starting ethernet", ESP3DClientType::all_clients,
|
esp3d_commands.dispatch("Starting ethernet", ESP3DClientType::all_clients,
|
||||||
@ -104,7 +105,7 @@ bool EthConfig::begin(int8_t& espMode) {
|
|||||||
}
|
}
|
||||||
res = true;
|
res = true;
|
||||||
} else {
|
} else {
|
||||||
esp3d_commands.dispatch("Failed starting ethernet write failed",
|
esp3d_commands.dispatch("Failed starting ethernet failed",
|
||||||
ESP3DClientType::all_clients, no_id,
|
ESP3DClientType::all_clients, no_id,
|
||||||
ESP3DMessageType::unique, ESP3DClientType::system,
|
ESP3DMessageType::unique, ESP3DClientType::system,
|
||||||
ESP3DAuthenticationLevel::admin);
|
ESP3DAuthenticationLevel::admin);
|
||||||
@ -120,7 +121,7 @@ bool EthConfig::begin(int8_t& espMode) {
|
|||||||
ESP3DMessageType::unique, ESP3DClientType::system,
|
ESP3DMessageType::unique, ESP3DClientType::system,
|
||||||
ESP3DAuthenticationLevel::admin);
|
ESP3DAuthenticationLevel::admin);
|
||||||
}
|
}
|
||||||
espMode = ESP3DSettings::readByte(ESP_STA_FALLBACK_MODE);
|
espMode = ESP3DSettings::readByte(ESP_ETH_STA_FALLBACK_MODE);
|
||||||
res = true;
|
res = true;
|
||||||
} else {
|
} else {
|
||||||
if (ESP3DSettings::isVerboseBoot()) {
|
if (ESP3DSettings::isVerboseBoot()) {
|
||||||
@ -130,20 +131,9 @@ bool EthConfig::begin(int8_t& espMode) {
|
|||||||
ESP3DAuthenticationLevel::admin);
|
ESP3DAuthenticationLevel::admin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
// if(!StartSRV()){
|
|
||||||
// res = false;
|
|
||||||
//
|
|
||||||
// } else {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
// Static IP or DHCP client ?
|
||||||
// if ((ESP3DSettings::readByte(ESP_STA_IP_MODE) != DHCP_MODE) || (espMode
|
if ((ESP3DSettings::readByte(ESP_ETH_STA_IP_MODE) != DHCP_MODE)) {
|
||||||
// == ESP_ETH_SRV)){
|
|
||||||
if ((ESP3DSettings::readByte(ESP_STA_IP_MODE) != DHCP_MODE)) {
|
|
||||||
// as no event to display static IP
|
|
||||||
esp3d_commands.dispatch(ETH.localIP().toString().c_str(),
|
esp3d_commands.dispatch(ETH.localIP().toString().c_str(),
|
||||||
ESP3DClientType::all_clients, no_id,
|
ESP3DClientType::all_clients, no_id,
|
||||||
ESP3DMessageType::unique, ESP3DClientType::system,
|
ESP3DMessageType::unique, ESP3DClientType::system,
|
||||||
@ -158,8 +148,10 @@ bool EthConfig::begin(int8_t& espMode) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void EthConfig::end() {
|
void EthConfig::end() {
|
||||||
// esp_eth_disable();
|
// ETH.end();
|
||||||
_started = false;
|
_started = false;
|
||||||
|
_ipMode = DHCP_MODE;
|
||||||
|
_connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EthConfig::started() { return _started; }
|
bool EthConfig::started() { return _started; }
|
||||||
|
@ -55,12 +55,13 @@ class EthConfig {
|
|||||||
static void handle();
|
static void handle();
|
||||||
static bool started();
|
static bool started();
|
||||||
static void setConnected(bool connected) { _connected = connected; }
|
static void setConnected(bool connected) { _connected = connected; }
|
||||||
|
static uint8_t ipMode(bool fromsettings = false);
|
||||||
static bool linkUp();
|
static bool linkUp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _started;
|
static bool _started;
|
||||||
static bool _connected;
|
static bool _connected;
|
||||||
|
static uint8_t _ipMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_ETH_CONFIG_H
|
#endif //_ETH_CONFIG_H
|
||||||
|
@ -127,27 +127,11 @@ uint8_t ESP_SD::getState(bool refresh) {
|
|||||||
ESP_SD_MOSI_PIN != -1 ? ESP_SD_MOSI_PIN : MOSI,
|
ESP_SD_MOSI_PIN != -1 ? ESP_SD_MOSI_PIN : MOSI,
|
||||||
ESP_SD_SCK_PIN != -1 ? ESP_SD_SCK_PIN : SCK);
|
ESP_SD_SCK_PIN != -1 ? ESP_SD_SCK_PIN : SCK);
|
||||||
// refresh content if card was removed
|
// refresh content if card was removed
|
||||||
#if !(defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1)
|
|
||||||
if (xPortGetCoreID() == 0) {
|
|
||||||
disableCore0WDT();
|
|
||||||
} else {
|
|
||||||
disableCore1WDT();
|
|
||||||
}
|
|
||||||
#endif // !(defined(ESP_SD_DETECT_PIN)
|
|
||||||
if (SD.begin((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN,
|
if (SD.begin((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN,
|
||||||
SD_SCK_MHZ(FREQMZ / _spi_speed_divider))) {
|
SD_SCK_MHZ(FREQMZ / _spi_speed_divider))) {
|
||||||
csd_t m_csd;
|
|
||||||
if (SD.card()->readCSD(&m_csd) && sdCardCapacity(&m_csd) > 0) {
|
|
||||||
_state = ESP_SDCARD_IDLE;
|
_state = ESP_SDCARD_IDLE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#if !(defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1)
|
|
||||||
if (xPortGetCoreID() == 0) {
|
|
||||||
enableCore0WDT();
|
|
||||||
} else {
|
|
||||||
enableCore1WDT();
|
|
||||||
}
|
|
||||||
#endif // !(defined(ESP_SD_DETECT_PIN)
|
|
||||||
return _state;
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,12 +123,7 @@ uint8_t ESP_SD::getState(bool refresh) {
|
|||||||
if (SD.begin((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN,
|
if (SD.begin((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN,
|
||||||
SD_SCK_HZ(F_CPU / _spi_speed_divider))) {
|
SD_SCK_HZ(F_CPU / _spi_speed_divider))) {
|
||||||
esp3d_log("Init SD State ok");
|
esp3d_log("Init SD State ok");
|
||||||
csd_t m_csd;
|
_state = ESP_SDCARD_IDLE;
|
||||||
if (SD.card()->readCSD(&m_csd) && sdCardCapacity(&m_csd) > 0) {
|
|
||||||
_state = ESP_SDCARD_IDLE;
|
|
||||||
} else {
|
|
||||||
esp3d_log_e("Cannot get card size");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
esp3d_log_e("Init SD State failed");
|
esp3d_log_e("Init SD State failed");
|
||||||
}
|
}
|
||||||
@ -463,6 +458,9 @@ ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode,
|
|||||||
}
|
}
|
||||||
// todo need also to add short filename
|
// todo need also to add short filename
|
||||||
const char* ESP_SDFile::shortname() const {
|
const char* ESP_SDFile::shortname() const {
|
||||||
|
#if SDFAT_FILE_TYPE != 1
|
||||||
|
return _name.c_str();
|
||||||
|
#else
|
||||||
static char sname[13];
|
static char sname[13];
|
||||||
File ftmp = SD.open(_filename.c_str());
|
File ftmp = SD.open(_filename.c_str());
|
||||||
if (ftmp) {
|
if (ftmp) {
|
||||||
@ -475,6 +473,7 @@ const char* ESP_SDFile::shortname() const {
|
|||||||
} else {
|
} else {
|
||||||
return _name.c_str();
|
return _name.c_str();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP_SDFile::close() {
|
void ESP_SDFile::close() {
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#ifndef FTP_SERVER_H
|
#ifndef FTP_SERVER_H
|
||||||
#define FTP_SERVER_H
|
#define FTP_SERVER_H
|
||||||
|
|
||||||
class WiFiServer;
|
#include <WiFiClient.h>
|
||||||
class WiFiClient;
|
#include <WiFiServer.h>
|
||||||
#ifndef FF_MAX_LFN
|
#ifndef FF_MAX_LFN
|
||||||
#define FF_MAX_LFN 255
|
#define FF_MAX_LFN 255
|
||||||
#endif
|
#endif
|
||||||
|
@ -317,7 +317,7 @@ void GcodeHost::processCommand() {
|
|||||||
bool isESPcmd = esp3d_commands.is_esp_command(
|
bool isESPcmd = esp3d_commands.is_esp_command(
|
||||||
(uint8_t *)_currentCommand.c_str(), _currentCommand.length());
|
(uint8_t *)_currentCommand.c_str(), _currentCommand.length());
|
||||||
if (isESPcmd) {
|
if (isESPcmd) {
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::no_client, esp3d_commands.getOutputClient(),
|
ESP3DClientType::no_client, esp3d_commands.getOutputClient(),
|
||||||
(uint8_t *)_currentCommand.c_str(), _currentCommand.length(), _auth);
|
(uint8_t *)_currentCommand.c_str(), _currentCommand.length(), _auth);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
@ -331,7 +331,7 @@ void GcodeHost::processCommand() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::stream, esp3d_commands.getOutputClient(),
|
ESP3DClientType::stream, esp3d_commands.getOutputClient(),
|
||||||
(uint8_t *)_currentCommand.c_str(), _currentCommand.length(), _auth);
|
(uint8_t *)_currentCommand.c_str(), _currentCommand.length(), _auth);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
@ -74,7 +74,7 @@ void HTTP_Server::handle_web_command() {
|
|||||||
}
|
}
|
||||||
esp3d_log("Web Command: %s", cmd.c_str());
|
esp3d_log("Web Command: %s", cmd.c_str());
|
||||||
if (esp3d_commands.is_esp_command((uint8_t *)cmd.c_str(), cmd.length())) {
|
if (esp3d_commands.is_esp_command((uint8_t *)cmd.c_str(), cmd.length())) {
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::http, esp3d_commands.getOutputClient(),
|
ESP3DClientType::http, esp3d_commands.getOutputClient(),
|
||||||
(uint8_t *)cmd.c_str(), cmd.length(), auth_level);
|
(uint8_t *)cmd.c_str(), cmd.length(), auth_level);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
@ -39,7 +39,7 @@ void HTTP_Server::handle_config() {
|
|||||||
if (_webserver->hasArg("json")) {
|
if (_webserver->hasArg("json")) {
|
||||||
cmd += " json=" + _webserver->arg("json");
|
cmd += " json=" + _webserver->arg("json");
|
||||||
}
|
}
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::http, ESP3DClientType::http, (uint8_t *)cmd.c_str(),
|
ESP3DClientType::http, ESP3DClientType::http, (uint8_t *)cmd.c_str(),
|
||||||
cmd.length(), auth_level);
|
cmd.length(), auth_level);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
@ -289,7 +289,7 @@ bool HTTP_Server::dispatch(ESP3DMessage* msg) {
|
|||||||
_webserver->sendContent("");
|
_webserver->sendContent("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP3DMessageManager::deleteMsg(msg);
|
esp3d_message_manager.deleteMsg(msg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -346,13 +346,7 @@ void HTTP_Server::end() {
|
|||||||
void HTTP_Server::handle() {
|
void HTTP_Server::handle() {
|
||||||
if (_started) {
|
if (_started) {
|
||||||
if (_webserver) {
|
if (_webserver) {
|
||||||
#ifdef DISABLE_WDT_CORE_0
|
|
||||||
disableCore0WDT();
|
|
||||||
#endif // DISABLE_WDT_CORE_0
|
|
||||||
_webserver->handleClient();
|
_webserver->handleClient();
|
||||||
#ifdef DISABLE_WDT_CORE_0
|
|
||||||
enableCore0WDT();
|
|
||||||
#endif // DISABLE_WDT_CORE_0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,15 @@
|
|||||||
|
|
||||||
#include "../../include/esp3d_config.h"
|
#include "../../include/esp3d_config.h"
|
||||||
|
|
||||||
#ifdef ESP_LUA_INTERPRETER_FEATURE
|
#if defined(ESP_LUA_INTERPRETER_FEATURE) && defined(ARDUINO_ARCH_ESP32)
|
||||||
|
|
||||||
#include "../../core/esp3d_commands.h"
|
#include "../../core/esp3d_commands.h"
|
||||||
#include "../../core/esp3d_hal.h"
|
#include "../../core/esp3d_hal.h"
|
||||||
#include "../../core/esp3d_settings.h"
|
#include "../../core/esp3d_settings.h"
|
||||||
#include "lua_interpreter_service.h"
|
#include "lua_interpreter_service.h"
|
||||||
|
#if defined(NOTIFICATION_FEATURE)
|
||||||
|
#include "../notifications/notifications_service.h"
|
||||||
|
#endif // NOTIFICATION_FEATURE
|
||||||
#if defined(FILESYSTEM_FEATURE)
|
#if defined(FILESYSTEM_FEATURE)
|
||||||
#include "../filesystem/esp_filesystem.h"
|
#include "../filesystem/esp_filesystem.h"
|
||||||
#endif // FILESYSTEM_FEATURE
|
#endif // FILESYSTEM_FEATURE
|
||||||
@ -39,20 +42,21 @@ LuaInterpreter esp3d_lua_interpreter;
|
|||||||
|
|
||||||
LuaInterpreter::LuaInterpreter() {
|
LuaInterpreter::LuaInterpreter() {
|
||||||
_scriptTask = NULL;
|
_scriptTask = NULL;
|
||||||
_isRunning = false;
|
|
||||||
_isPaused = false;
|
|
||||||
_pauseTime = 0;
|
_pauseTime = 0;
|
||||||
_pauseSemaphore = xSemaphoreCreateBinary();
|
|
||||||
_luaFSType = Lua_Filesystem_Type::none;
|
_luaFSType = Lua_Filesystem_Type::none;
|
||||||
xSemaphoreGive(_pauseSemaphore); // Initialize as available
|
|
||||||
setupFunctions();
|
setupFunctions();
|
||||||
registerConstants();
|
registerConstants();
|
||||||
_scriptBuffer = nullptr;
|
_scriptBuffer = nullptr;
|
||||||
|
_stateMutex = xSemaphoreCreateMutex();
|
||||||
|
_messageInFIFO.setMaxSize(10); // no limit
|
||||||
|
_messageInFIFO.setId("in");
|
||||||
|
_messageOutFIFO.setMaxSize(0); // no limit
|
||||||
|
_messageOutFIFO.setId("out");
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaInterpreter::~LuaInterpreter() {
|
LuaInterpreter::~LuaInterpreter() {
|
||||||
deleteScriptTask();
|
deleteScriptTask();
|
||||||
vSemaphoreDelete(_pauseSemaphore);
|
vSemaphoreDelete(_stateMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaInterpreter::dispatch(ESP3DMessage *message) {
|
bool LuaInterpreter::dispatch(ESP3DMessage *message) {
|
||||||
@ -60,90 +64,105 @@ bool LuaInterpreter::dispatch(ESP3DMessage *message) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (message->size > 0 && message->data) {
|
if (message->size > 0 && message->data) {
|
||||||
_messageFIFO.push(message);
|
_messageInFIFO.push(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *LuaInterpreter::getLastError() {
|
||||||
|
esp3d_log("getLastError %s %s", _lastError.c_str(), _luaEngine.getLastError());
|
||||||
|
if (_lastError.length() == 0) {
|
||||||
|
return _luaEngine.getLastError();
|
||||||
|
}
|
||||||
|
return _lastError.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
bool LuaInterpreter::createScriptTask() {
|
bool LuaInterpreter::createScriptTask() {
|
||||||
if (_scriptTask != NULL) {
|
if (_scriptTask != NULL) {
|
||||||
deleteScriptTask();
|
deleteScriptTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseType_t xReturned = xTaskCreate(scriptExecutionTask, "LuaScriptTask", 8192,
|
_lastError = "";
|
||||||
this, tskIDLE_PRIORITY + 1, &_scriptTask);
|
BaseType_t xReturned = xTaskCreatePinnedToCore(
|
||||||
|
scriptExecutionTask, /* Task function. */
|
||||||
|
"LuaScriptTask", /* name of task. */
|
||||||
|
8192, /* Stack size of task */
|
||||||
|
this, /* parameter of the task = is main or bridge*/
|
||||||
|
1, /* priority of the task */
|
||||||
|
&_scriptTask, /* Task handle to keep track of created task */
|
||||||
|
1 /* Core to run the task */
|
||||||
|
);
|
||||||
|
|
||||||
if (xReturned != pdPASS) {
|
if (xReturned != pdPASS) {
|
||||||
_lastError = "Failed to create script task";
|
if (_lastError.length() == 0) _lastError = "Failed to create script task";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_isRunning = true;
|
|
||||||
_isPaused = false;
|
|
||||||
_startTime = millis();
|
_startTime = millis();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaInterpreter::executeScriptAsync(const char *script) {
|
bool LuaInterpreter::executeScriptAsync(const char *script) {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (_isRunning) {
|
if (_luaEngine.isRunning()) {
|
||||||
_lastError = "A script is already running";
|
if (_lastError.length() == 0) _lastError = "A script is already running";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_currentScriptName = script;
|
_currentScriptName = script;
|
||||||
if (!createScriptTask()) {
|
if (!createScriptTask()) {
|
||||||
_lastError = "Failed to create script task";
|
if (_lastError.length() == 0) _lastError = "Failed to create script task";
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaInterpreter::abortCurrentScript() {
|
void LuaInterpreter::abortScript() {
|
||||||
if (_isRunning && _scriptTask != NULL) {
|
if (_luaEngine.isRunning() && _scriptTask != NULL) {
|
||||||
deleteScriptTask();
|
if (_lastError.length() == 0) _lastError = "Script aborted";
|
||||||
_lastError = "Script aborted";
|
_luaEngine.stopExecution();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaInterpreter::pauseScript() {
|
bool LuaInterpreter::pauseScript() {
|
||||||
if (_isRunning && !_isPaused) {
|
if (_luaEngine.isRunning() && !_luaEngine.isPaused()) {
|
||||||
_isPaused = true;
|
_luaEngine.pauseExecution();
|
||||||
_pauseTime = millis();
|
_pauseTime = millis();
|
||||||
xSemaphoreTake(_pauseSemaphore, 0);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaInterpreter::resumeScript() {
|
bool LuaInterpreter::resumeScript() {
|
||||||
if (_isRunning && _isPaused) {
|
if (_luaEngine.isRunning() && _luaEngine.isPaused()) {
|
||||||
_isPaused = false;
|
_luaEngine.resumeExecution();
|
||||||
_startTime += (millis() - _pauseTime);
|
_startTime += (millis() - _pauseTime);
|
||||||
xSemaphoreGive(_pauseSemaphore);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaInterpreter::resetLuaEnvironment() {
|
||||||
|
_luaEngine.resetState();
|
||||||
|
setupFunctions();
|
||||||
|
registerConstants();
|
||||||
|
}
|
||||||
|
|
||||||
void LuaInterpreter::deleteScriptTask() {
|
void LuaInterpreter::deleteScriptTask() {
|
||||||
if (_scriptTask != NULL) {
|
esp3d_log("Delete script task start");
|
||||||
vTaskDelete(_scriptTask);
|
|
||||||
_scriptTask = NULL;
|
|
||||||
}
|
|
||||||
if (_scriptBuffer) {
|
if (_scriptBuffer) {
|
||||||
|
esp3d_log("Free script buffer");
|
||||||
free(_scriptBuffer);
|
free(_scriptBuffer);
|
||||||
_scriptBuffer = nullptr;
|
_scriptBuffer = nullptr;
|
||||||
}
|
}
|
||||||
_isRunning = false;
|
esp3d_log("Reset lua environment");
|
||||||
_isPaused = false;
|
|
||||||
_luaFSType = Lua_Filesystem_Type::none;
|
_luaFSType = Lua_Filesystem_Type::none;
|
||||||
}
|
if (_lastError != "") resetLuaEnvironment();
|
||||||
|
if (_scriptTask != NULL) {
|
||||||
void LuaInterpreter::checkPause() {
|
esp3d_log("Delete script task");
|
||||||
if (_isPaused) {
|
TaskHandle_t tmpTask = _scriptTask;
|
||||||
xSemaphoreTake(_pauseSemaphore, portMAX_DELAY);
|
_scriptTask = NULL;
|
||||||
xSemaphoreGive(_pauseSemaphore);
|
vTaskDelete(tmpTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +171,7 @@ void LuaInterpreter::scriptExecutionTask(void *parameter) {
|
|||||||
String scriptName = self->_currentScriptName;
|
String scriptName = self->_currentScriptName;
|
||||||
if (self->_scriptBuffer) {
|
if (self->_scriptBuffer) {
|
||||||
free(self->_scriptBuffer);
|
free(self->_scriptBuffer);
|
||||||
|
self->_scriptBuffer = nullptr;
|
||||||
}
|
}
|
||||||
self->_lastError = "";
|
self->_lastError = "";
|
||||||
size_t fileSize = 0;
|
size_t fileSize = 0;
|
||||||
@ -175,8 +195,9 @@ void LuaInterpreter::scriptExecutionTask(void *parameter) {
|
|||||||
fileSize = FSfileHandle.size();
|
fileSize = FSfileHandle.size();
|
||||||
esp3d_log("File %s opened, size is %d", scriptName.c_str(), fileSize);
|
esp3d_log("File %s opened, size is %d", scriptName.c_str(), fileSize);
|
||||||
if (fileSize > ESP_LUA_MAX_SCRIPT_SIZE) {
|
if (fileSize > ESP_LUA_MAX_SCRIPT_SIZE) {
|
||||||
self->_lastError = "File size is too large";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "File size is too large";
|
||||||
|
esp3d_log_e("%s", "File size is too large");
|
||||||
} else {
|
} else {
|
||||||
// allocate memory for the script
|
// allocate memory for the script
|
||||||
self->_scriptBuffer = (char *)malloc(fileSize + 1);
|
self->_scriptBuffer = (char *)malloc(fileSize + 1);
|
||||||
@ -188,24 +209,28 @@ void LuaInterpreter::scriptExecutionTask(void *parameter) {
|
|||||||
esp3d_log("File %s read into buffer", scriptName.c_str());
|
esp3d_log("File %s read into buffer", scriptName.c_str());
|
||||||
// check if the read is ok
|
// check if the read is ok
|
||||||
if (readSize != fileSize) {
|
if (readSize != fileSize) {
|
||||||
self->_lastError = "Failed to read file";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "Failed to read file";
|
||||||
|
esp3d_log_e("%s", self->_lastError.c_str());
|
||||||
} else {
|
} else {
|
||||||
self->_luaFSType = Lua_Filesystem_Type::fLash;
|
self->_luaFSType = Lua_Filesystem_Type::fLash;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self->_lastError = "Failed to allocate memory for script";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "Failed to allocate memory for script";
|
||||||
|
esp3d_log_e("%s", "Failed to allocate memory for script");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FSfileHandle.close();
|
FSfileHandle.close();
|
||||||
} else {
|
} else {
|
||||||
self->_lastError = "File is not open: " + scriptName;
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "File is not open: " + scriptName;
|
||||||
|
esp3d_log_e("%s", self->_lastError.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self->_lastError = "File not found: " + scriptName;
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "File not found: " + scriptName;
|
||||||
|
esp3d_log_e("%s", "File is not open: " + scriptName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // FILESYSTEM_FEATURE
|
#endif // FILESYSTEM_FEATURE
|
||||||
@ -216,12 +241,13 @@ void LuaInterpreter::scriptExecutionTask(void *parameter) {
|
|||||||
esp3d_log("Processing SD file %s", scriptName.c_str());
|
esp3d_log("Processing SD file %s", scriptName.c_str());
|
||||||
// Check if the SD file system is available
|
// Check if the SD file system is available
|
||||||
if (!ESP_SD::accessFS()) {
|
if (!ESP_SD::accessFS()) {
|
||||||
self->_lastError = "SD file system not found";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "SD file system not found";
|
||||||
|
esp3d_log_e("%s", "SD file system not found");
|
||||||
} else {
|
} else {
|
||||||
if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) {
|
if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) {
|
||||||
self->_lastError = "SD card not present";
|
if (self->_lastError.length() == 0) self->_lastError = "SD card not present";
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
esp3d_log_e("%s", "SD card not present");
|
||||||
} else {
|
} else {
|
||||||
ESP_SD::setState(ESP_SDCARD_BUSY);
|
ESP_SD::setState(ESP_SDCARD_BUSY);
|
||||||
// Check script name exists
|
// Check script name exists
|
||||||
@ -232,8 +258,9 @@ void LuaInterpreter::scriptExecutionTask(void *parameter) {
|
|||||||
// Check script file size is under 2048 bytes
|
// Check script file size is under 2048 bytes
|
||||||
fileSize = SDfileHandle.size();
|
fileSize = SDfileHandle.size();
|
||||||
if (fileSize > ESP_LUA_MAX_SCRIPT_SIZE) {
|
if (fileSize > ESP_LUA_MAX_SCRIPT_SIZE) {
|
||||||
self->_lastError = "File size is too large";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "File size is too large";
|
||||||
|
esp3d_log_e("%s", "File size is too large");
|
||||||
} else {
|
} else {
|
||||||
// allocate memory for the script
|
// allocate memory for the script
|
||||||
self->_scriptBuffer = (char *)malloc(fileSize + 1);
|
self->_scriptBuffer = (char *)malloc(fileSize + 1);
|
||||||
@ -245,25 +272,29 @@ void LuaInterpreter::scriptExecutionTask(void *parameter) {
|
|||||||
esp3d_log("File %s read into buffer", scriptName.c_str());
|
esp3d_log("File %s read into buffer", scriptName.c_str());
|
||||||
// check if the read is ok
|
// check if the read is ok
|
||||||
if (readSize != fileSize) {
|
if (readSize != fileSize) {
|
||||||
self->_lastError = "Failed to read file";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "Failed to read file";
|
||||||
|
esp3d_log_e("%s", "Failed to read file");
|
||||||
} else {
|
} else {
|
||||||
self->_luaFSType = Lua_Filesystem_Type::sd;
|
self->_luaFSType = Lua_Filesystem_Type::sd;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self->_lastError = "Failed to allocate memory for script";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "Failed to allocate memory for script";
|
||||||
|
esp3d_log_e("%s", "Failed to allocate memory for script");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// close the file
|
// close the file
|
||||||
SDfileHandle.close();
|
SDfileHandle.close();
|
||||||
} else {
|
} else {
|
||||||
self->_lastError = "File is not open: " + scriptName;
|
if (self->_lastError.length() == 0) self->_lastError =
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
"File is not open: " + scriptName;
|
||||||
|
esp3d_log_e("%s", "File is not open: " + scriptName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self->_lastError = "File not found: " + scriptName;
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "File not found: " + scriptName;
|
||||||
|
esp3d_log_e("%s", "File not found: " + scriptName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_SD::releaseFS();
|
ESP_SD::releaseFS();
|
||||||
@ -271,30 +302,76 @@ void LuaInterpreter::scriptExecutionTask(void *parameter) {
|
|||||||
}
|
}
|
||||||
#endif // SD_DEVICE
|
#endif // SD_DEVICE
|
||||||
// Check if the file system type is not determined
|
// Check if the file system type is not determined
|
||||||
if (self->_luaFSType == Lua_Filesystem_Type::none &&
|
esp3d_log("Check state");
|
||||||
self->_lastError.length() == 0) {
|
if (self->_luaFSType == Lua_Filesystem_Type::none) {
|
||||||
self->_lastError = "Cannot determine file system type";
|
if (self->_lastError.length() == 0)
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
self->_lastError = "Cannot determine file system type";
|
||||||
}
|
esp3d_log_e("%s", "Cannot determine file system type");
|
||||||
// Execute the script
|
} else {
|
||||||
if (self->_luaFSType != Lua_Filesystem_Type::none && self->_scriptBuffer) {
|
// Execute the script
|
||||||
if (!self->_luaEngine.executeScript(self->_scriptBuffer)) {
|
esp3d_log("Execute script");
|
||||||
self->_lastError = "Script execution failed";
|
if (self->_luaFSType != Lua_Filesystem_Type::none && self->_scriptBuffer) {
|
||||||
esp3d_log_e(% s, self->_lastError.c_str());
|
if (!self->_luaEngine.executeScript(self->_scriptBuffer)) {
|
||||||
|
if (self->_lastError.length() == 0) {
|
||||||
|
self->_lastError = "Script execution failed";
|
||||||
|
}
|
||||||
|
esp3d_log_e("%s", "Script execution failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
esp3d_log("Delete script task");
|
||||||
self->deleteScriptTask();
|
self->deleteScriptTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long LuaInterpreter::getExecutionTime() const {
|
bool LuaInterpreter::begin() {
|
||||||
if (!_isRunning) return 0;
|
end();
|
||||||
if (_isPaused) return _pauseTime - _startTime;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaInterpreter::end() { deleteScriptTask(); }
|
||||||
|
|
||||||
|
void LuaInterpreter::handle() {
|
||||||
|
static bool notificationSent = false;
|
||||||
|
if (_luaEngine.isRunning() && notificationSent) {
|
||||||
|
notificationSent = false;
|
||||||
|
}
|
||||||
|
if (_messageOutFIFO.size() > 0 || _luaEngine.hasError()) {
|
||||||
|
if (xSemaphoreTake(_stateMutex, portMAX_DELAY) == pdTRUE) {
|
||||||
|
// Check if the script is in error state and if still running
|
||||||
|
if (_luaEngine.hasError()) {
|
||||||
|
_lastError = _luaEngine.getLastError();
|
||||||
|
#ifdef NOTIFICATION_FEATURE
|
||||||
|
if (!notificationSent) {
|
||||||
|
String errorMsg = "Error: " + _lastError;
|
||||||
|
notificationsservice.sendAutoNotification(errorMsg.c_str());
|
||||||
|
notificationSent = true;
|
||||||
|
}
|
||||||
|
#endif // NOTIFICATION_FEATURE
|
||||||
|
}
|
||||||
|
if (_messageOutFIFO.size() > 0) {
|
||||||
|
esp3d_log("lua_interpreter message size %d", _messageOutFIFO.size());
|
||||||
|
}
|
||||||
|
ESP3DMessage *msg = _messageOutFIFO.pop();
|
||||||
|
if (msg) {
|
||||||
|
esp3d_log("Processing message: %s", msg->data);
|
||||||
|
esp3d_commands.process(msg);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(_stateMutex);
|
||||||
|
} else {
|
||||||
|
esp3d_log_e("Mutex not taken");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t LuaInterpreter::getExecutionTime() {
|
||||||
|
if (!_luaEngine.isRunning()) return 0;
|
||||||
|
if (_luaEngine.isPaused()) return _pauseTime - _startTime;
|
||||||
return millis() - _startTime;
|
return millis() - _startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaInterpreter::isScriptRunning() const { return _isRunning; }
|
bool LuaInterpreter::isScriptRunning() { return _luaEngine.isRunning(); }
|
||||||
|
|
||||||
bool LuaInterpreter::isScriptPaused() const { return _isPaused; }
|
bool LuaInterpreter::isScriptPaused() { return _luaEngine.isPaused(); }
|
||||||
|
|
||||||
void LuaInterpreter::setupFunctions() {
|
void LuaInterpreter::setupFunctions() {
|
||||||
_luaEngine.registerFunction("pinMode", l_pinMode);
|
_luaEngine.registerFunction("pinMode", l_pinMode);
|
||||||
@ -304,9 +381,10 @@ void LuaInterpreter::setupFunctions() {
|
|||||||
_luaEngine.registerFunction("analogRead", l_analogRead);
|
_luaEngine.registerFunction("analogRead", l_analogRead);
|
||||||
_luaEngine.registerFunction("available", l_available, this);
|
_luaEngine.registerFunction("available", l_available, this);
|
||||||
_luaEngine.registerFunction("readData", l_readData, this);
|
_luaEngine.registerFunction("readData", l_readData, this);
|
||||||
_luaEngine.registerFunction("delay", l_delay);
|
_luaEngine.registerFunction("delay", l_delay, this);
|
||||||
_luaEngine.registerFunction("yield", l_yield);
|
_luaEngine.registerFunction("yield", l_yield);
|
||||||
_luaEngine.registerFunction("millis", l_millis);
|
_luaEngine.registerFunction("millis", l_millis);
|
||||||
|
_luaEngine.registerFunction("print", l_print, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaInterpreter::registerConstants() {
|
void LuaInterpreter::registerConstants() {
|
||||||
@ -354,21 +432,45 @@ int LuaInterpreter::l_analogRead(lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_print(lua_State *L) {
|
int LuaInterpreter::l_print(lua_State *L) {
|
||||||
|
esp3d_log("lua_interpreter output");
|
||||||
|
LuaInterpreter *self =
|
||||||
|
(LuaInterpreter *)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
String dataString;
|
String dataString;
|
||||||
|
dataString = "";
|
||||||
int nargs = lua_gettop(L);
|
int nargs = lua_gettop(L);
|
||||||
|
// esp3d_log("lua_interpreter output args %d", nargs);
|
||||||
for (int i = 1; i <= nargs; i++) {
|
for (int i = 1; i <= nargs; i++) {
|
||||||
|
// esp3d_log("lua_interpreter output arg %d", i);
|
||||||
if (lua_isstring(L, i)) {
|
if (lua_isstring(L, i)) {
|
||||||
dataString += lua_tostring(L, i);
|
dataString += lua_tostring(L, i);
|
||||||
|
} else if (lua_isnumber(L, i)) {
|
||||||
|
dataString += String(lua_tonumber(L, i));
|
||||||
|
} else if (lua_isboolean(L, i)) {
|
||||||
|
dataString += lua_toboolean(L, i) ? "true" : "false";
|
||||||
|
} else if (lua_isnil(L, i)) {
|
||||||
|
dataString += "nil";
|
||||||
|
} else {
|
||||||
|
dataString += lua_typename(L, lua_type(L, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
if (!dataString.endsWith("\n")) {
|
||||||
|
dataString += "\n";
|
||||||
|
}
|
||||||
|
esp3d_log("lua_interpreter output %s", dataString.c_str());
|
||||||
|
esp3d_log("Message Creation");
|
||||||
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::lua_script, esp3d_commands.getOutputClient(),
|
ESP3DClientType::lua_script, esp3d_commands.getOutputClient(),
|
||||||
(uint8_t *)dataString.c_str(), dataString.length(),
|
(uint8_t *)dataString.c_str(), dataString.length(),
|
||||||
ESP3DAuthenticationLevel::admin);
|
ESP3DAuthenticationLevel::admin);
|
||||||
|
esp3d_log("Message created");
|
||||||
|
|
||||||
if (msg) {
|
if (msg) {
|
||||||
// process command
|
// process command
|
||||||
esp3d_commands.process(msg);
|
msg->type = ESP3DMessageType::unique;
|
||||||
|
esp3d_log("Message sent to fifo list");
|
||||||
|
// push to FIFO
|
||||||
|
self->_messageOutFIFO.push(msg);
|
||||||
} else {
|
} else {
|
||||||
esp3d_log_e("Cannot create message");
|
esp3d_log_e("Cannot create message");
|
||||||
}
|
}
|
||||||
@ -378,17 +480,17 @@ int l_print(lua_State *L) {
|
|||||||
int LuaInterpreter::l_available(lua_State *L) {
|
int LuaInterpreter::l_available(lua_State *L) {
|
||||||
LuaInterpreter *self =
|
LuaInterpreter *self =
|
||||||
(LuaInterpreter *)lua_touserdata(L, lua_upvalueindex(1));
|
(LuaInterpreter *)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
lua_pushinteger(L, self->_messageFIFO.size());
|
lua_pushinteger(L, self->_messageInFIFO.size());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaInterpreter::l_readData(lua_State *L) {
|
int LuaInterpreter::l_readData(lua_State *L) {
|
||||||
LuaInterpreter *self =
|
LuaInterpreter *self =
|
||||||
(LuaInterpreter *)lua_touserdata(L, lua_upvalueindex(1));
|
(LuaInterpreter *)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
ESP3DMessage *message = self->_messageFIFO.pop();
|
ESP3DMessage *message = self->_messageInFIFO.pop();
|
||||||
if (message) {
|
if (message) {
|
||||||
lua_pushlstring(L, (const char *)message->data, message->size);
|
lua_pushlstring(L, (const char *)message->data, message->size);
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
}
|
}
|
||||||
@ -396,8 +498,27 @@ int LuaInterpreter::l_readData(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaInterpreter::l_delay(lua_State *L) {
|
int LuaInterpreter::l_delay(lua_State *L) {
|
||||||
|
LuaInterpreter *self =
|
||||||
|
(LuaInterpreter *)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int ms = luaL_checkinteger(L, 1);
|
int ms = luaL_checkinteger(L, 1);
|
||||||
vTaskDelay(pdMS_TO_TICKS(ms));
|
TickType_t delayTicks = pdMS_TO_TICKS(ms);
|
||||||
|
// Check if during delay the script is aborted or paused
|
||||||
|
while (delayTicks > 0) {
|
||||||
|
TickType_t delayThis = (delayTicks > ESP_LUA_CHECK_INTERVAL)
|
||||||
|
? ESP_LUA_CHECK_INTERVAL
|
||||||
|
: delayTicks;
|
||||||
|
vTaskDelay(delayThis);
|
||||||
|
delayTicks -= delayThis;
|
||||||
|
while (self->_luaEngine.isPaused()) {
|
||||||
|
vTaskDelay(ESP_LUA_CHECK_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(self->_luaEngine.isRunning())) {
|
||||||
|
if (self->_lastError.length() == 0)
|
||||||
|
self->_lastError = "Execution stopped";
|
||||||
|
luaL_error(L, "Execution stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <EspLuaEngine.h>
|
#include <EspLuaEngine.h>
|
||||||
|
|
||||||
@ -39,28 +39,30 @@ class LuaInterpreter {
|
|||||||
~LuaInterpreter();
|
~LuaInterpreter();
|
||||||
|
|
||||||
bool executeScriptAsync(const char* script);
|
bool executeScriptAsync(const char* script);
|
||||||
void abortCurrentScript();
|
void abortScript();
|
||||||
bool pauseScript();
|
bool pauseScript();
|
||||||
bool resumeScript();
|
bool resumeScript();
|
||||||
const char* getCurrentScriptName() { return _currentScriptName.c_str(); }
|
const char* getCurrentScriptName() { return _currentScriptName.c_str(); }
|
||||||
unsigned long getExecutionTime() const;
|
uint64_t getExecutionTime();
|
||||||
bool isScriptRunning() const;
|
bool isScriptRunning();
|
||||||
bool isScriptPaused() const;
|
bool isScriptPaused();
|
||||||
const char* getLastError() const;
|
const char* getLastError();
|
||||||
bool dispatch(ESP3DMessage* message);
|
bool dispatch(ESP3DMessage* message);
|
||||||
|
bool begin();
|
||||||
|
void end();
|
||||||
|
void handle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EspLuaEngine _luaEngine;
|
EspLuaEngine _luaEngine;
|
||||||
TaskHandle_t _scriptTask;
|
TaskHandle_t _scriptTask;
|
||||||
char* _scriptBuffer;
|
char* _scriptBuffer;
|
||||||
SemaphoreHandle_t _pauseSemaphore;
|
SemaphoreHandle_t _stateMutex;
|
||||||
ESP3DMessageFIFO _messageFIFO;
|
ESP3DMessageFIFO _messageInFIFO;
|
||||||
|
ESP3DMessageFIFO _messageOutFIFO;
|
||||||
Lua_Filesystem_Type _luaFSType;
|
Lua_Filesystem_Type _luaFSType;
|
||||||
String _currentScriptName;
|
String _currentScriptName;
|
||||||
unsigned long _startTime;
|
unsigned long _startTime;
|
||||||
unsigned long _pauseTime;
|
unsigned long _pauseTime;
|
||||||
bool _isRunning;
|
|
||||||
bool _isPaused;
|
|
||||||
String _lastError;
|
String _lastError;
|
||||||
|
|
||||||
static void scriptExecutionTask(void* parameter);
|
static void scriptExecutionTask(void* parameter);
|
||||||
@ -68,7 +70,7 @@ class LuaInterpreter {
|
|||||||
void registerConstants();
|
void registerConstants();
|
||||||
bool createScriptTask();
|
bool createScriptTask();
|
||||||
void deleteScriptTask();
|
void deleteScriptTask();
|
||||||
void checkPause();
|
void resetLuaEnvironment();
|
||||||
|
|
||||||
// Wrappers
|
// Wrappers
|
||||||
static int l_print(lua_State* L);
|
static int l_print(lua_State* L);
|
||||||
@ -85,3 +87,5 @@ class LuaInterpreter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern LuaInterpreter esp3d_lua_interpreter;
|
extern LuaInterpreter esp3d_lua_interpreter;
|
||||||
|
|
||||||
|
#endif // defined(ARDUINO_ARCH_ESP32)
|
@ -252,7 +252,7 @@ const char* mDNS_Service::answerIP(uint16_t index) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
tmp = MDNS.IP(index).toString();
|
tmp = MDNS.address(index).toString();
|
||||||
|
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#if defined(ARDUINO_ARCH_ESP8266)
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
@ -120,7 +120,7 @@ bool MKSService::dispatch(ESP3DMessage *message) {
|
|||||||
}
|
}
|
||||||
if (message->size > 0 && message->data) {
|
if (message->size > 0 && message->data) {
|
||||||
if (sendGcodeFrame((const char *)message->data)) {
|
if (sendGcodeFrame((const char *)message->data)) {
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,10 @@
|
|||||||
#include "../gcode_host/gcode_host.h"
|
#include "../gcode_host/gcode_host.h"
|
||||||
#endif // GCODE_HOST_FEATURE
|
#endif // GCODE_HOST_FEATURE
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
esp_netif_t *get_esp_interface_netif(esp_interface_t interface);
|
||||||
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
String NetConfig::_hostname = "";
|
String NetConfig::_hostname = "";
|
||||||
bool NetConfig::_needReconnect2AP = false;
|
bool NetConfig::_needReconnect2AP = false;
|
||||||
bool NetConfig::_events_registered = false;
|
bool NetConfig::_events_registered = false;
|
||||||
@ -231,11 +235,12 @@ void NetConfig::onWiFiEvent(WiFiEvent_t event) {
|
|||||||
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
|
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
|
||||||
if (_started) {
|
if (_started) {
|
||||||
_needReconnect2AP = true;
|
_needReconnect2AP = true;
|
||||||
|
esp3d_log("WiFi STA lost IP");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef ETH_FEATURE
|
#ifdef ETH_FEATURE
|
||||||
case ARDUINO_EVENT_ETH_START: {
|
case ARDUINO_EVENT_ETH_START: {
|
||||||
EthConfig::setConnected(false);
|
esp3d_log("Ethernet started");
|
||||||
if (ESP3DSettings::isVerboseBoot()) {
|
if (ESP3DSettings::isVerboseBoot()) {
|
||||||
esp3d_commands.dispatch(
|
esp3d_commands.dispatch(
|
||||||
"Checking connection", ESP3DClientType::all_clients, no_id,
|
"Checking connection", ESP3DClientType::all_clients, no_id,
|
||||||
@ -248,18 +253,24 @@ void NetConfig::onWiFiEvent(WiFiEvent_t event) {
|
|||||||
no_id, ESP3DMessageType::unique,
|
no_id, ESP3DMessageType::unique,
|
||||||
ESP3DClientType::system,
|
ESP3DClientType::system,
|
||||||
ESP3DAuthenticationLevel::admin);
|
ESP3DAuthenticationLevel::admin);
|
||||||
|
esp3d_log("Ethernet connected");
|
||||||
EthConfig::setConnected(true);
|
EthConfig::setConnected(true);
|
||||||
} break;
|
} break;
|
||||||
case ARDUINO_EVENT_ETH_DISCONNECTED: {
|
case ARDUINO_EVENT_ETH_DISCONNECTED: {
|
||||||
|
esp3d_log("Ethernet disconnected");
|
||||||
esp3d_commands.dispatch("Cable disconnected",
|
esp3d_commands.dispatch("Cable disconnected",
|
||||||
ESP3DClientType::all_clients, no_id,
|
ESP3DClientType::all_clients, no_id,
|
||||||
ESP3DMessageType::unique, ESP3DClientType::system,
|
ESP3DMessageType::unique, ESP3DClientType::system,
|
||||||
ESP3DAuthenticationLevel::admin);
|
ESP3DAuthenticationLevel::admin);
|
||||||
EthConfig::setConnected(false);
|
EthConfig::setConnected(false);
|
||||||
} break;
|
} break;
|
||||||
|
case ARDUINO_EVENT_ETH_LOST_IP:
|
||||||
|
esp3d_log("Ethernet lost IP");
|
||||||
|
break;
|
||||||
case ARDUINO_EVENT_ETH_GOT_IP: {
|
case ARDUINO_EVENT_ETH_GOT_IP: {
|
||||||
#if COMMUNICATION_PROTOCOL != MKS_SERIAL
|
#if COMMUNICATION_PROTOCOL != MKS_SERIAL
|
||||||
#if defined(ESP_GOT_IP_HOOK) && defined(GCODE_HOST_FEATURE)
|
#if defined(ESP_GOT_IP_HOOK) && defined(GCODE_HOST_FEATURE)
|
||||||
|
ESP3DHal::wait(500);
|
||||||
String ipMsg = esp3d_string::expandString(ESP_GOT_IP_HOOK);
|
String ipMsg = esp3d_string::expandString(ESP_GOT_IP_HOOK);
|
||||||
esp3d_log("Got IP, sending hook: %s", ipMsg.c_str());
|
esp3d_log("Got IP, sending hook: %s", ipMsg.c_str());
|
||||||
esp3d_gcode_host.processScript(ipMsg.c_str(),
|
esp3d_gcode_host.processScript(ipMsg.c_str(),
|
||||||
@ -268,7 +279,9 @@ void NetConfig::onWiFiEvent(WiFiEvent_t event) {
|
|||||||
#endif // #if COMMUNICATION_PROTOCOL == MKS_SERIAL
|
#endif // #if COMMUNICATION_PROTOCOL == MKS_SERIAL
|
||||||
EthConfig::setConnected(true);
|
EthConfig::setConnected(true);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_STOP:
|
case ARDUINO_EVENT_ETH_STOP:
|
||||||
|
esp3d_log("Ethernet stopped");
|
||||||
EthConfig::setConnected(false);
|
EthConfig::setConnected(false);
|
||||||
break;
|
break;
|
||||||
#endif // ETH_FEATURE
|
#endif // ETH_FEATURE
|
||||||
@ -523,12 +536,20 @@ void NetConfig::handle() {
|
|||||||
bool NetConfig::isIPModeDHCP(uint8_t mode) {
|
bool NetConfig::isIPModeDHCP(uint8_t mode) {
|
||||||
bool started = false;
|
bool started = false;
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
tcpip_adapter_dhcp_status_t dhcp_status;
|
if (mode == ESP_WIFI_STA || mode == ESP_WIFI_AP) {
|
||||||
tcpip_adapter_dhcpc_get_status((mode == ESP_WIFI_STA) ? TCPIP_ADAPTER_IF_STA
|
esp_netif_dhcp_status_t dhcp_status;
|
||||||
: (mode == ESP_WIFI_AP) ? TCPIP_ADAPTER_IF_AP
|
esp_netif_dhcpc_get_status((mode == ESP_WIFI_STA) ? get_esp_interface_netif(ESP_IF_WIFI_STA)
|
||||||
: TCPIP_ADAPTER_IF_ETH,
|
: get_esp_interface_netif(ESP_IF_WIFI_AP),
|
||||||
&dhcp_status);
|
&dhcp_status);
|
||||||
started = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
|
esp3d_log("DHCP Status %d", (int)dhcp_status);
|
||||||
|
started = (dhcp_status == ESP_NETIF_DHCP_STARTED);
|
||||||
|
}
|
||||||
|
#if defined(ETH_FEATURE)
|
||||||
|
if (mode == ESP_ETH_STA) {
|
||||||
|
started = (EthConfig::ipMode()==DHCP_MODE);
|
||||||
|
}
|
||||||
|
#endif // ETH_FEATURE
|
||||||
|
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
(void)mode;
|
(void)mode;
|
||||||
@ -540,12 +561,13 @@ bool NetConfig::isIPModeDHCP(uint8_t mode) {
|
|||||||
bool NetConfig::isDHCPServer(uint8_t mode) {
|
bool NetConfig::isDHCPServer(uint8_t mode) {
|
||||||
bool itis = false;
|
bool itis = false;
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
tcpip_adapter_dhcp_status_t dhcp_status;
|
//Fzor some reason esp_netif_dhcps_get_status() give always !DHCP_MODE for Ethernet even if it is set to DHCP
|
||||||
tcpip_adapter_dhcps_get_status((mode == ESP_WIFI_STA) ? TCPIP_ADAPTER_IF_STA
|
if (mode == ESP_WIFI_AP) {
|
||||||
: (mode == ESP_WIFI_AP) ? TCPIP_ADAPTER_IF_AP
|
esp_netif_dhcp_status_t dhcp_status;
|
||||||
: TCPIP_ADAPTER_IF_ETH,
|
esp_netif_dhcps_get_status(get_esp_interface_netif(ESP_IF_WIFI_AP),
|
||||||
&dhcp_status);
|
&dhcp_status);
|
||||||
itis = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
|
itis = (dhcp_status == ESP_NETIF_DHCP_STARTED);
|
||||||
|
}
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
(void)mode;
|
(void)mode;
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include <esp_netif.h>
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
|
@ -37,7 +37,7 @@ HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1};
|
|||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) ||defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
#define MAX_SERIAL 2
|
#define MAX_SERIAL 2
|
||||||
HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1};
|
HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1};
|
||||||
#else
|
#else
|
||||||
@ -293,7 +293,7 @@ void ESP3DSerialService::flushbuffer() {
|
|||||||
|
|
||||||
// dispatch command
|
// dispatch command
|
||||||
if (_started) {
|
if (_started) {
|
||||||
ESP3DMessage *message = ESP3DMessageManager::newMsg(
|
ESP3DMessage *message = esp3d_message_manager.newMsg(
|
||||||
_origin,
|
_origin,
|
||||||
_id == MAIN_SERIAL ? ESP3DClientType::all_clients
|
_id == MAIN_SERIAL ? ESP3DClientType::all_clients
|
||||||
: esp3d_commands.getOutputClient(),
|
: esp3d_commands.getOutputClient(),
|
||||||
@ -550,7 +550,7 @@ bool ESP3DSerialService::dispatch(ESP3DMessage *message) {
|
|||||||
if (writeBytes(message->data, message->size) == message->size) {
|
if (writeBytes(message->data, message->size) == message->size) {
|
||||||
flush();
|
flush();
|
||||||
// Delete message now
|
// Delete message now
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
done = true;
|
done = true;
|
||||||
} else {
|
} else {
|
||||||
esp3d_log_e("Error while sending data");
|
esp3d_log_e("Error while sending data");
|
||||||
|
@ -167,7 +167,7 @@ void Serial_2_Socket::handle_flush() {
|
|||||||
}
|
}
|
||||||
void Serial_2_Socket::flush(void) {
|
void Serial_2_Socket::flush(void) {
|
||||||
if (_TXbufferSize > 0 && _started && !_paused) {
|
if (_TXbufferSize > 0 && _started && !_paused) {
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::socket_serial, ESP3DClientType::all_clients, _TXbuffer,
|
ESP3DClientType::socket_serial, ESP3DClientType::all_clients, _TXbuffer,
|
||||||
_TXbufferSize, _auth);
|
_TXbufferSize, _auth);
|
||||||
// dispatch command
|
// dispatch command
|
||||||
@ -195,7 +195,7 @@ bool Serial_2_Socket::dispatch(ESP3DMessage *message) {
|
|||||||
esp3d_log_e("Serial2Socket: cannot push all data");
|
esp3d_log_e("Serial2Socket: cannot push all data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
esp3d_log_e("Serial2Socket: no data in message");
|
esp3d_log_e("Serial2Socket: no data in message");
|
||||||
|
@ -22,8 +22,7 @@
|
|||||||
|
|
||||||
#if defined(TELNET_FEATURE) || \
|
#if defined(TELNET_FEATURE) || \
|
||||||
(defined(ESP_LOG_FEATURE) && ESP_LOG_FEATURE == LOG_OUTPUT_TELNET)
|
(defined(ESP_LOG_FEATURE) && ESP_LOG_FEATURE == LOG_OUTPUT_TELNET)
|
||||||
#include <WiFiClient.h>
|
|
||||||
#include <WiFiServer.h>
|
|
||||||
|
|
||||||
#include "../../core/esp3d_commands.h"
|
#include "../../core/esp3d_commands.h"
|
||||||
#include "../../core/esp3d_message.h"
|
#include "../../core/esp3d_message.h"
|
||||||
@ -200,7 +199,7 @@ bool Telnet_Server::dispatch(ESP3DMessage *message) {
|
|||||||
if (sentcnt != message->size) {
|
if (sentcnt != message->size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -221,7 +220,7 @@ void Telnet_Server::flushbuffer() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_buffer[_buffer_size] = 0x0;
|
_buffer[_buffer_size] = 0x0;
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
ESP3DClientType::telnet, esp3d_commands.getOutputClient(), _buffer,
|
ESP3DClientType::telnet, esp3d_commands.getOutputClient(), _buffer,
|
||||||
_buffer_size, _auth);
|
_buffer_size, _auth);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
#ifndef _TELNET_SERVER_H
|
#ifndef _TELNET_SERVER_H
|
||||||
#define _TELNET_SERVER_H
|
#define _TELNET_SERVER_H
|
||||||
|
|
||||||
class WiFiServer;
|
#include <WiFiClient.h>
|
||||||
class WiFiClient;
|
#include <WiFiServer.h>
|
||||||
|
|
||||||
#include "../../core/esp3d_message.h"
|
#include "../../core/esp3d_message.h"
|
||||||
|
|
||||||
#define ESP3D_TELNET_BUFFER_SIZE 1200
|
#define ESP3D_TELNET_BUFFER_SIZE 1200
|
||||||
|
@ -63,11 +63,11 @@ const uint16_t ServstringKeysPos[] = {ESP_TIME_ZONE,
|
|||||||
ESP_NOTIFICATION_TOKEN2,
|
ESP_NOTIFICATION_TOKEN2,
|
||||||
ESP_NOTIFICATION_SETTINGS};
|
ESP_NOTIFICATION_SETTINGS};
|
||||||
|
|
||||||
const char* IPKeysVal[] = {"STA_IP", "STA_GW", "STA_MSK", "STA_DNS", "AP_IP"};
|
const char* IPKeysVal[] = {"STA_IP", "STA_GW", "STA_MSK", "STA_DNS", "AP_IP","ETH_STA_IP", "ETH_STA_GW", "ETH_STA_MSK", "ETH_STA_DNS"};
|
||||||
|
|
||||||
const uint16_t IPKeysPos[] = {ESP_STA_IP_VALUE, ESP_STA_GATEWAY_VALUE,
|
const uint16_t IPKeysPos[] = {ESP_STA_IP_VALUE, ESP_STA_GATEWAY_VALUE,
|
||||||
ESP_STA_MASK_VALUE, ESP_STA_DNS_VALUE,
|
ESP_STA_MASK_VALUE, ESP_STA_DNS_VALUE,
|
||||||
ESP_AP_IP_VALUE};
|
ESP_AP_IP_VALUE, ESP_ETH_STA_IP_VALUE, ESP_ETH_STA_GATEWAY_VALUE, ESP_ETH_STA_MASK_VALUE, ESP_ETH_STA_DNS_VALUE};
|
||||||
|
|
||||||
const char* ServintKeysVal[] = {
|
const char* ServintKeysVal[] = {
|
||||||
"Serial_Bridge_Baud"
|
"Serial_Bridge_Baud"
|
||||||
@ -226,7 +226,7 @@ bool processingFileFunction(const char* section, const char* key,
|
|||||||
} else if (strcasecmp("OFF", value) == 0) {
|
} else if (strcasecmp("OFF", value) == 0) {
|
||||||
b = ESP_NO_NETWORK;
|
b = ESP_NO_NETWORK;
|
||||||
} else {
|
} else {
|
||||||
P = -1; // invalide value
|
P = -1; // invalid value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,7 +243,23 @@ bool processingFileFunction(const char* section, const char* key,
|
|||||||
} else if (strcasecmp("OFF", value) == 0) {
|
} else if (strcasecmp("OFF", value) == 0) {
|
||||||
b = ESP_NO_NETWORK;
|
b = ESP_NO_NETWORK;
|
||||||
} else {
|
} else {
|
||||||
P = -1; // invalide value
|
P = -1; // invalid value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ETH STA fallback mode BT, OFF
|
||||||
|
if (!done) {
|
||||||
|
if (strcasecmp("eth_sta_fallback", key) == 0) {
|
||||||
|
T = 'B';
|
||||||
|
P = ESP_STA_FALLBACK_MODE;
|
||||||
|
done = true;
|
||||||
|
if (strcasecmp("BT", value) == 0) {
|
||||||
|
b = ESP_BT;
|
||||||
|
} else if (strcasecmp("OFF", value) == 0) {
|
||||||
|
b = ESP_NO_NETWORK;
|
||||||
|
} else {
|
||||||
|
P = -1; // invalid value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,10 +275,27 @@ bool processingFileFunction(const char* section, const char* key,
|
|||||||
} else if (strcasecmp("STATIC", key) == 0) {
|
} else if (strcasecmp("STATIC", key) == 0) {
|
||||||
b = STATIC_IP_MODE;
|
b = STATIC_IP_MODE;
|
||||||
} else {
|
} else {
|
||||||
P = -1; // invalide value
|
P = -1; // invalid value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ETH STA IP Mode DHCP / STATIC
|
||||||
|
if (!done) {
|
||||||
|
if (strcasecmp("ETH_STA_IP_mode", key) == 0) {
|
||||||
|
T = 'B';
|
||||||
|
P = ESP_ETH_STA_IP_MODE;
|
||||||
|
done = true;
|
||||||
|
if (strcasecmp("DHCP", value) == 0) {
|
||||||
|
b = DHCP_MODE;
|
||||||
|
} else if (strcasecmp("STATIC", key) == 0) {
|
||||||
|
b = STATIC_IP_MODE;
|
||||||
|
} else {
|
||||||
|
P = -1; // invalid value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strcasecmp("services", section) == 0) {
|
} else if (strcasecmp("services", section) == 0) {
|
||||||
if (!done) {
|
if (!done) {
|
||||||
done = processString(ServstringKeysVal, ServstringKeysPos,
|
done = processString(ServstringKeysVal, ServstringKeysPos,
|
||||||
@ -310,7 +343,7 @@ bool processingFileFunction(const char* section, const char* key,
|
|||||||
} else if (strcasecmp("HOMEASSISTANT", value) == 0) {
|
} else if (strcasecmp("HOMEASSISTANT", value) == 0) {
|
||||||
b = ESP_HOMEASSISTANT_NOTIFICATION;
|
b = ESP_HOMEASSISTANT_NOTIFICATION;
|
||||||
} else {
|
} else {
|
||||||
P = -1; // invalide value
|
P = -1; // invalid value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +366,7 @@ bool processingFileFunction(const char* section, const char* key,
|
|||||||
} else if (strcasecmp("BME280", key) == 0) {
|
} else if (strcasecmp("BME280", key) == 0) {
|
||||||
b = BME280_DEVICE;
|
b = BME280_DEVICE;
|
||||||
} else {
|
} else {
|
||||||
P = -1; // invalide value
|
P = -1; // invalid value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,7 +399,7 @@ bool processingFileFunction(const char* section, const char* key,
|
|||||||
} else if (strcasecmp("SMOOTHIEWARE", value) == 0) {
|
} else if (strcasecmp("SMOOTHIEWARE", value) == 0) {
|
||||||
b = SMOOTHIEWARE;
|
b = SMOOTHIEWARE;
|
||||||
} else {
|
} else {
|
||||||
P = -1; // invalide value
|
P = -1; // invalid value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,8 @@ typedef ESP_SDFile WebDavFile;
|
|||||||
typedef ESP_SD WebDavFS;
|
typedef ESP_SD WebDavFS;
|
||||||
#endif // WEBDAV_FEATURE == FS_SD
|
#endif // WEBDAV_FEATURE == FS_SD
|
||||||
|
|
||||||
class WiFiServer;
|
#include <WiFiClient.h>
|
||||||
class WiFiClient;
|
#include <WiFiServer.h>
|
||||||
|
|
||||||
class WebdavServer {
|
class WebdavServer {
|
||||||
public:
|
public:
|
||||||
|
@ -64,7 +64,7 @@ bool WebSocket_Server::dispatch(ESP3DMessage *message) {
|
|||||||
if (sentcnt != message->size) {
|
if (sentcnt != message->size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ESP3DMessageManager::deleteMsg(message);
|
esp3d_message_manager.deleteMsg(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -330,7 +330,7 @@ void WebSocket_Server::flushRXbuffer() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_RXbuffer[_RXbufferSize] = 0x0;
|
_RXbuffer[_RXbufferSize] = 0x0;
|
||||||
ESP3DMessage *msg = ESP3DMessageManager::newMsg(
|
ESP3DMessage *msg = esp3d_message_manager.newMsg(
|
||||||
_type, esp3d_commands.getOutputClient(), _RXbuffer, _RXbufferSize, _auth);
|
_type, esp3d_commands.getOutputClient(), _RXbuffer, _RXbufferSize, _auth);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
// process command
|
// process command
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#if defined(WIFI_FEATURE)
|
#if defined(WIFI_FEATURE)
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
#include <esp_wifi_ap_get_sta_list.h>
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
#endif // ARDUINO_ARCH_ESP8266
|
#endif // ARDUINO_ARCH_ESP8266
|
||||||
@ -30,6 +31,10 @@
|
|||||||
#include "../network/netconfig.h"
|
#include "../network/netconfig.h"
|
||||||
#include "../wifi/wificonfig.h"
|
#include "../wifi/wificonfig.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
esp_netif_t *get_esp_interface_netif(esp_interface_t interface);
|
||||||
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0};
|
const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0};
|
||||||
|
|
||||||
IPAddress WiFiConfig::_ap_gateway;
|
IPAddress WiFiConfig::_ap_gateway;
|
||||||
@ -468,8 +473,8 @@ const char* WiFiConfig::AP_Auth_String() {
|
|||||||
const char* WiFiConfig::AP_Gateway_String() {
|
const char* WiFiConfig::AP_Gateway_String() {
|
||||||
static String tmp;
|
static String tmp;
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
tcpip_adapter_ip_info_t ip_AP;
|
esp_netif_ip_info_t ip_AP;
|
||||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_AP);
|
esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip_AP);
|
||||||
tmp = IPAddress(ip_AP.gw.addr).toString();
|
tmp = IPAddress(ip_AP.gw.addr).toString();
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
@ -485,8 +490,8 @@ const char* WiFiConfig::AP_Gateway_String() {
|
|||||||
const char* WiFiConfig::AP_Mask_String() {
|
const char* WiFiConfig::AP_Mask_String() {
|
||||||
static String tmp;
|
static String tmp;
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
tcpip_adapter_ip_info_t ip_AP;
|
esp_netif_ip_info_t ip_AP;
|
||||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_AP);
|
esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip_AP);
|
||||||
tmp = IPAddress(ip_AP.netmask.addr).toString();
|
tmp = IPAddress(ip_AP.netmask.addr).toString();
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
@ -509,16 +514,22 @@ const char* WiFiConfig::getConnectedSTA(uint8_t* totalcount, bool reset) {
|
|||||||
if (current > count) {
|
if (current > count) {
|
||||||
current = 0;
|
current = 0;
|
||||||
}
|
}
|
||||||
static wifi_sta_list_t station;
|
static wifi_sta_list_t sta_list;
|
||||||
static tcpip_adapter_sta_list_t tcpip_sta_list;
|
static wifi_sta_mac_ip_list_t tcpip_sta_list;
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
current = 0;
|
current = 0;
|
||||||
esp_wifi_ap_get_sta_list(&station);
|
if(esp_wifi_ap_get_sta_list(&sta_list)!=ESP_OK){
|
||||||
tcpip_adapter_get_sta_list(&station, &tcpip_sta_list);
|
return "";
|
||||||
count = station.num;
|
}
|
||||||
|
if (sta_list.num > 0) {
|
||||||
|
ESP_ERROR_CHECK(
|
||||||
|
esp_wifi_ap_get_sta_list_with_ip(&sta_list, &tcpip_sta_list));
|
||||||
|
}
|
||||||
|
count = sta_list.num;
|
||||||
}
|
}
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
data = IPAddress(tcpip_sta_list.sta[current].ip.addr).toString();
|
data = IPAddress(tcpip_sta_list.sta[current].ip.addr).toString();
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#define AUTH_WPA_WPA2_PSK WIFI_AUTH_WPA_WPA2_PSK
|
#define AUTH_WPA_WPA2_PSK WIFI_AUTH_WPA_WPA2_PSK
|
||||||
#define ENC_TYPE_NONE AUTH_OPEN
|
#define ENC_TYPE_NONE AUTH_OPEN
|
||||||
#define WiFiMode_t wifi_mode_t
|
#define WiFiMode_t wifi_mode_t
|
||||||
|
#include <esp_netif.h>
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
#endif // ARDUINO_ARCH_ESP32
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
|
215
extra-libraries/ESP32/SdFat-2.1.2/.gitignore
vendored
215
extra-libraries/ESP32/SdFat-2.1.2/.gitignore
vendored
@ -1,215 +0,0 @@
|
|||||||
#################
|
|
||||||
## Eclipse
|
|
||||||
#################
|
|
||||||
|
|
||||||
*.pydevproject
|
|
||||||
.project
|
|
||||||
.metadata
|
|
||||||
bin/
|
|
||||||
tmp/
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
*~.nib
|
|
||||||
local.properties
|
|
||||||
.classpath
|
|
||||||
.settings/
|
|
||||||
.loadpath
|
|
||||||
|
|
||||||
# External tool builders
|
|
||||||
.externalToolBuilders/
|
|
||||||
|
|
||||||
# Locally stored "Eclipse launch configurations"
|
|
||||||
*.launch
|
|
||||||
|
|
||||||
# CDT-specific
|
|
||||||
.cproject
|
|
||||||
|
|
||||||
# PDT-specific
|
|
||||||
.buildpath
|
|
||||||
|
|
||||||
|
|
||||||
#################
|
|
||||||
## Visual Studio
|
|
||||||
#################
|
|
||||||
|
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
|
||||||
## files generated by popular Visual Studio add-ons.
|
|
||||||
|
|
||||||
# User-specific files
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
*.sln.docstates
|
|
||||||
|
|
||||||
# Build results
|
|
||||||
|
|
||||||
[Dd]ebug/
|
|
||||||
[Rr]elease/
|
|
||||||
x64/
|
|
||||||
build/
|
|
||||||
[Bb]in/
|
|
||||||
[Oo]bj/
|
|
||||||
|
|
||||||
# MSTest test Results
|
|
||||||
[Tt]est[Rr]esult*/
|
|
||||||
[Bb]uild[Ll]og.*
|
|
||||||
|
|
||||||
*_i.c
|
|
||||||
*_p.c
|
|
||||||
*.ilk
|
|
||||||
*.meta
|
|
||||||
*.obj
|
|
||||||
*.pch
|
|
||||||
*.pdb
|
|
||||||
*.pgc
|
|
||||||
*.pgd
|
|
||||||
*.rsp
|
|
||||||
*.sbr
|
|
||||||
*.tlb
|
|
||||||
*.tli
|
|
||||||
*.tlh
|
|
||||||
*.tmp
|
|
||||||
*.tmp_proj
|
|
||||||
*.log
|
|
||||||
*.vspscc
|
|
||||||
*.vssscc
|
|
||||||
.builds
|
|
||||||
*.pidb
|
|
||||||
*.log
|
|
||||||
*.scc
|
|
||||||
|
|
||||||
# Visual C++ cache files
|
|
||||||
ipch/
|
|
||||||
*.aps
|
|
||||||
*.ncb
|
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
|
||||||
*.cachefile
|
|
||||||
|
|
||||||
# Visual Studio profiler
|
|
||||||
*.psess
|
|
||||||
*.vsp
|
|
||||||
*.vspx
|
|
||||||
|
|
||||||
# Guidance Automation Toolkit
|
|
||||||
*.gpState
|
|
||||||
|
|
||||||
# ReSharper is a .NET coding add-in
|
|
||||||
_ReSharper*/
|
|
||||||
*.[Rr]e[Ss]harper
|
|
||||||
|
|
||||||
# TeamCity is a build add-in
|
|
||||||
_TeamCity*
|
|
||||||
|
|
||||||
# DotCover is a Code Coverage Tool
|
|
||||||
*.dotCover
|
|
||||||
|
|
||||||
# NCrunch
|
|
||||||
*.ncrunch*
|
|
||||||
.*crunch*.local.xml
|
|
||||||
|
|
||||||
# Installshield output folder
|
|
||||||
[Ee]xpress/
|
|
||||||
|
|
||||||
# DocProject is a documentation generator add-in
|
|
||||||
DocProject/buildhelp/
|
|
||||||
DocProject/Help/*.HxT
|
|
||||||
DocProject/Help/*.HxC
|
|
||||||
DocProject/Help/*.hhc
|
|
||||||
DocProject/Help/*.hhk
|
|
||||||
DocProject/Help/*.hhp
|
|
||||||
DocProject/Help/Html2
|
|
||||||
DocProject/Help/html
|
|
||||||
|
|
||||||
# Click-Once directory
|
|
||||||
publish/
|
|
||||||
|
|
||||||
# Publish Web Output
|
|
||||||
*.Publish.xml
|
|
||||||
*.pubxml
|
|
||||||
|
|
||||||
# NuGet Packages Directory
|
|
||||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
|
||||||
#packages/
|
|
||||||
|
|
||||||
# Windows Azure Build Output
|
|
||||||
csx
|
|
||||||
*.build.csdef
|
|
||||||
|
|
||||||
# Windows Store app package directory
|
|
||||||
AppPackages/
|
|
||||||
|
|
||||||
# Others
|
|
||||||
sql/
|
|
||||||
*.Cache
|
|
||||||
ClientBin/
|
|
||||||
[Ss]tyle[Cc]op.*
|
|
||||||
~$*
|
|
||||||
*~
|
|
||||||
*.dbmdl
|
|
||||||
*.[Pp]ublish.xml
|
|
||||||
*.pfx
|
|
||||||
*.publishsettings
|
|
||||||
|
|
||||||
# RIA/Silverlight projects
|
|
||||||
Generated_Code/
|
|
||||||
|
|
||||||
# Backup & report files from converting an old project file to a newer
|
|
||||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
|
||||||
_UpgradeReport_Files/
|
|
||||||
Backup*/
|
|
||||||
UpgradeLog*.XML
|
|
||||||
UpgradeLog*.htm
|
|
||||||
|
|
||||||
# SQL Server files
|
|
||||||
App_Data/*.mdf
|
|
||||||
App_Data/*.ldf
|
|
||||||
|
|
||||||
#############
|
|
||||||
## Windows detritus
|
|
||||||
#############
|
|
||||||
|
|
||||||
# Windows image file caches
|
|
||||||
Thumbs.db
|
|
||||||
ehthumbs.db
|
|
||||||
|
|
||||||
# Folder config file
|
|
||||||
Desktop.ini
|
|
||||||
|
|
||||||
# Recycle Bin used on file shares
|
|
||||||
$RECYCLE.BIN/
|
|
||||||
|
|
||||||
# Mac crap
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
|
|
||||||
#############
|
|
||||||
## Python
|
|
||||||
#############
|
|
||||||
|
|
||||||
*.py[co]
|
|
||||||
|
|
||||||
# Packages
|
|
||||||
*.egg
|
|
||||||
*.egg-info
|
|
||||||
dist/
|
|
||||||
build/
|
|
||||||
eggs/
|
|
||||||
parts/
|
|
||||||
var/
|
|
||||||
sdist/
|
|
||||||
develop-eggs/
|
|
||||||
.installed.cfg
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
.coverage
|
|
||||||
.tox
|
|
||||||
|
|
||||||
#Translations
|
|
||||||
*.mo
|
|
||||||
|
|
||||||
#Mr Developer
|
|
||||||
.mr.developer.cfg
|
|
@ -1,50 +0,0 @@
|
|||||||
2021-01-06
|
|
||||||
|
|
||||||
Run the SdErrorCode example to produce an updated list.
|
|
||||||
|
|
||||||
Code,Symbol - failed operation
|
|
||||||
0X00,SD_CARD_ERROR_NONE - No error
|
|
||||||
0X01,SD_CARD_ERROR_CMD0 - Card reset failed
|
|
||||||
0X02,SD_CARD_ERROR_CMD2 - SDIO read CID
|
|
||||||
0X03,SD_CARD_ERROR_CMD3 - SDIO publish RCA
|
|
||||||
0X04,SD_CARD_ERROR_CMD6 - Switch card function
|
|
||||||
0X05,SD_CARD_ERROR_CMD7 - SDIO card select
|
|
||||||
0X06,SD_CARD_ERROR_CMD8 - Send and check interface settings
|
|
||||||
0X07,SD_CARD_ERROR_CMD9 - Read CSD data
|
|
||||||
0X08,SD_CARD_ERROR_CMD10 - Read CID data
|
|
||||||
0X09,SD_CARD_ERROR_CMD12 - Stop multiple block read
|
|
||||||
0X0A,SD_CARD_ERROR_CMD13 - Read card status
|
|
||||||
0X0B,SD_CARD_ERROR_CMD17 - Read single block
|
|
||||||
0X0C,SD_CARD_ERROR_CMD18 - Read multiple blocks
|
|
||||||
0X0D,SD_CARD_ERROR_CMD24 - Write single block
|
|
||||||
0X0E,SD_CARD_ERROR_CMD25 - Write multiple blocks
|
|
||||||
0X0F,SD_CARD_ERROR_CMD32 - Set first erase block
|
|
||||||
0X10,SD_CARD_ERROR_CMD33 - Set last erase block
|
|
||||||
0X11,SD_CARD_ERROR_CMD38 - Erase selected blocks
|
|
||||||
0X12,SD_CARD_ERROR_CMD58 - Read OCR register
|
|
||||||
0X13,SD_CARD_ERROR_CMD59 - Set CRC mode
|
|
||||||
0X14,SD_CARD_ERROR_ACMD6 - Set SDIO bus width
|
|
||||||
0X15,SD_CARD_ERROR_ACMD13 - Read extended status
|
|
||||||
0X16,SD_CARD_ERROR_ACMD23 - Set pre-erased count
|
|
||||||
0X17,SD_CARD_ERROR_ACMD41 - Activate card initialization
|
|
||||||
0X18,SD_CARD_ERROR_READ_TOKEN - Bad read data token
|
|
||||||
0X19,SD_CARD_ERROR_READ_CRC - Read CRC error
|
|
||||||
0X1A,SD_CARD_ERROR_READ_FIFO - SDIO fifo read timeout
|
|
||||||
0X1B,SD_CARD_ERROR_READ_REG - Read CID or CSD failed.
|
|
||||||
0X1C,SD_CARD_ERROR_READ_START - Bad readStart argument
|
|
||||||
0X1D,SD_CARD_ERROR_READ_TIMEOUT - Read data timeout
|
|
||||||
0X1E,SD_CARD_ERROR_STOP_TRAN - Multiple block stop failed
|
|
||||||
0X1F,SD_CARD_ERROR_TRANSFER_COMPLETE - SDIO transfer complete
|
|
||||||
0X20,SD_CARD_ERROR_WRITE_DATA - Write data not accepted
|
|
||||||
0X21,SD_CARD_ERROR_WRITE_FIFO - SDIO fifo write timeout
|
|
||||||
0X22,SD_CARD_ERROR_WRITE_START - Bad writeStart argument
|
|
||||||
0X23,SD_CARD_ERROR_WRITE_PROGRAMMING - Flash programming
|
|
||||||
0X24,SD_CARD_ERROR_WRITE_TIMEOUT - Write timeout
|
|
||||||
0X25,SD_CARD_ERROR_DMA - DMA transfer failed
|
|
||||||
0X26,SD_CARD_ERROR_ERASE - Card did not accept erase commands
|
|
||||||
0X27,SD_CARD_ERROR_ERASE_SINGLE_SECTOR - Card does not support erase
|
|
||||||
0X28,SD_CARD_ERROR_ERASE_TIMEOUT - Erase command timeout
|
|
||||||
0X29,SD_CARD_ERROR_INIT_NOT_CALLED - Card has not been initialized
|
|
||||||
0X2A,SD_CARD_ERROR_INVALID_CARD_CONFIG - Invalid card config
|
|
||||||
0X2B,SD_CARD_ERROR_FUNCTION_NOT_SUPPORTED - Unsupported SDIO command
|
|
||||||
0X2C,SD_CARD_ERROR_UNKNOWN - Unknown error
|
|
Binary file not shown.
@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* Example use of chdir(), ls(), mkdir(), and rmdir().
|
|
||||||
*/
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
#include "sdios.h"
|
|
||||||
// SD card chip select pin.
|
|
||||||
const uint8_t chipSelect = SS;
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// File system object.
|
|
||||||
SdFat sd;
|
|
||||||
|
|
||||||
// Directory file.
|
|
||||||
SdFile root;
|
|
||||||
|
|
||||||
// Use for file creation in folders.
|
|
||||||
SdFile file;
|
|
||||||
|
|
||||||
// Create a Serial output stream.
|
|
||||||
ArduinoOutStream cout(Serial);
|
|
||||||
|
|
||||||
// Buffer for Serial input.
|
|
||||||
char cinBuf[40];
|
|
||||||
|
|
||||||
// Create a serial input stream.
|
|
||||||
ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));
|
|
||||||
//==============================================================================
|
|
||||||
// Error messages stored in flash.
|
|
||||||
#define error(msg) sd.errorHalt(F(msg))
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
delay(1000);
|
|
||||||
|
|
||||||
cout << F("Type any character to start\n");
|
|
||||||
// Wait for input line and discard.
|
|
||||||
cin.readline();
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
// Initialize at the highest speed supported by the board that is
|
|
||||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
|
||||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
|
||||||
sd.initErrorHalt();
|
|
||||||
}
|
|
||||||
if (sd.exists("Folder1")
|
|
||||||
|| sd.exists("Folder1/file1.txt")
|
|
||||||
|| sd.exists("Folder1/File2.txt")) {
|
|
||||||
error("Please remove existing Folder1, file1.txt, and File2.txt");
|
|
||||||
}
|
|
||||||
|
|
||||||
int rootFileCount = 0;
|
|
||||||
if (!root.open("/")) {
|
|
||||||
error("open root failed");
|
|
||||||
}
|
|
||||||
while (file.openNext(&root, O_RDONLY)) {
|
|
||||||
if (!file.isHidden()) {
|
|
||||||
rootFileCount++;
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
if (rootFileCount > 10) {
|
|
||||||
error("Too many files in root. Please use an empty SD.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rootFileCount) {
|
|
||||||
cout << F("\nPlease use an empty SD for best results.\n\n");
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
// Create a new folder.
|
|
||||||
if (!sd.mkdir("Folder1")) {
|
|
||||||
error("Create Folder1 failed");
|
|
||||||
}
|
|
||||||
cout << F("Created Folder1\n");
|
|
||||||
|
|
||||||
// Create a file in Folder1 using a path.
|
|
||||||
if (!file.open("Folder1/file1.txt", O_WRONLY | O_CREAT)) {
|
|
||||||
error("create Folder1/file1.txt failed");
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
cout << F("Created Folder1/file1.txt\n");
|
|
||||||
|
|
||||||
// Change volume working directory to Folder1.
|
|
||||||
if (!sd.chdir("Folder1")) {
|
|
||||||
error("chdir failed for Folder1.\n");
|
|
||||||
}
|
|
||||||
cout << F("chdir to Folder1\n");
|
|
||||||
|
|
||||||
// Create File2.txt in current directory.
|
|
||||||
if (!file.open("File2.txt", O_WRONLY | O_CREAT)) {
|
|
||||||
error("create File2.txt failed");
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
cout << F("Created File2.txt in current directory\n");
|
|
||||||
|
|
||||||
cout << F("\nList of files on the SD.\n");
|
|
||||||
sd.ls("/", LS_R);
|
|
||||||
|
|
||||||
// Remove files from current directory.
|
|
||||||
if (!sd.remove("file1.txt") || !sd.remove("File2.txt")) {
|
|
||||||
error("remove failed");
|
|
||||||
}
|
|
||||||
cout << F("\nfile1.txt and File2.txt removed.\n");
|
|
||||||
|
|
||||||
// Change current directory to root.
|
|
||||||
if (!sd.chdir()) {
|
|
||||||
error("chdir to root failed.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << F("\nList of files on the SD.\n");
|
|
||||||
sd.ls(LS_R);
|
|
||||||
|
|
||||||
// Remove Folder1.
|
|
||||||
if (!sd.rmdir("Folder1")) {
|
|
||||||
error("rmdir for Folder1 failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << F("\nFolder1 removed.\n");
|
|
||||||
cout << F("\nList of files on the SD.\n");
|
|
||||||
sd.ls(LS_R);
|
|
||||||
cout << F("Done!\n");
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Nothing happens in loop.
|
|
||||||
void loop() {}
|
|
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Print size, modify date/time, and name for all files in root.
|
|
||||||
*/
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
|
|
||||||
// SD default chip select pin.
|
|
||||||
const uint8_t chipSelect = SS;
|
|
||||||
|
|
||||||
// file system object
|
|
||||||
SdFat sd;
|
|
||||||
|
|
||||||
SdFile root;
|
|
||||||
SdFile file;
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.println("Type any character to start");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize at the highest speed supported by the board that is
|
|
||||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
|
||||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
|
||||||
sd.initErrorHalt();
|
|
||||||
}
|
|
||||||
if (!root.open("/")) {
|
|
||||||
sd.errorHalt("open root failed");
|
|
||||||
}
|
|
||||||
// Open next file in root.
|
|
||||||
// Warning, openNext starts at the current directory position
|
|
||||||
// so a rewind of the directory may be required.
|
|
||||||
while (file.openNext(&root, O_RDONLY)) {
|
|
||||||
file.printFileSize(&Serial);
|
|
||||||
Serial.write(' ');
|
|
||||||
file.printModifyDateTime(&Serial);
|
|
||||||
Serial.write(' ');
|
|
||||||
file.printName(&Serial);
|
|
||||||
if (file.isDir()) {
|
|
||||||
// Indicate a directory.
|
|
||||||
Serial.write('/');
|
|
||||||
}
|
|
||||||
Serial.println();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
if (root.getError()) {
|
|
||||||
Serial.println("openNext failed");
|
|
||||||
} else {
|
|
||||||
Serial.println("Done!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void loop() {}
|
|
@ -1,161 +0,0 @@
|
|||||||
// Quick hardware test for SPI card access.
|
|
||||||
//
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
#include "sdios.h"
|
|
||||||
//
|
|
||||||
// Set DISABLE_CHIP_SELECT to disable a second SPI device.
|
|
||||||
// For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
|
|
||||||
// to 10 to disable the Ethernet controller.
|
|
||||||
const int8_t DISABLE_CHIP_SELECT = -1;
|
|
||||||
//
|
|
||||||
// Test with reduced SPI speed for breadboards. SD_SCK_MHZ(4) will select
|
|
||||||
// the highest speed supported by the board that is not over 4 MHz.
|
|
||||||
// Change SPI_SPEED to SD_SCK_MHZ(50) for best performance.
|
|
||||||
#define SPI_SPEED SD_SCK_MHZ(4)
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// File system object.
|
|
||||||
SdFat sd;
|
|
||||||
|
|
||||||
// Serial streams
|
|
||||||
ArduinoOutStream cout(Serial);
|
|
||||||
|
|
||||||
// input buffer for line
|
|
||||||
char cinBuf[40];
|
|
||||||
ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));
|
|
||||||
|
|
||||||
// SD card chip select
|
|
||||||
int chipSelect;
|
|
||||||
|
|
||||||
void cardOrSpeed() {
|
|
||||||
cout << F("Try another SD card or reduce the SPI bus speed.\n");
|
|
||||||
cout << F("Edit SPI_SPEED in this program to change it.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void reformatMsg() {
|
|
||||||
cout << F("Try reformatting the card. For best results use\n");
|
|
||||||
cout << F("the SdFormatter program in SdFat/examples or download\n");
|
|
||||||
cout << F("and use SDFormatter from www.sdcard.org/downloads.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
cout << F("\nSPI pins:\n");
|
|
||||||
cout << F("MISO: ") << int(MISO) << endl;
|
|
||||||
cout << F("MOSI: ") << int(MOSI) << endl;
|
|
||||||
cout << F("SCK: ") << int(SCK) << endl;
|
|
||||||
cout << F("SS: ") << int(SS) << endl;
|
|
||||||
|
|
||||||
if (DISABLE_CHIP_SELECT < 0) {
|
|
||||||
cout << F(
|
|
||||||
"\nBe sure to edit DISABLE_CHIP_SELECT if you have\n"
|
|
||||||
"a second SPI device. For example, with the Ethernet\n"
|
|
||||||
"shield, DISABLE_CHIP_SELECT should be set to 10\n"
|
|
||||||
"to disable the Ethernet controller.\n");
|
|
||||||
}
|
|
||||||
cout << F(
|
|
||||||
"\nSD chip select is the key hardware option.\n"
|
|
||||||
"Common values are:\n"
|
|
||||||
"Arduino Ethernet shield, pin 4\n"
|
|
||||||
"Sparkfun SD shield, pin 8\n"
|
|
||||||
"Adafruit SD shields and modules, pin 10\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool firstTry = true;
|
|
||||||
void loop() {
|
|
||||||
// Read any existing Serial data.
|
|
||||||
do {
|
|
||||||
delay(10);
|
|
||||||
} while (Serial.available() && Serial.read() >= 0);
|
|
||||||
|
|
||||||
if (!firstTry) {
|
|
||||||
cout << F("\nRestarting\n");
|
|
||||||
}
|
|
||||||
firstTry = false;
|
|
||||||
|
|
||||||
cout << F("\nEnter the chip select pin number: ");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
cin.readline();
|
|
||||||
if (cin >> chipSelect) {
|
|
||||||
cout << chipSelect << endl;
|
|
||||||
} else {
|
|
||||||
cout << F("\nInvalid pin number\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (DISABLE_CHIP_SELECT < 0) {
|
|
||||||
cout << F(
|
|
||||||
"\nAssuming the SD is the only SPI device.\n"
|
|
||||||
"Edit DISABLE_CHIP_SELECT to disable another device.\n");
|
|
||||||
} else {
|
|
||||||
cout << F("\nDisabling SPI device on pin ");
|
|
||||||
cout << int(DISABLE_CHIP_SELECT) << endl;
|
|
||||||
pinMode(DISABLE_CHIP_SELECT, OUTPUT);
|
|
||||||
digitalWrite(DISABLE_CHIP_SELECT, HIGH);
|
|
||||||
}
|
|
||||||
if (!sd.begin(chipSelect, SPI_SPEED)) {
|
|
||||||
if (sd.card()->errorCode()) {
|
|
||||||
cout << F(
|
|
||||||
"\nSD initialization failed.\n"
|
|
||||||
"Do not reformat the card!\n"
|
|
||||||
"Is the card correctly inserted?\n"
|
|
||||||
"Is chipSelect set to the correct value?\n"
|
|
||||||
"Does another SPI device need to be disabled?\n"
|
|
||||||
"Is there a wiring/soldering problem?\n");
|
|
||||||
cout << F("\nerrorCode: ") << hex << showbase;
|
|
||||||
cout << int(sd.card()->errorCode());
|
|
||||||
cout << F(", errorData: ") << int(sd.card()->errorData());
|
|
||||||
cout << dec << noshowbase << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (sd.vol()->fatType() == 0) {
|
|
||||||
cout << F("Can't find a valid FAT16/FAT32 partition.\n");
|
|
||||||
reformatMsg();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cout << F("begin failed, can't determine error type\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cout << F("\nCard successfully initialized.\n");
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
uint32_t size = sd.card()->cardSize();
|
|
||||||
if (size == 0) {
|
|
||||||
cout << F("Can't determine the card size.\n");
|
|
||||||
cardOrSpeed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint32_t sizeMB = 0.000512 * size + 0.5;
|
|
||||||
cout << F("Card size: ") << sizeMB;
|
|
||||||
cout << F(" MB (MB = 1,000,000 bytes)\n");
|
|
||||||
cout << endl;
|
|
||||||
cout << F("Volume is FAT") << int(sd.vol()->fatType());
|
|
||||||
cout << F(", Cluster size (bytes): ") << 512L * sd.vol()->blocksPerCluster();
|
|
||||||
cout << endl << endl;
|
|
||||||
|
|
||||||
cout << F("Files found (date time size name):\n");
|
|
||||||
sd.ls(LS_R | LS_DATE | LS_SIZE);
|
|
||||||
|
|
||||||
if ((sizeMB > 1100 && sd.vol()->blocksPerCluster() < 64)
|
|
||||||
|| (sizeMB < 2200 && sd.vol()->fatType() == 32)) {
|
|
||||||
cout << F("\nThis card should be reformatted for best performance.\n");
|
|
||||||
cout << F("Use a cluster size of 32 KB for cards larger than 1 GB.\n");
|
|
||||||
cout << F("Only cards larger than 2 GB should be formatted FAT32.\n");
|
|
||||||
reformatMsg();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Read any extra Serial data.
|
|
||||||
do {
|
|
||||||
delay(10);
|
|
||||||
} while (Serial.available() && Serial.read() >= 0);
|
|
||||||
cout << F("\nSuccess! Type any character to restart.\n");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,552 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program will format an SD or SDHC card.
|
|
||||||
* Warning all data will be deleted!
|
|
||||||
*
|
|
||||||
* For SD/SDHC cards larger than 64 MB this
|
|
||||||
* program attempts to match the format
|
|
||||||
* generated by SDFormatter available here:
|
|
||||||
*
|
|
||||||
* http://www.sdcard.org/consumers/formatter/
|
|
||||||
*
|
|
||||||
* For smaller cards this program uses FAT16
|
|
||||||
* and SDFormatter uses FAT12.
|
|
||||||
*/
|
|
||||||
#error use new Version 2 SdFormatter
|
|
||||||
// Set USE_SDIO to zero for SPI card access.
|
|
||||||
#define USE_SDIO 0
|
|
||||||
//
|
|
||||||
// Change the value of chipSelect if your hardware does
|
|
||||||
// not use the default value, SS. Common values are:
|
|
||||||
// Arduino Ethernet shield: pin 4
|
|
||||||
// Sparkfun SD shield: pin 8
|
|
||||||
// Adafruit SD shields and modules: pin 10
|
|
||||||
const uint8_t chipSelect = SS;
|
|
||||||
|
|
||||||
// Initialize at highest supported speed not over 50 MHz.
|
|
||||||
// Reduce max speed if errors occur.
|
|
||||||
#define SPI_SPEED SD_SCK_MHZ(50)
|
|
||||||
|
|
||||||
// Print extra info for debug if DEBUG_PRINT is nonzero
|
|
||||||
#define DEBUG_PRINT 0
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
#include "sdios.h"
|
|
||||||
#if DEBUG_PRINT
|
|
||||||
#include "FreeStack.h"
|
|
||||||
#endif // DEBUG_PRINT
|
|
||||||
|
|
||||||
// Serial output stream
|
|
||||||
ArduinoOutStream cout(Serial);
|
|
||||||
|
|
||||||
#if USE_SDIO
|
|
||||||
// Use faster SdioCardEX
|
|
||||||
SdioCardEX card;
|
|
||||||
// SdioCard card;
|
|
||||||
#else // USE_SDIO
|
|
||||||
Sd2Card card;
|
|
||||||
#endif // USE_SDIO
|
|
||||||
|
|
||||||
uint32_t cardSizeBlocks;
|
|
||||||
uint32_t cardCapacityMB;
|
|
||||||
|
|
||||||
// cache for SD block
|
|
||||||
cache_t cache;
|
|
||||||
|
|
||||||
// MBR information
|
|
||||||
uint8_t partType;
|
|
||||||
uint32_t relSector;
|
|
||||||
uint32_t partSize;
|
|
||||||
|
|
||||||
// Fake disk geometry
|
|
||||||
uint8_t numberOfHeads;
|
|
||||||
uint8_t sectorsPerTrack;
|
|
||||||
|
|
||||||
// FAT parameters
|
|
||||||
uint16_t reservedSectors;
|
|
||||||
uint8_t sectorsPerCluster;
|
|
||||||
uint32_t fatStart;
|
|
||||||
uint32_t fatSize;
|
|
||||||
uint32_t dataStart;
|
|
||||||
|
|
||||||
// constants for file system structure
|
|
||||||
uint16_t const BU16 = 128;
|
|
||||||
uint16_t const BU32 = 8192;
|
|
||||||
|
|
||||||
// strings needed in file system structures
|
|
||||||
char noName[] = "NO NAME ";
|
|
||||||
char fat16str[] = "FAT16 ";
|
|
||||||
char fat32str[] = "FAT32 ";
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#define sdError(msg) {cout << F("error: ") << F(msg) << endl; sdErrorHalt();}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void sdErrorHalt() {
|
|
||||||
if (card.errorCode()) {
|
|
||||||
cout << F("SD error: ") << hex << int(card.errorCode());
|
|
||||||
cout << ',' << int(card.errorData()) << dec << endl;
|
|
||||||
}
|
|
||||||
while (true) {}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#if DEBUG_PRINT
|
|
||||||
void debugPrint() {
|
|
||||||
cout << F("FreeStack: ") << FreeStack() << endl;
|
|
||||||
cout << F("partStart: ") << relSector << endl;
|
|
||||||
cout << F("partSize: ") << partSize << endl;
|
|
||||||
cout << F("reserved: ") << reservedSectors << endl;
|
|
||||||
cout << F("fatStart: ") << fatStart << endl;
|
|
||||||
cout << F("fatSize: ") << fatSize << endl;
|
|
||||||
cout << F("dataStart: ") << dataStart << endl;
|
|
||||||
cout << F("clusterCount: ");
|
|
||||||
cout << ((relSector + partSize - dataStart)/sectorsPerCluster) << endl;
|
|
||||||
cout << endl;
|
|
||||||
cout << F("Heads: ") << int(numberOfHeads) << endl;
|
|
||||||
cout << F("Sectors: ") << int(sectorsPerTrack) << endl;
|
|
||||||
cout << F("Cylinders: ");
|
|
||||||
cout << cardSizeBlocks/(numberOfHeads*sectorsPerTrack) << endl;
|
|
||||||
}
|
|
||||||
#endif // DEBUG_PRINT
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// write cached block to the card
|
|
||||||
uint8_t writeCache(uint32_t lbn) {
|
|
||||||
return card.writeBlock(lbn, cache.data);
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// initialize appropriate sizes for SD capacity
|
|
||||||
void initSizes() {
|
|
||||||
if (cardCapacityMB <= 6) {
|
|
||||||
sdError("Card is too small.");
|
|
||||||
} else if (cardCapacityMB <= 16) {
|
|
||||||
sectorsPerCluster = 2;
|
|
||||||
} else if (cardCapacityMB <= 32) {
|
|
||||||
sectorsPerCluster = 4;
|
|
||||||
} else if (cardCapacityMB <= 64) {
|
|
||||||
sectorsPerCluster = 8;
|
|
||||||
} else if (cardCapacityMB <= 128) {
|
|
||||||
sectorsPerCluster = 16;
|
|
||||||
} else if (cardCapacityMB <= 1024) {
|
|
||||||
sectorsPerCluster = 32;
|
|
||||||
} else if (cardCapacityMB <= 32768) {
|
|
||||||
sectorsPerCluster = 64;
|
|
||||||
} else {
|
|
||||||
// SDXC cards
|
|
||||||
sectorsPerCluster = 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << F("Blocks/Cluster: ") << int(sectorsPerCluster) << endl;
|
|
||||||
// set fake disk geometry
|
|
||||||
sectorsPerTrack = cardCapacityMB <= 256 ? 32 : 63;
|
|
||||||
|
|
||||||
if (cardCapacityMB <= 16) {
|
|
||||||
numberOfHeads = 2;
|
|
||||||
} else if (cardCapacityMB <= 32) {
|
|
||||||
numberOfHeads = 4;
|
|
||||||
} else if (cardCapacityMB <= 128) {
|
|
||||||
numberOfHeads = 8;
|
|
||||||
} else if (cardCapacityMB <= 504) {
|
|
||||||
numberOfHeads = 16;
|
|
||||||
} else if (cardCapacityMB <= 1008) {
|
|
||||||
numberOfHeads = 32;
|
|
||||||
} else if (cardCapacityMB <= 2016) {
|
|
||||||
numberOfHeads = 64;
|
|
||||||
} else if (cardCapacityMB <= 4032) {
|
|
||||||
numberOfHeads = 128;
|
|
||||||
} else {
|
|
||||||
numberOfHeads = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// zero cache and optionally set the sector signature
|
|
||||||
void clearCache(uint8_t addSig) {
|
|
||||||
memset(&cache, 0, sizeof(cache));
|
|
||||||
if (addSig) {
|
|
||||||
cache.mbr.mbrSig0 = BOOTSIG0;
|
|
||||||
cache.mbr.mbrSig1 = BOOTSIG1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// zero FAT and root dir area on SD
|
|
||||||
void clearFatDir(uint32_t bgn, uint32_t count) {
|
|
||||||
clearCache(false);
|
|
||||||
#if USE_SDIO
|
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
|
||||||
if (!card.writeBlock(bgn + i, cache.data)) {
|
|
||||||
sdError("Clear FAT/DIR writeBlock failed");
|
|
||||||
}
|
|
||||||
if ((i & 0XFF) == 0) {
|
|
||||||
cout << '.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else // USE_SDIO
|
|
||||||
if (!card.writeStart(bgn, count)) {
|
|
||||||
sdError("Clear FAT/DIR writeStart failed");
|
|
||||||
}
|
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
|
||||||
if ((i & 0XFF) == 0) {
|
|
||||||
cout << '.';
|
|
||||||
}
|
|
||||||
if (!card.writeData(cache.data)) {
|
|
||||||
sdError("Clear FAT/DIR writeData failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!card.writeStop()) {
|
|
||||||
sdError("Clear FAT/DIR writeStop failed");
|
|
||||||
}
|
|
||||||
#endif // USE_SDIO
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// return cylinder number for a logical block number
|
|
||||||
uint16_t lbnToCylinder(uint32_t lbn) {
|
|
||||||
return lbn / (numberOfHeads * sectorsPerTrack);
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// return head number for a logical block number
|
|
||||||
uint8_t lbnToHead(uint32_t lbn) {
|
|
||||||
return (lbn % (numberOfHeads * sectorsPerTrack)) / sectorsPerTrack;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// return sector number for a logical block number
|
|
||||||
uint8_t lbnToSector(uint32_t lbn) {
|
|
||||||
return (lbn % sectorsPerTrack) + 1;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// format and write the Master Boot Record
|
|
||||||
void writeMbr() {
|
|
||||||
clearCache(true);
|
|
||||||
part_t* p = cache.mbr.part;
|
|
||||||
p->boot = 0;
|
|
||||||
uint16_t c = lbnToCylinder(relSector);
|
|
||||||
if (c > 1023) {
|
|
||||||
sdError("MBR CHS");
|
|
||||||
}
|
|
||||||
p->beginCylinderHigh = c >> 8;
|
|
||||||
p->beginCylinderLow = c & 0XFF;
|
|
||||||
p->beginHead = lbnToHead(relSector);
|
|
||||||
p->beginSector = lbnToSector(relSector);
|
|
||||||
p->type = partType;
|
|
||||||
uint32_t endLbn = relSector + partSize - 1;
|
|
||||||
c = lbnToCylinder(endLbn);
|
|
||||||
if (c <= 1023) {
|
|
||||||
p->endCylinderHigh = c >> 8;
|
|
||||||
p->endCylinderLow = c & 0XFF;
|
|
||||||
p->endHead = lbnToHead(endLbn);
|
|
||||||
p->endSector = lbnToSector(endLbn);
|
|
||||||
} else {
|
|
||||||
// Too big flag, c = 1023, h = 254, s = 63
|
|
||||||
p->endCylinderHigh = 3;
|
|
||||||
p->endCylinderLow = 255;
|
|
||||||
p->endHead = 254;
|
|
||||||
p->endSector = 63;
|
|
||||||
}
|
|
||||||
p->firstSector = relSector;
|
|
||||||
p->totalSectors = partSize;
|
|
||||||
if (!writeCache(0)) {
|
|
||||||
sdError("write MBR");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// generate serial number from card size and micros since boot
|
|
||||||
uint32_t volSerialNumber() {
|
|
||||||
return (cardSizeBlocks << 8) + micros();
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// format the SD as FAT16
|
|
||||||
void makeFat16() {
|
|
||||||
uint32_t nc;
|
|
||||||
for (dataStart = 2 * BU16;; dataStart += BU16) {
|
|
||||||
nc = (cardSizeBlocks - dataStart)/sectorsPerCluster;
|
|
||||||
fatSize = (nc + 2 + 255)/256;
|
|
||||||
uint32_t r = BU16 + 1 + 2 * fatSize + 32;
|
|
||||||
if (dataStart < r) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
relSector = dataStart - r + BU16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// check valid cluster count for FAT16 volume
|
|
||||||
if (nc < 4085 || nc >= 65525) {
|
|
||||||
sdError("Bad cluster count");
|
|
||||||
}
|
|
||||||
reservedSectors = 1;
|
|
||||||
fatStart = relSector + reservedSectors;
|
|
||||||
partSize = nc * sectorsPerCluster + 2 * fatSize + reservedSectors + 32;
|
|
||||||
if (partSize < 32680) {
|
|
||||||
partType = 0X01;
|
|
||||||
} else if (partSize < 65536) {
|
|
||||||
partType = 0X04;
|
|
||||||
} else {
|
|
||||||
partType = 0X06;
|
|
||||||
}
|
|
||||||
// write MBR
|
|
||||||
writeMbr();
|
|
||||||
clearCache(true);
|
|
||||||
fat_boot_t* pb = &cache.fbs;
|
|
||||||
pb->jump[0] = 0XEB;
|
|
||||||
pb->jump[1] = 0X00;
|
|
||||||
pb->jump[2] = 0X90;
|
|
||||||
for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
|
|
||||||
pb->oemId[i] = ' ';
|
|
||||||
}
|
|
||||||
pb->bytesPerSector = 512;
|
|
||||||
pb->sectorsPerCluster = sectorsPerCluster;
|
|
||||||
pb->reservedSectorCount = reservedSectors;
|
|
||||||
pb->fatCount = 2;
|
|
||||||
pb->rootDirEntryCount = 512;
|
|
||||||
pb->mediaType = 0XF8;
|
|
||||||
pb->sectorsPerFat16 = fatSize;
|
|
||||||
pb->sectorsPerTrack = sectorsPerTrack;
|
|
||||||
pb->headCount = numberOfHeads;
|
|
||||||
pb->hidddenSectors = relSector;
|
|
||||||
pb->totalSectors32 = partSize;
|
|
||||||
pb->driveNumber = 0X80;
|
|
||||||
pb->bootSignature = EXTENDED_BOOT_SIG;
|
|
||||||
pb->volumeSerialNumber = volSerialNumber();
|
|
||||||
memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
|
|
||||||
memcpy(pb->fileSystemType, fat16str, sizeof(pb->fileSystemType));
|
|
||||||
// write partition boot sector
|
|
||||||
if (!writeCache(relSector)) {
|
|
||||||
sdError("FAT16 write PBS failed");
|
|
||||||
}
|
|
||||||
// clear FAT and root directory
|
|
||||||
clearFatDir(fatStart, dataStart - fatStart);
|
|
||||||
clearCache(false);
|
|
||||||
cache.fat16[0] = 0XFFF8;
|
|
||||||
cache.fat16[1] = 0XFFFF;
|
|
||||||
// write first block of FAT and backup for reserved clusters
|
|
||||||
if (!writeCache(fatStart)
|
|
||||||
|| !writeCache(fatStart + fatSize)) {
|
|
||||||
sdError("FAT16 reserve failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// format the SD as FAT32
|
|
||||||
void makeFat32() {
|
|
||||||
uint32_t nc;
|
|
||||||
relSector = BU32;
|
|
||||||
for (dataStart = 2 * BU32;; dataStart += BU32) {
|
|
||||||
nc = (cardSizeBlocks - dataStart)/sectorsPerCluster;
|
|
||||||
fatSize = (nc + 2 + 127)/128;
|
|
||||||
uint32_t r = relSector + 9 + 2 * fatSize;
|
|
||||||
if (dataStart >= r) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// error if too few clusters in FAT32 volume
|
|
||||||
if (nc < 65525) {
|
|
||||||
sdError("Bad cluster count");
|
|
||||||
}
|
|
||||||
reservedSectors = dataStart - relSector - 2 * fatSize;
|
|
||||||
fatStart = relSector + reservedSectors;
|
|
||||||
partSize = nc * sectorsPerCluster + dataStart - relSector;
|
|
||||||
// type depends on address of end sector
|
|
||||||
// max CHS has lbn = 16450560 = 1024*255*63
|
|
||||||
if ((relSector + partSize) <= 16450560) {
|
|
||||||
// FAT32
|
|
||||||
partType = 0X0B;
|
|
||||||
} else {
|
|
||||||
// FAT32 with INT 13
|
|
||||||
partType = 0X0C;
|
|
||||||
}
|
|
||||||
writeMbr();
|
|
||||||
clearCache(true);
|
|
||||||
|
|
||||||
fat32_boot_t* pb = &cache.fbs32;
|
|
||||||
pb->jump[0] = 0XEB;
|
|
||||||
pb->jump[1] = 0X00;
|
|
||||||
pb->jump[2] = 0X90;
|
|
||||||
for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
|
|
||||||
pb->oemId[i] = ' ';
|
|
||||||
}
|
|
||||||
pb->bytesPerSector = 512;
|
|
||||||
pb->sectorsPerCluster = sectorsPerCluster;
|
|
||||||
pb->reservedSectorCount = reservedSectors;
|
|
||||||
pb->fatCount = 2;
|
|
||||||
pb->mediaType = 0XF8;
|
|
||||||
pb->sectorsPerTrack = sectorsPerTrack;
|
|
||||||
pb->headCount = numberOfHeads;
|
|
||||||
pb->hidddenSectors = relSector;
|
|
||||||
pb->totalSectors32 = partSize;
|
|
||||||
pb->sectorsPerFat32 = fatSize;
|
|
||||||
pb->fat32RootCluster = 2;
|
|
||||||
pb->fat32FSInfo = 1;
|
|
||||||
pb->fat32BackBootBlock = 6;
|
|
||||||
pb->driveNumber = 0X80;
|
|
||||||
pb->bootSignature = EXTENDED_BOOT_SIG;
|
|
||||||
pb->volumeSerialNumber = volSerialNumber();
|
|
||||||
memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
|
|
||||||
memcpy(pb->fileSystemType, fat32str, sizeof(pb->fileSystemType));
|
|
||||||
// write partition boot sector and backup
|
|
||||||
if (!writeCache(relSector)
|
|
||||||
|| !writeCache(relSector + 6)) {
|
|
||||||
sdError("FAT32 write PBS failed");
|
|
||||||
}
|
|
||||||
clearCache(true);
|
|
||||||
// write extra boot area and backup
|
|
||||||
if (!writeCache(relSector + 2)
|
|
||||||
|| !writeCache(relSector + 8)) {
|
|
||||||
sdError("FAT32 PBS ext failed");
|
|
||||||
}
|
|
||||||
fat32_fsinfo_t* pf = &cache.fsinfo;
|
|
||||||
pf->leadSignature = FSINFO_LEAD_SIG;
|
|
||||||
pf->structSignature = FSINFO_STRUCT_SIG;
|
|
||||||
pf->freeCount = 0XFFFFFFFF;
|
|
||||||
pf->nextFree = 0XFFFFFFFF;
|
|
||||||
// write FSINFO sector and backup
|
|
||||||
if (!writeCache(relSector + 1)
|
|
||||||
|| !writeCache(relSector + 7)) {
|
|
||||||
sdError("FAT32 FSINFO failed");
|
|
||||||
}
|
|
||||||
clearFatDir(fatStart, 2 * fatSize + sectorsPerCluster);
|
|
||||||
clearCache(false);
|
|
||||||
cache.fat32[0] = 0x0FFFFFF8;
|
|
||||||
cache.fat32[1] = 0x0FFFFFFF;
|
|
||||||
cache.fat32[2] = 0x0FFFFFFF;
|
|
||||||
// write first block of FAT and backup for reserved clusters
|
|
||||||
if (!writeCache(fatStart)
|
|
||||||
|| !writeCache(fatStart + fatSize)) {
|
|
||||||
sdError("FAT32 reserve failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// flash erase all data
|
|
||||||
uint32_t const ERASE_SIZE = 262144L;
|
|
||||||
void eraseCard() {
|
|
||||||
cout << endl << F("Erasing\n");
|
|
||||||
uint32_t firstBlock = 0;
|
|
||||||
uint32_t lastBlock;
|
|
||||||
uint16_t n = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
lastBlock = firstBlock + ERASE_SIZE - 1;
|
|
||||||
if (lastBlock >= cardSizeBlocks) {
|
|
||||||
lastBlock = cardSizeBlocks - 1;
|
|
||||||
}
|
|
||||||
if (!card.erase(firstBlock, lastBlock)) {
|
|
||||||
sdError("erase failed");
|
|
||||||
}
|
|
||||||
cout << '.';
|
|
||||||
if ((n++)%32 == 31) {
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
firstBlock += ERASE_SIZE;
|
|
||||||
} while (firstBlock < cardSizeBlocks);
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
if (!card.readBlock(0, cache.data)) {
|
|
||||||
sdError("readBlock");
|
|
||||||
}
|
|
||||||
cout << hex << showbase << setfill('0') << internal;
|
|
||||||
cout << F("All data set to ") << setw(4) << int(cache.data[0]) << endl;
|
|
||||||
cout << dec << noshowbase << setfill(' ') << right;
|
|
||||||
cout << F("Erase done\n");
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void formatCard() {
|
|
||||||
cout << endl;
|
|
||||||
cout << F("Formatting\n");
|
|
||||||
initSizes();
|
|
||||||
if (card.type() != SD_CARD_TYPE_SDHC) {
|
|
||||||
cout << F("FAT16\n");
|
|
||||||
makeFat16();
|
|
||||||
} else {
|
|
||||||
cout << F("FAT32\n");
|
|
||||||
makeFat32();
|
|
||||||
}
|
|
||||||
#if DEBUG_PRINT
|
|
||||||
debugPrint();
|
|
||||||
#endif // DEBUG_PRINT
|
|
||||||
cout << F("Format done\n");
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void setup() {
|
|
||||||
char c;
|
|
||||||
Serial.begin(9600);
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
cout << F("Type any character to start\n");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
// Discard any extra characters.
|
|
||||||
do {
|
|
||||||
delay(10);
|
|
||||||
} while (Serial.available() && Serial.read() >= 0);
|
|
||||||
cout << F(
|
|
||||||
"\n"
|
|
||||||
"This program can erase and/or format SD/SDHC cards.\n"
|
|
||||||
"\n"
|
|
||||||
"Erase uses the card's fast flash erase command.\n"
|
|
||||||
"Flash erase sets all data to 0X00 for most cards\n"
|
|
||||||
"and 0XFF for a few vendor's cards.\n"
|
|
||||||
"\n"
|
|
||||||
"Cards larger than 2 GB will be formatted FAT32 and\n"
|
|
||||||
"smaller cards will be formatted FAT16.\n"
|
|
||||||
"\n"
|
|
||||||
"Warning, all data on the card will be erased.\n"
|
|
||||||
"Enter 'Y' to continue: ");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
c = Serial.read();
|
|
||||||
cout << c << endl;
|
|
||||||
if (c != 'Y') {
|
|
||||||
cout << F("Quiting, you did not enter 'Y'.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Read any existing Serial data.
|
|
||||||
do {
|
|
||||||
delay(10);
|
|
||||||
} while (Serial.available() && Serial.read() >= 0);
|
|
||||||
|
|
||||||
cout << F(
|
|
||||||
"\n"
|
|
||||||
"Options are:\n"
|
|
||||||
"E - erase the card and skip formatting.\n"
|
|
||||||
"F - erase and then format the card. (recommended)\n"
|
|
||||||
"Q - quick format the card without erase.\n"
|
|
||||||
"\n"
|
|
||||||
"Enter option: ");
|
|
||||||
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
c = Serial.read();
|
|
||||||
cout << c << endl;
|
|
||||||
if (!strchr("EFQ", c)) {
|
|
||||||
cout << F("Quiting, invalid option entered.") << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if USE_SDIO
|
|
||||||
if (!card.begin()) {
|
|
||||||
sdError("card.begin failed");
|
|
||||||
}
|
|
||||||
#else // USE_SDIO
|
|
||||||
if (!card.begin(chipSelect, SPI_SPEED)) {
|
|
||||||
cout << F(
|
|
||||||
"\nSD initialization failure!\n"
|
|
||||||
"Is the SD card inserted correctly?\n"
|
|
||||||
"Is chip select correct at the top of this program?\n");
|
|
||||||
sdError("card.begin failed");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
cardSizeBlocks = card.cardSize();
|
|
||||||
if (cardSizeBlocks == 0) {
|
|
||||||
sdError("cardSize");
|
|
||||||
}
|
|
||||||
cardCapacityMB = (cardSizeBlocks + 2047)/2048;
|
|
||||||
|
|
||||||
cout << F("Card Size: ") << setprecision(0) << 1.048576*cardCapacityMB;
|
|
||||||
cout << F(" MB, (MB = 1,000,000 bytes)") << endl;
|
|
||||||
|
|
||||||
if (c == 'E' || c == 'F') {
|
|
||||||
eraseCard();
|
|
||||||
}
|
|
||||||
if (c == 'F' || c == 'Q') {
|
|
||||||
formatCard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void loop() {}
|
|
@ -1,248 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program attempts to initialize an SD card and analyze its structure.
|
|
||||||
*/
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
#include "sdios.h"
|
|
||||||
#error Use new Version 2 SdInfo
|
|
||||||
// Set USE_SDIO to zero for SPI card access.
|
|
||||||
#define USE_SDIO 0
|
|
||||||
/*
|
|
||||||
* SD chip select pin. Common values are:
|
|
||||||
*
|
|
||||||
* Arduino Ethernet shield, pin 4.
|
|
||||||
* SparkFun SD shield, pin 8.
|
|
||||||
* Adafruit SD shields and modules, pin 10.
|
|
||||||
* Default SD chip select is the SPI SS pin.
|
|
||||||
*/
|
|
||||||
const uint8_t SD_CHIP_SELECT = SS;
|
|
||||||
/*
|
|
||||||
* Set DISABLE_CHIP_SELECT to disable a second SPI device.
|
|
||||||
* For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
|
|
||||||
* to 10 to disable the Ethernet controller.
|
|
||||||
*/
|
|
||||||
const int8_t DISABLE_CHIP_SELECT = -1;
|
|
||||||
|
|
||||||
#if USE_SDIO
|
|
||||||
// Use faster SdioCardEX
|
|
||||||
SdFatSdioEX sd;
|
|
||||||
// SdFatSdio sd;
|
|
||||||
#else // USE_SDIO
|
|
||||||
SdFat sd;
|
|
||||||
#endif // USE_SDIO
|
|
||||||
|
|
||||||
// serial output steam
|
|
||||||
ArduinoOutStream cout(Serial);
|
|
||||||
|
|
||||||
// global for card size
|
|
||||||
uint32_t cardSize;
|
|
||||||
|
|
||||||
// global for card erase size
|
|
||||||
uint32_t eraseSize;
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// store error strings in flash
|
|
||||||
#define sdErrorMsg(msg) sd.errorPrint(F(msg));
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
uint8_t cidDmp() {
|
|
||||||
cid_t cid;
|
|
||||||
if (!sd.card()->readCID(&cid)) {
|
|
||||||
sdErrorMsg("readCID failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cout << F("\nManufacturer ID: ");
|
|
||||||
cout << hex << int(cid.mid) << dec << endl;
|
|
||||||
cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
|
|
||||||
cout << F("Product: ");
|
|
||||||
for (uint8_t i = 0; i < 5; i++) {
|
|
||||||
cout << cid.pnm[i];
|
|
||||||
}
|
|
||||||
cout << F("\nVersion: ");
|
|
||||||
cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
|
|
||||||
cout << F("Serial number: ") << hex << cid.psn << dec << endl;
|
|
||||||
cout << F("Manufacturing date: ");
|
|
||||||
cout << int(cid.mdt_month) << '/';
|
|
||||||
cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
|
|
||||||
cout << endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
uint8_t csdDmp() {
|
|
||||||
csd_t csd;
|
|
||||||
uint8_t eraseSingleBlock;
|
|
||||||
if (!sd.card()->readCSD(&csd)) {
|
|
||||||
sdErrorMsg("readCSD failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (csd.v1.csd_ver == 0) {
|
|
||||||
eraseSingleBlock = csd.v1.erase_blk_en;
|
|
||||||
eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
|
|
||||||
} else if (csd.v2.csd_ver == 1) {
|
|
||||||
eraseSingleBlock = csd.v2.erase_blk_en;
|
|
||||||
eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low;
|
|
||||||
} else {
|
|
||||||
cout << F("csd version error\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
eraseSize++;
|
|
||||||
cout << F("cardSize: ") << 0.000512*cardSize;
|
|
||||||
cout << F(" MB (MB = 1,000,000 bytes)\n");
|
|
||||||
|
|
||||||
cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
|
|
||||||
cout << F("eraseSingleBlock: ");
|
|
||||||
if (eraseSingleBlock) {
|
|
||||||
cout << F("true\n");
|
|
||||||
} else {
|
|
||||||
cout << F("false\n");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// print partition table
|
|
||||||
uint8_t partDmp() {
|
|
||||||
mbr_t mbr;
|
|
||||||
if (!sd.card()->readBlock(0, (uint8_t*)&mbr)) {
|
|
||||||
sdErrorMsg("read MBR failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (uint8_t ip = 1; ip < 5; ip++) {
|
|
||||||
part_t *pt = &mbr.part[ip - 1];
|
|
||||||
if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) {
|
|
||||||
cout << F("\nNo MBR. Assuming Super Floppy format.\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << F("\nSD Partition Table\n");
|
|
||||||
cout << F("part,boot,type,start,length\n");
|
|
||||||
for (uint8_t ip = 1; ip < 5; ip++) {
|
|
||||||
part_t *pt = &mbr.part[ip - 1];
|
|
||||||
cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type);
|
|
||||||
cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void volDmp() {
|
|
||||||
cout << F("\nVolume is FAT") << int(sd.vol()->fatType()) << endl;
|
|
||||||
cout << F("blocksPerCluster: ") << int(sd.vol()->blocksPerCluster()) << endl;
|
|
||||||
cout << F("clusterCount: ") << sd.vol()->clusterCount() << endl;
|
|
||||||
cout << F("freeClusters: ");
|
|
||||||
uint32_t volFree = sd.vol()->freeClusterCount();
|
|
||||||
cout << volFree << endl;
|
|
||||||
float fs = 0.000512*volFree*sd.vol()->blocksPerCluster();
|
|
||||||
cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n");
|
|
||||||
cout << F("fatStartBlock: ") << sd.vol()->fatStartBlock() << endl;
|
|
||||||
cout << F("fatCount: ") << int(sd.vol()->fatCount()) << endl;
|
|
||||||
cout << F("blocksPerFat: ") << sd.vol()->blocksPerFat() << endl;
|
|
||||||
cout << F("rootDirStart: ") << sd.vol()->rootDirStart() << endl;
|
|
||||||
cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl;
|
|
||||||
if (sd.vol()->dataStartBlock() % eraseSize) {
|
|
||||||
cout << F("Data area is not aligned on flash erase boundaries!\n");
|
|
||||||
cout << F("Download and use formatter from www.sdcard.org!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
// use uppercase in hex and use 0X base prefix
|
|
||||||
cout << uppercase << showbase << endl;
|
|
||||||
|
|
||||||
// F stores strings in flash to save RAM
|
|
||||||
cout << F("SdFat version: ") << SD_FAT_VERSION << endl;
|
|
||||||
#if !USE_SDIO
|
|
||||||
if (DISABLE_CHIP_SELECT < 0) {
|
|
||||||
cout << F(
|
|
||||||
"\nAssuming the SD is the only SPI device.\n"
|
|
||||||
"Edit DISABLE_CHIP_SELECT to disable another device.\n");
|
|
||||||
} else {
|
|
||||||
cout << F("\nDisabling SPI device on pin ");
|
|
||||||
cout << int(DISABLE_CHIP_SELECT) << endl;
|
|
||||||
pinMode(DISABLE_CHIP_SELECT, OUTPUT);
|
|
||||||
digitalWrite(DISABLE_CHIP_SELECT, HIGH);
|
|
||||||
}
|
|
||||||
cout << F("\nAssuming the SD chip select pin is: ") <<int(SD_CHIP_SELECT);
|
|
||||||
cout << F("\nEdit SD_CHIP_SELECT to change the SD chip select pin.\n");
|
|
||||||
#endif // !USE_SDIO
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void loop() {
|
|
||||||
// Read any existing Serial data.
|
|
||||||
do {
|
|
||||||
delay(10);
|
|
||||||
} while (Serial.available() && Serial.read() >= 0);
|
|
||||||
|
|
||||||
// F stores strings in flash to save RAM
|
|
||||||
cout << F("\ntype any character to start\n");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t t = millis();
|
|
||||||
#if USE_SDIO
|
|
||||||
if (!sd.cardBegin()) {
|
|
||||||
sdErrorMsg("\ncardBegin failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#else // USE_SDIO
|
|
||||||
// Initialize at the highest speed supported by the board that is
|
|
||||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
|
||||||
if (!sd.cardBegin(SD_CHIP_SELECT, SD_SCK_MHZ(50))) {
|
|
||||||
sdErrorMsg("cardBegin failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif // USE_SDIO
|
|
||||||
t = millis() - t;
|
|
||||||
|
|
||||||
cardSize = sd.card()->cardSize();
|
|
||||||
if (cardSize == 0) {
|
|
||||||
sdErrorMsg("cardSize failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cout << F("\ninit time: ") << t << " ms" << endl;
|
|
||||||
cout << F("\nCard type: ");
|
|
||||||
switch (sd.card()->type()) {
|
|
||||||
case SD_CARD_TYPE_SD1:
|
|
||||||
cout << F("SD1\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SD_CARD_TYPE_SD2:
|
|
||||||
cout << F("SD2\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SD_CARD_TYPE_SDHC:
|
|
||||||
if (cardSize < 70000000) {
|
|
||||||
cout << F("SDHC\n");
|
|
||||||
} else {
|
|
||||||
cout << F("SDXC\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
cout << F("Unknown\n");
|
|
||||||
}
|
|
||||||
if (!cidDmp()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!csdDmp()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint32_t ocr;
|
|
||||||
if (!sd.card()->readOCR(&ocr)) {
|
|
||||||
sdErrorMsg("\nreadOCR failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cout << F("OCR: ") << hex << ocr << dec << endl;
|
|
||||||
if (!partDmp()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!sd.fsBegin()) {
|
|
||||||
sdErrorMsg("\nFile System initialization failed.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
volDmp();
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
// An example of the SdFatSoftSpi template class.
|
|
||||||
// This example is for an Adafruit Data Logging Shield on a Mega.
|
|
||||||
// Software SPI is required on Mega since this shield connects to pins 10-13.
|
|
||||||
// This example will also run on an Uno and other boards using software SPI.
|
|
||||||
//
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
#error See Version 2 software SPI example
|
|
||||||
#if ENABLE_SOFTWARE_SPI_CLASS // Must be set in SdFat/SdFatConfig.h
|
|
||||||
//
|
|
||||||
// Pin numbers in templates must be constants.
|
|
||||||
const uint8_t SOFT_MISO_PIN = 12;
|
|
||||||
const uint8_t SOFT_MOSI_PIN = 11;
|
|
||||||
const uint8_t SOFT_SCK_PIN = 13;
|
|
||||||
//
|
|
||||||
// Chip select may be constant or RAM variable.
|
|
||||||
const uint8_t SD_CHIP_SELECT_PIN = 10;
|
|
||||||
|
|
||||||
// SdFat software SPI template
|
|
||||||
SdFatSoftSpi<SOFT_MISO_PIN, SOFT_MOSI_PIN, SOFT_SCK_PIN> sd;
|
|
||||||
|
|
||||||
// Test file.
|
|
||||||
SdFile file;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
Serial.println("Type any character to start");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sd.begin(SD_CHIP_SELECT_PIN)) {
|
|
||||||
sd.initErrorHalt();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file.open("SoftSPI.txt", O_RDWR | O_CREAT)) {
|
|
||||||
sd.errorHalt(F("open failed"));
|
|
||||||
}
|
|
||||||
file.println(F("This line was printed using software SPI."));
|
|
||||||
|
|
||||||
file.rewind();
|
|
||||||
|
|
||||||
while (file.available()) {
|
|
||||||
Serial.write(file.read());
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
Serial.println(F("Done."));
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void loop() {}
|
|
||||||
#else // ENABLE_SOFTWARE_SPI_CLASS
|
|
||||||
#error ENABLE_SOFTWARE_SPI_CLASS must be set non-zero in SdFat/SdFatConfig.h
|
|
||||||
#endif //ENABLE_SOFTWARE_SPI_CLASS
|
|
@ -1,169 +0,0 @@
|
|||||||
// Simple performance test for Teensy 3.5/3.6 SDHC.
|
|
||||||
// Demonstrates yield() efficiency.
|
|
||||||
|
|
||||||
// Warning SdFatSdio and SdFatSdioEX normally should
|
|
||||||
// not both be used in a program.
|
|
||||||
// Each has its own cache and member variables.
|
|
||||||
|
|
||||||
#include "SdFat.h"
|
|
||||||
#error See Version 2 SDIO example
|
|
||||||
// 32 KiB buffer.
|
|
||||||
const size_t BUF_DIM = 32768;
|
|
||||||
|
|
||||||
// 8 MiB file.
|
|
||||||
const uint32_t FILE_SIZE = 256UL*BUF_DIM;
|
|
||||||
|
|
||||||
SdFatSdio sd;
|
|
||||||
|
|
||||||
SdFatSdioEX sdEx;
|
|
||||||
|
|
||||||
File file;
|
|
||||||
|
|
||||||
uint8_t buf[BUF_DIM];
|
|
||||||
|
|
||||||
// buffer as uint32_t
|
|
||||||
uint32_t* buf32 = (uint32_t*)buf;
|
|
||||||
|
|
||||||
// Total usec in read/write calls.
|
|
||||||
uint32_t totalMicros = 0;
|
|
||||||
// Time in yield() function.
|
|
||||||
uint32_t yieldMicros = 0;
|
|
||||||
// Number of yield calls.
|
|
||||||
uint32_t yieldCalls = 0;
|
|
||||||
// Max busy time for single yield call.
|
|
||||||
uint32_t yieldMaxUsec = 0;
|
|
||||||
// Control access to the two versions of SdFat.
|
|
||||||
bool useEx = false;
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool sdBusy() {
|
|
||||||
return useEx ? sdEx.card()->isBusy() : sd.card()->isBusy();
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void errorHalt(const char* msg) {
|
|
||||||
if (useEx) {
|
|
||||||
sdEx.errorHalt(msg);
|
|
||||||
} else {
|
|
||||||
sd.errorHalt(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
uint32_t kHzSdClk() {
|
|
||||||
return useEx ? sdEx.card()->kHzSdClk() : sd.card()->kHzSdClk();
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Replace "weak" system yield() function.
|
|
||||||
void yield() {
|
|
||||||
// Only count cardBusy time.
|
|
||||||
if (!sdBusy()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint32_t m = micros();
|
|
||||||
yieldCalls++;
|
|
||||||
while (sdBusy()) {
|
|
||||||
// Do something here.
|
|
||||||
}
|
|
||||||
m = micros() - m;
|
|
||||||
if (m > yieldMaxUsec) {
|
|
||||||
yieldMaxUsec = m;
|
|
||||||
}
|
|
||||||
yieldMicros += m;
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void runTest() {
|
|
||||||
// Zero Stats
|
|
||||||
totalMicros = 0;
|
|
||||||
yieldMicros = 0;
|
|
||||||
yieldCalls = 0;
|
|
||||||
yieldMaxUsec = 0;
|
|
||||||
if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) {
|
|
||||||
errorHalt("open failed");
|
|
||||||
}
|
|
||||||
Serial.println("\nsize,write,read");
|
|
||||||
Serial.println("bytes,KB/sec,KB/sec");
|
|
||||||
for (size_t nb = 512; nb <= BUF_DIM; nb *= 2) {
|
|
||||||
file.truncate(0);
|
|
||||||
uint32_t nRdWr = FILE_SIZE/nb;
|
|
||||||
Serial.print(nb);
|
|
||||||
Serial.print(',');
|
|
||||||
uint32_t t = micros();
|
|
||||||
for (uint32_t n = 0; n < nRdWr; n++) {
|
|
||||||
// Set start and end of buffer.
|
|
||||||
buf32[0] = n;
|
|
||||||
buf32[nb/4 - 1] = n;
|
|
||||||
if (nb != file.write(buf, nb)) {
|
|
||||||
errorHalt("write failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t = micros() - t;
|
|
||||||
totalMicros += t;
|
|
||||||
Serial.print(1000.0*FILE_SIZE/t);
|
|
||||||
Serial.print(',');
|
|
||||||
file.rewind();
|
|
||||||
t = micros();
|
|
||||||
|
|
||||||
for (uint32_t n = 0; n < nRdWr; n++) {
|
|
||||||
if ((int)nb != file.read(buf, nb)) {
|
|
||||||
errorHalt("read failed");
|
|
||||||
}
|
|
||||||
// crude check of data.
|
|
||||||
if (buf32[0] != n || buf32[nb/4 - 1] != n) {
|
|
||||||
errorHalt("data check");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t = micros() - t;
|
|
||||||
totalMicros += t;
|
|
||||||
Serial.println(1000.0*FILE_SIZE/t);
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
Serial.print("\ntotalMicros ");
|
|
||||||
Serial.println(totalMicros);
|
|
||||||
Serial.print("yieldMicros ");
|
|
||||||
Serial.println(yieldMicros);
|
|
||||||
Serial.print("yieldCalls ");
|
|
||||||
Serial.println(yieldCalls);
|
|
||||||
Serial.print("yieldMaxUsec ");
|
|
||||||
Serial.println(yieldMaxUsec);
|
|
||||||
Serial.print("kHzSdClk ");
|
|
||||||
Serial.println(kHzSdClk());
|
|
||||||
Serial.println("Done");
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
while (!Serial) {
|
|
||||||
}
|
|
||||||
Serial.println("SdFatSdioEX uses extended multi-block transfers without DMA.");
|
|
||||||
Serial.println("SdFatSdio uses a traditional DMA SDIO implementation.");
|
|
||||||
Serial.println("Note the difference is speed and busy yield time.\n");
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void loop() {
|
|
||||||
do {
|
|
||||||
delay(10);
|
|
||||||
} while (Serial.available() && Serial.read());
|
|
||||||
|
|
||||||
Serial.println("Type '1' for SdFatSdioEX or '2' for SdFatSdio");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
}
|
|
||||||
char c = Serial.read();
|
|
||||||
if (c != '1' && c != '2') {
|
|
||||||
Serial.println("Invalid input");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (c =='1') {
|
|
||||||
useEx = true;
|
|
||||||
if (!sdEx.begin()) {
|
|
||||||
sd.initErrorHalt("SdFatSdioEX begin() failed");
|
|
||||||
}
|
|
||||||
// make sdEx the current volume.
|
|
||||||
sdEx.chvol();
|
|
||||||
} else {
|
|
||||||
useEx = false;
|
|
||||||
if (!sd.begin()) {
|
|
||||||
sd.initErrorHalt("SdFatSdio begin() failed");
|
|
||||||
}
|
|
||||||
// make sd the current volume.
|
|
||||||
sd.chvol();
|
|
||||||
}
|
|
||||||
runTest();
|
|
||||||
}
|
|
@ -1,222 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program is a simple binary write/read benchmark.
|
|
||||||
*/
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
#include "sdios.h"
|
|
||||||
#include "FreeStack.h"
|
|
||||||
|
|
||||||
// Set USE_SDIO to zero for SPI card access.
|
|
||||||
#define USE_SDIO 0
|
|
||||||
|
|
||||||
// SD chip select pin
|
|
||||||
const uint8_t chipSelect = SS;
|
|
||||||
|
|
||||||
// Size of read/write.
|
|
||||||
const size_t BUF_SIZE = 512;
|
|
||||||
|
|
||||||
// File size in MB where MB = 1,000,000 bytes.
|
|
||||||
const uint32_t FILE_SIZE_MB = 5;
|
|
||||||
|
|
||||||
// Write pass count.
|
|
||||||
const uint8_t WRITE_COUNT = 2;
|
|
||||||
|
|
||||||
// Read pass count.
|
|
||||||
const uint8_t READ_COUNT = 2;
|
|
||||||
//==============================================================================
|
|
||||||
// End of configuration constants.
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// File size in bytes.
|
|
||||||
const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB;
|
|
||||||
|
|
||||||
uint8_t buf[BUF_SIZE];
|
|
||||||
|
|
||||||
// file system
|
|
||||||
#if USE_SDIO
|
|
||||||
// Traditional DMA version.
|
|
||||||
// SdFatSdio sd;
|
|
||||||
// Faster version.
|
|
||||||
SdFatSdioEX sd;
|
|
||||||
#else // USE_SDIO
|
|
||||||
SdFat sd;
|
|
||||||
#endif // USE_SDIO
|
|
||||||
|
|
||||||
// Set ENABLE_EXTENDED_TRANSFER_CLASS to use extended SD I/O.
|
|
||||||
// Requires dedicated use of the SPI bus.
|
|
||||||
// SdFatEX sd;
|
|
||||||
|
|
||||||
// Set ENABLE_SOFTWARE_SPI_CLASS to use software SPI.
|
|
||||||
// Args are misoPin, mosiPin, sckPin.
|
|
||||||
// SdFatSoftSpi<6, 7, 5> sd;
|
|
||||||
|
|
||||||
// test file
|
|
||||||
SdFile file;
|
|
||||||
|
|
||||||
// Serial output stream
|
|
||||||
ArduinoOutStream cout(Serial);
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Store error strings in flash to save RAM.
|
|
||||||
#define error(s) sd.errorHalt(F(s))
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void cidDmp() {
|
|
||||||
cid_t cid;
|
|
||||||
if (!sd.card()->readCID(&cid)) {
|
|
||||||
error("readCID failed");
|
|
||||||
}
|
|
||||||
cout << F("\nManufacturer ID: ");
|
|
||||||
cout << hex << int(cid.mid) << dec << endl;
|
|
||||||
cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
|
|
||||||
cout << F("Product: ");
|
|
||||||
for (uint8_t i = 0; i < 5; i++) {
|
|
||||||
cout << cid.pnm[i];
|
|
||||||
}
|
|
||||||
cout << F("\nVersion: ");
|
|
||||||
cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
|
|
||||||
cout << F("Serial number: ") << hex << cid.psn << dec << endl;
|
|
||||||
cout << F("Manufacturing date: ");
|
|
||||||
cout << int(cid.mdt_month) << '/';
|
|
||||||
cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
delay(1000);
|
|
||||||
cout << F("\nUse a freshly formatted SD for best performance.\n");
|
|
||||||
|
|
||||||
// use uppercase in hex and use 0X base prefix
|
|
||||||
cout << uppercase << showbase << endl;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void loop() {
|
|
||||||
float s;
|
|
||||||
uint32_t t;
|
|
||||||
uint32_t maxLatency;
|
|
||||||
uint32_t minLatency;
|
|
||||||
uint32_t totalLatency;
|
|
||||||
|
|
||||||
// Discard any input.
|
|
||||||
do {
|
|
||||||
delay(10);
|
|
||||||
} while (Serial.available() && Serial.read() >= 0);
|
|
||||||
|
|
||||||
// F( stores strings in flash to save RAM
|
|
||||||
cout << F("Type any character to start\n");
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
cout << F("chipSelect: ") << int(chipSelect) << endl;
|
|
||||||
cout << F("FreeStack: ") << FreeStack() << endl;
|
|
||||||
|
|
||||||
#if USE_SDIO
|
|
||||||
if (!sd.begin()) {
|
|
||||||
sd.initErrorHalt();
|
|
||||||
}
|
|
||||||
#else // USE_SDIO
|
|
||||||
// Initialize at the highest speed supported by the board that is
|
|
||||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
|
||||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
|
||||||
sd.initErrorHalt();
|
|
||||||
}
|
|
||||||
#endif // USE_SDIO
|
|
||||||
cout << F("Type is FAT") << int(sd.vol()->fatType()) << endl;
|
|
||||||
cout << F("Card size: ") << sd.card()->cardSize()*512E-9;
|
|
||||||
cout << F(" GB (GB = 1E9 bytes)") << endl;
|
|
||||||
|
|
||||||
cidDmp();
|
|
||||||
|
|
||||||
// open or create file - truncate existing file.
|
|
||||||
if (!file.open("bench.dat", O_RDWR | O_CREAT | O_TRUNC)) {
|
|
||||||
error("open failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill buf with known data
|
|
||||||
for (size_t i = 0; i < (BUF_SIZE-2); i++) {
|
|
||||||
buf[i] = 'A' + (i % 26);
|
|
||||||
}
|
|
||||||
buf[BUF_SIZE-2] = '\r';
|
|
||||||
buf[BUF_SIZE-1] = '\n';
|
|
||||||
|
|
||||||
cout << F("File size ") << FILE_SIZE_MB << F(" MB\n");
|
|
||||||
cout << F("Buffer size ") << BUF_SIZE << F(" bytes\n");
|
|
||||||
cout << F("Starting write test, please wait.") << endl << endl;
|
|
||||||
|
|
||||||
// do write test
|
|
||||||
uint32_t n = FILE_SIZE/sizeof(buf);
|
|
||||||
cout <<F("write speed and latency") << endl;
|
|
||||||
cout << F("speed,max,min,avg") << endl;
|
|
||||||
cout << F("KB/Sec,usec,usec,usec") << endl;
|
|
||||||
for (uint8_t nTest = 0; nTest < WRITE_COUNT; nTest++) {
|
|
||||||
file.truncate(0);
|
|
||||||
maxLatency = 0;
|
|
||||||
minLatency = 9999999;
|
|
||||||
totalLatency = 0;
|
|
||||||
t = millis();
|
|
||||||
for (uint32_t i = 0; i < n; i++) {
|
|
||||||
uint32_t m = micros();
|
|
||||||
if (file.write(buf, sizeof(buf)) != sizeof(buf)) {
|
|
||||||
sd.errorPrint("write failed");
|
|
||||||
file.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m = micros() - m;
|
|
||||||
if (maxLatency < m) {
|
|
||||||
maxLatency = m;
|
|
||||||
}
|
|
||||||
if (minLatency > m) {
|
|
||||||
minLatency = m;
|
|
||||||
}
|
|
||||||
totalLatency += m;
|
|
||||||
}
|
|
||||||
file.sync();
|
|
||||||
t = millis() - t;
|
|
||||||
s = file.fileSize();
|
|
||||||
cout << s/t <<',' << maxLatency << ',' << minLatency;
|
|
||||||
cout << ',' << totalLatency/n << endl;
|
|
||||||
}
|
|
||||||
cout << endl << F("Starting read test, please wait.") << endl;
|
|
||||||
cout << endl <<F("read speed and latency") << endl;
|
|
||||||
cout << F("speed,max,min,avg") << endl;
|
|
||||||
cout << F("KB/Sec,usec,usec,usec") << endl;
|
|
||||||
|
|
||||||
// do read test
|
|
||||||
for (uint8_t nTest = 0; nTest < READ_COUNT; nTest++) {
|
|
||||||
file.rewind();
|
|
||||||
maxLatency = 0;
|
|
||||||
minLatency = 9999999;
|
|
||||||
totalLatency = 0;
|
|
||||||
t = millis();
|
|
||||||
for (uint32_t i = 0; i < n; i++) {
|
|
||||||
buf[BUF_SIZE-1] = 0;
|
|
||||||
uint32_t m = micros();
|
|
||||||
int32_t nr = file.read(buf, sizeof(buf));
|
|
||||||
if (nr != sizeof(buf)) {
|
|
||||||
sd.errorPrint("read failed");
|
|
||||||
file.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m = micros() - m;
|
|
||||||
if (maxLatency < m) {
|
|
||||||
maxLatency = m;
|
|
||||||
}
|
|
||||||
if (minLatency > m) {
|
|
||||||
minLatency = m;
|
|
||||||
}
|
|
||||||
totalLatency += m;
|
|
||||||
if (buf[BUF_SIZE-1] != '\n') {
|
|
||||||
error("data check");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s = file.fileSize();
|
|
||||||
t = millis() - t;
|
|
||||||
cout << s/t <<',' << maxLatency << ',' << minLatency;
|
|
||||||
cout << ',' << totalLatency/n << endl;
|
|
||||||
}
|
|
||||||
cout << endl << F("Done") << endl;
|
|
||||||
file.close();
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program demonstrates use of SdFile::rename()
|
|
||||||
* and SdFat::rename().
|
|
||||||
*/
|
|
||||||
#include <SPI.h>
|
|
||||||
#include "SdFat.h"
|
|
||||||
#include "sdios.h"
|
|
||||||
|
|
||||||
// SD chip select pin
|
|
||||||
const uint8_t chipSelect = SS;
|
|
||||||
|
|
||||||
// file system
|
|
||||||
SdFat sd;
|
|
||||||
|
|
||||||
// Serial print stream
|
|
||||||
ArduinoOutStream cout(Serial);
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// store error strings in flash to save RAM
|
|
||||||
#define error(s) sd.errorHalt(F(s))
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// Wait for USB Serial
|
|
||||||
while (!Serial) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
cout << F("Insert an empty SD. Type any character to start.") << endl;
|
|
||||||
while (!Serial.available()) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize at the highest speed supported by the board that is
|
|
||||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
|
||||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
|
||||||
sd.initErrorHalt();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove file/dirs from previous run.
|
|
||||||
if (sd.exists("dir2/DIR3/NAME3.txt")) {
|
|
||||||
cout << F("Removing /dir2/DIR3/NAME3.txt") << endl;
|
|
||||||
if (!sd.remove("dir2/DIR3/NAME3.txt") ||
|
|
||||||
!sd.rmdir("dir2/DIR3/") ||
|
|
||||||
!sd.rmdir("dir2/")) {
|
|
||||||
error("remove/rmdir failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// create a file and write one line to the file
|
|
||||||
SdFile file("Name1.txt", O_WRONLY | O_CREAT);
|
|
||||||
if (!file.isOpen()) {
|
|
||||||
error("Name1.txt");
|
|
||||||
}
|
|
||||||
file.println("A test line for Name1.txt");
|
|
||||||
|
|
||||||
// rename the file name2.txt and add a line.
|
|
||||||
if (!file.rename("name2.txt")) {
|
|
||||||
error("name2.txt");
|
|
||||||
}
|
|
||||||
file.println("A test line for name2.txt");
|
|
||||||
|
|
||||||
// list files
|
|
||||||
cout << F("------") << endl;
|
|
||||||
sd.ls(LS_R);
|
|
||||||
|
|
||||||
// make a new directory - "Dir1"
|
|
||||||
if (!sd.mkdir("Dir1")) {
|
|
||||||
error("Dir1");
|
|
||||||
}
|
|
||||||
|
|
||||||
// move file into Dir1, rename it NAME3.txt and add a line
|
|
||||||
if (!file.rename("Dir1/NAME3.txt")) {
|
|
||||||
error("NAME3.txt");
|
|
||||||
}
|
|
||||||
file.println("A line for Dir1/NAME3.txt");
|
|
||||||
|
|
||||||
// list files
|
|
||||||
cout << F("------") << endl;
|
|
||||||
sd.ls(LS_R);
|
|
||||||
|
|
||||||
// make directory "dir2"
|
|
||||||
if (!sd.mkdir("dir2")) {
|
|
||||||
error("dir2");
|
|
||||||
}
|
|
||||||
|
|
||||||
// close file before rename(oldPath, newPath)
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// move Dir1 into dir2 and rename it DIR3
|
|
||||||
if (!sd.rename("Dir1", "dir2/DIR3")) {
|
|
||||||
error("dir2/DIR3");
|
|
||||||
}
|
|
||||||
|
|
||||||
// open file for append in new location and add a line
|
|
||||||
if (!file.open("dir2/DIR3/NAME3.txt", O_WRONLY | O_APPEND)) {
|
|
||||||
error("dir2/DIR3/NAME3.txt");
|
|
||||||
}
|
|
||||||
file.println("A line for dir2/DIR3/NAME3.txt");
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// list files
|
|
||||||
cout << F("------") << endl;
|
|
||||||
sd.ls(LS_R);
|
|
||||||
|
|
||||||
cout << F("Done") << endl;
|
|
||||||
}
|
|
||||||
void loop() {}
|
|
Binary file not shown.
@ -1,89 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2011-2020 Bill Greiman
|
|
||||||
* This file is part of the SdFat library for SD memory cards.
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "PrintBasic.h"
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
size_t PrintBasic::print(long n, uint8_t base) {
|
|
||||||
if (n < 0 && base == 10) {
|
|
||||||
return print('-') + printNum(-n, base);
|
|
||||||
}
|
|
||||||
return printNum(n, base);
|
|
||||||
}
|
|
||||||
size_t PrintBasic::printNum(unsigned long n, uint8_t base) {
|
|
||||||
const uint8_t DIM = 8*sizeof(long);
|
|
||||||
char buf[DIM];
|
|
||||||
char *str = &buf[DIM];
|
|
||||||
|
|
||||||
if (base < 2) return 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
char c = n%base;
|
|
||||||
n /= base;
|
|
||||||
*--str = c + (c < 10 ? '0' : 'A' - 10);
|
|
||||||
} while (n);
|
|
||||||
return write(str, &buf[DIM] - str);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t PrintBasic::printDouble(double n, uint8_t prec) {
|
|
||||||
// Max printable 32-bit floating point number. AVR uses 32-bit double.
|
|
||||||
const double maxfp = static_cast<double>(0XFFFFFF00UL);
|
|
||||||
size_t rtn = 0;
|
|
||||||
|
|
||||||
if (isnan(n)) {
|
|
||||||
return write("NaN");
|
|
||||||
}
|
|
||||||
if (n < 0) {
|
|
||||||
n = -n;
|
|
||||||
rtn += print('-');
|
|
||||||
}
|
|
||||||
if (isinf(n)) {
|
|
||||||
return rtn + write("Inf");
|
|
||||||
}
|
|
||||||
if (n > maxfp) {
|
|
||||||
return rtn + write("Ovf");
|
|
||||||
}
|
|
||||||
|
|
||||||
double round = 0.5;
|
|
||||||
for (uint8_t i = 0; i < prec; ++i) {
|
|
||||||
round *= 0.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
n += round;
|
|
||||||
|
|
||||||
uint32_t whole = (uint32_t)n;
|
|
||||||
rtn += print(whole);
|
|
||||||
|
|
||||||
if (prec) {
|
|
||||||
rtn += print('.');
|
|
||||||
double fraction = n - static_cast<double>(whole);
|
|
||||||
for (uint8_t i = 0; i < prec; i++) {
|
|
||||||
fraction *= 10.0;
|
|
||||||
uint8_t digit = fraction;
|
|
||||||
rtn += print(digit);
|
|
||||||
fraction -= digit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rtn;
|
|
||||||
}
|
|
@ -1,490 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2011-2021 Bill Greiman
|
|
||||||
* This file is part of the SdFat library for SD memory cards.
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef SdCardInfo_h
|
|
||||||
#define SdCardInfo_h
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../common/SysCall.h"
|
|
||||||
// Based on the document:
|
|
||||||
//
|
|
||||||
// SD Specifications
|
|
||||||
// Part 1
|
|
||||||
// Physical Layer
|
|
||||||
// Simplified Specification
|
|
||||||
// Version 5.00
|
|
||||||
// Aug 10, 2016
|
|
||||||
//
|
|
||||||
// https://www.sdcard.org/downloads/pls/
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// SD card errors
|
|
||||||
// See the SD Specification for command info.
|
|
||||||
#define SD_ERROR_CODE_LIST\
|
|
||||||
SD_CARD_ERROR(NONE, "No error")\
|
|
||||||
SD_CARD_ERROR(CMD0, "Card reset failed")\
|
|
||||||
SD_CARD_ERROR(CMD2, "SDIO read CID")\
|
|
||||||
SD_CARD_ERROR(CMD3, "SDIO publish RCA")\
|
|
||||||
SD_CARD_ERROR(CMD6, "Switch card function")\
|
|
||||||
SD_CARD_ERROR(CMD7, "SDIO card select")\
|
|
||||||
SD_CARD_ERROR(CMD8, "Send and check interface settings")\
|
|
||||||
SD_CARD_ERROR(CMD9, "Read CSD data")\
|
|
||||||
SD_CARD_ERROR(CMD10, "Read CID data")\
|
|
||||||
SD_CARD_ERROR(CMD12, "Stop multiple block read")\
|
|
||||||
SD_CARD_ERROR(CMD13, "Read card status")\
|
|
||||||
SD_CARD_ERROR(CMD17, "Read single block")\
|
|
||||||
SD_CARD_ERROR(CMD18, "Read multiple blocks")\
|
|
||||||
SD_CARD_ERROR(CMD24, "Write single block")\
|
|
||||||
SD_CARD_ERROR(CMD25, "Write multiple blocks")\
|
|
||||||
SD_CARD_ERROR(CMD32, "Set first erase block")\
|
|
||||||
SD_CARD_ERROR(CMD33, "Set last erase block")\
|
|
||||||
SD_CARD_ERROR(CMD38, "Erase selected blocks")\
|
|
||||||
SD_CARD_ERROR(CMD58, "Read OCR register")\
|
|
||||||
SD_CARD_ERROR(CMD59, "Set CRC mode")\
|
|
||||||
SD_CARD_ERROR(ACMD6, "Set SDIO bus width")\
|
|
||||||
SD_CARD_ERROR(ACMD13, "Read extended status")\
|
|
||||||
SD_CARD_ERROR(ACMD23, "Set pre-erased count")\
|
|
||||||
SD_CARD_ERROR(ACMD41, "Activate card initialization")\
|
|
||||||
SD_CARD_ERROR(READ_TOKEN, "Bad read data token")\
|
|
||||||
SD_CARD_ERROR(READ_CRC, "Read CRC error")\
|
|
||||||
SD_CARD_ERROR(READ_FIFO, "SDIO fifo read timeout")\
|
|
||||||
SD_CARD_ERROR(READ_REG, "Read CID or CSD failed.")\
|
|
||||||
SD_CARD_ERROR(READ_START, "Bad readStart argument")\
|
|
||||||
SD_CARD_ERROR(READ_TIMEOUT, "Read data timeout")\
|
|
||||||
SD_CARD_ERROR(STOP_TRAN, "Multiple block stop failed")\
|
|
||||||
SD_CARD_ERROR(TRANSFER_COMPLETE, "SDIO transfer complete")\
|
|
||||||
SD_CARD_ERROR(WRITE_DATA, "Write data not accepted")\
|
|
||||||
SD_CARD_ERROR(WRITE_FIFO, "SDIO fifo write timeout")\
|
|
||||||
SD_CARD_ERROR(WRITE_START, "Bad writeStart argument")\
|
|
||||||
SD_CARD_ERROR(WRITE_PROGRAMMING, "Flash programming")\
|
|
||||||
SD_CARD_ERROR(WRITE_TIMEOUT, "Write timeout")\
|
|
||||||
SD_CARD_ERROR(DMA, "DMA transfer failed")\
|
|
||||||
SD_CARD_ERROR(ERASE, "Card did not accept erase commands")\
|
|
||||||
SD_CARD_ERROR(ERASE_SINGLE_SECTOR, "Card does not support erase")\
|
|
||||||
SD_CARD_ERROR(ERASE_TIMEOUT, "Erase command timeout")\
|
|
||||||
SD_CARD_ERROR(INIT_NOT_CALLED, "Card has not been initialized")\
|
|
||||||
SD_CARD_ERROR(INVALID_CARD_CONFIG, "Invalid card config")\
|
|
||||||
SD_CARD_ERROR(FUNCTION_NOT_SUPPORTED, "Unsupported SDIO command")
|
|
||||||
|
|
||||||
enum {
|
|
||||||
#define SD_CARD_ERROR(e, m) SD_CARD_ERROR_##e,
|
|
||||||
SD_ERROR_CODE_LIST
|
|
||||||
#undef SD_CARD_ERROR
|
|
||||||
SD_CARD_ERROR_UNKNOWN
|
|
||||||
};
|
|
||||||
void printSdErrorSymbol(print_t* pr, uint8_t code);
|
|
||||||
void printSdErrorText(print_t* pr, uint8_t code);
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// card types
|
|
||||||
/** Standard capacity V1 SD card */
|
|
||||||
const uint8_t SD_CARD_TYPE_SD1 = 1;
|
|
||||||
/** Standard capacity V2 SD card */
|
|
||||||
const uint8_t SD_CARD_TYPE_SD2 = 2;
|
|
||||||
/** High Capacity SD card */
|
|
||||||
const uint8_t SD_CARD_TYPE_SDHC = 3;
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// SD operation timeouts
|
|
||||||
/** CMD0 retry count */
|
|
||||||
const uint8_t SD_CMD0_RETRY = 10;
|
|
||||||
/** command timeout ms */
|
|
||||||
const uint16_t SD_CMD_TIMEOUT = 300;
|
|
||||||
/** erase timeout ms */
|
|
||||||
const uint16_t SD_ERASE_TIMEOUT = 10000;
|
|
||||||
/** init timeout ms */
|
|
||||||
const uint16_t SD_INIT_TIMEOUT = 2000;
|
|
||||||
/** read timeout ms */
|
|
||||||
const uint16_t SD_READ_TIMEOUT = 300;
|
|
||||||
/** write time out ms */
|
|
||||||
const uint16_t SD_WRITE_TIMEOUT = 600;
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// SD card commands
|
|
||||||
/** GO_IDLE_STATE - init card in spi mode if CS low */
|
|
||||||
const uint8_t CMD0 = 0X00;
|
|
||||||
/** ALL_SEND_CID - Asks any card to send the CID. */
|
|
||||||
const uint8_t CMD2 = 0X02;
|
|
||||||
/** SEND_RELATIVE_ADDR - Ask the card to publish a new RCA. */
|
|
||||||
const uint8_t CMD3 = 0X03;
|
|
||||||
/** SWITCH_FUNC - Switch Function Command */
|
|
||||||
const uint8_t CMD6 = 0X06;
|
|
||||||
/** SELECT/DESELECT_CARD - toggles between the stand-by and transfer states. */
|
|
||||||
const uint8_t CMD7 = 0X07;
|
|
||||||
/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
|
|
||||||
const uint8_t CMD8 = 0X08;
|
|
||||||
/** SEND_CSD - read the Card Specific Data (CSD register) */
|
|
||||||
const uint8_t CMD9 = 0X09;
|
|
||||||
/** SEND_CID - read the card identification information (CID register) */
|
|
||||||
const uint8_t CMD10 = 0X0A;
|
|
||||||
/** VOLTAGE_SWITCH -Switch to 1.8V bus signaling level. */
|
|
||||||
const uint8_t CMD11 = 0X0B;
|
|
||||||
/** STOP_TRANSMISSION - end multiple sector read sequence */
|
|
||||||
const uint8_t CMD12 = 0X0C;
|
|
||||||
/** SEND_STATUS - read the card status register */
|
|
||||||
const uint8_t CMD13 = 0X0D;
|
|
||||||
/** READ_SINGLE_SECTOR - read a single data sector from the card */
|
|
||||||
const uint8_t CMD17 = 0X11;
|
|
||||||
/** READ_MULTIPLE_SECTOR - read multiple data sectors from the card */
|
|
||||||
const uint8_t CMD18 = 0X12;
|
|
||||||
/** WRITE_SECTOR - write a single data sector to the card */
|
|
||||||
const uint8_t CMD24 = 0X18;
|
|
||||||
/** WRITE_MULTIPLE_SECTOR - write sectors of data until a STOP_TRANSMISSION */
|
|
||||||
const uint8_t CMD25 = 0X19;
|
|
||||||
/** ERASE_WR_BLK_START - sets the address of the first sector to be erased */
|
|
||||||
const uint8_t CMD32 = 0X20;
|
|
||||||
/** ERASE_WR_BLK_END - sets the address of the last sector of the continuous
|
|
||||||
range to be erased*/
|
|
||||||
const uint8_t CMD33 = 0X21;
|
|
||||||
/** ERASE - erase all previously selected sectors */
|
|
||||||
const uint8_t CMD38 = 0X26;
|
|
||||||
/** APP_CMD - escape for application specific command */
|
|
||||||
const uint8_t CMD55 = 0X37;
|
|
||||||
/** READ_OCR - read the OCR register of a card */
|
|
||||||
const uint8_t CMD58 = 0X3A;
|
|
||||||
/** CRC_ON_OFF - enable or disable CRC checking */
|
|
||||||
const uint8_t CMD59 = 0X3B;
|
|
||||||
/** SET_BUS_WIDTH - Defines the data bus width for data transfer. */
|
|
||||||
const uint8_t ACMD6 = 0X06;
|
|
||||||
/** SD_STATUS - Send the SD Status. */
|
|
||||||
const uint8_t ACMD13 = 0X0D;
|
|
||||||
/** SET_WR_BLK_ERASE_COUNT - Set the number of write sectors to be
|
|
||||||
pre-erased before writing */
|
|
||||||
const uint8_t ACMD23 = 0X17;
|
|
||||||
/** SD_SEND_OP_COMD - Sends host capacity support information and
|
|
||||||
activates the card's initialization process */
|
|
||||||
const uint8_t ACMD41 = 0X29;
|
|
||||||
//==============================================================================
|
|
||||||
// CARD_STATUS
|
|
||||||
/** The command's argument was out of the allowed range for this card. */
|
|
||||||
const uint32_t CARD_STATUS_OUT_OF_RANGE = 1UL << 31;
|
|
||||||
/** A misaligned address which did not match the sector length. */
|
|
||||||
const uint32_t CARD_STATUS_ADDRESS_ERROR = 1UL << 30;
|
|
||||||
/** The transferred sector length is not allowed for this card. */
|
|
||||||
const uint32_t CARD_STATUS_SECTOR_LEN_ERROR = 1UL << 29;
|
|
||||||
/** An error in the sequence of erase commands occurred. */
|
|
||||||
const uint32_t CARD_STATUS_ERASE_SEQ_ERROR = 1UL <<28;
|
|
||||||
/** An invalid selection of write-sectors for erase occurred. */
|
|
||||||
const uint32_t CARD_STATUS_ERASE_PARAM = 1UL << 27;
|
|
||||||
/** Set when the host attempts to write to a protected sector. */
|
|
||||||
const uint32_t CARD_STATUS_WP_VIOLATION = 1UL << 26;
|
|
||||||
/** When set, signals that the card is locked by the host. */
|
|
||||||
const uint32_t CARD_STATUS_CARD_IS_LOCKED = 1UL << 25;
|
|
||||||
/** Set when a sequence or password error has been detected. */
|
|
||||||
const uint32_t CARD_STATUS_LOCK_UNLOCK_FAILED = 1UL << 24;
|
|
||||||
/** The CRC check of the previous command failed. */
|
|
||||||
const uint32_t CARD_STATUS_COM_CRC_ERROR = 1UL << 23;
|
|
||||||
/** Command not legal for the card state. */
|
|
||||||
const uint32_t CARD_STATUS_ILLEGAL_COMMAND = 1UL << 22;
|
|
||||||
/** Card internal ECC was applied but failed to correct the data. */
|
|
||||||
const uint32_t CARD_STATUS_CARD_ECC_FAILED = 1UL << 21;
|
|
||||||
/** Internal card controller error */
|
|
||||||
const uint32_t CARD_STATUS_CC_ERROR = 1UL << 20;
|
|
||||||
/** A general or an unknown error occurred during the operation. */
|
|
||||||
const uint32_t CARD_STATUS_ERROR = 1UL << 19;
|
|
||||||
// bits 19, 18, and 17 reserved.
|
|
||||||
/** Permanent WP set or attempt to change read only values of CSD. */
|
|
||||||
const uint32_t CARD_STATUS_CSD_OVERWRITE = 1UL <<16;
|
|
||||||
/** partial address space was erased due to write protect. */
|
|
||||||
const uint32_t CARD_STATUS_WP_ERASE_SKIP = 1UL << 15;
|
|
||||||
/** The command has been executed without using the internal ECC. */
|
|
||||||
const uint32_t CARD_STATUS_CARD_ECC_DISABLED = 1UL << 14;
|
|
||||||
/** out of erase sequence command was received. */
|
|
||||||
const uint32_t CARD_STATUS_ERASE_RESET = 1UL << 13;
|
|
||||||
/** The state of the card when receiving the command.
|
|
||||||
* 0 = idle
|
|
||||||
* 1 = ready
|
|
||||||
* 2 = ident
|
|
||||||
* 3 = stby
|
|
||||||
* 4 = tran
|
|
||||||
* 5 = data
|
|
||||||
* 6 = rcv
|
|
||||||
* 7 = prg
|
|
||||||
* 8 = dis
|
|
||||||
* 9-14 = reserved
|
|
||||||
* 15 = reserved for I/O mode
|
|
||||||
*/
|
|
||||||
const uint32_t CARD_STATUS_CURRENT_STATE = 0XF << 9;
|
|
||||||
/** Shift for current state. */
|
|
||||||
const uint32_t CARD_STATUS_CURRENT_STATE_SHIFT = 9;
|
|
||||||
/** Corresponds to buffer empty signaling on the bus. */
|
|
||||||
const uint32_t CARD_STATUS_READY_FOR_DATA = 1UL << 8;
|
|
||||||
// bit 7 reserved.
|
|
||||||
/** Extension Functions may set this bit to get host to deal with events. */
|
|
||||||
const uint32_t CARD_STATUS_FX_EVENT = 1UL << 6;
|
|
||||||
/** The card will expect ACMD, or the command has been interpreted as ACMD */
|
|
||||||
const uint32_t CARD_STATUS_APP_CMD = 1UL << 5;
|
|
||||||
// bit 4 reserved.
|
|
||||||
/** Error in the sequence of the authentication process. */
|
|
||||||
const uint32_t CARD_STATUS_AKE_SEQ_ERROR = 1UL << 3;
|
|
||||||
// bits 2,1, and 0 reserved for manufacturer test mode.
|
|
||||||
//==============================================================================
|
|
||||||
/** status for card in the ready state */
|
|
||||||
const uint8_t R1_READY_STATE = 0X00;
|
|
||||||
/** status for card in the idle state */
|
|
||||||
const uint8_t R1_IDLE_STATE = 0X01;
|
|
||||||
/** status bit for illegal command */
|
|
||||||
const uint8_t R1_ILLEGAL_COMMAND = 0X04;
|
|
||||||
/** start data token for read or write single sector*/
|
|
||||||
const uint8_t DATA_START_SECTOR = 0XFE;
|
|
||||||
/** stop token for write multiple sectors*/
|
|
||||||
const uint8_t STOP_TRAN_TOKEN = 0XFD;
|
|
||||||
/** start data token for write multiple sectors*/
|
|
||||||
const uint8_t WRITE_MULTIPLE_TOKEN = 0XFC;
|
|
||||||
/** mask for data response tokens after a write sector operation */
|
|
||||||
const uint8_t DATA_RES_MASK = 0X1F;
|
|
||||||
/** write data accepted token */
|
|
||||||
const uint8_t DATA_RES_ACCEPTED = 0X05;
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
* \class CID
|
|
||||||
* \brief Card IDentification (CID) register.
|
|
||||||
*/
|
|
||||||
typedef struct CID {
|
|
||||||
// byte 0
|
|
||||||
/** Manufacturer ID */
|
|
||||||
unsigned char mid;
|
|
||||||
// byte 1-2
|
|
||||||
/** OEM/Application ID */
|
|
||||||
char oid[2];
|
|
||||||
// byte 3-7
|
|
||||||
/** Product name */
|
|
||||||
char pnm[5];
|
|
||||||
// byte 8
|
|
||||||
/** Product revision least significant digit */
|
|
||||||
unsigned char prv_m : 4;
|
|
||||||
/** Product revision most significant digit */
|
|
||||||
unsigned char prv_n : 4;
|
|
||||||
// byte 9-12
|
|
||||||
/** Product serial number */
|
|
||||||
uint32_t psn;
|
|
||||||
// byte 13
|
|
||||||
/** Manufacturing date year high digit */
|
|
||||||
unsigned char mdt_year_high : 4;
|
|
||||||
/** not used */
|
|
||||||
unsigned char reserved : 4;
|
|
||||||
// byte 14
|
|
||||||
/** Manufacturing date month */
|
|
||||||
unsigned char mdt_month : 4;
|
|
||||||
/** Manufacturing date year low digit */
|
|
||||||
unsigned char mdt_year_low : 4;
|
|
||||||
// byte 15
|
|
||||||
/** not used always 1 */
|
|
||||||
unsigned char always1 : 1;
|
|
||||||
/** CRC7 checksum */
|
|
||||||
unsigned char crc : 7;
|
|
||||||
} __attribute__((packed)) cid_t;
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
|
||||||
/**
|
|
||||||
* \class CSDV1
|
|
||||||
* \brief CSD register for version 1.00 cards .
|
|
||||||
*/
|
|
||||||
typedef struct CSDV1 {
|
|
||||||
// byte 0
|
|
||||||
unsigned char reserved1 : 6;
|
|
||||||
unsigned char csd_ver : 2;
|
|
||||||
// byte 1
|
|
||||||
unsigned char taac;
|
|
||||||
// byte 2
|
|
||||||
unsigned char nsac;
|
|
||||||
// byte 3
|
|
||||||
unsigned char tran_speed;
|
|
||||||
// byte 4
|
|
||||||
unsigned char ccc_high;
|
|
||||||
// byte 5
|
|
||||||
unsigned char read_bl_len : 4;
|
|
||||||
unsigned char ccc_low : 4;
|
|
||||||
// byte 6
|
|
||||||
unsigned char c_size_high : 2;
|
|
||||||
unsigned char reserved2 : 2;
|
|
||||||
unsigned char dsr_imp : 1;
|
|
||||||
unsigned char read_blk_misalign : 1;
|
|
||||||
unsigned char write_blk_misalign : 1;
|
|
||||||
unsigned char read_bl_partial : 1;
|
|
||||||
// byte 7
|
|
||||||
unsigned char c_size_mid;
|
|
||||||
// byte 8
|
|
||||||
unsigned char vdd_r_curr_max : 3;
|
|
||||||
unsigned char vdd_r_curr_min : 3;
|
|
||||||
unsigned char c_size_low : 2;
|
|
||||||
// byte 9
|
|
||||||
unsigned char c_size_mult_high : 2;
|
|
||||||
unsigned char vdd_w_cur_max : 3;
|
|
||||||
unsigned char vdd_w_curr_min : 3;
|
|
||||||
// byte 10
|
|
||||||
unsigned char sector_size_high : 6;
|
|
||||||
unsigned char erase_blk_en : 1;
|
|
||||||
unsigned char c_size_mult_low : 1;
|
|
||||||
// byte 11
|
|
||||||
unsigned char wp_grp_size : 7;
|
|
||||||
unsigned char sector_size_low : 1;
|
|
||||||
// byte 12
|
|
||||||
unsigned char write_bl_len_high : 2;
|
|
||||||
unsigned char r2w_factor : 3;
|
|
||||||
unsigned char reserved3 : 2;
|
|
||||||
unsigned char wp_grp_enable : 1;
|
|
||||||
// byte 13
|
|
||||||
unsigned char reserved4 : 5;
|
|
||||||
unsigned char write_partial : 1;
|
|
||||||
unsigned char write_bl_len_low : 2;
|
|
||||||
// byte 14
|
|
||||||
unsigned char reserved5: 2;
|
|
||||||
unsigned char file_format : 2;
|
|
||||||
unsigned char tmp_write_protect : 1;
|
|
||||||
unsigned char perm_write_protect : 1;
|
|
||||||
unsigned char copy : 1;
|
|
||||||
/** Indicates the file format on the card */
|
|
||||||
unsigned char file_format_grp : 1;
|
|
||||||
// byte 15
|
|
||||||
unsigned char always1 : 1;
|
|
||||||
unsigned char crc : 7;
|
|
||||||
} __attribute__((packed)) csd1_t;
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
* \class CSDV2
|
|
||||||
* \brief CSD register for version 2.00 cards.
|
|
||||||
*/
|
|
||||||
typedef struct CSDV2 {
|
|
||||||
// byte 0
|
|
||||||
unsigned char reserved1 : 6;
|
|
||||||
unsigned char csd_ver : 2;
|
|
||||||
// byte 1
|
|
||||||
/** fixed to 0X0E */
|
|
||||||
unsigned char taac;
|
|
||||||
// byte 2
|
|
||||||
/** fixed to 0 */
|
|
||||||
unsigned char nsac;
|
|
||||||
// byte 3
|
|
||||||
unsigned char tran_speed;
|
|
||||||
// byte 4
|
|
||||||
unsigned char ccc_high;
|
|
||||||
// byte 5
|
|
||||||
/** This field is fixed to 9h, which indicates READ_BL_LEN=512 Byte */
|
|
||||||
unsigned char read_bl_len : 4;
|
|
||||||
unsigned char ccc_low : 4;
|
|
||||||
// byte 6
|
|
||||||
/** not used */
|
|
||||||
unsigned char reserved2 : 4;
|
|
||||||
unsigned char dsr_imp : 1;
|
|
||||||
/** fixed to 0 */
|
|
||||||
unsigned char read_blk_misalign : 1;
|
|
||||||
/** fixed to 0 */
|
|
||||||
unsigned char write_blk_misalign : 1;
|
|
||||||
/** fixed to 0 - no partial read */
|
|
||||||
unsigned char read_bl_partial : 1;
|
|
||||||
// byte 7
|
|
||||||
/** high part of card size */
|
|
||||||
unsigned char c_size_high : 6;
|
|
||||||
/** not used */
|
|
||||||
unsigned char reserved3 : 2;
|
|
||||||
// byte 8
|
|
||||||
/** middle part of card size */
|
|
||||||
unsigned char c_size_mid;
|
|
||||||
// byte 9
|
|
||||||
/** low part of card size */
|
|
||||||
unsigned char c_size_low;
|
|
||||||
// byte 10
|
|
||||||
/** sector size is fixed at 64 KB */
|
|
||||||
unsigned char sector_size_high : 6;
|
|
||||||
/** fixed to 1 - erase single is supported */
|
|
||||||
unsigned char erase_blk_en : 1;
|
|
||||||
/** not used */
|
|
||||||
unsigned char reserved4 : 1;
|
|
||||||
// byte 11
|
|
||||||
unsigned char wp_grp_size : 7;
|
|
||||||
/** sector size is fixed at 64 KB */
|
|
||||||
unsigned char sector_size_low : 1;
|
|
||||||
// byte 12
|
|
||||||
/** write_bl_len fixed for 512 byte sectors */
|
|
||||||
unsigned char write_bl_len_high : 2;
|
|
||||||
/** fixed value of 2 */
|
|
||||||
unsigned char r2w_factor : 3;
|
|
||||||
/** not used */
|
|
||||||
unsigned char reserved5 : 2;
|
|
||||||
/** fixed value of 0 - no write protect groups */
|
|
||||||
unsigned char wp_grp_enable : 1;
|
|
||||||
// byte 13
|
|
||||||
unsigned char reserved6 : 5;
|
|
||||||
/** always zero - no partial sector read*/
|
|
||||||
unsigned char write_partial : 1;
|
|
||||||
/** write_bl_len fixed for 512 byte sectors */
|
|
||||||
unsigned char write_bl_len_low : 2;
|
|
||||||
// byte 14
|
|
||||||
unsigned char reserved7: 2;
|
|
||||||
/** Do not use always 0 */
|
|
||||||
unsigned char file_format : 2;
|
|
||||||
unsigned char tmp_write_protect : 1;
|
|
||||||
unsigned char perm_write_protect : 1;
|
|
||||||
unsigned char copy : 1;
|
|
||||||
/** Do not use always 0 */
|
|
||||||
unsigned char file_format_grp : 1;
|
|
||||||
// byte 15
|
|
||||||
/** not used always 1 */
|
|
||||||
unsigned char always1 : 1;
|
|
||||||
/** checksum */
|
|
||||||
unsigned char crc : 7;
|
|
||||||
} __attribute__((packed)) csd2_t;
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
* \class csd_t
|
|
||||||
* \brief Union of old and new style CSD register.
|
|
||||||
*/
|
|
||||||
union csd_t {
|
|
||||||
csd1_t v1;
|
|
||||||
csd2_t v2;
|
|
||||||
};
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
inline uint32_t sdCardCapacity(csd_t* csd) {
|
|
||||||
if (csd->v1.csd_ver == 0) {
|
|
||||||
uint8_t read_bl_len = csd->v1.read_bl_len;
|
|
||||||
uint16_t c_size = (csd->v1.c_size_high << 10)
|
|
||||||
| (csd->v1.c_size_mid << 2) | csd->v1.c_size_low;
|
|
||||||
uint8_t c_size_mult = (csd->v1.c_size_mult_high << 1)
|
|
||||||
| csd->v1.c_size_mult_low;
|
|
||||||
return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7);
|
|
||||||
} else if (csd->v2.csd_ver == 1) {
|
|
||||||
return (((uint32_t)csd->v2.c_size_high << 16) +
|
|
||||||
((uint16_t)csd->v2.c_size_mid << 8) + csd->v2.c_size_low + 1) << 10;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// fields are big endian
|
|
||||||
typedef struct SdStatus {
|
|
||||||
uint8_t busWidthSecureMode;
|
|
||||||
uint8_t reserved1;
|
|
||||||
uint8_t sdCardType[2];
|
|
||||||
uint8_t sizeOfProtectedArea[4];
|
|
||||||
uint8_t speedClass;
|
|
||||||
uint8_t performanceMove;
|
|
||||||
uint8_t auSize;
|
|
||||||
uint8_t eraseSize[2];
|
|
||||||
uint8_t eraseTimeoutOffset;
|
|
||||||
uint8_t uhsSpeedAuSize;
|
|
||||||
uint8_t videoSpeed;
|
|
||||||
uint8_t vscAuSize[2];
|
|
||||||
uint8_t susAddr[3];
|
|
||||||
uint8_t reserved2[3];
|
|
||||||
uint8_t reservedManufacturer[40];
|
|
||||||
} SdStatus_t;
|
|
||||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
|
||||||
#endif // SdCardInfo_h
|
|
@ -1,277 +0,0 @@
|
|||||||
#ifndef SdioTeensy_h
|
|
||||||
#define SdioTeensy_h
|
|
||||||
|
|
||||||
// From Paul's SD.h driver.
|
|
||||||
|
|
||||||
#if defined(__IMXRT1062__)
|
|
||||||
#define MAKE_REG_MASK(m,s) (((uint32_t)(((uint32_t)(m) << s))))
|
|
||||||
#define MAKE_REG_GET(x,m,s) (((uint32_t)(((uint32_t)(x)>>s) & m)))
|
|
||||||
#define MAKE_REG_SET(x,m,s) (((uint32_t)(((uint32_t)(x) & m) << s)))
|
|
||||||
|
|
||||||
#define SDHC_BLKATTR_BLKSIZE_MASK MAKE_REG_MASK(0x1FFF,0) //uint32_t)(((n) & 0x1FFF)<<0) // Transfer Block Size Mask
|
|
||||||
#define SDHC_BLKATTR_BLKSIZE(n) MAKE_REG_SET(n,0x1FFF,0) //uint32_t)(((n) & 0x1FFF)<<0) // Transfer Block Size
|
|
||||||
#define SDHC_BLKATTR_BLKCNT_MASK MAKE_REG_MASK(0x1FFF,16) //((uint32_t)0x1FFF<<16)
|
|
||||||
#define SDHC_BLKATTR_BLKCNT(n) MAKE_REG_SET(n,0x1FFF,16) //(uint32_t)(((n) & 0x1FFF)<<16) // Blocks Count For Current Transfer
|
|
||||||
|
|
||||||
#define SDHC_XFERTYP_CMDINX(n) MAKE_REG_SET(n,0x3F,24) //(uint32_t)(((n) & 0x3F)<<24)// Command Index
|
|
||||||
#define SDHC_XFERTYP_CMDTYP(n) MAKE_REG_SET(n,0x3,22) //(uint32_t)(((n) & 0x3)<<22) // Command Type
|
|
||||||
#define SDHC_XFERTYP_DPSEL MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data Present Select
|
|
||||||
#define SDHC_XFERTYP_CICEN MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Command Index Check Enable
|
|
||||||
#define SDHC_XFERTYP_CCCEN MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command CRC Check Enable
|
|
||||||
#define SDHC_XFERTYP_RSPTYP(n) MAKE_REG_SET(n,0x3,16) //(uint32_t)(((n) & 0x3)<<16) // Response Type Select
|
|
||||||
#define SDHC_XFERTYP_MSBSEL MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Multi/Single Block Select
|
|
||||||
#define SDHC_XFERTYP_DTDSEL MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Data Transfer Direction Select
|
|
||||||
#define SDHC_XFERTYP_AC12EN MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Auto CMD12 Enable
|
|
||||||
#define SDHC_XFERTYP_BCEN MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Block Count Enable
|
|
||||||
#define SDHC_XFERTYP_DMAEN MAKE_REG_MASK(0x3,0) //((uint32_t)0x00000001) // DMA Enable
|
|
||||||
|
|
||||||
#define SDHC_PRSSTAT_DLSL_MASK MAKE_REG_MASK(0xFF,24) //((uint32_t)0xFF000000) // DAT Line Signal Level
|
|
||||||
#define SDHC_PRSSTAT_CLSL MAKE_REG_MASK(0x1,23) //((uint32_t)0x00800000) // CMD Line Signal Level
|
|
||||||
#define SDHC_PRSSTAT_WPSPL MAKE_REG_MASK(0x1,19) //
|
|
||||||
#define SDHC_PRSSTAT_CDPL MAKE_REG_MASK(0x1,18) //
|
|
||||||
#define SDHC_PRSSTAT_CINS MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Card Inserted
|
|
||||||
#define SDHC_PRSSTAT_TSCD MAKE_REG_MASK(0x1,15)
|
|
||||||
#define SDHC_PRSSTAT_RTR MAKE_REG_MASK(0x1,12)
|
|
||||||
#define SDHC_PRSSTAT_BREN MAKE_REG_MASK(0x1,11) //((uint32_t)0x00000800) // Buffer Read Enable
|
|
||||||
#define SDHC_PRSSTAT_BWEN MAKE_REG_MASK(0x1,10) //((uint32_t)0x00000400) // Buffer Write Enable
|
|
||||||
#define SDHC_PRSSTAT_RTA MAKE_REG_MASK(0x1,9) //((uint32_t)0x00000200) // Read Transfer Active
|
|
||||||
#define SDHC_PRSSTAT_WTA MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Write Transfer Active
|
|
||||||
#define SDHC_PRSSTAT_SDOFF MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // SD Clock Gated Off Internally
|
|
||||||
#define SDHC_PRSSTAT_PEROFF MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // SDHC clock Gated Off Internally
|
|
||||||
#define SDHC_PRSSTAT_HCKOFF MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // System Clock Gated Off Internally
|
|
||||||
#define SDHC_PRSSTAT_IPGOFF MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Bus Clock Gated Off Internally
|
|
||||||
#define SDHC_PRSSTAT_SDSTB MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // SD Clock Stable
|
|
||||||
#define SDHC_PRSSTAT_DLA MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Data Line Active
|
|
||||||
#define SDHC_PRSSTAT_CDIHB MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Command Inhibit (DAT)
|
|
||||||
#define SDHC_PRSSTAT_CIHB MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Inhibit (CMD)
|
|
||||||
|
|
||||||
#define SDHC_PROTCT_NONEXACT_BLKRD MAKE_REG_MASK(0x1,30) //
|
|
||||||
#define SDHC_PROTCT_BURST_LENEN(n) MAKE_REG_SET(n,0x7,12) //
|
|
||||||
#define SDHC_PROCTL_WECRM MAKE_REG_MASK(0x1,26) //((uint32_t)0x04000000) // Wakeup Event Enable On SD Card Removal
|
|
||||||
#define SDHC_PROCTL_WECINS MAKE_REG_MASK(0x1,25) //((uint32_t)0x02000000) // Wakeup Event Enable On SD Card Insertion
|
|
||||||
#define SDHC_PROCTL_WECINT MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Wakeup Event Enable On Card Interrupt
|
|
||||||
#define SDHC_PROCTL_RD_DONE_NOBLK MAKE_REG_MASK(0x1,20) //
|
|
||||||
#define SDHC_PROCTL_IABG MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Interrupt At Block Gap
|
|
||||||
#define SDHC_PROCTL_RWCTL MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Read Wait Control
|
|
||||||
#define SDHC_PROCTL_CREQ MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Continue Request
|
|
||||||
#define SDHC_PROCTL_SABGREQ MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Stop At Block Gap Request
|
|
||||||
#define SDHC_PROCTL_DMAS(n) MAKE_REG_SET(n,0x3,8) //(uint32_t)(((n) & 0x3)<<8) // DMA Select
|
|
||||||
#define SDHC_PROCTL_CDSS MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Detect Signal Selection
|
|
||||||
#define SDHC_PROCTL_CDTL MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Detect Test Level
|
|
||||||
#define SDHC_PROCTL_EMODE(n) MAKE_REG_SET(n,0x3,4) //(uint32_t)(((n) & 0x3)<<4) // Endian Mode
|
|
||||||
#define SDHC_PROCTL_EMODE_MASK MAKE_REG_MASK(0x3,4) //(uint32_t)((0x3)<<4) // Endian Mode
|
|
||||||
#define SDHC_PROCTL_D3CD MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DAT3 As Card Detection Pin
|
|
||||||
#define SDHC_PROCTL_DTW(n) MAKE_REG_SET(n,0x3,1) //(uint32_t)(((n) & 0x3)<<1) // Data Transfer Width, 0=1bit, 1=4bit, 2=8bit
|
|
||||||
#define SDHC_PROCTL_DTW_MASK MAKE_REG_MASK(0x3,1) //((uint32_t)0x00000006)
|
|
||||||
#define SDHC_PROCTL_LCTL MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // LED Control
|
|
||||||
|
|
||||||
#define SDHC_SYSCTL_RSTT MAKE_REG_MASK(0x1,28) //
|
|
||||||
#define SDHC_SYSCTL_INITA MAKE_REG_MASK(0x1,27) //((uint32_t)0x08000000) // Initialization Active
|
|
||||||
#define SDHC_SYSCTL_RSTD MAKE_REG_MASK(0x1,26) //((uint32_t)0x04000000) // Software Reset For DAT Line
|
|
||||||
#define SDHC_SYSCTL_RSTC MAKE_REG_MASK(0x1,25) //((uint32_t)0x02000000) // Software Reset For CMD Line
|
|
||||||
#define SDHC_SYSCTL_RSTA MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Software Reset For ALL
|
|
||||||
#define SDHC_SYSCTL_DTOCV(n) MAKE_REG_SET(n,0xF,16) //(uint32_t)(((n) & 0xF)<<16) // Data Timeout Counter Value
|
|
||||||
#define SDHC_SYSCTL_DTOCV_MASK MAKE_REG_MASK(0xF,16) //((uint32_t)0x000F0000)
|
|
||||||
#define SDHC_SYSCTL_SDCLKFS(n) MAKE_REG_SET(n,0xFF,8) //(uint32_t)(((n) & 0xFF)<<8) // SDCLK Frequency Select
|
|
||||||
#define SDHC_SYSCTL_SDCLKFS_MASK MAKE_REG_MASK(0xFF,8) //((uint32_t)0x0000FF00)
|
|
||||||
#define SDHC_SYSCTL_DVS(n) MAKE_REG_SET(n,0xF,4) //(uint32_t)(((n) & 0xF)<<4) // Divisor
|
|
||||||
#define SDHC_SYSCTL_DVS_MASK MAKE_REG_MASK(0xF,4) //((uint32_t)0x000000F0)
|
|
||||||
|
|
||||||
#define SDHC_SYSCTL_SDCLKEN ((uint32_t)0x00000008) // SD Clock Enable
|
|
||||||
#define SDHC_SYSCTL_PEREN ((uint32_t)0x00000004) // Peripheral Clock Enable
|
|
||||||
#define SDHC_SYSCTL_HCKEN ((uint32_t)0x00000002) // System Clock Enable
|
|
||||||
#define SDHC_SYSCTL_IPGEN ((uint32_t)0x00000001) // IPG Clock Enable
|
|
||||||
|
|
||||||
#define SDHC_IRQSTAT_DMAE MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // DMA Error
|
|
||||||
#define SDHC_IRQSTAT_TNE MAKE_REG_MASK(0x1,26) //
|
|
||||||
#define SDHC_IRQSTAT_AC12E MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Auto CMD12 Error
|
|
||||||
#define SDHC_IRQSTAT_DEBE MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Data End Bit Error
|
|
||||||
#define SDHC_IRQSTAT_DCE MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data CRC Error
|
|
||||||
#define SDHC_IRQSTAT_DTOE MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Data Timeout Error
|
|
||||||
#define SDHC_IRQSTAT_CIE MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command Index Error
|
|
||||||
#define SDHC_IRQSTAT_CEBE MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Command End Bit Error
|
|
||||||
#define SDHC_IRQSTAT_CCE MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Command CRC Error
|
|
||||||
#define SDHC_IRQSTAT_CTOE MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Command Timeout Error
|
|
||||||
#define SDHC_IRQSTAT_TP MAKE_REG_MASK(0x1,14) //
|
|
||||||
#define SDHC_IRQSTAT_RTE MAKE_REG_MASK(0x1,12) //
|
|
||||||
#define SDHC_IRQSTAT_CINT MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Card Interrupt
|
|
||||||
#define SDHC_IRQSTAT_CRM MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Removal
|
|
||||||
#define SDHC_IRQSTAT_CINS MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Insertion
|
|
||||||
#define SDHC_IRQSTAT_BRR MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Buffer Read Ready
|
|
||||||
#define SDHC_IRQSTAT_BWR MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Buffer Write Ready
|
|
||||||
#define SDHC_IRQSTAT_DINT MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DMA Interrupt
|
|
||||||
#define SDHC_IRQSTAT_BGE MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Block Gap Event
|
|
||||||
#define SDHC_IRQSTAT_TC MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Transfer Complete
|
|
||||||
#define SDHC_IRQSTAT_CC MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Complete
|
|
||||||
|
|
||||||
#define SDHC_IRQSTATEN_DMAESEN MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // DMA Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_TNESEN MAKE_REG_MASK(0x1,26) //
|
|
||||||
#define SDHC_IRQSTATEN_AC12ESEN MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Auto CMD12 Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_DEBESEN MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Data End Bit Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_DCESEN MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data CRC Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_DTOESEN MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Data Timeout Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_CIESEN MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command Index Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_CEBESEN MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Command End Bit Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_CCESEN MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Command CRC Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_CTOESEN MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Command Timeout Error Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_TPSEN MAKE_REG_MASK(0x1,14) //
|
|
||||||
#define SDHC_IRQSTATEN_RTESEN MAKE_REG_MASK(0x1,12) //
|
|
||||||
#define SDHC_IRQSTATEN_CINTSEN MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Card Interrupt Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_CRMSEN MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Removal Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_CINSEN MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Insertion Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_BRRSEN MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Buffer Read Ready Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_BWRSEN MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Buffer Write Ready Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_DINTSEN MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DMA Interrupt Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_BGESEN MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Block Gap Event Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_TCSEN MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Transfer Complete Status Enable
|
|
||||||
#define SDHC_IRQSTATEN_CCSEN MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Complete Status Enable
|
|
||||||
|
|
||||||
#define SDHC_IRQSIGEN_DMAEIEN MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // DMA Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_TNEIEN MAKE_REG_MASK(0x1,26) //
|
|
||||||
#define SDHC_IRQSIGEN_AC12EIEN MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Auto CMD12 Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_DEBEIEN MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Data End Bit Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_DCEIEN MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data CRC Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_DTOEIEN MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Data Timeout Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_CIEIEN MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command Index Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_CEBEIEN MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Command End Bit Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_CCEIEN MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Command CRC Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_CTOEIEN MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Command Timeout Error Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_TPIEN MAKE_REG_MASK(0x1,14) //
|
|
||||||
#define SDHC_IRQSIGEN_RTEIEN MAKE_REG_MASK(0x1,12) //
|
|
||||||
#define SDHC_IRQSIGEN_CINTIEN MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Card Interrupt Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_CRMIEN MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Removal Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_CINSIEN MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Insertion Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_BRRIEN MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Buffer Read Ready Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_BWRIEN MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Buffer Write Ready Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_DINTIEN MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DMA Interrupt Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_BGEIEN MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Block Gap Event Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_TCIEN MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Transfer Complete Interrupt Enable
|
|
||||||
#define SDHC_IRQSIGEN_CCIEN MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Complete Interrupt Enable
|
|
||||||
|
|
||||||
#define SDHC_AC12ERR_SMPLCLK_SEL MAKE_REG_MASK(0x1,23) //
|
|
||||||
#define SDHC_AC12ERR_EXEC_TUNING MAKE_REG_MASK(0x1,22) //
|
|
||||||
#define SDHC_AC12ERR_CNIBAC12E MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Command Not Issued By Auto CMD12 Error
|
|
||||||
#define SDHC_AC12ERR_AC12IE MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Auto CMD12 Index Error
|
|
||||||
#define SDHC_AC12ERR_AC12CE MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // Auto CMD12 CRC Error
|
|
||||||
#define SDHC_AC12ERR_AC12EBE MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Auto CMD12 End Bit Error
|
|
||||||
#define SDHC_AC12ERR_AC12TOE MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Auto CMD12 Timeout Error
|
|
||||||
#define SDHC_AC12ERR_AC12NE MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Auto CMD12 Not Executed
|
|
||||||
|
|
||||||
#define SDHC_HTCAPBLT_VS18 MAKE_REG_MASK(0x1,26) //
|
|
||||||
#define SDHC_HTCAPBLT_VS30 MAKE_REG_MASK(0x1,25) //
|
|
||||||
#define SDHC_HTCAPBLT_VS33 MAKE_REG_MASK(0x1,24) //
|
|
||||||
#define SDHC_HTCAPBLT_SRS MAKE_REG_MASK(0x1,23) //
|
|
||||||
#define SDHC_HTCAPBLT_DMAS MAKE_REG_MASK(0x1,22) //
|
|
||||||
#define SDHC_HTCAPBLT_HSS MAKE_REG_MASK(0x1,21) //
|
|
||||||
#define SDHC_HTCAPBLT_ADMAS MAKE_REG_MASK(0x1,20) //
|
|
||||||
#define SDHC_HTCAPBLT_MBL_VAL MAKE_REG_GET((USDHC1_HOST_CTRL_CAP),0x7,16) //
|
|
||||||
#define SDHC_HTCAPBLT_RETUN_MODE MAKE_REG_GET((USDHC1_HOST_CTRL_CAP),0x3,14) //
|
|
||||||
#define SDHC_HTCAPBLT_TUNE_SDR50 MAKE_REG_MASK(0x1,13) //
|
|
||||||
#define SDHC_HTCAPBLT_TIME_RETUN(n) MAKE_REG_SET(n,0xF,8) //
|
|
||||||
|
|
||||||
#define SDHC_WML_WR_BRSTLEN_MASK MAKE_REG_MASK(0x1F,24) //
|
|
||||||
#define SDHC_WML_RD_BRSTLEN_MASK MAKE_REG_MASK(0x1F,8) //
|
|
||||||
#define SDHC_WML_WR_WML_MASK MAKE_REG_MASK(0xFF,16) //
|
|
||||||
#define SDHC_WML_RD_WML_MASK MAKE_REG_MASK(0xFF,0) //
|
|
||||||
#define SDHC_WML_WR_BRSTLEN(n) MAKE_REG_SET(n,0x1F,24) //(uint32_t)(((n) & 0x7F)<<16) // Write Burst Len
|
|
||||||
#define SDHC_WML_RD_BRSTLEN(n) MAKE_REG_SET(n,0x1F,8) //(uint32_t)(((n) & 0x7F)<<0) // Read Burst Len
|
|
||||||
#define SDHC_WML_WR_WML(n) MAKE_REG_SET(n,0xFF,16) //(uint32_t)(((n) & 0x7F)<<16) // Write Watermark Level
|
|
||||||
#define SDHC_WML_RD_WML(n) MAKE_REG_SET(n,0xFF,0) //(uint32_t)(((n) & 0x7F)<<0) // Read Watermark Level
|
|
||||||
#define SDHC_WML_WRWML(n) MAKE_REG_SET(n,0xFF,16) //(uint32_t)(((n) & 0x7F)<<16) // Write Watermark Level
|
|
||||||
#define SDHC_WML_RDWML(n) MAKE_REG_SET(n,0xFF,0) //(uint32_t)(((n) & 0x7F)<<0) // Read Watermark Level
|
|
||||||
|
|
||||||
// Teensy 4.0 only
|
|
||||||
#define SDHC_MIX_CTRL_DMAEN MAKE_REG_MASK(0x1,0) //
|
|
||||||
#define SDHC_MIX_CTRL_BCEN MAKE_REG_MASK(0x1,1) //
|
|
||||||
#define SDHC_MIX_CTRL_AC12EN MAKE_REG_MASK(0x1,2) //
|
|
||||||
#define SDHC_MIX_CTRL_DDR_EN MAKE_REG_MASK(0x1,3) //
|
|
||||||
#define SDHC_MIX_CTRL_DTDSEL MAKE_REG_MASK(0x1,4) //
|
|
||||||
#define SDHC_MIX_CTRL_MSBSEL MAKE_REG_MASK(0x1,5) //
|
|
||||||
#define SDHC_MIX_CTRL_NIBBLE_POS MAKE_REG_MASK(0x1,6) //
|
|
||||||
#define SDHC_MIX_CTRL_AC23EN MAKE_REG_MASK(0x1,7) //
|
|
||||||
|
|
||||||
#define SDHC_FEVT_CINT MAKE_REG_MASK(0x1,31) //((uint32_t)0x80000000) // Force Event Card Interrupt
|
|
||||||
#define SDHC_FEVT_DMAE MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // Force Event DMA Error
|
|
||||||
#define SDHC_FEVT_AC12E MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Force Event Auto CMD12 Error
|
|
||||||
#define SDHC_FEVT_DEBE MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Force Event Data End Bit Error
|
|
||||||
#define SDHC_FEVT_DCE MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Force Event Data CRC Error
|
|
||||||
#define SDHC_FEVT_DTOE MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Force Event Data Timeout Error
|
|
||||||
#define SDHC_FEVT_CIE MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Force Event Command Index Error
|
|
||||||
#define SDHC_FEVT_CEBE MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Force Event Command End Bit Error
|
|
||||||
#define SDHC_FEVT_CCE MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Force Event Command CRC Error
|
|
||||||
#define SDHC_FEVT_CTOE MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Force Event Command Timeout Error
|
|
||||||
#define SDHC_FEVT_CNIBAC12E MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Force Event Command Not Executed By Auto Command 12 Error
|
|
||||||
#define SDHC_FEVT_AC12IE MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Force Event Auto Command 12 Index Error
|
|
||||||
#define SDHC_FEVT_AC12EBE MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // Force Event Auto Command 12 End Bit Error
|
|
||||||
#define SDHC_FEVT_AC12CE MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Force Event Auto Command 12 CRC Error
|
|
||||||
#define SDHC_FEVT_AC12TOE MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Force Event Auto Command 12 Time Out Error
|
|
||||||
#define SDHC_FEVT_AC12NE MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Force Event Auto Command 12 Not Executed
|
|
||||||
|
|
||||||
#define SDHC_ADMAES_ADMADCE MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008)
|
|
||||||
#define SDHC_ADMAES_ADMALME MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004)
|
|
||||||
#define SDHC_ADMAES_ADMAES_MASK MAKE_REG_MASK(0x3,0) //((uint32_t)0x00000003)
|
|
||||||
|
|
||||||
#define SDHC_MMCBOOT_BOOTBLKCNT(n) MAKE_REG_MASK(0xFF,16) //(uint32_t)(((n) & 0xFFF)<<16) // stop at block gap value of automatic mode
|
|
||||||
#define SDHC_MMCBOOT_AUTOSABGEN MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // enable auto stop at block gap function
|
|
||||||
#define SDHC_MMCBOOT_BOOTEN MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Boot Mode Enable
|
|
||||||
#define SDHC_MMCBOOT_BOOTMODE MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Boot Mode Select
|
|
||||||
#define SDHC_MMCBOOT_BOOTACK MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Boot Ack Mode Select
|
|
||||||
#define SDHC_MMCBOOT_DTOCVACK(n) MAKE_REG_MASK(0xF,0) //(uint32_t)(((n) & 0xF)<<0) // Boot ACK Time Out Counter Value
|
|
||||||
//#define SDHC_HOSTVER (*(volatile uint32_t*)0x400B10FC) // Host Controller Version
|
|
||||||
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD0_FRAC_MASK 0x3f
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD0_FRAC(n) ((n) & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK)
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD1_FRAC_MASK (0x3f<<8)
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD1_FRAC(n) (((n)<<8) & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK)
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD2_FRAC_MASK (0x3f<<16)
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD2_FRAC(n) (((n)<<16) & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK)
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD3_FRAC_MASK ((0x3f<<24)
|
|
||||||
#define CCM_ANALOG_PFD_528_PFD3_FRAC(n) (((n)<<24) & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK)
|
|
||||||
|
|
||||||
#define SDHC_DSADDR (USDHC1_DS_ADDR ) // DMA System Address register
|
|
||||||
#define SDHC_BLKATTR (USDHC1_BLK_ATT) // Block Attributes register
|
|
||||||
#define SDHC_CMDARG (USDHC1_CMD_ARG) // Command Argument register
|
|
||||||
#define SDHC_XFERTYP (USDHC1_CMD_XFR_TYP) // Transfer Type register
|
|
||||||
#define SDHC_CMDRSP0 (USDHC1_CMD_RSP0) // Command Response 0
|
|
||||||
#define SDHC_CMDRSP1 (USDHC1_CMD_RSP1) // Command Response 1
|
|
||||||
#define SDHC_CMDRSP2 (USDHC1_CMD_RSP2) // Command Response 2
|
|
||||||
#define SDHC_CMDRSP3 (USDHC1_CMD_RSP3) // Command Response 3
|
|
||||||
#define SDHC_DATPORT (USDHC1_DATA_BUFF_ACC_PORT) // Buffer Data Port register
|
|
||||||
#define SDHC_PRSSTAT (USDHC1_PRES_STATE) // Present State register
|
|
||||||
#define SDHC_PROCTL (USDHC1_PROT_CTRL) // Protocol Control register
|
|
||||||
#define SDHC_SYSCTL (USDHC1_SYS_CTRL) // System Control register
|
|
||||||
#define SDHC_IRQSTAT (USDHC1_INT_STATUS) // Interrupt Status register
|
|
||||||
#define SDHC_IRQSTATEN (USDHC1_INT_STATUS_EN) // Interrupt Status Enable register
|
|
||||||
#define SDHC_IRQSIGEN (USDHC1_INT_SIGNAL_EN) // Interrupt Signal Enable register
|
|
||||||
#define SDHC_AC12ERR (USDHC1_AUTOCMD12_ERR_STATUS) // Auto CMD12 Error Status Register
|
|
||||||
#define SDHC_HTCAPBLT (USDHC1_HOST_CTRL_CAP) // Host Controller Capabilities
|
|
||||||
#define SDHC_WML (USDHC1_WTMK_LVL) // Watermark Level Register
|
|
||||||
#define SDHC_MIX_CTRL (USDHC1_MIX_CTRL) // Mixer Control
|
|
||||||
#define SDHC_FEVT (USDHC1_FORCE_EVENT) // Force Event register
|
|
||||||
#define SDHC_ADMAES (USDHC1_ADMA_ERR_STATUS) // ADMA Error Status register
|
|
||||||
#define SDHC_ADSADDR (USDHC1_ADMA_SYS_ADDR) // ADMA System Addressregister
|
|
||||||
#define SDHC_VENDOR (USDHC1_VEND_SPEC) // Vendor Specific register
|
|
||||||
#define SDHC_MMCBOOT (USDHC1_MMC_BOOT) // MMC Boot register
|
|
||||||
#define SDHC_VENDOR2 (USDHC2_VEND_SPEC2) // Vendor Specific2 register
|
|
||||||
//
|
|
||||||
#define IRQ_SDHC IRQ_SDHC1
|
|
||||||
|
|
||||||
#define SDHC_MAX_DVS (0xF + 1U)
|
|
||||||
#define SDHC_MAX_CLKFS (0xFF + 1U)
|
|
||||||
#define SDHC_PREV_DVS(x) ((x) -= 1U)
|
|
||||||
#define SDHC_PREV_CLKFS(x, y) ((x) >>= (y))
|
|
||||||
|
|
||||||
#define CCM_CSCDR1_USDHC1_CLK_PODF_MASK (0x7<<11)
|
|
||||||
#define CCM_CSCDR1_USDHC1_CLK_PODF(n) (((n)&0x7)<<11)
|
|
||||||
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_SRE ((0x1<)<0)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_PKE ((0x1)<<12)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_PUE ((0x1)<<13)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_HYS ((0x1)<<16)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_SPEED(n) (((n)&0x3)<<6)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_PUS(n) (((n)&0x3)<<14)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_PUS_MASK ((0x3)<<14)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_DSE(n) (((n)&0x7)<<3)
|
|
||||||
#define IOMUXC_SW_PAD_CTL_PAD_DSE_MASK ((0x7)<<3)
|
|
||||||
#endif // defined(__IMXRT1062__)
|
|
||||||
#endif // SdioTeensy_h
|
|
@ -1,582 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2011-2021 Bill Greiman
|
|
||||||
* This file is part of the SdFat library for SD memory cards.
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef SdFat_h
|
|
||||||
#define SdFat_h
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* \brief main SdFs include file.
|
|
||||||
*/
|
|
||||||
#include "common/SysCall.h"
|
|
||||||
#include "SdCard/SdCard.h"
|
|
||||||
#include "ExFatLib/ExFatLib.h"
|
|
||||||
#include "FatLib/FatLib.h"
|
|
||||||
#include "FsLib/FsLib.h"
|
|
||||||
#if INCLUDE_SDIOS
|
|
||||||
#include "sdios.h"
|
|
||||||
#endif // INCLUDE_SDIOS
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** SdFat version for cpp use. */
|
|
||||||
#define SD_FAT_VERSION 20102
|
|
||||||
/** SdFat version as string. */
|
|
||||||
#define SD_FAT_VERSION_STR "2.1.2"
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
* \class SdBase
|
|
||||||
* \brief base SD file system template class.
|
|
||||||
*/
|
|
||||||
template <class Vol, class Fmt>
|
|
||||||
class SdBase : public Vol
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Initialize SD card and file system.
|
|
||||||
*
|
|
||||||
* \param[in] csPin SD card chip select pin.
|
|
||||||
* \return true for success or false for failure.
|
|
||||||
*/
|
|
||||||
bool begin(SdCsPin_t csPin = SS)
|
|
||||||
{
|
|
||||||
#ifdef BUILTIN_SDCARD
|
|
||||||
if (csPin == BUILTIN_SDCARD) {
|
|
||||||
return begin(SdioConfig(FIFO_SDIO));
|
|
||||||
}
|
|
||||||
#endif // BUILTIN_SDCARD
|
|
||||||
return begin(SdSpiConfig(csPin, SHARED_SPI));
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Initialize SD card and file system.
|
|
||||||
*
|
|
||||||
* \param[in] csPin SD card chip select pin.
|
|
||||||
* \param[in] maxSck Maximum SCK frequency.
|
|
||||||
* \return true for success or false for failure.
|
|
||||||
*/
|
|
||||||
bool begin(SdCsPin_t csPin, uint32_t maxSck)
|
|
||||||
{
|
|
||||||
return begin(SdSpiConfig(csPin, SHARED_SPI, maxSck));
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Initialize SD card and file system for SPI mode.
|
|
||||||
*
|
|
||||||
* \param[in] spiConfig SPI configuration.
|
|
||||||
* \return true for success or false for failure.
|
|
||||||
*/
|
|
||||||
bool begin(SdSpiConfig spiConfig)
|
|
||||||
{
|
|
||||||
return cardBegin(spiConfig) && Vol::begin(m_card);
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
/** Initialize SD card and file system for SDIO mode.
|
|
||||||
*
|
|
||||||
* \param[in] sdioConfig SDIO configuration.
|
|
||||||
* \return true for success or false for failure.
|
|
||||||
*/
|
|
||||||
bool begin(SdioConfig sdioConfig)
|
|
||||||
{
|
|
||||||
return cardBegin(sdioConfig) && Vol::begin(m_card);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** \return Pointer to SD card object. */
|
|
||||||
SdCard* card()
|
|
||||||
{
|
|
||||||
return m_card;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Initialize SD card in SPI mode.
|
|
||||||
*
|
|
||||||
* \param[in] spiConfig SPI configuration.
|
|
||||||
* \return true for success or false for failure.
|
|
||||||
*/
|
|
||||||
bool cardBegin(SdSpiConfig spiConfig)
|
|
||||||
{
|
|
||||||
m_card = m_cardFactory.newCard(spiConfig);
|
|
||||||
return m_card && !m_card->errorCode();
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Initialize SD card in SDIO mode.
|
|
||||||
*
|
|
||||||
* \param[in] sdioConfig SDIO configuration.
|
|
||||||
* \return true for success or false for failure.
|
|
||||||
*/
|
|
||||||
bool cardBegin(SdioConfig sdioConfig)
|
|
||||||
{
|
|
||||||
m_card = m_cardFactory.newCard(sdioConfig);
|
|
||||||
return m_card && !m_card->errorCode();
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** End use of card. */
|
|
||||||
void end()
|
|
||||||
{
|
|
||||||
Vol::end();
|
|
||||||
if (m_card) {
|
|
||||||
m_card->end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
*/
|
|
||||||
void errorHalt(print_t* pr)
|
|
||||||
{
|
|
||||||
if (sdErrorCode()) {
|
|
||||||
pr->print(F("SdError: 0X"));
|
|
||||||
pr->print(sdErrorCode(), HEX);
|
|
||||||
pr->print(F(",0X"));
|
|
||||||
pr->println(sdErrorData(), HEX);
|
|
||||||
} else if (!Vol::fatType()) {
|
|
||||||
pr->println(F("Check SD format."));
|
|
||||||
}
|
|
||||||
while (true) {}
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorHalt(print_t* pr, const char* msg)
|
|
||||||
{
|
|
||||||
pr->print(F("error: "));
|
|
||||||
pr->println(msg);
|
|
||||||
errorHalt(pr);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print msg and halt.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorHalt(print_t* pr, const __FlashStringHelper* msg)
|
|
||||||
{
|
|
||||||
pr->print(F("error: "));
|
|
||||||
pr->println(msg);
|
|
||||||
errorHalt(pr);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Format SD card
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
* \return true for success else false.
|
|
||||||
*/
|
|
||||||
bool format(print_t* pr = nullptr)
|
|
||||||
{
|
|
||||||
Fmt fmt;
|
|
||||||
uint8_t* mem = Vol::end();
|
|
||||||
if (!mem) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool switchSpi = hasDedicatedSpi() && !isDedicatedSpi();
|
|
||||||
if (switchSpi && !setDedicatedSpi(true)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
bool rtn = fmt.format(card(), mem, pr);
|
|
||||||
if (switchSpi && !setDedicatedSpi(false)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return rtn;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** \return the free cluster count. */
|
|
||||||
uint32_t freeClusterCount()
|
|
||||||
{
|
|
||||||
bool switchSpi = hasDedicatedSpi() && !isDedicatedSpi();
|
|
||||||
if (switchSpi && !setDedicatedSpi(true)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
uint32_t rtn = Vol::freeClusterCount();
|
|
||||||
if (switchSpi && !setDedicatedSpi(false)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return rtn;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** \return true if can be in dedicated SPI state */
|
|
||||||
bool hasDedicatedSpi()
|
|
||||||
{
|
|
||||||
return m_card ? m_card->hasDedicatedSpi() : false;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
*/
|
|
||||||
void initErrorHalt(print_t* pr)
|
|
||||||
{
|
|
||||||
initErrorPrint(pr);
|
|
||||||
while (true) {}
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void initErrorHalt(print_t* pr, const char* msg)
|
|
||||||
{
|
|
||||||
pr->println(msg);
|
|
||||||
initErrorHalt(pr);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void initErrorHalt(print_t* pr, const __FlashStringHelper* msg)
|
|
||||||
{
|
|
||||||
pr->println(msg);
|
|
||||||
initErrorHalt(pr);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Print error details after begin() fails.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
*/
|
|
||||||
void initErrorPrint(print_t* pr)
|
|
||||||
{
|
|
||||||
pr->println(F("begin() failed"));
|
|
||||||
if (sdErrorCode()) {
|
|
||||||
pr->println(F("Do not reformat the SD."));
|
|
||||||
if (sdErrorCode() == SD_CARD_ERROR_CMD0) {
|
|
||||||
pr->println(F("No card, wrong chip select pin, or wiring error?"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errorPrint(pr);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** \return true if in dedicated SPI state. */
|
|
||||||
bool isDedicatedSpi()
|
|
||||||
{
|
|
||||||
return m_card ? m_card->isDedicatedSpi() : false;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print volume FAT/exFAT type.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
*/
|
|
||||||
void printFatType(print_t* pr)
|
|
||||||
{
|
|
||||||
if (Vol::fatType() == FAT_TYPE_EXFAT) {
|
|
||||||
pr->print(F("exFAT"));
|
|
||||||
} else {
|
|
||||||
pr->print(F("FAT"));
|
|
||||||
pr->print(Vol::fatType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print SD errorCode and errorData.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
*/
|
|
||||||
void errorPrint(print_t* pr)
|
|
||||||
{
|
|
||||||
if (sdErrorCode()) {
|
|
||||||
pr->print(F("SdError: 0X"));
|
|
||||||
pr->print(sdErrorCode(), HEX);
|
|
||||||
pr->print(F(",0X"));
|
|
||||||
pr->println(sdErrorData(), HEX);
|
|
||||||
} else if (!Vol::fatType()) {
|
|
||||||
pr->println(F("Check SD format."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print msg, any SD error code.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorPrint(print_t* pr, char const* msg)
|
|
||||||
{
|
|
||||||
pr->print(F("error: "));
|
|
||||||
pr->println(msg);
|
|
||||||
errorPrint(pr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** %Print msg, any SD error code.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorPrint(print_t* pr, const __FlashStringHelper* msg)
|
|
||||||
{
|
|
||||||
pr->print(F("error: "));
|
|
||||||
pr->println(msg);
|
|
||||||
errorPrint(pr);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and return.
|
|
||||||
*
|
|
||||||
* \param[in] pr Print destination.
|
|
||||||
*/
|
|
||||||
void printSdError(print_t* pr)
|
|
||||||
{
|
|
||||||
if (sdErrorCode()) {
|
|
||||||
if (sdErrorCode() == SD_CARD_ERROR_CMD0) {
|
|
||||||
pr->println(F("No card, wrong chip select pin, or wiring error?"));
|
|
||||||
}
|
|
||||||
pr->print(F("SD error: "));
|
|
||||||
printSdErrorSymbol(pr, sdErrorCode());
|
|
||||||
pr->print(F(" = 0x"));
|
|
||||||
pr->print(sdErrorCode(), HEX);
|
|
||||||
pr->print(F(",0x"));
|
|
||||||
pr->println(sdErrorData(), HEX);
|
|
||||||
} else if (!Vol::fatType()) {
|
|
||||||
pr->println(F("Check SD format."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** \return SD card error code. */
|
|
||||||
uint8_t sdErrorCode()
|
|
||||||
{
|
|
||||||
if (m_card) {
|
|
||||||
return m_card->errorCode();
|
|
||||||
}
|
|
||||||
return SD_CARD_ERROR_INVALID_CARD_CONFIG;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** \return SD card error data. */
|
|
||||||
uint8_t sdErrorData()
|
|
||||||
{
|
|
||||||
return m_card ? m_card->errorData() : 0;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Set SPI sharing state
|
|
||||||
* \param[in] value desired state.
|
|
||||||
* \return true for success else false;
|
|
||||||
*/
|
|
||||||
bool setDedicatedSpi(bool value)
|
|
||||||
{
|
|
||||||
if (m_card) {
|
|
||||||
return m_card->setDedicatedSpi(value);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** \return pointer to base volume */
|
|
||||||
Vol* vol()
|
|
||||||
{
|
|
||||||
return reinterpret_cast<Vol*>(this);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Initialize file system after call to cardBegin.
|
|
||||||
*
|
|
||||||
* \return true for success or false for failure.
|
|
||||||
*/
|
|
||||||
bool volumeBegin()
|
|
||||||
{
|
|
||||||
return Vol::begin(m_card);
|
|
||||||
}
|
|
||||||
#if ENABLE_ARDUINO_SERIAL
|
|
||||||
/** Print error details after begin() fails. */
|
|
||||||
void initErrorPrint()
|
|
||||||
{
|
|
||||||
initErrorPrint(&Serial);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print msg to Serial and halt.
|
|
||||||
*
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorHalt(const __FlashStringHelper* msg)
|
|
||||||
{
|
|
||||||
errorHalt(&Serial, msg);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info to Serial and halt. */
|
|
||||||
void errorHalt()
|
|
||||||
{
|
|
||||||
errorHalt(&Serial);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorHalt(const char* msg)
|
|
||||||
{
|
|
||||||
errorHalt(&Serial, msg);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt. */
|
|
||||||
void initErrorHalt()
|
|
||||||
{
|
|
||||||
initErrorHalt(&Serial);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print msg, any SD error code.
|
|
||||||
*
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorPrint(const char* msg)
|
|
||||||
{
|
|
||||||
errorPrint(&Serial, msg);
|
|
||||||
}
|
|
||||||
/** %Print msg, any SD error code.
|
|
||||||
*
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void errorPrint(const __FlashStringHelper* msg)
|
|
||||||
{
|
|
||||||
errorPrint(&Serial, msg);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void initErrorHalt(const char* msg)
|
|
||||||
{
|
|
||||||
initErrorHalt(&Serial, msg);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** %Print error info and halt.
|
|
||||||
*
|
|
||||||
* \param[in] msg Message to print.
|
|
||||||
*/
|
|
||||||
void initErrorHalt(const __FlashStringHelper* msg)
|
|
||||||
{
|
|
||||||
initErrorHalt(&Serial, msg);
|
|
||||||
}
|
|
||||||
#endif // ENABLE_ARDUINO_SERIAL
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
private:
|
|
||||||
SdCard* m_card = nullptr;
|
|
||||||
SdCardFactory m_cardFactory;
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* \class SdFat32
|
|
||||||
* \brief SD file system class for FAT volumes.
|
|
||||||
*/
|
|
||||||
class SdFat32 : public SdBase<FatVolume, FatFormatter>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* \class SdExFat
|
|
||||||
* \brief SD file system class for exFAT volumes.
|
|
||||||
*/
|
|
||||||
class SdExFat : public SdBase<ExFatVolume, ExFatFormatter>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* \class SdFs
|
|
||||||
* \brief SD file system class for FAT16, FAT32, and exFAT volumes.
|
|
||||||
*/
|
|
||||||
class SdFs : public SdBase<FsVolume, FsFormatter>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#if SDFAT_FILE_TYPE == 1 || defined(DOXYGEN)
|
|
||||||
/** Select type for SdFat. */
|
|
||||||
typedef SdFat32 SdFat;
|
|
||||||
/** Select type for SdBaseFile. */
|
|
||||||
typedef FatFile SdBaseFile;
|
|
||||||
#elif SDFAT_FILE_TYPE == 2
|
|
||||||
typedef SdExFat SdFat;
|
|
||||||
typedef ExFatFile SdBaseFile;
|
|
||||||
#elif SDFAT_FILE_TYPE == 3
|
|
||||||
typedef SdFs SdFat;
|
|
||||||
typedef FsBaseFile SdBaseFile;
|
|
||||||
#else // SDFAT_FILE_TYPE
|
|
||||||
#error Invalid SDFAT_FILE_TYPE
|
|
||||||
#endif // SDFAT_FILE_TYPE
|
|
||||||
//
|
|
||||||
// Only define File if FS.h is not included.
|
|
||||||
// Line with test for __has_include must not have operators or parentheses.
|
|
||||||
#if defined __has_include
|
|
||||||
#if __has_include(<FS.h>)
|
|
||||||
#define HAS_INCLUDE_FS_H
|
|
||||||
//#warning File not defined because __has_include(FS.h)
|
|
||||||
#endif // __has_include(<FS.h>)
|
|
||||||
#endif // defined __has_include
|
|
||||||
#ifndef HAS_INCLUDE_FS_H
|
|
||||||
#if SDFAT_FILE_TYPE == 1 || defined(DOXYGEN)
|
|
||||||
/** Select type for File. */
|
|
||||||
typedef File32 File;
|
|
||||||
#elif SDFAT_FILE_TYPE == 2
|
|
||||||
typedef ExFile File;
|
|
||||||
#elif SDFAT_FILE_TYPE == 3
|
|
||||||
typedef FsFile File;
|
|
||||||
#endif // SDFAT_FILE_TYPE
|
|
||||||
#endif // HAS_INCLUDE_FS_H
|
|
||||||
/**
|
|
||||||
* \class SdFile
|
|
||||||
* \brief FAT16/FAT32 file with Print.
|
|
||||||
*/
|
|
||||||
class SdFile : public PrintFile<SdBaseFile>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SdFile() {}
|
|
||||||
/** Create an open SdFile.
|
|
||||||
* \param[in] path path for file.
|
|
||||||
* \param[in] oflag open flags.
|
|
||||||
*/
|
|
||||||
SdFile(const char* path, oflag_t oflag)
|
|
||||||
{
|
|
||||||
open(path, oflag);
|
|
||||||
}
|
|
||||||
/** Set the date/time callback function
|
|
||||||
*
|
|
||||||
* \param[in] dateTime The user's call back function. The callback
|
|
||||||
* function is of the form:
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* void dateTime(uint16_t* date, uint16_t* time) {
|
|
||||||
* uint16_t year;
|
|
||||||
* uint8_t month, day, hour, minute, second;
|
|
||||||
*
|
|
||||||
* // User gets date and time from GPS or real-time clock here
|
|
||||||
*
|
|
||||||
* // return date using FS_DATE macro to format fields
|
|
||||||
* *date = FS_DATE(year, month, day);
|
|
||||||
*
|
|
||||||
* // return time using FS_TIME macro to format fields
|
|
||||||
* *time = FS_TIME(hour, minute, second);
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* Sets the function that is called when a file is created or when
|
|
||||||
* a file's directory entry is modified by sync(). All timestamps,
|
|
||||||
* access, creation, and modify, are set when a file is created.
|
|
||||||
* sync() maintains the last access date and last modify date/time.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void dateTimeCallback(
|
|
||||||
void (*dateTime)(uint16_t* date, uint16_t* time))
|
|
||||||
{
|
|
||||||
FsDateTime::setCallback(dateTime);
|
|
||||||
}
|
|
||||||
/** Cancel the date/time callback function. */
|
|
||||||
static void dateTimeCallbackCancel()
|
|
||||||
{
|
|
||||||
FsDateTime::clearCallback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // SdFat_h
|
|
@ -1,115 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2011-2021 Bill Greiman
|
|
||||||
* This file is part of the SdFat library for SD memory cards.
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "FsUtf.h"
|
|
||||||
namespace FsUtf {
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
char* cpToMb(uint32_t cp, char* str, char* end) {
|
|
||||||
size_t n = end - str;
|
|
||||||
if (cp < 0X80) {
|
|
||||||
if (n < 1) goto fail;
|
|
||||||
*(str++) = static_cast<uint8_t>(cp);
|
|
||||||
} else if (cp < 0X800) {
|
|
||||||
if (n < 2) goto fail;
|
|
||||||
*(str++) = static_cast<uint8_t>((cp >> 6) | 0XC0);
|
|
||||||
*(str++) = static_cast<uint8_t>((cp & 0X3F) | 0X80);
|
|
||||||
} else if (cp < 0X10000) {
|
|
||||||
if (n < 3) goto fail;
|
|
||||||
*(str++) = static_cast<uint8_t>((cp >> 12) | 0XE0);
|
|
||||||
*(str++) = static_cast<uint8_t>(((cp >> 6) & 0X3F) | 0X80);
|
|
||||||
*(str++) = static_cast<uint8_t>((cp & 0X3F) | 0X80);
|
|
||||||
} else {
|
|
||||||
if (n < 4) goto fail;
|
|
||||||
*(str++) = static_cast<uint8_t>((cp >> 18) | 0XF0);
|
|
||||||
*(str++) = static_cast<uint8_t>(((cp >> 12) & 0X3F)| 0X80);
|
|
||||||
*(str++) = static_cast<uint8_t>(((cp >> 6) & 0X3F) | 0X80);
|
|
||||||
*(str++) = static_cast<uint8_t>((cp & 0X3F) | 0X80);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// to do? improve error check
|
|
||||||
const char* mbToCp(const char* str, const char* end, uint32_t* rtn) {
|
|
||||||
size_t n;
|
|
||||||
uint32_t cp;
|
|
||||||
if (str >= end) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
uint8_t ch = str[0];
|
|
||||||
if ((ch & 0X80) == 0) {
|
|
||||||
*rtn = ch;
|
|
||||||
return str + 1;
|
|
||||||
}
|
|
||||||
if ((ch & 0XE0) == 0XC0) {
|
|
||||||
cp = ch & 0X1F;
|
|
||||||
n = 2;
|
|
||||||
} else if ((ch & 0XF0) == 0XE0) {
|
|
||||||
cp = ch & 0X0F;
|
|
||||||
n = 3;
|
|
||||||
} else if ((ch & 0XF8) == 0XF0) {
|
|
||||||
cp = ch & 0X07;
|
|
||||||
n = 4;
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if ((str + n) > end) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
for (size_t i = 1; i < n; i++) {
|
|
||||||
ch = str[i];
|
|
||||||
if ((ch & 0XC0) != 0X80) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
cp <<= 6;
|
|
||||||
cp |= ch & 0X3F;
|
|
||||||
}
|
|
||||||
// Don't allow over long as ASCII.
|
|
||||||
if (cp < 0X80 || !isValidCp(cp)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
*rtn = cp;
|
|
||||||
return str + n;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
const char* mbToU16(const char* str,
|
|
||||||
const char* end, uint16_t* hs, uint16_t* ls) {
|
|
||||||
uint32_t cp;
|
|
||||||
const char* ptr = mbToCp(str, end, &cp);
|
|
||||||
if (!ptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (cp <= 0XFFFF) {
|
|
||||||
*hs = cp;
|
|
||||||
*ls = 0;
|
|
||||||
} else {
|
|
||||||
*hs = highSurrogate(cp);
|
|
||||||
*ls = lowSurrogate(cp);
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
} // namespace FsUtf
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2011-2021 Bill Greiman
|
|
||||||
* This file is part of the SdFat library for SD memory cards.
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef FsUtf_h
|
|
||||||
#define FsUtf_h
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* \brief Unicode Transformation Format functions.
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
namespace FsUtf {
|
|
||||||
/** High surrogate for a code point.
|
|
||||||
* \param{in} cp code point.
|
|
||||||
* \return high surrogate.
|
|
||||||
*/
|
|
||||||
inline uint16_t highSurrogate(uint32_t cp) {
|
|
||||||
return (cp >> 10) + (0XD800 - (0X10000 >> 10));
|
|
||||||
}
|
|
||||||
/** Low surrogate for a code point.
|
|
||||||
* \param{in} cp code point.
|
|
||||||
* \return low surrogate.
|
|
||||||
*/
|
|
||||||
inline uint16_t lowSurrogate(uint32_t cp) {
|
|
||||||
return (cp & 0X3FF) + 0XDC00;
|
|
||||||
}
|
|
||||||
/** Check for a valid code point.
|
|
||||||
* \param[in] cp code point.
|
|
||||||
* \return true if valid else false.
|
|
||||||
*/
|
|
||||||
inline bool isValidCp(uint32_t cp) {
|
|
||||||
return cp <= 0x10FFFF && (cp < 0XD800 || cp > 0XDFFF);
|
|
||||||
}
|
|
||||||
/** Check for UTF-16 surrogate.
|
|
||||||
* \param[in] c UTF-16 unit.
|
|
||||||
* \return true if c is a surrogate else false.
|
|
||||||
*/
|
|
||||||
inline bool isSurrogate(uint16_t c) {
|
|
||||||
return 0XD800 <= c && c <= 0XDFFF;
|
|
||||||
}
|
|
||||||
/** Check for UTF-16 high surrogate.
|
|
||||||
* \param[in] c UTF-16 unit..
|
|
||||||
* \return true if c is a high surrogate else false.
|
|
||||||
*/
|
|
||||||
inline bool isHighSurrogate(uint16_t c) {
|
|
||||||
return 0XD800 <= c && c <= 0XDBFF;
|
|
||||||
}
|
|
||||||
/** Check for UTF-16 low surrogate.
|
|
||||||
* \param[in] c UTF-16 unit..
|
|
||||||
* \return true if c is a low surrogate else false.
|
|
||||||
*/
|
|
||||||
inline bool isLowSurrogate(uint16_t c) {
|
|
||||||
return 0XDC00 <= c && c <= 0XDFFF;
|
|
||||||
}
|
|
||||||
/** Convert UFT-16 surrogate pair to code point.
|
|
||||||
* \param[in] hs high surrogate.
|
|
||||||
* \param[in] ls low surrogate.
|
|
||||||
* \return code point.
|
|
||||||
*/
|
|
||||||
inline uint32_t u16ToCp(uint16_t hs, uint16_t ls) {
|
|
||||||
return 0X10000 + (((hs & 0X3FF) << 10) | (ls & 0X3FF));
|
|
||||||
}
|
|
||||||
/** Encodes a 32 bit code point as a UTF-8 sequence.
|
|
||||||
* \param[in] cp code point to encode.
|
|
||||||
* \param[out] str location for UTF-8 sequence.
|
|
||||||
* \param[in] end location following last character of str.
|
|
||||||
* \return location one beyond last encoded character.
|
|
||||||
*/
|
|
||||||
char* cpToMb(uint32_t cp, char* str, char* end);
|
|
||||||
/** Get next code point from a UTF-8 sequence.
|
|
||||||
* \param[in] str location for UTF-8 sequence.
|
|
||||||
* \param[in] end location following last character of str.
|
|
||||||
* May be nullptr if str is zero terminated.
|
|
||||||
* \param[out] rtn location for the code point.
|
|
||||||
* \return location of next UTF-8 character in str of nullptr for error.
|
|
||||||
*/
|
|
||||||
const char* mbToCp(const char* str, const char* end, uint32_t* rtn);
|
|
||||||
/** Get next code point from a UTF-8 sequence as UTF-16.
|
|
||||||
* \param[in] str location for UTF-8 sequence.
|
|
||||||
* \param[in] end location following last character of str.
|
|
||||||
* \param[out] hs location for the code point or high surrogate.
|
|
||||||
* \param[out] ls location for zero or high surrogate.
|
|
||||||
* \return location of next UTF-8 character in str of nullptr for error.
|
|
||||||
*/
|
|
||||||
const char* mbToU16(const char* str,
|
|
||||||
const char* end, uint16_t* hs, uint16_t* ls);
|
|
||||||
} // namespace FsUtf
|
|
||||||
#endif // FsUtf_h
|
|
36
extra-libraries/ESP32/SdFat-2.2.3/.gitignore
vendored
Normal file
36
extra-libraries/ESP32/SdFat-2.2.3/.gitignore
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Operating System Files
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must ends with two \r.
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear on external disk
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
@ -1,8 +1,8 @@
|
|||||||
### Warning: This is SdFat Version 2.
|
File copy constructors and file assignment operators have been made private by
|
||||||
|
default in 2.2.3 to prevent call by value and multiple copies of file instances.
|
||||||
|
|
||||||
Earlier releases of Version 1 are here:
|
SdFatConfig.h has options to make file constructors and assignment operators
|
||||||
|
public.
|
||||||
https://github.com/greiman/SdFat/releases
|
|
||||||
|
|
||||||
UTF-8 encoded filenames are supported in v2.1.0 or later.
|
UTF-8 encoded filenames are supported in v2.1.0 or later.
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
# Doxyfile 1.9.2
|
# Doxyfile 1.9.6
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project.
|
# doxygen (www.doxygen.org) for a project.
|
||||||
@ -12,6 +12,16 @@
|
|||||||
# For lists, items can also be appended using:
|
# For lists, items can also be appended using:
|
||||||
# TAG += value [value, ...]
|
# TAG += value [value, ...]
|
||||||
# Values that contain spaces should be placed between quotes (\" \").
|
# Values that contain spaces should be placed between quotes (\" \").
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
#
|
||||||
|
# Use doxygen to compare the used configuration file with the template
|
||||||
|
# configuration file:
|
||||||
|
# doxygen -x [configFile]
|
||||||
|
# Use doxygen to compare the used configuration file with the template
|
||||||
|
# configuration file without replacing the environment variables or CMake type
|
||||||
|
# replacement variables:
|
||||||
|
# doxygen -x_noenv [configFile]
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Project related configuration options
|
# Project related configuration options
|
||||||
@ -60,16 +70,28 @@ PROJECT_LOGO =
|
|||||||
|
|
||||||
OUTPUT_DIRECTORY = .
|
OUTPUT_DIRECTORY = .
|
||||||
|
|
||||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
|
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
|
||||||
# directories (in 2 levels) under the output directory of each output format and
|
# sub-directories (in 2 levels) under the output directory of each output format
|
||||||
# will distribute the generated files over these directories. Enabling this
|
# and will distribute the generated files over these directories. Enabling this
|
||||||
# option can be useful when feeding doxygen a huge amount of source files, where
|
# option can be useful when feeding doxygen a huge amount of source files, where
|
||||||
# putting all generated files in the same directory would otherwise causes
|
# putting all generated files in the same directory would otherwise causes
|
||||||
# performance problems for the file system.
|
# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to
|
||||||
|
# control the number of sub-directories.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
CREATE_SUBDIRS = NO
|
CREATE_SUBDIRS = NO
|
||||||
|
|
||||||
|
# Controls the number of sub-directories that will be created when
|
||||||
|
# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every
|
||||||
|
# level increment doubles the number of directories, resulting in 4096
|
||||||
|
# directories at level 8 which is the default and also the maximum value. The
|
||||||
|
# sub-directories are organized in 2 levels, the first level always has a fixed
|
||||||
|
# number of 16 directories.
|
||||||
|
# Minimum value: 0, maximum value: 8, default value: 8.
|
||||||
|
# This tag requires that the tag CREATE_SUBDIRS is set to YES.
|
||||||
|
|
||||||
|
CREATE_SUBDIRS_LEVEL = 8
|
||||||
|
|
||||||
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
|
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
|
||||||
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
||||||
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
|
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
|
||||||
@ -81,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO
|
|||||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||||
# documentation generated by doxygen is written. Doxygen will use this
|
# documentation generated by doxygen is written. Doxygen will use this
|
||||||
# information to generate all constant output in the proper language.
|
# information to generate all constant output in the proper language.
|
||||||
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
|
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian,
|
||||||
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
|
# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English
|
||||||
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
|
# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek,
|
||||||
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
|
# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with
|
||||||
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
|
# English messages), Korean, Korean-en (Korean with English messages), Latvian,
|
||||||
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
|
# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese,
|
||||||
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
|
# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish,
|
||||||
# Ukrainian and Vietnamese.
|
# Swedish, Turkish, Ukrainian and Vietnamese.
|
||||||
# The default value is: English.
|
# The default value is: English.
|
||||||
|
|
||||||
OUTPUT_LANGUAGE = English
|
OUTPUT_LANGUAGE = English
|
||||||
@ -452,7 +474,7 @@ TYPEDEF_HIDES_STRUCT = NO
|
|||||||
|
|
||||||
LOOKUP_CACHE_SIZE = 0
|
LOOKUP_CACHE_SIZE = 0
|
||||||
|
|
||||||
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
|
# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use
|
||||||
# during processing. When set to 0 doxygen will based this on the number of
|
# during processing. When set to 0 doxygen will based this on the number of
|
||||||
# cores available in the system. You can set it explicitly to a value larger
|
# cores available in the system. You can set it explicitly to a value larger
|
||||||
# than 0 to get more control over the balance between CPU load and processing
|
# than 0 to get more control over the balance between CPU load and processing
|
||||||
@ -546,7 +568,8 @@ HIDE_UNDOC_MEMBERS = NO
|
|||||||
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
|
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
|
||||||
# undocumented classes that are normally visible in the class hierarchy. If set
|
# undocumented classes that are normally visible in the class hierarchy. If set
|
||||||
# to NO, these classes will be included in the various overviews. This option
|
# to NO, these classes will be included in the various overviews. This option
|
||||||
# has no effect if EXTRACT_ALL is enabled.
|
# will also hide undocumented C++ concepts if enabled. This option has no effect
|
||||||
|
# if EXTRACT_ALL is enabled.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_UNDOC_CLASSES = NO
|
HIDE_UNDOC_CLASSES = NO
|
||||||
@ -577,14 +600,15 @@ INTERNAL_DOCS = NO
|
|||||||
# filesystem is case sensitive (i.e. it supports files in the same directory
|
# filesystem is case sensitive (i.e. it supports files in the same directory
|
||||||
# whose names only differ in casing), the option must be set to YES to properly
|
# whose names only differ in casing), the option must be set to YES to properly
|
||||||
# deal with such files in case they appear in the input. For filesystems that
|
# deal with such files in case they appear in the input. For filesystems that
|
||||||
# are not case sensitive the option should be be set to NO to properly deal with
|
# are not case sensitive the option should be set to NO to properly deal with
|
||||||
# output files written for symbols that only differ in casing, such as for two
|
# output files written for symbols that only differ in casing, such as for two
|
||||||
# classes, one named CLASS and the other named Class, and to also support
|
# classes, one named CLASS and the other named Class, and to also support
|
||||||
# references to files without having to specify the exact matching casing. On
|
# references to files without having to specify the exact matching casing. On
|
||||||
# Windows (including Cygwin) and MacOS, users should typically set this option
|
# Windows (including Cygwin) and MacOS, users should typically set this option
|
||||||
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
||||||
# YES.
|
# YES.
|
||||||
# The default value is: system dependent.
|
# Possible values are: SYSTEM, NO and YES.
|
||||||
|
# The default value is: SYSTEM.
|
||||||
|
|
||||||
CASE_SENSE_NAMES = NO
|
CASE_SENSE_NAMES = NO
|
||||||
|
|
||||||
@ -836,6 +860,14 @@ WARN_IF_INCOMPLETE_DOC = YES
|
|||||||
|
|
||||||
WARN_NO_PARAMDOC = YES
|
WARN_NO_PARAMDOC = YES
|
||||||
|
|
||||||
|
# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about
|
||||||
|
# undocumented enumeration values. If set to NO, doxygen will accept
|
||||||
|
# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag
|
||||||
|
# will automatically be disabled.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
WARN_IF_UNDOC_ENUM_VAL = NO
|
||||||
|
|
||||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||||
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
||||||
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
||||||
@ -851,13 +883,27 @@ WARN_AS_ERROR = NO
|
|||||||
# and the warning text. Optionally the format may contain $version, which will
|
# and the warning text. Optionally the format may contain $version, which will
|
||||||
# be replaced by the version of the file (if it could be obtained via
|
# be replaced by the version of the file (if it could be obtained via
|
||||||
# FILE_VERSION_FILTER)
|
# FILE_VERSION_FILTER)
|
||||||
|
# See also: WARN_LINE_FORMAT
|
||||||
# The default value is: $file:$line: $text.
|
# The default value is: $file:$line: $text.
|
||||||
|
|
||||||
WARN_FORMAT = "$file:$line: $text"
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
|
||||||
|
# In the $text part of the WARN_FORMAT command it is possible that a reference
|
||||||
|
# to a more specific place is given. To make it easier to jump to this place
|
||||||
|
# (outside of doxygen) the user can define a custom "cut" / "paste" string.
|
||||||
|
# Example:
|
||||||
|
# WARN_LINE_FORMAT = "'vi $file +$line'"
|
||||||
|
# See also: WARN_FORMAT
|
||||||
|
# The default value is: at line $line of file $file.
|
||||||
|
|
||||||
|
WARN_LINE_FORMAT = "at line $line of file $file"
|
||||||
|
|
||||||
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
|
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
|
||||||
# messages should be written. If left blank the output is written to standard
|
# messages should be written. If left blank the output is written to standard
|
||||||
# error (stderr).
|
# error (stderr). In case the file specified cannot be opened for writing the
|
||||||
|
# warning and error messages are written to standard error. When as file - is
|
||||||
|
# specified the warning and error messages are written to standard output
|
||||||
|
# (stdout).
|
||||||
|
|
||||||
WARN_LOGFILE =
|
WARN_LOGFILE =
|
||||||
|
|
||||||
@ -887,10 +933,21 @@ INPUT = ../src \
|
|||||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||||
# documentation (see:
|
# documentation (see:
|
||||||
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
||||||
|
# See also: INPUT_FILE_ENCODING
|
||||||
# The default value is: UTF-8.
|
# The default value is: UTF-8.
|
||||||
|
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
|
|
||||||
|
# This tag can be used to specify the character encoding of the source files
|
||||||
|
# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify
|
||||||
|
# character encoding on a per file pattern basis. Doxygen will compare the file
|
||||||
|
# name with each pattern and apply the encoding instead of the default
|
||||||
|
# INPUT_ENCODING) if there is a match. The character encodings are a list of the
|
||||||
|
# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding
|
||||||
|
# "INPUT_ENCODING" for further information on supported encodings.
|
||||||
|
|
||||||
|
INPUT_FILE_ENCODING =
|
||||||
|
|
||||||
# If the value of the INPUT tag contains directories, you can use the
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
|
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
|
||||||
# *.h) to filter out the source-files in the directories.
|
# *.h) to filter out the source-files in the directories.
|
||||||
@ -981,7 +1038,7 @@ EXCLUDE_PATTERNS =
|
|||||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||||
# output. The symbol name can be a fully qualified name, a word, or if the
|
# output. The symbol name can be a fully qualified name, a word, or if the
|
||||||
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
||||||
# AClass::ANamespace, ANamespace::*Test
|
# ANamespace::AClass, ANamespace::*Test
|
||||||
#
|
#
|
||||||
# Note that the wildcards are matched against the file with absolute path, so to
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
# exclude all test directories use the pattern */test/*
|
# exclude all test directories use the pattern */test/*
|
||||||
@ -1029,6 +1086,11 @@ IMAGE_PATH =
|
|||||||
# code is scanned, but not when the output code is generated. If lines are added
|
# code is scanned, but not when the output code is generated. If lines are added
|
||||||
# or removed, the anchors will not be placed correctly.
|
# or removed, the anchors will not be placed correctly.
|
||||||
#
|
#
|
||||||
|
# Note that doxygen will use the data processed and written to standard output
|
||||||
|
# for further processing, therefore nothing else, like debug statements or used
|
||||||
|
# commands (so in case of a Windows batch file always use @echo OFF), should be
|
||||||
|
# written to standard output.
|
||||||
|
#
|
||||||
# Note that for custom extensions or not directly supported extensions you also
|
# Note that for custom extensions or not directly supported extensions you also
|
||||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||||
# properly processed by doxygen.
|
# properly processed by doxygen.
|
||||||
@ -1070,6 +1132,15 @@ FILTER_SOURCE_PATTERNS =
|
|||||||
|
|
||||||
USE_MDFILE_AS_MAINPAGE =
|
USE_MDFILE_AS_MAINPAGE =
|
||||||
|
|
||||||
|
# The Fortran standard specifies that for fixed formatted Fortran code all
|
||||||
|
# characters from position 72 are to be considered as comment. A common
|
||||||
|
# extension is to allow longer lines before the automatic comment starts. The
|
||||||
|
# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can
|
||||||
|
# be processed before the automatic comment starts.
|
||||||
|
# Minimum value: 7, maximum value: 10000, default value: 72.
|
||||||
|
|
||||||
|
FORTRAN_COMMENT_AFTER = 72
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to source browsing
|
# Configuration options related to source browsing
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -1207,10 +1278,11 @@ CLANG_DATABASE_PATH =
|
|||||||
|
|
||||||
ALPHABETICAL_INDEX = NO
|
ALPHABETICAL_INDEX = NO
|
||||||
|
|
||||||
# In case all classes in a project start with a common prefix, all classes will
|
# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes)
|
||||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
# that should be ignored while generating the index headers. The IGNORE_PREFIX
|
||||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
# tag works for classes, function and member names. The entity will be placed in
|
||||||
# while generating the index headers.
|
# the alphabetical list under the first letter of the entity name that remains
|
||||||
|
# after removing the prefix.
|
||||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||||
|
|
||||||
IGNORE_PREFIX =
|
IGNORE_PREFIX =
|
||||||
@ -1289,7 +1361,12 @@ HTML_STYLESHEET =
|
|||||||
# Doxygen will copy the style sheet files to the output directory.
|
# Doxygen will copy the style sheet files to the output directory.
|
||||||
# Note: The order of the extra style sheet files is of importance (e.g. the last
|
# Note: The order of the extra style sheet files is of importance (e.g. the last
|
||||||
# style sheet in the list overrules the setting of the previous ones in the
|
# style sheet in the list overrules the setting of the previous ones in the
|
||||||
# list). For an example see the documentation.
|
# list).
|
||||||
|
# Note: Since the styling of scrollbars can currently not be overruled in
|
||||||
|
# Webkit/Chromium, the styling will be left out of the default doxygen.css if
|
||||||
|
# one or more extra stylesheets have been specified. So if scrollbar
|
||||||
|
# customization is desired it has to be added explicitly. For an example see the
|
||||||
|
# documentation.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_EXTRA_STYLESHEET =
|
HTML_EXTRA_STYLESHEET =
|
||||||
@ -1304,6 +1381,19 @@ HTML_EXTRA_STYLESHEET =
|
|||||||
|
|
||||||
HTML_EXTRA_FILES =
|
HTML_EXTRA_FILES =
|
||||||
|
|
||||||
|
# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
|
||||||
|
# should be rendered with a dark or light theme.
|
||||||
|
# Possible values are: LIGHT always generate light mode output, DARK always
|
||||||
|
# generate dark mode output, AUTO_LIGHT automatically set the mode according to
|
||||||
|
# the user preference, use light mode if no preference is set (the default),
|
||||||
|
# AUTO_DARK automatically set the mode according to the user preference, use
|
||||||
|
# dark mode if no preference is set and TOGGLE allow to user to switch between
|
||||||
|
# light and dark mode via a button.
|
||||||
|
# The default value is: AUTO_LIGHT.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_COLORSTYLE = AUTO_LIGHT
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||||
# will adjust the colors in the style sheet and background images according to
|
# will adjust the colors in the style sheet and background images according to
|
||||||
# this color. Hue is specified as an angle on a color-wheel, see
|
# this color. Hue is specified as an angle on a color-wheel, see
|
||||||
@ -1398,6 +1488,13 @@ GENERATE_DOCSET = NO
|
|||||||
|
|
||||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||||
|
|
||||||
|
# This tag determines the URL of the docset feed. A documentation feed provides
|
||||||
|
# an umbrella under which multiple documentation sets from a single provider
|
||||||
|
# (such as a company or product suite) can be grouped.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
|
DOCSET_FEEDURL =
|
||||||
|
|
||||||
# This tag specifies a string that should uniquely identify the documentation
|
# This tag specifies a string that should uniquely identify the documentation
|
||||||
# set bundle. This should be a reverse domain-name style string, e.g.
|
# set bundle. This should be a reverse domain-name style string, e.g.
|
||||||
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
|
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
|
||||||
@ -1602,7 +1699,7 @@ GENERATE_TREEVIEW = NO
|
|||||||
# area (value NO) or if it should extend to the full height of the window (value
|
# area (value NO) or if it should extend to the full height of the window (value
|
||||||
# YES). Setting this to YES gives a layout similar to
|
# YES). Setting this to YES gives a layout similar to
|
||||||
# https://docs.readthedocs.io with more room for contents, but less room for the
|
# https://docs.readthedocs.io with more room for contents, but less room for the
|
||||||
# project logo, title, and description. If either GENERATOR_TREEVIEW or
|
# project logo, title, and description. If either GENERATE_TREEVIEW or
|
||||||
# DISABLE_INDEX is set to NO, this option has no effect.
|
# DISABLE_INDEX is set to NO, this option has no effect.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
@ -1633,6 +1730,13 @@ TREEVIEW_WIDTH = 250
|
|||||||
|
|
||||||
EXT_LINKS_IN_WINDOW = NO
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
|
||||||
|
# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email
|
||||||
|
# addresses.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
OBFUSCATE_EMAILS = YES
|
||||||
|
|
||||||
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
|
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
|
||||||
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
||||||
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
||||||
@ -1653,17 +1757,6 @@ HTML_FORMULA_FORMAT = png
|
|||||||
|
|
||||||
FORMULA_FONTSIZE = 10
|
FORMULA_FONTSIZE = 10
|
||||||
|
|
||||||
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
|
|
||||||
# generated for formulas are transparent PNGs. Transparent PNGs are not
|
|
||||||
# supported properly for IE 6.0, but are supported on all modern browsers.
|
|
||||||
#
|
|
||||||
# Note that when changing this option you need to delete any form_*.png files in
|
|
||||||
# the HTML output directory before the changes have effect.
|
|
||||||
# The default value is: YES.
|
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
|
||||||
|
|
||||||
FORMULA_TRANSPARENT = YES
|
|
||||||
|
|
||||||
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
||||||
# to create new LaTeX commands to be used in formulas as building blocks. See
|
# to create new LaTeX commands to be used in formulas as building blocks. See
|
||||||
# the section "Including formulas" for details.
|
# the section "Including formulas" for details.
|
||||||
@ -2258,7 +2351,8 @@ SEARCH_INCLUDES = YES
|
|||||||
|
|
||||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||||
# contain include files that are not input files but should be processed by the
|
# contain include files that are not input files but should be processed by the
|
||||||
# preprocessor.
|
# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of
|
||||||
|
# RECURSIVE has no effect here.
|
||||||
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
||||||
|
|
||||||
INCLUDE_PATH =
|
INCLUDE_PATH =
|
||||||
@ -2354,15 +2448,6 @@ EXTERNAL_PAGES = YES
|
|||||||
# Configuration options related to the dot tool
|
# Configuration options related to the dot tool
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
|
|
||||||
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
|
|
||||||
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
|
|
||||||
# disabled, but it is recommended to install and use dot, since it yields more
|
|
||||||
# powerful graphs.
|
|
||||||
# The default value is: YES.
|
|
||||||
|
|
||||||
CLASS_DIAGRAMS = YES
|
|
||||||
|
|
||||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||||
# then run dia to produce the diagram and insert it in the documentation. The
|
# then run dia to produce the diagram and insert it in the documentation. The
|
||||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||||
@ -2395,35 +2480,50 @@ HAVE_DOT = YES
|
|||||||
|
|
||||||
DOT_NUM_THREADS = 0
|
DOT_NUM_THREADS = 0
|
||||||
|
|
||||||
# When you want a differently looking font in the dot files that doxygen
|
# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of
|
||||||
# generates you can specify the font name using DOT_FONTNAME. You need to make
|
# subgraphs. When you want a differently looking font in the dot files that
|
||||||
# sure dot is able to find the font, which can be done by putting it in a
|
# doxygen generates you can specify fontname, fontcolor and fontsize attributes.
|
||||||
# standard location or by setting the DOTFONTPATH environment variable or by
|
# For details please see <a href=https://graphviz.org/doc/info/attrs.html>Node,
|
||||||
# setting DOT_FONTPATH to the directory containing the font.
|
# Edge and Graph Attributes specification</a> You need to make sure dot is able
|
||||||
# The default value is: Helvetica.
|
# to find the font, which can be done by putting it in a standard location or by
|
||||||
|
# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
|
||||||
|
# directory containing the font. Default graphviz fontsize is 14.
|
||||||
|
# The default value is: fontname=Helvetica,fontsize=10.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_FONTNAME = Helvetica
|
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
|
||||||
|
|
||||||
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
|
# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can
|
||||||
# dot graphs.
|
# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. <a
|
||||||
# Minimum value: 4, maximum value: 24, default value: 10.
|
# href=https://graphviz.org/doc/info/arrows.html>Complete documentation about
|
||||||
|
# arrows shapes.</a>
|
||||||
|
# The default value is: labelfontname=Helvetica,labelfontsize=10.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_FONTSIZE = 10
|
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
|
||||||
|
|
||||||
# By default doxygen will tell dot to use the default font as specified with
|
# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes
|
||||||
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
|
# around nodes set 'shape=plain' or 'shape=plaintext' <a
|
||||||
# the path where dot can find it using this tag.
|
# href=https://www.graphviz.org/doc/info/shapes.html>Shapes specification</a>
|
||||||
|
# The default value is: shape=box,height=0.2,width=0.4.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
|
||||||
|
|
||||||
|
# You can set the path where dot can find font specified with fontname in
|
||||||
|
# DOT_COMMON_ATTR and others dot attributes.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_FONTPATH =
|
DOT_FONTPATH =
|
||||||
|
|
||||||
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
|
# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
|
||||||
# each documented class showing the direct and indirect inheritance relations.
|
# graph for each documented class showing the direct and indirect inheritance
|
||||||
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
|
# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
|
||||||
|
# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
|
||||||
|
# to TEXT the direct and indirect inheritance relations will be shown as texts /
|
||||||
|
# links.
|
||||||
|
# Possible values are: NO, YES, TEXT and GRAPH.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
|
||||||
|
|
||||||
CLASS_GRAPH = YES
|
CLASS_GRAPH = YES
|
||||||
|
|
||||||
@ -2437,7 +2537,8 @@ CLASS_GRAPH = YES
|
|||||||
COLLABORATION_GRAPH = YES
|
COLLABORATION_GRAPH = YES
|
||||||
|
|
||||||
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
|
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
|
||||||
# groups, showing the direct groups dependencies.
|
# groups, showing the direct groups dependencies. See also the chapter Grouping
|
||||||
|
# in the manual.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
@ -2552,6 +2653,13 @@ GRAPHICAL_HIERARCHY = YES
|
|||||||
|
|
||||||
DIRECTORY_GRAPH = YES
|
DIRECTORY_GRAPH = YES
|
||||||
|
|
||||||
|
# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels
|
||||||
|
# of child directories generated in directory dependency graphs by dot.
|
||||||
|
# Minimum value: 1, maximum value: 25, default value: 1.
|
||||||
|
# This tag requires that the tag DIRECTORY_GRAPH is set to YES.
|
||||||
|
|
||||||
|
DIR_GRAPH_MAX_DEPTH = 1
|
||||||
|
|
||||||
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
||||||
# generated by dot. For an explanation of the image formats see the section
|
# generated by dot. For an explanation of the image formats see the section
|
||||||
# output formats in the documentation of the dot tool (Graphviz (see:
|
# output formats in the documentation of the dot tool (Graphviz (see:
|
||||||
@ -2605,10 +2713,10 @@ MSCFILE_DIRS =
|
|||||||
DIAFILE_DIRS =
|
DIAFILE_DIRS =
|
||||||
|
|
||||||
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
|
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
|
||||||
# path where java can find the plantuml.jar file. If left blank, it is assumed
|
# path where java can find the plantuml.jar file or to the filename of jar file
|
||||||
# PlantUML is not used or called during a preprocessing step. Doxygen will
|
# to be used. If left blank, it is assumed PlantUML is not used or called during
|
||||||
# generate a warning when it encounters a \startuml command in this case and
|
# a preprocessing step. Doxygen will generate a warning when it encounters a
|
||||||
# will not generate output for the diagram.
|
# \startuml command in this case and will not generate output for the diagram.
|
||||||
|
|
||||||
PLANTUML_JAR_PATH =
|
PLANTUML_JAR_PATH =
|
||||||
|
|
||||||
@ -2646,18 +2754,6 @@ DOT_GRAPH_MAX_NODES = 50
|
|||||||
|
|
||||||
MAX_DOT_GRAPH_DEPTH = 1000
|
MAX_DOT_GRAPH_DEPTH = 1000
|
||||||
|
|
||||||
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
|
||||||
# background. This is disabled by default, because dot on Windows does not seem
|
|
||||||
# to support this out of the box.
|
|
||||||
#
|
|
||||||
# Warning: Depending on the platform used, enabling this option may lead to
|
|
||||||
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
|
|
||||||
# read).
|
|
||||||
# The default value is: NO.
|
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
|
||||||
|
|
||||||
DOT_TRANSPARENT = YES
|
|
||||||
|
|
||||||
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
|
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
|
||||||
# files in one run (i.e. multiple -o and -T options on the command line). This
|
# files in one run (i.e. multiple -o and -T options on the command line). This
|
||||||
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
|
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
|
||||||
@ -2670,6 +2766,8 @@ DOT_MULTI_TARGETS = NO
|
|||||||
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
|
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
|
||||||
# explaining the meaning of the various boxes and arrows in the dot generated
|
# explaining the meaning of the various boxes and arrows in the dot generated
|
||||||
# graphs.
|
# graphs.
|
||||||
|
# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
|
||||||
|
# graphical representation for inheritance and collaboration diagrams is used.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
51
extra-libraries/ESP32/SdFat-2.2.3/doc/SdErrorCodes.txt
Normal file
51
extra-libraries/ESP32/SdFat-2.2.3/doc/SdErrorCodes.txt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
2022-07-01
|
||||||
|
|
||||||
|
Run the SdErrorCode example to produce an updated list.
|
||||||
|
|
||||||
|
Code,Symbol - failed operation
|
||||||
|
0X00,SD_CARD_ERROR_NONE - No error
|
||||||
|
0X01,SD_CARD_ERROR_CMD0 - Card reset failed
|
||||||
|
0X02,SD_CARD_ERROR_CMD2 - SDIO read CID
|
||||||
|
0X03,SD_CARD_ERROR_CMD3 - SDIO publish RCA
|
||||||
|
0X04,SD_CARD_ERROR_CMD6 - Switch card function
|
||||||
|
0X05,SD_CARD_ERROR_CMD7 - SDIO card select
|
||||||
|
0X06,SD_CARD_ERROR_CMD8 - Send and check interface settings
|
||||||
|
0X07,SD_CARD_ERROR_CMD9 - Read CSD data
|
||||||
|
0X08,SD_CARD_ERROR_CMD10 - Read CID data
|
||||||
|
0X09,SD_CARD_ERROR_CMD12 - Stop multiple block read
|
||||||
|
0X0A,SD_CARD_ERROR_CMD13 - Read card status
|
||||||
|
0X0B,SD_CARD_ERROR_CMD17 - Read single block
|
||||||
|
0X0C,SD_CARD_ERROR_CMD18 - Read multiple blocks
|
||||||
|
0X0D,SD_CARD_ERROR_CMD24 - Write single block
|
||||||
|
0X0E,SD_CARD_ERROR_CMD25 - Write multiple blocks
|
||||||
|
0X0F,SD_CARD_ERROR_CMD32 - Set first erase block
|
||||||
|
0X10,SD_CARD_ERROR_CMD33 - Set last erase block
|
||||||
|
0X11,SD_CARD_ERROR_CMD38 - Erase selected blocks
|
||||||
|
0X12,SD_CARD_ERROR_CMD58 - Read OCR register
|
||||||
|
0X13,SD_CARD_ERROR_CMD59 - Set CRC mode
|
||||||
|
0X14,SD_CARD_ERROR_ACMD6 - Set SDIO bus width
|
||||||
|
0X15,SD_CARD_ERROR_ACMD13 - Read extended status
|
||||||
|
0X16,SD_CARD_ERROR_ACMD23 - Set pre-erased count
|
||||||
|
0X17,SD_CARD_ERROR_ACMD41 - Activate card initialization
|
||||||
|
0X18,SD_CARD_ERROR_ACMD51 - Read SCR data
|
||||||
|
0X19,SD_CARD_ERROR_READ_TOKEN - Bad read data token
|
||||||
|
0X1A,SD_CARD_ERROR_READ_CRC - Read CRC error
|
||||||
|
0X1B,SD_CARD_ERROR_READ_FIFO - SDIO fifo read timeout
|
||||||
|
0X1C,SD_CARD_ERROR_READ_REG - Read CID or CSD failed.
|
||||||
|
0X1D,SD_CARD_ERROR_READ_START - Bad readStart argument
|
||||||
|
0X1E,SD_CARD_ERROR_READ_TIMEOUT - Read data timeout
|
||||||
|
0X1F,SD_CARD_ERROR_STOP_TRAN - Multiple block stop failed
|
||||||
|
0X20,SD_CARD_ERROR_TRANSFER_COMPLETE - SDIO transfer complete
|
||||||
|
0X21,SD_CARD_ERROR_WRITE_DATA - Write data not accepted
|
||||||
|
0X22,SD_CARD_ERROR_WRITE_FIFO - SDIO fifo write timeout
|
||||||
|
0X23,SD_CARD_ERROR_WRITE_START - Bad writeStart argument
|
||||||
|
0X24,SD_CARD_ERROR_WRITE_PROGRAMMING - Flash programming
|
||||||
|
0X25,SD_CARD_ERROR_WRITE_TIMEOUT - Write timeout
|
||||||
|
0X26,SD_CARD_ERROR_DMA - DMA transfer failed
|
||||||
|
0X27,SD_CARD_ERROR_ERASE - Card did not accept erase commands
|
||||||
|
0X28,SD_CARD_ERROR_ERASE_SINGLE_SECTOR - Card does not support erase
|
||||||
|
0X29,SD_CARD_ERROR_ERASE_TIMEOUT - Erase command timeout
|
||||||
|
0X2A,SD_CARD_ERROR_INIT_NOT_CALLED - Card has not been initialized
|
||||||
|
0X2B,SD_CARD_ERROR_INVALID_CARD_CONFIG - Invalid card config
|
||||||
|
0X2C,SD_CARD_ERROR_FUNCTION_NOT_SUPPORTED - Unsupported SDIO command
|
||||||
|
0X2D,SD_CARD_ERROR_UNKNOWN - Unknown error
|
BIN
extra-libraries/ESP32/SdFat-2.2.3/doc/html.zip
Normal file
BIN
extra-libraries/ESP32/SdFat-2.2.3/doc/html.zip
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2011-2021 Bill Greiman
|
* Copyright (c) 2011-2024 Bill Greiman
|
||||||
* This file is part of the SdFat library for SD memory cards.
|
* This file is part of the SdFat library for SD memory cards.
|
||||||
*
|
*
|
||||||
* MIT License
|
* MIT License
|
||||||
@ -31,19 +31,19 @@ This is a major new version of SdFat. It is mostly
|
|||||||
backward compatible with SdFat Version 1 for FAT16/FAT32 cards.
|
backward compatible with SdFat Version 1 for FAT16/FAT32 cards.
|
||||||
|
|
||||||
You should edit SdFatConfig.h to select features. The default version of
|
You should edit SdFatConfig.h to select features. The default version of
|
||||||
SdFatConfig.h is suitable for UNO and other small AVR boards.
|
SdFatConfig.h is suitable for UNO and other small AVR boards.
|
||||||
|
|
||||||
\section Intro Introduction
|
\section Intro Introduction
|
||||||
|
|
||||||
The Arduino %SdFat library supports FAT16, FAT32, and exFAT file systems
|
The Arduino %SdFat library supports FAT16, FAT32, and exFAT file systems
|
||||||
on Standard SD, SDHC, and SDXC cards.
|
on Standard SD, SDHC, and SDXC cards.
|
||||||
|
|
||||||
In %SdFat version 1, SdFat and File are the main classes.
|
In %SdFat version 1, SdFat and File are the main classes.
|
||||||
|
|
||||||
In %SdFat version 2, SdFat and File are defined by typedefs in terms of the
|
In %SdFat version 2, SdFat and File are defined by typedefs in terms of the
|
||||||
following classes.
|
following classes.
|
||||||
|
|
||||||
The file system classes in the %SdFat library are SdFat32, SdExFat, and SdFs.
|
The file system classes in the %SdFat library are SdFat32, SdExFat, and SdFs.
|
||||||
SdFat32 supports FAT16 and FAT32. SdExFat supports exFAT, SdFs supports
|
SdFat32 supports FAT16 and FAT32. SdExFat supports exFAT, SdFs supports
|
||||||
FAT16, FAT32, and exFAT.
|
FAT16, FAT32, and exFAT.
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ boards.
|
|||||||
#endif // defined(__AVR__) && FLASHEND < 0X8000
|
#endif // defined(__AVR__) && FLASHEND < 0X8000
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
It is possible to use option three, support or FAT16/FAT32 and exFat
|
It is possible to use option three, support or FAT16/FAT32 and exFat
|
||||||
on an Uno or other AVR board with 32KB flash and 2KB SRAM but memory
|
on an Uno or other AVR board with 32KB flash and 2KB SRAM but memory
|
||||||
will be very limited.
|
will be very limited.
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ Uno memory use for a simple data logger is:
|
|||||||
>
|
>
|
||||||
> option 2, exFAT, 14942 bytes of flash and 895 bytes of SRAM.
|
> option 2, exFAT, 14942 bytes of flash and 895 bytes of SRAM.
|
||||||
>
|
>
|
||||||
> option 3, FAT16/FAT32 and exFAT, 21834 bytes of flash and 908 bytes of SRAM.
|
> option 3, FAT16/FAT32 and exFAT, 21834 bytes of flash and 908 bytes of SRAM.
|
||||||
|
|
||||||
Please read documentation under the above classes tab for more information.
|
Please read documentation under the above classes tab for more information.
|
||||||
|
|
||||||
@ -113,8 +113,8 @@ multi-block write.
|
|||||||
|
|
||||||
Relative paths in %SdFat are resolved in a manner similar to Windows.
|
Relative paths in %SdFat are resolved in a manner similar to Windows.
|
||||||
|
|
||||||
Each instance of SdFat32, SdExFat, and SdFs has a current directory.
|
Each instance of SdFat32, SdExFat, and SdFs has a current directory.
|
||||||
This directory is called the volume working directory, vwd.
|
This directory is called the volume working directory, vwd.
|
||||||
Initially this directory is the root directory for the volume.
|
Initially this directory is the root directory for the volume.
|
||||||
|
|
||||||
The volume working directory is changed by calling the chdir(path).
|
The volume working directory is changed by calling the chdir(path).
|
||||||
@ -149,9 +149,9 @@ will open "/music/BigBand.wav" on sd2.
|
|||||||
|
|
||||||
\section Install Installation
|
\section Install Installation
|
||||||
|
|
||||||
You must manually install %SdFat by renaming the download folder %SdFat
|
You must manually install %SdFat by renaming the download folder %SdFat
|
||||||
and copy the %SdFat folder to the Arduino libraries folder in your
|
and copy the %SdFat folder to the Arduino libraries folder in your
|
||||||
sketchbook folder.
|
sketchbook folder.
|
||||||
|
|
||||||
It will be necessary to unzip and rename the folder if you download a zip
|
It will be necessary to unzip and rename the folder if you download a zip
|
||||||
file from GitHub.
|
file from GitHub.
|
@ -3,7 +3,8 @@
|
|||||||
const size_t BLOCK_SIZE = 64;
|
const size_t BLOCK_SIZE = 64;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// First block of file.
|
// First block of file.
|
||||||
const size_t PIN_NUM_DIM = BLOCK_SIZE - 3*sizeof(uint32_t) - 2*sizeof(uint8_t);
|
const size_t PIN_NUM_DIM =
|
||||||
|
BLOCK_SIZE - 3 * sizeof(uint32_t) - 2 * sizeof(uint8_t);
|
||||||
struct metadata_t {
|
struct metadata_t {
|
||||||
uint32_t adcFrequency; // ADC clock frequency
|
uint32_t adcFrequency; // ADC clock frequency
|
||||||
uint32_t cpuFrequency; // CPU clock frequency
|
uint32_t cpuFrequency; // CPU clock frequency
|
||||||
@ -14,15 +15,16 @@ struct metadata_t {
|
|||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Data block for 8-bit ADC mode.
|
// Data block for 8-bit ADC mode.
|
||||||
const size_t DATA_DIM8 = (BLOCK_SIZE - 2*sizeof(uint16_t))/sizeof(uint8_t);
|
const size_t DATA_DIM8 = (BLOCK_SIZE - 2 * sizeof(uint16_t)) / sizeof(uint8_t);
|
||||||
struct block8_t {
|
struct block8_t {
|
||||||
uint16_t count; // count of data values
|
uint16_t count; // count of data values
|
||||||
uint16_t overrun; // count of overruns since last block
|
uint16_t overrun; // count of overruns since last block
|
||||||
uint8_t data[DATA_DIM8];
|
uint8_t data[DATA_DIM8];
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Data block for 10-bit ADC mode.
|
// Data block for 10-bit ADC mode.
|
||||||
const size_t DATA_DIM16 = (BLOCK_SIZE - 2*sizeof(uint16_t))/sizeof(uint16_t);
|
const size_t DATA_DIM16 =
|
||||||
|
(BLOCK_SIZE - 2 * sizeof(uint16_t)) / sizeof(uint16_t);
|
||||||
struct block16_t {
|
struct block16_t {
|
||||||
unsigned short count; // count of data values
|
unsigned short count; // count of data values
|
||||||
unsigned short overrun; // count of overruns since last block
|
unsigned short overrun; // count of overruns since last block
|
@ -20,10 +20,11 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include "SdFat.h"
|
|
||||||
|
#include "AvrAdcLogger.h"
|
||||||
#include "BufferedPrint.h"
|
#include "BufferedPrint.h"
|
||||||
#include "FreeStack.h"
|
#include "FreeStack.h"
|
||||||
#include "AvrAdcLogger.h"
|
#include "SdFat.h"
|
||||||
|
|
||||||
// Save SRAM if 328.
|
// Save SRAM if 328.
|
||||||
#ifdef __AVR_ATmega328P__
|
#ifdef __AVR_ATmega328P__
|
||||||
@ -73,7 +74,7 @@ const float SAMPLE_RATE = 5000; // Must be 0.25 or greater.
|
|||||||
// constant instead of being calculated from SAMPLE_RATE. SAMPLE_RATE is not
|
// constant instead of being calculated from SAMPLE_RATE. SAMPLE_RATE is not
|
||||||
// used in the code below. For example, setting SAMPLE_INTERVAL = 2.0e-4
|
// used in the code below. For example, setting SAMPLE_INTERVAL = 2.0e-4
|
||||||
// will result in a 200 microsecond sample interval.
|
// will result in a 200 microsecond sample interval.
|
||||||
const float SAMPLE_INTERVAL = 1.0/SAMPLE_RATE;
|
const float SAMPLE_INTERVAL = 1.0 / SAMPLE_RATE;
|
||||||
|
|
||||||
// Setting ROUND_SAMPLE_INTERVAL non-zero will cause the sample interval to
|
// Setting ROUND_SAMPLE_INTERVAL non-zero will cause the sample interval to
|
||||||
// be rounded to a a multiple of the ADC clock period and will reduce sample
|
// be rounded to a a multiple of the ADC clock period and will reduce sample
|
||||||
@ -109,11 +110,11 @@ const size_t NAME_DIM = 40;
|
|||||||
#elif RAMEND < 0X10FF
|
#elif RAMEND < 0X10FF
|
||||||
const size_t FIFO_SIZE_BYTES = 512;
|
const size_t FIFO_SIZE_BYTES = 512;
|
||||||
#elif RAMEND < 0X20FF
|
#elif RAMEND < 0X20FF
|
||||||
const size_t FIFO_SIZE_BYTES = 4*512;
|
const size_t FIFO_SIZE_BYTES = 4 * 512;
|
||||||
#elif RAMEND < 0X40FF
|
#elif RAMEND < 0X40FF
|
||||||
const size_t FIFO_SIZE_BYTES = 12*512;
|
const size_t FIFO_SIZE_BYTES = 12 * 512;
|
||||||
#else // RAMEND
|
#else // RAMEND
|
||||||
const size_t FIFO_SIZE_BYTES = 16*512;
|
const size_t FIFO_SIZE_BYTES = 16 * 512;
|
||||||
#endif // RAMEND
|
#endif // RAMEND
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// ADC clock rate.
|
// ADC clock rate.
|
||||||
@ -136,7 +137,7 @@ const size_t FIFO_SIZE_BYTES = 16*512;
|
|||||||
#define TMP_FILE_NAME "tmp_adc.bin"
|
#define TMP_FILE_NAME "tmp_adc.bin"
|
||||||
|
|
||||||
// Number of analog pins to log.
|
// Number of analog pins to log.
|
||||||
const uint8_t PIN_COUNT = sizeof(PIN_LIST)/sizeof(PIN_LIST[0]);
|
const uint8_t PIN_COUNT = sizeof(PIN_LIST) / sizeof(PIN_LIST[0]);
|
||||||
|
|
||||||
// Minimum ADC clock cycles per sample interval
|
// Minimum ADC clock cycles per sample interval
|
||||||
const uint16_t MIN_ADC_CYCLES = 15;
|
const uint16_t MIN_ADC_CYCLES = 15;
|
||||||
@ -151,6 +152,7 @@ const uint32_t MAX_FILE_SIZE = MAX_FILE_SIZE_MiB << 20;
|
|||||||
|
|
||||||
// Max SPI rate for AVR is 10 MHz for F_CPU 20 MHz, 8 MHz for F_CPU 16 MHz.
|
// Max SPI rate for AVR is 10 MHz for F_CPU 20 MHz, 8 MHz for F_CPU 16 MHz.
|
||||||
#define SPI_CLOCK SD_SCK_MHZ(10)
|
#define SPI_CLOCK SD_SCK_MHZ(10)
|
||||||
|
|
||||||
// Select fastest interface.
|
// Select fastest interface.
|
||||||
#if ENABLE_DEDICATED_SPI
|
#if ENABLE_DEDICATED_SPI
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
||||||
@ -180,19 +182,19 @@ file_t csvFile;
|
|||||||
char binName[] = LOG_FILE_NAME;
|
char binName[] = LOG_FILE_NAME;
|
||||||
|
|
||||||
#if RECORD_EIGHT_BITS
|
#if RECORD_EIGHT_BITS
|
||||||
const size_t BLOCK_MAX_COUNT = PIN_COUNT*(DATA_DIM8/PIN_COUNT);
|
const size_t BLOCK_MAX_COUNT = PIN_COUNT * (DATA_DIM8 / PIN_COUNT);
|
||||||
typedef block8_t block_t;
|
typedef block8_t block_t;
|
||||||
#else // RECORD_EIGHT_BITS
|
#else // RECORD_EIGHT_BITS
|
||||||
const size_t BLOCK_MAX_COUNT = PIN_COUNT*(DATA_DIM16/PIN_COUNT);
|
const size_t BLOCK_MAX_COUNT = PIN_COUNT * (DATA_DIM16 / PIN_COUNT);
|
||||||
typedef block16_t block_t;
|
typedef block16_t block_t;
|
||||||
#endif // RECORD_EIGHT_BITS
|
#endif // RECORD_EIGHT_BITS
|
||||||
|
|
||||||
// Size of FIFO in blocks.
|
// Size of FIFO in blocks.
|
||||||
size_t const FIFO_DIM = FIFO_SIZE_BYTES/sizeof(block_t);
|
size_t const FIFO_DIM = FIFO_SIZE_BYTES / sizeof(block_t);
|
||||||
block_t* fifoData;
|
block_t* fifoData;
|
||||||
volatile size_t fifoCount = 0; // volatile - shared, ISR and background.
|
volatile size_t fifoCount = 0; // volatile - shared, ISR and background.
|
||||||
size_t fifoHead = 0; // Only accessed by ISR during logging.
|
size_t fifoHead = 0; // Only accessed by ISR during logging.
|
||||||
size_t fifoTail = 0; // Only accessed by writer during logging.
|
size_t fifoTail = 0; // Only accessed by writer during logging.
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Interrupt Service Routines
|
// Interrupt Service Routines
|
||||||
|
|
||||||
@ -219,7 +221,7 @@ ISR(ADC_vect) {
|
|||||||
// Read ADC data.
|
// Read ADC data.
|
||||||
#if RECORD_EIGHT_BITS
|
#if RECORD_EIGHT_BITS
|
||||||
uint8_t d = ADCH;
|
uint8_t d = ADCH;
|
||||||
#else // RECORD_EIGHT_BITS
|
#else // RECORD_EIGHT_BITS
|
||||||
// This will access ADCL first.
|
// This will access ADCL first.
|
||||||
uint16_t d = ADC;
|
uint16_t d = ADC;
|
||||||
#endif // RECORD_EIGHT_BITS
|
#endif // RECORD_EIGHT_BITS
|
||||||
@ -245,7 +247,7 @@ ISR(ADC_vect) {
|
|||||||
if (adcindex == 0) {
|
if (adcindex == 0) {
|
||||||
timerFlag = false;
|
timerFlag = false;
|
||||||
}
|
}
|
||||||
adcindex = adcindex < (PIN_COUNT - 1) ? adcindex + 1 : 0;
|
adcindex = adcindex < (PIN_COUNT - 1) ? adcindex + 1 : 0;
|
||||||
} else {
|
} else {
|
||||||
timerFlag = false;
|
timerFlag = false;
|
||||||
}
|
}
|
||||||
@ -277,7 +279,7 @@ ISR(TIMER1_COMPB_vect) {
|
|||||||
}
|
}
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Error messages stored in flash.
|
// Error messages stored in flash.
|
||||||
#define error(msg) (Serial.println(F(msg)),errorHalt())
|
#define error(msg) (Serial.println(F(msg)), errorHalt())
|
||||||
#define assert(e) ((e) ? (void)0 : error("assert: " #e))
|
#define assert(e) ((e) ? (void)0 : error("assert: " #e))
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@ -336,12 +338,13 @@ void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10) {
|
|||||||
#error unexpected ADC prescaler bits
|
#error unexpected ADC prescaler bits
|
||||||
#endif
|
#endif
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
inline bool adcActive() {return (1 << ADIE) & ADCSRA;}
|
inline bool adcActive() { return (1 << ADIE) & ADCSRA; }
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// initialize ADC and timer1
|
// initialize ADC and timer1
|
||||||
void adcInit(metadata_t* meta) {
|
void adcInit(metadata_t* meta) {
|
||||||
uint8_t adps; // prescaler bits for ADCSRA
|
uint8_t adps; // prescaler bits for ADCSRA
|
||||||
uint32_t ticks = F_CPU*SAMPLE_INTERVAL + 0.5; // Sample interval cpu cycles.
|
uint32_t ticks =
|
||||||
|
F_CPU * SAMPLE_INTERVAL + 0.5; // Sample interval cpu cycles.
|
||||||
|
|
||||||
if (ADC_REF & ~((1 << REFS0) | (1 << REFS1))) {
|
if (ADC_REF & ~((1 << REFS0) | (1 << REFS1))) {
|
||||||
error("Invalid ADC reference");
|
error("Invalid ADC reference");
|
||||||
@ -351,9 +354,9 @@ void adcInit(metadata_t* meta) {
|
|||||||
error("Invalid ADC prescaler");
|
error("Invalid ADC prescaler");
|
||||||
}
|
}
|
||||||
adps = ADC_PRESCALER;
|
adps = ADC_PRESCALER;
|
||||||
#else // ADC_PRESCALER
|
#else // ADC_PRESCALER
|
||||||
// Allow extra cpu cycles to change ADC settings if more than one pin.
|
// Allow extra cpu cycles to change ADC settings if more than one pin.
|
||||||
int32_t adcCycles = (ticks - ISR_TIMER0)/PIN_COUNT - ISR_SETUP_ADC;
|
int32_t adcCycles = (ticks - ISR_TIMER0) / PIN_COUNT - ISR_SETUP_ADC;
|
||||||
|
|
||||||
for (adps = 7; adps > 0; adps--) {
|
for (adps = 7; adps > 0; adps--) {
|
||||||
if (adcCycles >= (MIN_ADC_CYCLES << adps)) {
|
if (adcCycles >= (MIN_ADC_CYCLES << adps)) {
|
||||||
@ -410,19 +413,19 @@ void adcInit(metadata_t* meta) {
|
|||||||
// no prescale, CTC mode
|
// no prescale, CTC mode
|
||||||
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);
|
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);
|
||||||
tshift = 0;
|
tshift = 0;
|
||||||
} else if (ticks < 0X10000*8) {
|
} else if (ticks < 0X10000 * 8) {
|
||||||
// prescale 8, CTC mode
|
// prescale 8, CTC mode
|
||||||
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
|
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
|
||||||
tshift = 3;
|
tshift = 3;
|
||||||
} else if (ticks < 0X10000*64) {
|
} else if (ticks < 0X10000 * 64) {
|
||||||
// prescale 64, CTC mode
|
// prescale 64, CTC mode
|
||||||
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11) | (1 << CS10);
|
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11) | (1 << CS10);
|
||||||
tshift = 6;
|
tshift = 6;
|
||||||
} else if (ticks < 0X10000*256) {
|
} else if (ticks < 0X10000 * 256) {
|
||||||
// prescale 256, CTC mode
|
// prescale 256, CTC mode
|
||||||
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12);
|
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12);
|
||||||
tshift = 8;
|
tshift = 8;
|
||||||
} else if (ticks < 0X10000*1024) {
|
} else if (ticks < 0X10000 * 1024) {
|
||||||
// prescale 1024, CTC mode
|
// prescale 1024, CTC mode
|
||||||
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12) | (1 << CS10);
|
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12) | (1 << CS10);
|
||||||
tshift = 10;
|
tshift = 10;
|
||||||
@ -442,7 +445,7 @@ void adcInit(metadata_t* meta) {
|
|||||||
// Sample interval in CPU clock ticks.
|
// Sample interval in CPU clock ticks.
|
||||||
meta->sampleInterval = ticks;
|
meta->sampleInterval = ticks;
|
||||||
meta->cpuFrequency = F_CPU;
|
meta->cpuFrequency = F_CPU;
|
||||||
float sampleRate = (float)meta->cpuFrequency/meta->sampleInterval;
|
float sampleRate = (float)meta->cpuFrequency / meta->sampleInterval;
|
||||||
Serial.print(F("Sample pins:"));
|
Serial.print(F("Sample pins:"));
|
||||||
for (uint8_t i = 0; i < meta->pinCount; i++) {
|
for (uint8_t i = 0; i < meta->pinCount; i++) {
|
||||||
Serial.print(' ');
|
Serial.print(' ');
|
||||||
@ -452,11 +455,11 @@ void adcInit(metadata_t* meta) {
|
|||||||
Serial.print(F("ADC bits: "));
|
Serial.print(F("ADC bits: "));
|
||||||
Serial.println(meta->recordEightBits ? 8 : 10);
|
Serial.println(meta->recordEightBits ? 8 : 10);
|
||||||
Serial.print(F("ADC clock kHz: "));
|
Serial.print(F("ADC clock kHz: "));
|
||||||
Serial.println(meta->adcFrequency/1000);
|
Serial.println(meta->adcFrequency / 1000);
|
||||||
Serial.print(F("Sample Rate: "));
|
Serial.print(F("Sample Rate: "));
|
||||||
Serial.println(sampleRate);
|
Serial.println(sampleRate);
|
||||||
Serial.print(F("Sample interval usec: "));
|
Serial.print(F("Sample interval usec: "));
|
||||||
Serial.println(1000000.0/sampleRate);
|
Serial.println(1000000.0 / sampleRate);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// enable ADC and timer1 interrupts
|
// enable ADC and timer1 interrupts
|
||||||
@ -508,7 +511,7 @@ void binaryToCsv() {
|
|||||||
if (nb < 0) {
|
if (nb < 0) {
|
||||||
error("read binFile failed");
|
error("read binFile failed");
|
||||||
}
|
}
|
||||||
size_t nd = nb/sizeof(block_t);
|
size_t nd = nb / sizeof(block_t);
|
||||||
if (nd < 1) {
|
if (nd < 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -519,7 +522,8 @@ void binaryToCsv() {
|
|||||||
error("Invalid pinCount");
|
error("Invalid pinCount");
|
||||||
}
|
}
|
||||||
bp.print(F("Interval,"));
|
bp.print(F("Interval,"));
|
||||||
float intervalMicros = 1.0e6*pm->sampleInterval/(float)pm->cpuFrequency;
|
float intervalMicros =
|
||||||
|
1.0e6 * pm->sampleInterval / (float)pm->cpuFrequency;
|
||||||
bp.print(intervalMicros, 4);
|
bp.print(intervalMicros, 4);
|
||||||
bp.println(F(",usec"));
|
bp.println(F(",usec"));
|
||||||
for (uint8_t i = 0; i < PIN_COUNT; i++) {
|
for (uint8_t i = 0; i < PIN_COUNT; i++) {
|
||||||
@ -541,14 +545,15 @@ void binaryToCsv() {
|
|||||||
}
|
}
|
||||||
for (size_t j = 0; j < pd->count; j += PIN_COUNT) {
|
for (size_t j = 0; j < pd->count; j += PIN_COUNT) {
|
||||||
for (size_t i = 0; i < PIN_COUNT; i++) {
|
for (size_t i = 0; i < PIN_COUNT; i++) {
|
||||||
if (!bp.printField(pd->data[i + j], i == (PIN_COUNT-1) ? '\n' : ',')) {
|
if (!bp.printField(pd->data[i + j],
|
||||||
|
i == (PIN_COUNT - 1) ? '\n' : ',')) {
|
||||||
error("printField failed");
|
error("printField failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((millis() - tPct) > 1000) {
|
if ((millis() - tPct) > 1000) {
|
||||||
uint8_t pct = binFile.curPosition()/(binFile.fileSize()/100);
|
uint8_t pct = binFile.curPosition() / (binFile.fileSize() / 100);
|
||||||
if (pct != lastPct) {
|
if (pct != lastPct) {
|
||||||
tPct = millis();
|
tPct = millis();
|
||||||
lastPct = pct;
|
lastPct = pct;
|
||||||
@ -561,7 +566,7 @@ void binaryToCsv() {
|
|||||||
error("close csvFile failed");
|
error("close csvFile failed");
|
||||||
}
|
}
|
||||||
Serial.print(F("Done: "));
|
Serial.print(F("Done: "));
|
||||||
Serial.print(0.001*(millis() - t0));
|
Serial.print(0.001 * (millis() - t0));
|
||||||
Serial.println(F(" Seconds"));
|
Serial.println(F(" Seconds"));
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -619,7 +624,7 @@ bool createCsvFile() {
|
|||||||
error("no dot in binName");
|
error("no dot in binName");
|
||||||
}
|
}
|
||||||
strcpy(dot + 1, "csv");
|
strcpy(dot + 1, "csv");
|
||||||
if (!csvFile.open(csvName, O_WRONLY|O_CREAT|O_TRUNC)) {
|
if (!csvFile.open(csvName, O_WRONLY | O_CREAT | O_TRUNC)) {
|
||||||
error("open csvFile failed");
|
error("open csvFile failed");
|
||||||
}
|
}
|
||||||
Serial.print(F("Writing: "));
|
Serial.print(F("Writing: "));
|
||||||
@ -632,7 +637,7 @@ bool createCsvFile() {
|
|||||||
void logData() {
|
void logData() {
|
||||||
uint32_t t0;
|
uint32_t t0;
|
||||||
uint32_t t1;
|
uint32_t t1;
|
||||||
uint32_t overruns =0;
|
uint32_t overruns = 0;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
uint32_t maxLatencyUsec = 0;
|
uint32_t maxLatencyUsec = 0;
|
||||||
size_t maxFifoUse = 0;
|
size_t maxFifoUse = 0;
|
||||||
@ -676,7 +681,7 @@ void logData() {
|
|||||||
if (m > maxLatencyUsec) {
|
if (m > maxLatencyUsec) {
|
||||||
maxLatencyUsec = m;
|
maxLatencyUsec = m;
|
||||||
}
|
}
|
||||||
if (tmpFifoCount >maxFifoUse) {
|
if (tmpFifoCount > maxFifoUse) {
|
||||||
maxFifoUse = tmpFifoCount;
|
maxFifoUse = tmpFifoCount;
|
||||||
}
|
}
|
||||||
count += pBlock->count;
|
count += pBlock->count;
|
||||||
@ -711,7 +716,7 @@ void logData() {
|
|||||||
isrStop = true;
|
isrStop = true;
|
||||||
}
|
}
|
||||||
if (fifoCount == 0 && !adcActive()) {
|
if (fifoCount == 0 && !adcActive()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
@ -726,9 +731,9 @@ void logData() {
|
|||||||
Serial.print(F("Max write latency usec: "));
|
Serial.print(F("Max write latency usec: "));
|
||||||
Serial.println(maxLatencyUsec);
|
Serial.println(maxLatencyUsec);
|
||||||
Serial.print(F("Record time sec: "));
|
Serial.print(F("Record time sec: "));
|
||||||
Serial.println(0.001*(t1 - t0), 3);
|
Serial.println(0.001 * (t1 - t0), 3);
|
||||||
Serial.print(F("Sample count: "));
|
Serial.print(F("Sample count: "));
|
||||||
Serial.println(count/PIN_COUNT);
|
Serial.println(count / PIN_COUNT);
|
||||||
Serial.print(F("Overruns: "));
|
Serial.print(F("Overruns: "));
|
||||||
Serial.println(overruns);
|
Serial.println(overruns);
|
||||||
Serial.print(F("FIFO_DIM: "));
|
Serial.print(F("FIFO_DIM: "));
|
||||||
@ -767,13 +772,13 @@ void printData() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
binFile.rewind();
|
binFile.rewind();
|
||||||
if (binFile.read(&buf , sizeof(buf)) != sizeof(buf)) {
|
if (binFile.read(&buf, sizeof(buf)) != sizeof(buf)) {
|
||||||
error("Read metadata failed");
|
error("Read metadata failed");
|
||||||
}
|
}
|
||||||
Serial.println(F("Type any character to stop"));
|
Serial.println(F("Type any character to stop"));
|
||||||
delay(1000);
|
delay(1000);
|
||||||
while (!Serial.available() &&
|
while (!Serial.available() &&
|
||||||
binFile.read(&buf , sizeof(buf)) == sizeof(buf)) {
|
binFile.read(&buf, sizeof(buf)) == sizeof(buf)) {
|
||||||
if (buf.count == 0) {
|
if (buf.count == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -783,7 +788,7 @@ void printData() {
|
|||||||
}
|
}
|
||||||
for (size_t i = 0; i < buf.count; i++) {
|
for (size_t i = 0; i < buf.count; i++) {
|
||||||
Serial.print(buf.data[i], DEC);
|
Serial.print(buf.data[i], DEC);
|
||||||
if ((i+1)%PIN_COUNT) {
|
if ((i + 1) % PIN_COUNT) {
|
||||||
Serial.print(',');
|
Serial.print(',');
|
||||||
} else {
|
} else {
|
||||||
Serial.println();
|
Serial.println();
|
||||||
@ -795,7 +800,7 @@ void printData() {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool serialReadLine(char* str, size_t size) {
|
bool serialReadLine(char* str, size_t size) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while(!Serial.available()) {
|
while (!Serial.available()) {
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
int c = Serial.read();
|
int c = Serial.read();
|
||||||
@ -806,7 +811,8 @@ bool serialReadLine(char* str, size_t size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t m = millis();
|
uint32_t m = millis();
|
||||||
while (!Serial.available() && (millis() - m) < 100){}
|
while (!Serial.available() && (millis() - m) < 100) {
|
||||||
|
}
|
||||||
if (!Serial.available()) break;
|
if (!Serial.available()) break;
|
||||||
}
|
}
|
||||||
str[n] = 0;
|
str[n] = 0;
|
||||||
@ -818,9 +824,11 @@ void setup(void) {
|
|||||||
pinMode(ERROR_LED_PIN, OUTPUT);
|
pinMode(ERROR_LED_PIN, OUTPUT);
|
||||||
}
|
}
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
while(!Serial) {}
|
while (!Serial) {
|
||||||
|
}
|
||||||
Serial.println(F("Type any character to begin."));
|
Serial.println(F("Type any character to begin."));
|
||||||
while(!Serial.available()) {}
|
while (!Serial.available()) {
|
||||||
|
}
|
||||||
|
|
||||||
FillStack();
|
FillStack();
|
||||||
|
|
||||||
@ -828,9 +836,9 @@ void setup(void) {
|
|||||||
analogRead(PIN_LIST[0]);
|
analogRead(PIN_LIST[0]);
|
||||||
|
|
||||||
#if !ENABLE_DEDICATED_SPI
|
#if !ENABLE_DEDICATED_SPI
|
||||||
Serial.println(F(
|
Serial.println(
|
||||||
"\nFor best performance edit SdFatConfig.h\n"
|
F("\nFor best performance edit SdFatConfig.h\n"
|
||||||
"and set ENABLE_DEDICATED_SPI nonzero"));
|
"and set ENABLE_DEDICATED_SPI nonzero"));
|
||||||
#endif // !ENABLE_DEDICATED_SPI
|
#endif // !ENABLE_DEDICATED_SPI
|
||||||
// Initialize SD.
|
// Initialize SD.
|
||||||
if (!sd.begin(SD_CONFIG)) {
|
if (!sd.begin(SD_CONFIG)) {
|
||||||
@ -864,7 +872,7 @@ void loop(void) {
|
|||||||
Serial.println(F("p - print data to Serial"));
|
Serial.println(F("p - print data to Serial"));
|
||||||
Serial.println(F("r - record ADC data"));
|
Serial.println(F("r - record ADC data"));
|
||||||
|
|
||||||
while(!Serial.available()) {
|
while (!Serial.available()) {
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
char c = tolower(Serial.read());
|
char c = tolower(Serial.read());
|
@ -28,11 +28,12 @@ File myFile;
|
|||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
while (!Serial) {}
|
while (!Serial) {
|
||||||
|
}
|
||||||
|
|
||||||
#if USE_SD_H
|
#if USE_SD_H
|
||||||
Serial.println(F("Using SD.h. Set USE_SD_H zero to use SdFat.h."));
|
Serial.println(F("Using SD.h. Set USE_SD_H zero to use SdFat.h."));
|
||||||
#else // USE_SD_H
|
#else // USE_SD_H
|
||||||
Serial.println(F("Using SdFat.h. Set USE_SD_H nonzero to use SD.h."));
|
Serial.println(F("Using SdFat.h. Set USE_SD_H nonzero to use SD.h."));
|
||||||
#endif // USE_SD_H
|
#endif // USE_SD_H
|
||||||
Serial.println(F("\nType any character to begin."));
|
Serial.println(F("\nType any character to begin."));
|
@ -1,12 +1,12 @@
|
|||||||
// Test and benchmark of the fast bufferedPrint class.
|
// Test and benchmark of the fast bufferedPrint class.
|
||||||
//
|
//
|
||||||
// Mainly for AVR but may improve print performance with other CPUs.
|
// Mainly for AVR but may improve print performance with other CPUs.
|
||||||
#include "SdFat.h"
|
|
||||||
#include "BufferedPrint.h"
|
#include "BufferedPrint.h"
|
||||||
|
#include "SdFat.h"
|
||||||
|
|
||||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||||
#define SD_FAT_TYPE 0
|
#define SD_FAT_TYPE 3
|
||||||
/*
|
/*
|
||||||
Change the value of SD_CS_PIN if you are using SPI and
|
Change the value of SD_CS_PIN if you are using SPI and
|
||||||
your hardware does not use the default value, SS.
|
your hardware does not use the default value, SS.
|
||||||
@ -19,7 +19,7 @@
|
|||||||
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
||||||
#ifndef SDCARD_SS_PIN
|
#ifndef SDCARD_SS_PIN
|
||||||
const uint8_t SD_CS_PIN = SS;
|
const uint8_t SD_CS_PIN = SS;
|
||||||
#else // SDCARD_SS_PIN
|
#else // SDCARD_SS_PIN
|
||||||
// Assume built-in SD is used.
|
// Assume built-in SD is used.
|
||||||
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
||||||
#endif // SDCARD_SS_PIN
|
#endif // SDCARD_SS_PIN
|
||||||
@ -30,7 +30,7 @@ const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
|||||||
// Try to select the best SD card configuration.
|
// Try to select the best SD card configuration.
|
||||||
#if HAS_SDIO_CLASS
|
#if HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
||||||
#elif ENABLE_DEDICATED_SPI
|
#elif ENABLE_DEDICATED_SPI
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
||||||
#else // HAS_SDIO_CLASS
|
#else // HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
||||||
@ -71,49 +71,48 @@ void benchmark() {
|
|||||||
bp.begin(&file);
|
bp.begin(&file);
|
||||||
}
|
}
|
||||||
uint32_t t = millis();
|
uint32_t t = millis();
|
||||||
switch(test) {
|
switch (test) {
|
||||||
case 0:
|
case 0:
|
||||||
Serial.println(F("Test of println(uint16_t)"));
|
Serial.println(F("Test of println(uint16_t)"));
|
||||||
for (uint16_t i = 0; i < N_PRINT; i++) {
|
for (uint16_t i = 0; i < N_PRINT; i++) {
|
||||||
file.println(i);
|
file.println(i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
Serial.println(F("Test of printField(uint16_t, char)"));
|
Serial.println(F("Test of printField(uint16_t, char)"));
|
||||||
for (uint16_t i = 0; i < N_PRINT; i++) {
|
for (uint16_t i = 0; i < N_PRINT; i++) {
|
||||||
bp.printField(i, '\n');
|
bp.printField(i, '\n');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
Serial.println(F("Test of println(uint32_t)"));
|
Serial.println(F("Test of println(uint32_t)"));
|
||||||
for (uint16_t i = 0; i < N_PRINT; i++) {
|
for (uint16_t i = 0; i < N_PRINT; i++) {
|
||||||
file.println(12345678UL + i);
|
file.println(12345678UL + i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
Serial.println(F("Test of printField(uint32_t, char)"));
|
Serial.println(F("Test of printField(uint32_t, char)"));
|
||||||
for (uint16_t i = 0; i < N_PRINT; i++) {
|
for (uint16_t i = 0; i < N_PRINT; i++) {
|
||||||
bp.printField(12345678UL + i, '\n');
|
bp.printField(12345678UL + i, '\n');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
Serial.println(F("Test of println(double)"));
|
Serial.println(F("Test of println(double)"));
|
||||||
for (uint16_t i = 0; i < N_PRINT; i++) {
|
for (uint16_t i = 0; i < N_PRINT; i++) {
|
||||||
file.println((double)0.01*i);
|
file.println((double)0.01 * i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
|
||||||
Serial.println(F("Test of printField(double, char)"));
|
|
||||||
for (uint16_t i = 0; i < N_PRINT; i++) {
|
|
||||||
bp.printField((double)0.01*i, '\n');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
Serial.println(F("Test of printField(double, char)"));
|
||||||
|
for (uint16_t i = 0; i < N_PRINT; i++) {
|
||||||
|
bp.printField((double)0.01 * i, '\n');
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (test & 1) {
|
if (test & 1) {
|
||||||
bp.sync();
|
bp.sync();
|
||||||
@ -125,13 +124,13 @@ void benchmark() {
|
|||||||
file.close();
|
file.close();
|
||||||
t = millis() - t;
|
t = millis() - t;
|
||||||
Serial.print(F("Time "));
|
Serial.print(F("Time "));
|
||||||
Serial.print(0.001*t, 3);
|
Serial.print(0.001 * t, 3);
|
||||||
Serial.println(F(" sec"));
|
Serial.println(F(" sec"));
|
||||||
Serial.print(F("File size "));
|
Serial.print(F("File size "));
|
||||||
Serial.print(0.001*s);
|
Serial.print(0.001 * s);
|
||||||
Serial.println(F(" KB"));
|
Serial.println(F(" KB"));
|
||||||
Serial.print(F("Write "));
|
Serial.print(F("Write "));
|
||||||
Serial.print(s/t);
|
Serial.print(s / t);
|
||||||
Serial.println(F(" KB/sec"));
|
Serial.println(F(" KB/sec"));
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
@ -139,23 +138,23 @@ void benchmark() {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void testMemberFunctions() {
|
void testMemberFunctions() {
|
||||||
BufferedPrint<Print, 32> bp(&Serial);
|
BufferedPrint<Print, 32> bp(&Serial);
|
||||||
char c = 'c'; // char
|
char c = 'c'; // char
|
||||||
//#define BASIC_TYPES
|
//#define BASIC_TYPES
|
||||||
#ifdef BASIC_TYPES
|
#ifdef BASIC_TYPES
|
||||||
signed char sc = -1; // signed 8-bit
|
signed char sc = -1; // signed 8-bit
|
||||||
unsigned char uc = 1; // unsiged 8-bit
|
unsigned char uc = 1; // unsiged 8-bit
|
||||||
signed short ss = -2; // signed 16-bit
|
signed short ss = -2; // signed 16-bit
|
||||||
unsigned short us = 2; // unsigned 16-bit
|
unsigned short us = 2; // unsigned 16-bit
|
||||||
signed long sl = -4; // signed 32-bit
|
signed long sl = -4; // signed 32-bit
|
||||||
unsigned long ul = 4; // unsigned 32-bit
|
unsigned long ul = 4; // unsigned 32-bit
|
||||||
#else // BASIC_TYPES
|
#else // BASIC_TYPES
|
||||||
int8_t sc = -1; // signed 8-bit
|
int8_t sc = -1; // signed 8-bit
|
||||||
uint8_t uc = 1; // unsiged 8-bit
|
uint8_t uc = 1; // unsiged 8-bit
|
||||||
int16_t ss = -2; // signed 16-bit
|
int16_t ss = -2; // signed 16-bit
|
||||||
uint16_t us = 2; // unsigned 16-bit
|
uint16_t us = 2; // unsigned 16-bit
|
||||||
int32_t sl = -4; // signed 32-bit
|
int32_t sl = -4; // signed 32-bit
|
||||||
uint32_t ul = 4; // unsigned 32-bit
|
uint32_t ul = 4; // unsigned 32-bit
|
||||||
#endif // BASIC_TYPES
|
#endif // BASIC_TYPES
|
||||||
float f = -1.234;
|
float f = -1.234;
|
||||||
double d = -5.678;
|
double d = -5.678;
|
||||||
bp.println();
|
bp.println();
|
||||||
@ -216,9 +215,11 @@ void testMemberFunctions() {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
while (!Serial) {}
|
while (!Serial) {
|
||||||
|
}
|
||||||
Serial.println("Type any character to begin.");
|
Serial.println("Type any character to begin.");
|
||||||
while(!Serial.available()) {}
|
while (!Serial.available()) {
|
||||||
|
}
|
||||||
if (!sd.begin(SD_CONFIG)) {
|
if (!sd.begin(SD_CONFIG)) {
|
||||||
sd.initErrorHalt(&Serial);
|
sd.initErrorHalt(&Serial);
|
||||||
}
|
}
|
||||||
@ -226,10 +227,10 @@ void setup() {
|
|||||||
Serial.println(F("Test member funcions:"));
|
Serial.println(F("Test member funcions:"));
|
||||||
testMemberFunctions();
|
testMemberFunctions();
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.println(F("Benchmark performance for uint16_t, uint32_t, and double:"));
|
Serial.println(
|
||||||
|
F("Benchmark performance for uint16_t, uint32_t, and double:"));
|
||||||
benchmark();
|
benchmark();
|
||||||
Serial.println("Done");
|
Serial.println("Done");
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void loop() {
|
void loop() {}
|
||||||
}
|
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||||
#define SD_FAT_TYPE 0
|
#define SD_FAT_TYPE 3
|
||||||
/*
|
/*
|
||||||
Change the value of SD_CS_PIN if you are using SPI and
|
Change the value of SD_CS_PIN if you are using SPI and
|
||||||
your hardware does not use the default value, SS.
|
your hardware does not use the default value, SS.
|
||||||
@ -18,19 +18,19 @@
|
|||||||
|
|
||||||
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
||||||
#ifndef SDCARD_SS_PIN
|
#ifndef SDCARD_SS_PIN
|
||||||
const uint8_t SD_CS_PIN = SS;
|
const uint8_t SD_CS_PIN = 4;
|
||||||
#else // SDCARD_SS_PIN
|
#else // SDCARD_SS_PIN
|
||||||
// Assume built-in SD is used.
|
// Assume built-in SD is used.
|
||||||
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
const uint8_t SD_CS_PIN = 4;
|
||||||
#endif // SDCARD_SS_PIN
|
#endif // SDCARD_SS_PIN
|
||||||
|
|
||||||
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
|
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
|
||||||
#define SPI_CLOCK SD_SCK_MHZ(50)
|
#define SPI_CLOCK SD_SCK_MHZ(16)
|
||||||
|
|
||||||
// Try to select the best SD card configuration.
|
// Try to select the best SD card configuration.
|
||||||
#if HAS_SDIO_CLASS
|
#if HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
||||||
#elif ENABLE_DEDICATED_SPI
|
#elif ENABLE_DEDICATED_SPI
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
||||||
#else // HAS_SDIO_CLASS
|
#else // HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
||||||
@ -78,9 +78,8 @@ void setup() {
|
|||||||
if (!sd.begin(SD_CONFIG)) {
|
if (!sd.begin(SD_CONFIG)) {
|
||||||
sd.initErrorHalt(&Serial);
|
sd.initErrorHalt(&Serial);
|
||||||
}
|
}
|
||||||
if (sd.exists("Folder1")
|
if (sd.exists("Folder1") || sd.exists("Folder1/file1.txt") ||
|
||||||
|| sd.exists("Folder1/file1.txt")
|
sd.exists("Folder1/File2.txt")) {
|
||||||
|| sd.exists("Folder1/File2.txt")) {
|
|
||||||
error("Please remove existing Folder1, file1.txt, and File2.txt");
|
error("Please remove existing Folder1, file1.txt, and File2.txt");
|
||||||
}
|
}
|
||||||
|
|
@ -3,9 +3,9 @@
|
|||||||
//
|
//
|
||||||
// The maximum data rate will depend on the quality of your SD,
|
// The maximum data rate will depend on the quality of your SD,
|
||||||
// the size of the FIFO, and using dedicated SPI.
|
// the size of the FIFO, and using dedicated SPI.
|
||||||
#include "SdFat.h"
|
|
||||||
#include "FreeStack.h"
|
|
||||||
#include "ExFatLogger.h"
|
#include "ExFatLogger.h"
|
||||||
|
#include "FreeStack.h"
|
||||||
|
#include "SdFat.h"
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// This example was designed for exFAT but will support FAT16/FAT32.
|
// This example was designed for exFAT but will support FAT16/FAT32.
|
||||||
// Note: Uno will not support SD_FAT_TYPE = 3.
|
// Note: Uno will not support SD_FAT_TYPE = 3.
|
||||||
@ -45,7 +45,7 @@ const uint32_t LOG_INTERVAL_USEC = 2000;
|
|||||||
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
||||||
#ifndef SDCARD_SS_PIN
|
#ifndef SDCARD_SS_PIN
|
||||||
const uint8_t SD_CS_PIN = SS;
|
const uint8_t SD_CS_PIN = SS;
|
||||||
#else // SDCARD_SS_PIN
|
#else // SDCARD_SS_PIN
|
||||||
// Assume built-in SD is used.
|
// Assume built-in SD is used.
|
||||||
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
||||||
#endif // SDCARD_SS_PIN
|
#endif // SDCARD_SS_PIN
|
||||||
@ -71,7 +71,7 @@ const uint32_t PREALLOCATE_SIZE_MiB = 1024UL;
|
|||||||
// Try to select the best SD card configuration.
|
// Try to select the best SD card configuration.
|
||||||
#if HAS_SDIO_CLASS
|
#if HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
||||||
#elif ENABLE_DEDICATED_SPI
|
#elif ENABLE_DEDICATED_SPI
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
||||||
#else // HAS_SDIO_CLASS
|
#else // HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
||||||
@ -127,11 +127,11 @@ void printRecord(Print* pr, data_t* data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
const uint64_t PREALLOCATE_SIZE = (uint64_t)PREALLOCATE_SIZE_MiB << 20;
|
const uint64_t PREALLOCATE_SIZE = (uint64_t)PREALLOCATE_SIZE_MiB << 20;
|
||||||
// Max length of file name including zero byte.
|
// Max length of file name including zero byte.
|
||||||
#define FILE_NAME_DIM 40
|
#define FILE_NAME_DIM 40
|
||||||
// Max number of records to buffer while SD is busy.
|
// Max number of records to buffer while SD is busy.
|
||||||
const size_t FIFO_DIM = 512*FIFO_SIZE_SECTORS/sizeof(data_t);
|
const size_t FIFO_DIM = 512 * FIFO_SIZE_SECTORS / sizeof(data_t);
|
||||||
|
|
||||||
#if SD_FAT_TYPE == 0
|
#if SD_FAT_TYPE == 0
|
||||||
typedef SdFat sd_t;
|
typedef SdFat sd_t;
|
||||||
@ -191,22 +191,22 @@ void binaryToCsv() {
|
|||||||
data_t binData[FIFO_DIM];
|
data_t binData[FIFO_DIM];
|
||||||
|
|
||||||
if (!binFile.seekSet(512)) {
|
if (!binFile.seekSet(512)) {
|
||||||
error("binFile.seek failed");
|
error("binFile.seek failed");
|
||||||
}
|
}
|
||||||
uint32_t tPct = millis();
|
uint32_t tPct = millis();
|
||||||
printRecord(&csvFile, nullptr);
|
printRecord(&csvFile, nullptr);
|
||||||
while (!Serial.available() && binFile.available()) {
|
while (!Serial.available() && binFile.available()) {
|
||||||
int nb = binFile.read(binData, sizeof(binData));
|
int nb = binFile.read(binData, sizeof(binData));
|
||||||
if (nb <= 0 ) {
|
if (nb <= 0) {
|
||||||
error("read binFile failed");
|
error("read binFile failed");
|
||||||
}
|
}
|
||||||
size_t nr = nb/sizeof(data_t);
|
size_t nr = nb / sizeof(data_t);
|
||||||
for (size_t i = 0; i < nr; i++) {
|
for (size_t i = 0; i < nr; i++) {
|
||||||
printRecord(&csvFile, &binData[i]);
|
printRecord(&csvFile, &binData[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((millis() - tPct) > 1000) {
|
if ((millis() - tPct) > 1000) {
|
||||||
uint8_t pct = binFile.curPosition()/(binFile.fileSize()/100);
|
uint8_t pct = binFile.curPosition() / (binFile.fileSize() / 100);
|
||||||
if (pct != lastPct) {
|
if (pct != lastPct) {
|
||||||
tPct = millis();
|
tPct = millis();
|
||||||
lastPct = pct;
|
lastPct = pct;
|
||||||
@ -221,7 +221,7 @@ void binaryToCsv() {
|
|||||||
}
|
}
|
||||||
csvFile.close();
|
csvFile.close();
|
||||||
Serial.print(F("Done: "));
|
Serial.print(F("Done: "));
|
||||||
Serial.print(0.001*(millis() - t0));
|
Serial.print(0.001 * (millis() - t0));
|
||||||
Serial.println(F(" Seconds"));
|
Serial.println(F(" Seconds"));
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -302,7 +302,7 @@ void logData() {
|
|||||||
uint16_t overrun = 0;
|
uint16_t overrun = 0;
|
||||||
uint16_t maxOverrun = 0;
|
uint16_t maxOverrun = 0;
|
||||||
uint32_t totalOverrun = 0;
|
uint32_t totalOverrun = 0;
|
||||||
uint32_t fifoBuf[128*FIFO_SIZE_SECTORS];
|
uint32_t fifoBuf[128 * FIFO_SIZE_SECTORS];
|
||||||
data_t* fifoData = (data_t*)fifoBuf;
|
data_t* fifoData = (data_t*)fifoBuf;
|
||||||
|
|
||||||
// Write dummy sector to start multi-block write.
|
// Write dummy sector to start multi-block write.
|
||||||
@ -315,7 +315,8 @@ void logData() {
|
|||||||
Serial.println(F("Type any character to stop"));
|
Serial.println(F("Type any character to stop"));
|
||||||
|
|
||||||
// Wait until SD is not busy.
|
// Wait until SD is not busy.
|
||||||
while (sd.card()->isBusy()) {}
|
while (sd.card()->isBusy()) {
|
||||||
|
}
|
||||||
|
|
||||||
// Start time for log file.
|
// Start time for log file.
|
||||||
uint32_t m = millis();
|
uint32_t m = millis();
|
||||||
@ -370,9 +371,9 @@ void logData() {
|
|||||||
if (!sd.card()->isBusy()) {
|
if (!sd.card()->isBusy()) {
|
||||||
size_t nw = fifoHead > fifoTail ? fifoCount : FIFO_DIM - fifoTail;
|
size_t nw = fifoHead > fifoTail ? fifoCount : FIFO_DIM - fifoTail;
|
||||||
// Limit write time by not writing more than 512 bytes.
|
// Limit write time by not writing more than 512 bytes.
|
||||||
const size_t MAX_WRITE = 512/sizeof(data_t);
|
const size_t MAX_WRITE = 512 / sizeof(data_t);
|
||||||
if (nw > MAX_WRITE) nw = MAX_WRITE;
|
if (nw > MAX_WRITE) nw = MAX_WRITE;
|
||||||
size_t nb = nw*sizeof(data_t);
|
size_t nb = nw * sizeof(data_t);
|
||||||
uint32_t usec = micros();
|
uint32_t usec = micros();
|
||||||
if (nb != binFile.write(fifoData + fifoTail, nb)) {
|
if (nb != binFile.write(fifoData + fifoTail, nb)) {
|
||||||
error("write binFile failed");
|
error("write binFile failed");
|
||||||
@ -392,7 +393,7 @@ void logData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Serial.print(F("\nLog time: "));
|
Serial.print(F("\nLog time: "));
|
||||||
Serial.print(0.001*(millis() - m));
|
Serial.print(0.001 * (millis() - m));
|
||||||
Serial.println(F(" Seconds"));
|
Serial.println(F(" Seconds"));
|
||||||
binFile.truncate();
|
binFile.truncate();
|
||||||
binFile.sync();
|
binFile.sync();
|
||||||
@ -469,7 +470,7 @@ void printUnusedStack() {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool serialReadLine(char* str, size_t size) {
|
bool serialReadLine(char* str, size_t size) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while(!Serial.available()) {
|
while (!Serial.available()) {
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -481,7 +482,8 @@ bool serialReadLine(char* str, size_t size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t m = millis();
|
uint32_t m = millis();
|
||||||
while (!Serial.available() && (millis() - m) < 100){}
|
while (!Serial.available() && (millis() - m) < 100) {
|
||||||
|
}
|
||||||
if (!Serial.available()) break;
|
if (!Serial.available()) break;
|
||||||
}
|
}
|
||||||
str[n] = 0;
|
str[n] = 0;
|
||||||
@ -525,9 +527,9 @@ void setup() {
|
|||||||
}
|
}
|
||||||
FillStack();
|
FillStack();
|
||||||
#if !ENABLE_DEDICATED_SPI
|
#if !ENABLE_DEDICATED_SPI
|
||||||
Serial.println(F(
|
Serial.println(
|
||||||
"\nFor best performance edit SdFatConfig.h\n"
|
F("\nFor best performance edit SdFatConfig.h\n"
|
||||||
"and set ENABLE_DEDICATED_SPI nonzero"));
|
"and set ENABLE_DEDICATED_SPI nonzero"));
|
||||||
#endif // !ENABLE_DEDICATED_SPI
|
#endif // !ENABLE_DEDICATED_SPI
|
||||||
|
|
||||||
Serial.print(FIFO_DIM);
|
Serial.print(FIFO_DIM);
|
||||||
@ -567,7 +569,7 @@ void loop() {
|
|||||||
Serial.println(F("p - print data to Serial"));
|
Serial.println(F("p - print data to Serial"));
|
||||||
Serial.println(F("r - record data"));
|
Serial.println(F("r - record data"));
|
||||||
Serial.println(F("t - test without logging"));
|
Serial.println(F("t - test without logging"));
|
||||||
while(!Serial.available()) {
|
while (!Serial.available()) {
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
char c = tolower(Serial.read());
|
char c = tolower(Serial.read());
|
@ -14,7 +14,8 @@ File file;
|
|||||||
#include "SdFat.h"
|
#include "SdFat.h"
|
||||||
// Setting ENABLE_DEDICATED_SPI to zero saves over 200 more bytes.
|
// Setting ENABLE_DEDICATED_SPI to zero saves over 200 more bytes.
|
||||||
#if ENABLE_DEDICATED_SPI
|
#if ENABLE_DEDICATED_SPI
|
||||||
#warning "Set ENABLE_DEDICATED_SPI zero in SdFat/src/SdFatConfig.h for minimum size"
|
#warning \
|
||||||
|
"Set ENABLE_DEDICATED_SPI zero in SdFat/src/SdFatConfig.h for minimum size"
|
||||||
#endif // ENABLE_DEDICATED_SPI
|
#endif // ENABLE_DEDICATED_SPI
|
||||||
// Insure FAT16/FAT32 only.
|
// Insure FAT16/FAT32 only.
|
||||||
SdFat32 SD;
|
SdFat32 SD;
|
||||||
@ -24,17 +25,19 @@ FatFile file;
|
|||||||
|
|
||||||
void error(const char* msg) {
|
void error(const char* msg) {
|
||||||
Serial.println(msg);
|
Serial.println(msg);
|
||||||
while(true);
|
while (true) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
int n;
|
int n;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
while (!Serial) {}
|
while (!Serial) {
|
||||||
|
}
|
||||||
Serial.println("Type any character to begin");
|
Serial.println("Type any character to begin");
|
||||||
while (!Serial.available()) {}
|
while (!Serial.available()) {
|
||||||
|
}
|
||||||
|
|
||||||
if (!SD.begin(CS_PIN)) error("SD.begin");
|
if (!SD.begin(CS_PIN)) error("SD.begin");
|
||||||
|
|
||||||
@ -47,12 +50,11 @@ void setup() {
|
|||||||
if (!file.openExistingSFN(SFN_PATH)) error("open");
|
if (!file.openExistingSFN(SFN_PATH)) error("open");
|
||||||
#endif
|
#endif
|
||||||
while ((n = file.read(buf, sizeof(buf)))) {
|
while ((n = file.read(buf, sizeof(buf)))) {
|
||||||
Serial.write(buf, n);
|
Serial.write(buf, n);
|
||||||
}
|
}
|
||||||
// close() is only needed if you write to the file. For example, read
|
// close() is only needed if you write to the file. For example, read
|
||||||
// config data, modify the data, rewind the file and write the data.
|
// config data, modify the data, rewind the file and write the data.
|
||||||
// file.close();
|
// file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {}
|
||||||
}
|
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||||
#define SD_FAT_TYPE 0
|
#define SD_FAT_TYPE 3
|
||||||
/*
|
/*
|
||||||
Change the value of SD_CS_PIN if you are using SPI and
|
Change the value of SD_CS_PIN if you are using SPI and
|
||||||
your hardware does not use the default value, SS.
|
your hardware does not use the default value, SS.
|
||||||
@ -17,19 +17,19 @@
|
|||||||
|
|
||||||
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
|
||||||
#ifndef SDCARD_SS_PIN
|
#ifndef SDCARD_SS_PIN
|
||||||
const uint8_t SD_CS_PIN = SS;
|
const uint8_t SD_CS_PIN = 4;
|
||||||
#else // SDCARD_SS_PIN
|
#else // SDCARD_SS_PIN
|
||||||
// Assume built-in SD is used.
|
// Assume built-in SD is used.
|
||||||
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
const uint8_t SD_CS_PIN = 4;
|
||||||
#endif // SDCARD_SS_PIN
|
#endif // SDCARD_SS_PIN
|
||||||
|
|
||||||
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
|
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
|
||||||
#define SPI_CLOCK SD_SCK_MHZ(50)
|
#define SPI_CLOCK SD_SCK_MHZ(30)
|
||||||
|
|
||||||
// Try to select the best SD card configuration.
|
// Try to select the best SD card configuration.
|
||||||
#if HAS_SDIO_CLASS
|
#if HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
||||||
#elif ENABLE_DEDICATED_SPI
|
#elif ENABLE_DEDICATED_SPI
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
||||||
#else // HAS_SDIO_CLASS
|
#else // HAS_SDIO_CLASS
|
||||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
|
||||||
@ -75,8 +75,12 @@ void setup() {
|
|||||||
if (!sd.begin(SD_CONFIG)) {
|
if (!sd.begin(SD_CONFIG)) {
|
||||||
sd.initErrorHalt(&Serial);
|
sd.initErrorHalt(&Serial);
|
||||||
}
|
}
|
||||||
// Open root directory
|
|
||||||
if (!dir.open("/")){
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void loop() {
|
||||||
|
// Open root directory
|
||||||
|
if (!dir.open("/")) {
|
||||||
error("dir.open failed");
|
error("dir.open failed");
|
||||||
}
|
}
|
||||||
// Open next file in root.
|
// Open next file in root.
|
||||||
@ -100,6 +104,7 @@ void setup() {
|
|||||||
} else {
|
} else {
|
||||||
Serial.println("Done!");
|
Serial.println("Done!");
|
||||||
}
|
}
|
||||||
}
|
dir.close();
|
||||||
//------------------------------------------------------------------------------
|
delay(2000);
|
||||||
void loop() {}
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user