Skip to content

Commit 8b7b806

Browse files
authored
v1.8
1 parent c17784f commit 8b7b806

File tree

8 files changed

+153
-40
lines changed

8 files changed

+153
-40
lines changed

appGlobals.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,15 @@
2929
/*********************** Fixed defines leave as is ***********************/
3030
/** Do not change anything below here unless you know what you are doing **/
3131

32-
//#define DEV_ONLY // leave commented out
33-
#define STATIC_IP_OCTAL "162" // dev only
32+
#define STATIC_IP_OCTAL "163" // dev only
3433
#define DEBUG_MEM false // leave as false
3534
#define FLUSH_DELAY 0 // for debugging crashes
3635
#define DBG_ON false // esp debug output
3736
#define DOT_MAX 50
3837
#define HOSTNAME_GRP 0
3938

4039
#define APP_NAME "ESP-TuyaDevice" // max 15 chars
41-
#define APP_VER "1.7"
40+
#define APP_VER "1.8"
4241

4342
#define HTTP_CLIENTS 2 // http, ws
4443
#define MAX_STREAMS 0
@@ -103,7 +102,6 @@
103102
#define LOG_PRI 1
104103
#define UART_PRI 1
105104
#define BATT_PRI 1
106-
#define IDLEMON_PRI 5
107105

108106
#define UART_RTS UART_PIN_NO_CHANGE
109107
#define UART_CTS UART_PIN_NO_CHANGE

globals.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44

55
#include "esp_arduino_version.h"
66

7-
#if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 3)
8-
#error Must be compiled with arduino-esp32 core v3.0.3 or higher
7+
#if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 1, 1)
8+
#error Must be compiled with arduino-esp32 core v3.1.1 or higher
99
#endif
1010

1111
#pragma once
12+
13+
//#define DEV_ONLY // leave commented out
14+
#ifdef DEV_ONLY
1215
// to compile with -Wall -Werror=all -Wextra
13-
//#pragma GCC diagnostic error "-Wformat=2"
16+
#pragma GCC diagnostic error "-Wformat=2"
17+
#pragma GCC diagnostic ignored "-Wformat-truncation"
1418
#pragma GCC diagnostic ignored "-Wformat-y2k"
1519
#pragma GCC diagnostic ignored "-Wunused-function"
1620
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
@@ -19,6 +23,7 @@
1923
//#pragma GCC diagnostic ignored "-Wignored-qualifiers"
2024
//#pragma GCC diagnostic ignored "-Wclass-memaccess"
2125
#pragma GCC diagnostic ignored "-Wvolatile"
26+
#endif
2227

2328
/******************** Libraries *******************/
2429

@@ -29,7 +34,7 @@
2934
#include "ping/ping_sock.h"
3035
#include <Preferences.h>
3136
#include <regex>
32-
#if !CONFIG_IDF_TARGET_ESP32C3
37+
#if (!CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32S2)
3338
#include <SD_MMC.h>
3439
#endif
3540
#include <LittleFS.h>
@@ -131,11 +136,13 @@ char* fmtSize (uint64_t sizeVal);
131136
void forceCrash();
132137
void formatElapsedTime(char* timeStr, uint32_t timeVal, bool noDays = false);
133138
void formatHex(const char* inData, size_t inLen);
139+
bool formatSDcard();
134140
bool fsStartTransfer(const char* fileFolder);
135141
const char* getEncType(int ssidIndex);
136142
void getExtIP();
137143
time_t getEpoch();
138144
size_t getFreeStorage();
145+
uint32_t getFrequency();
139146
bool getLocalNTP();
140147
float getNTCcelsius(uint16_t resistance, float oldTemp);
141148
void goToSleep(int wakeupPin, bool deepSleep);
@@ -150,6 +157,7 @@ void logPrint(const char *fmtStr, ...);
150157
void logSetup();
151158
void OTAprereq();
152159
bool parseJson(int rxSize);
160+
bool prepFreq(int maxFreq, int sampleInterval);
153161
bool prepI2C();
154162
void prepPeripherals();
155163
void prepSMTP();

prefs.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ static bool savePrefs(bool retain = true) {
191191
#endif
192192
#if INCLUDE_MQTT
193193
prefs.putString("mqtt_user_Pass", mqtt_user_Pass);
194+
#endif
195+
#if INCLUDE_RTSP
196+
prefs.putString("RTSP_Pass", RTSP_Pass);
194197
#endif
195198
prefs.end();
196199
LOG_INF("Saved preferences");
@@ -221,6 +224,9 @@ static bool loadPrefs() {
221224
#endif
222225
#if INCLUDE_MQTT
223226
prefs.getString("mqtt_user_Pass", mqtt_user_Pass, MAX_PWD_LEN);
227+
#endif
228+
#if INCLUDE_RTSP
229+
prefs.getString("RTSP_Pass", RTSP_Pass, MAX_PWD_LEN);
224230
#endif
225231
prefs.end();
226232
return true;
@@ -314,7 +320,20 @@ void updateStatus(const char* variable, const char* _value, bool fromUser) {
314320
else if (!strcmp(variable, "mqtt_user_Pass") && value[0] != '*') strncpy(mqtt_user_Pass, value, MAX_PWD_LEN-1);
315321
else if (!strcmp(variable, "mqtt_topic_prefix")) strncpy(mqtt_topic_prefix, value, (FILE_NAME_LEN/2)-1);
316322
#endif
317-
323+
#if INCLUDE_RTSP
324+
else if (!strcmp(variable, "RTSP_Name")) strncpy(RTSP_Name, value, MAX_HOST_LEN-1);
325+
else if (!strcmp(variable, "RTSP_Pass") && value[0] != '*')strncpy(RTSP_Pass, value, MAX_PWD_LEN-1);
326+
else if (!strcmp(variable, "rtsp00Video")) rtspVideo = streamVid = (bool)intVal;
327+
else if (!strcmp(variable, "rtsp01Audio")) rtspAudio = streamAud = (bool)intVal;
328+
else if (!strcmp(variable, "rtsp02Subtitles")) rtspSubtitles = streamSrt = (bool)intVal;
329+
else if (!strcmp(variable, "rtsp03Port")) rtspPort = intVal;
330+
else if (!strcmp(variable, "rtsp04VideoPort")) rtpVideoPort = intVal;
331+
else if (!strcmp(variable, "rtsp05AudioPort")) rtpAudioPort = intVal;
332+
else if (!strcmp(variable, "rtsp06SubtitlesPort")) rtpSubtitlesPort = intVal;
333+
else if (!strcmp(variable, "rtsp07Ip")) strncpy(RTP_ip, value, MAX_IP_LEN-1);
334+
else if (!strcmp(variable, "rtsp08MaxC")) rtspMaxClients = intVal;
335+
else if (!strcmp(variable, "rtsp09TTL")) rtpTTL = intVal;
336+
#endif
318337
// Other settings
319338
else if (!strcmp(variable, "clockUTC")) syncToBrowser((uint32_t)intVal);
320339
else if (!strcmp(variable, "timezone")) strncpy(timezone, value, FILE_NAME_LEN-1);
@@ -359,7 +378,7 @@ void updateStatus(const char* variable, const char* _value, bool fromUser) {
359378
} else {
360379
res = updateAppStatus(variable, value, fromUser);
361380
if (!res) {
362-
if (fromUser) LOG_WRN("Trying to config %s but feature not included", variable);
381+
if (fromUser) LOG_WRN("Unable to config %s as required cpp file not included", variable);
363382
else LOG_VRB("Unrecognised config: %s", variable);
364383
}
365384
}
@@ -410,6 +429,9 @@ void buildJsonString(uint8_t filter) {
410429
#endif
411430
#if INCLUDE_MQTT
412431
p += sprintf(p, "\"mqtt_user_Pass\":\"%.*s\",", strlen(mqtt_user_Pass), FILLSTAR);
432+
#endif
433+
#if INCLUDE_RTSP
434+
p += sprintf(p, "\"RTSP_Pass\":\"%.*s\",", strlen(RTSP_Pass), FILLSTAR);
413435
#endif
414436
}
415437
} else {

setupAssist.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ bool checkDataFiles() {
6969
return res;
7070
}
7171

72-
/// To customise the the setupPage, use example in extras folder setupPage.html and then use cyberchef.org to convert to hex (see example in extras folder for cyberchef settings)
72+
// To customise the the setupPage, use example in extras folder setupPage.html and then use cyberchef.org to convert to hex (see example in extras folder for cyberchef settings)
7373
const uint8_t setupPage_html_gz[] PROGMEM = {
7474
0x1f, 0x8b, 0x08, 0x08, 0xbd, 0xf2, 0x0a, 0x67, 0x00, 0xff, 0x73, 0x65, 0x74, 0x75, 0x70, 0x50,
7575
0x61, 0x67, 0x65, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0xc5, 0x38, 0xeb, 0x72, 0xdb, 0xba, 0xd1,

utils.cpp

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ bool dataFilesChecked = false;
1818
// allow any startup failures to be reported via browser for remote devices
1919
char startupFailure[SF_LEN] = {0};
2020
size_t alertBufferSize = 0;
21+
size_t maxAlertBuffSize = 32 * 1024;
2122
byte* alertBuffer = NULL; // buffer for telegram / smtp alert image
2223
RTC_NOINIT_ATTR uint32_t crashLoop;
2324
RTC_NOINIT_ATTR char brownoutStatus;
@@ -63,6 +64,7 @@ esp_ping_handle_t pingHandle = NULL;
6364
bool usePing = true;
6465

6566
static void startPing();
67+
static void printGpioInfo();
6668

6769
static void setupMdnsHost() {
6870
// set up MDNS service
@@ -886,9 +888,9 @@ void logSetup() {
886888
boardInfo();
887889
LOG_INF("Compiled with arduino-esp32 v%s", ESP_ARDUINO_VERSION_STR);
888890
wakeupResetReason();
889-
if (alertBuffer == NULL) alertBuffer = (byte*)ps_malloc(MAX_ALERT);
891+
if (alertBuffer == NULL) alertBuffer = psramFound() ? (byte*)ps_malloc(maxAlertBuffSize) : (byte*)malloc(maxAlertBuffSize);
890892
if (jsonBuff == NULL) jsonBuff = psramFound() ? (char*)ps_malloc(JSON_BUFF_LEN) : (char*)malloc(JSON_BUFF_LEN);
891-
debugMemory("logSetup");
893+
debugMemory("logSetup");
892894
}
893895

894896
void formatHex(const char* inData, size_t inLen) {
@@ -967,7 +969,7 @@ static const char* getTaskStateString(eTaskState state) {
967969
static void statsTask(void *arg) {
968970
// Output real time task stats periodically
969971
#define STATS_TASK_PRIO 10
970-
#define STATS_INTERVAL 5000
972+
#define STATS_INTERVAL 30000 // ms
971973
#define ARRAY_SIZE_OFFSET 40 // Increase this if ESP_ERR_INVALID_SIZE
972974

973975
static configRUN_TIME_COUNTER_TYPE prevRunCounter = 0;
@@ -1028,14 +1030,19 @@ void runTaskStats() {
10281030
}
10291031
#endif
10301032

1031-
void checkMemory(const char* source ) {
1032-
LOG_INF("%s Free: heap %u, block: %u, min: %u, pSRAM %u", source, ESP.getFreeHeap(), ESP.getMaxAllocHeap(), ESP.getMinFreeHeap(), ESP.getFreePsram());
1033+
void checkMemory(const char* source) {
1034+
LOG_INF("%s Free: heap %u, block: %u, min: %u, pSRAM %u", strlen(source) ? source : "Setup", ESP.getFreeHeap(), ESP.getMaxAllocHeap(), ESP.getMinFreeHeap(), ESP.getFreePsram());
10331035
if (ESP.getFreeHeap() < WARN_HEAP) LOG_WRN("Free heap only %u, min %u", ESP.getFreeHeap(), ESP.getMinFreeHeap());
10341036
if (ESP.getMaxAllocHeap() < WARN_ALLOC) LOG_WRN("Max allocatable heap block is only %u", ESP.getMaxAllocHeap());
1037+
if (!strlen(source) && DEBUG_MEM) {
1038+
printGpioInfo();
1039+
runTaskStats();
1040+
}
10351041
}
10361042

10371043
uint32_t checkStackUse(TaskHandle_t thisTask, int taskIdx) {
10381044
// get minimum free stack size for task since started
1045+
// taskIdx used to index minStack[] array
10391046
static uint32_t minStack[20];
10401047
uint32_t freeStack = 0;
10411048
if (thisTask != NULL) {
@@ -1060,6 +1067,35 @@ void debugMemory(const char* caller) {
10601067
}
10611068
}
10621069

1070+
#include "esp32-hal-periman.h"
1071+
static void printGpioInfo() {
1072+
// from https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/chip-debug-report.cpp
1073+
printf("Assigned GPIO Info:\n");
1074+
for (uint8_t i = 0; i < SOC_GPIO_PIN_COUNT; i++) {
1075+
if (!perimanPinIsValid(i)) continue; //invalid pin
1076+
peripheral_bus_type_t type = perimanGetPinBusType(i);
1077+
if (type == ESP32_BUS_TYPE_INIT) continue; //unused pin
1078+
1079+
#if defined(BOARD_HAS_PIN_REMAP)
1080+
int dpin = gpioNumberToDigitalPin(i);
1081+
if (dpin < 0) continue; //pin is not exported
1082+
else printf(" D%-3d|%4u : ", dpin, i);
1083+
#else
1084+
printf(" %4u : ", i);
1085+
#endif
1086+
const char *extra_type = perimanGetPinBusExtraType(i);
1087+
if (extra_type) printf("%s", extra_type);
1088+
else printf("%s", perimanGetTypeName(type));
1089+
int8_t bus_number = perimanGetPinBusNum(i);
1090+
if (bus_number != -1) printf("[%u]", bus_number);
1091+
1092+
int8_t bus_channel = perimanGetPinBusChannel(i);
1093+
if (bus_channel != -1) printf("[%u]", bus_channel);
1094+
printf("\n");
1095+
}
1096+
printf("\n");
1097+
}
1098+
10631099

10641100
/****************** send device to sleep (light or deep) & watchdog ******************/
10651101

utilsFS.cpp

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
11
// General purpose SD card and flash storage utilities
22
//
3-
// s60sc 2021, 2022
3+
// Card can be accessed using a 1 data bit or 4 data bits (if allowed by board)
4+
// 4 data bits is potentially faster on ESP32S3 (depending on card spec)
5+
// but requires 3 additional pins
6+
/* The following #defines must be declared under the relevant camera entry in camera_pins.h
7+
1 bit 4 bit
8+
SD_MMC_CMD SD_MMC_CMD
9+
SD_MMC_CLK SD_MMC_CLK
10+
SD_MMC_D0 SD_MMC_D0
11+
SD_MMC_D1
12+
SD_MMC_D2
13+
SD_MMC_D3
14+
*/
15+
// s60sc 2021, 2022, 2025
416

517
#include "appGlobals.h"
18+
#include "ff.h"
19+
#include "vfs_fat_internal.h"
620

721
// Storage settings
822
int sdMinCardFreeSpace = 100; // Minimum amount of card free Megabytes before sdFreeSpaceMode action is enabled
923
int sdFreeSpaceMode = 1; // 0 - No Check, 1 - Delete oldest dir, 2 - Upload oldest dir to FTP/HFS and then delete on SD
1024
bool formatIfMountFailed = true; // Auto format the file system if mount failed. Set to false to not auto format.
25+
static bool use1bitMode = true;
1126
static fs::FS fp = STORAGE;
27+
#if (!CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32S2)
28+
static int sdmmcFreq = BOARD_MAX_SDMMC_FREQ; // board specific default SD_MMC speed
29+
#endif
1230

1331
// hold sorted list of filenames/folders names in order of newest first
1432
static std::vector<std::string> fileVec;
@@ -17,31 +35,22 @@ static auto previousDir = "/~previous";
1735
static char fsType[10] = {0};
1836

1937
static void infoSD() {
20-
#if !(CONFIG_IDF_TARGET_ESP32C3)
38+
#if (!CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32S2)
2139
uint8_t cardType = SD_MMC.cardType();
2240
if (cardType == CARD_NONE) LOG_WRN("No SD card attached");
2341
else {
2442
char typeStr[8] = "UNKNOWN";
2543
if (cardType == CARD_MMC) strcpy(typeStr, "MMC");
2644
else if (cardType == CARD_SD) strcpy(typeStr, "SDSC");
2745
else if (cardType == CARD_SDHC) strcpy(typeStr, "SDHC");
28-
LOG_INF("SD card type %s, Size: %s", typeStr, fmtSize(SD_MMC.cardSize()));
46+
LOG_INF("SD card type %s, Size: %s, using %d bit mode @ %uMHz", typeStr, fmtSize(SD_MMC.cardSize()), use1bitMode ? 1 : 4, sdmmcFreq / 1000);
2947
}
3048
#endif
3149
}
3250

3351
static bool prepSD_MMC() {
3452
bool res = false;
35-
#if !(CONFIG_IDF_TARGET_ESP32C3)
36-
/* open SD card in MMC 1 bit mode
37-
MMC4 MMC1 ESP32 ESP32S3
38-
D2 12
39-
D3 .. 13
40-
CMD CMD 15 38
41-
CLK CLK 14 39
42-
D0 D0 2 40
43-
D1 4
44-
*/
53+
#if (!CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32S2)
4554
if (psramFound()) heap_caps_malloc_extmem_enable(MIN_RAM); // small number to force vector into psram
4655
fileVec.reserve(1000);
4756
if (psramFound()) heap_caps_malloc_extmem_enable(MAX_RAM);
@@ -50,11 +59,18 @@ static bool prepSD_MMC() {
5059
LOG_WRN("SD card pins not defined");
5160
return false;
5261
#else
62+
#if defined(SD_MMC_D1)
63+
// assume 4 bit mode
64+
SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0, SD_MMC_D1, SD_MMC_D2, SD_MMC_D3);
65+
use1bitMode = false;
66+
#else
67+
// assume 1 bit mode
5368
SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
69+
#endif
5470
#endif
5571
#endif
5672

57-
res = SD_MMC.begin("/sdcard", true, formatIfMountFailed);
73+
res = SD_MMC.begin("/sdcard", use1bitMode, formatIfMountFailed, sdmmcFreq);
5874
#if defined(CAMERA_MODEL_AI_THINKER)
5975
pinMode(4, OUTPUT);
6076
digitalWrite(4, 0); // set lamp pin fully off as sd_mmc library still initialises pin 4 in 1 line mode
@@ -88,7 +104,7 @@ static void listFolder(const char* rootDir) {
88104
bool startStorage() {
89105
// start required storage device (SD card or flash file system)
90106
bool res = false;
91-
#if !(CONFIG_IDF_TARGET_ESP32C3)
107+
#if (!CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32S2)
92108
if ((fs::SDMMCFS*)&STORAGE == &SD_MMC) {
93109
strcpy(fsType, "SD_MMC");
94110
res = prepSD_MMC();
@@ -413,3 +429,30 @@ esp_err_t downloadFile(File& df, httpd_req_t* req) {
413429
} else res = sendChunks(df, req); // send AVI
414430
return res;
415431
}
432+
433+
bool formatSDcard() {
434+
// format SD card, erases existing content
435+
// can take some time to complete
436+
// invoke from url: <cam ip>/control?formatSD=1
437+
LOG_INF("Format the SD card, wait ...");
438+
char drv[3] = {'0', ':', 0};
439+
const size_t workbuf_size = 4096;
440+
void* workbuf = NULL;
441+
size_t allocation_unit_size = 4 * 1024;
442+
int sector_size_default = 512;
443+
444+
workbuf = ff_memalloc(workbuf_size);
445+
if (workbuf == NULL) {
446+
LOG_ERR("workbuf memory not allocated");
447+
return false;
448+
}
449+
450+
size_t alloc_unit_size = esp_vfs_fat_get_allocation_unit_size(
451+
sector_size_default, allocation_unit_size);
452+
const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, alloc_unit_size};
453+
FRESULT res = f_mkfs(drv, &opt, workbuf, workbuf_size);
454+
ff_memfree(workbuf);
455+
if (res != FR_OK) LOG_ERR("SD card format failed");
456+
else LOG_INF("SD card formatted with alloc unit size %d", alloc_unit_size);
457+
return res != FR_OK ? false : true;
458+
}

webDav.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static int getMimeType(const char* path) {
6060
static void formatTime(time_t t) {
6161
// format time for XML property values
6262
tm* timeinfo = gmtime(&t);
63-
strftime(formattedTime, sizeof(formattedTime), "%a, %d %b %Y %H:%M:%S %Z", timeinfo);
63+
strftime(formattedTime, sizeof(formattedTime), "%a, %d %b %Y %H:%M:%S GMT", timeinfo);
6464
}
6565

6666
static bool haveResource(bool ignore = false) {

0 commit comments

Comments
 (0)