diff --git a/README.md b/README.md index fd86f56..eed3cb1 100644 --- a/README.md +++ b/README.md @@ -110,42 +110,3 @@ CLion is compatible with this project. Follow [the tutorial on Espressif's site] - If the `Open Project Wizard` does not open, access it via `Settings > Build, Execution, Deployment > CMake`. - When setting the `DIDF_TARGET`, ensure you specify `esp32s3`. -# me when it works - -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡤⣖⣤⣶⣿⣿⣿⣿⣿⣭⡶⠶⠒⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠈⠉⠁⠒⠤⠀⡔⠄⠀⠂ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡴⢋⣥⣾⣿⣿⣿⣿⣿⣿⡿⠛⠁⢀⣠⠔⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠛⠓⢤⡀⠀⠀⢀⣀⠈⠂⠉⠀ -⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠘⣿⣀⢻⡟⠉⣷⠀⠀⠀⠀⠀⠀⢀⡤⠎⠁⣀⣿⣿⣿⣿⣿⣿⣿⠟⢉⣠⣶⡾⠋⠀⠀⠀⠀⣀⣠⡤⢶⡾⠶⠀⠀⠀⠀⠀⠉⠶⣽⣾⣿⣷⣄⡀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣶⣬⣺⡟⠀⠀⠀⠀⢀⡴⠋⢀⣤⣾⣿⣿⣿⣿⣿⣿⡿⣣⣴⡿⠟⠁⠀⠀⣠⣤⣶⡿⠟⢉⣴⠋⠁⠀⠀⢀⡞⠀⠀⣦⠀⠙⢿⣿⣿⣿⣿⣦ -⠀⠀⠀⠀⠀⠰⡄⠀⠀⠀⠀⠀⠀⠀⠈⠁⠀⠀⠀⢀⣴⣯⣶⣿⣿⣿⡿⣽⣿⣿⣿⣿⣿⣿⢿⠋⡀⣀⣤⣾⠿⣿⡿⢋⣴⣾⠟⠀⠀⠀⠀⣴⠋⠀⠀⠀⢹⣦⠠⢪⣻⣿⣿⣿⣿ -⠀⠀⠀⠀⠀⠀⠻⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣻⢋⡞⣿⣿⣿⣿⣿⣿⣿⣷⣾⡿⠟⠉⣱⡾⣯⡶⣿⡿⠃⠀⠀⠀⢀⡼⠃⢠⣆⠀⠀⣇⣿⡆⡜⡏⢿⣿⣿⣿ -⠀⠀⠀⠀⠀⠀⠀⢷⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⣿⡟⠁⠀⠁⣰⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀⢠⣾⣿⠟⢡⣾⣿⠅⠀⠀⠀⣠⡿⠁⣰⣿⢸⢸⡆⣿⣿⣿⣼⣼⡈⣿⣿⣿ -⠀⠀⠀⠀⠀⠀⠀⠈⡇⠀⠀⠀⠀⠀⠀⠀⣴⣿⠟⣹⣿⡏⠀⠀⠀⢰⣿⣿⣿⣿⡿⠟⠉⠀⠀⠀⣰⣿⡿⠃⢠⣾⣿⠞⠀⠀⡴⣷⣿⠅⠀⣿⣿⢸⣾⡇⢻⣿⣿⣿⣿⣇⠸⣿⣿ -⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⢰⡿⠁⣸⣿⡟⢠⢀⢠⢀⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⢰⣿⠟⠀⢠⣿⣿⡟⠀⢀⣼⣿⣿⡿⠀⢰⣿⣿⡟⣿⣇⢸⣿⣿⣿⣿⣿⠀⣿⣿ -⠀⠀⠀⠀⢰⡾⢶⣀⣥⣤⡀⠀⠀⠀⢰⡟⠁⣴⣿⣿⣧⡟⣾⢋⣼⣿⡿⠋⠀⠀⠀⠀⠀⠀⢠⣿⠏⠀⠀⣼⣿⣿⠀⢀⣾⣿⣳⡿⠁⠀⡇⣿⣿⣿⣿⣿⡸⣿⣿⣿⣿⣿⡀⢻⡏ -⠀⠀⠀⠀⢸⣇⠀⠻⣇⣸⡇⠀⠀⢀⡞⠀⣼⢿⣿⣿⣿⣹⡟⣾⡿⠋⠑⠦⠤⠤⣀⣀⣀⠤⣾⡿⠂⠀⢸⣿⣿⡇⢀⣾⡿⢱⡿⠁⠀⠐⠁⣿⣿⣿⣿⣿⣇⣿⣿⣿⣿⣿⡇⢸⡇ -⠀⠀⠀⠀⠀⠙⢷⣴⠟⠋⠀⠀⠀⡾⠀⢰⠃⢈⣿⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⣄⡏⠀⠀⠀⢸⣿⡿⢀⣾⡿⣇⡾⠁⠀⠀⠀⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⡇ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠃⢰⠇⠀⠸⢸⣿⣿⣿⢋⡀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠸⠃⠀⠀⠀⢸⣿⡇⣾⡿⠁⡸⢣⡀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⡇ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢺⣠⠏⢀⡀⠀⣸⣿⣿⡏⢀⣹⣶⣶⣶⣿⣯⡒⢆⡀⠀⠀⠀⠀⠀⠀⢸⣿⢳⡿⠀⢰⠇⠀⠙⢦⡀⢀⠀⠀⠸⣿⣿⣿⡿⣿⣿⣿⣿⣿⡃⣼⠁ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡴⠋⣠⠞⠀⣼⢿⣿⣿⣱⡿⠋⠁⢠⣴⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠸⣿⣿⠃⠀⠀⠀⠀⠀⠀⠙⢮⡄⠀⠀⢻⣿⣿⣿⢿⣿⣿⣿⣿⠀⣿⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡾⣁⠞⠁⢀⣾⣿⢸⣿⡿⡿⠀⠀⣰⣿⣿⣿⣿⡟⢻⡇⠀⠀⠀⠀⠀⠀⠀⢻⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠲⣀⠈⢿⣿⣿⠈⣿⣿⣿⣿⢠⣿⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠟⠁⢀⣴⣿⣿⣿⣾⣿⣿⠃⠀⢠⡟⠉⠙⠛⢻⣷⣿⡇⠀⠀⠀⠀⠀⠀⠀⠸⠃⠀⠀⠀⠀⢠⣤⣀⠀⡀⠀⠀⠀⠙⠚⢿⣿⣧⠸⣿⣿⣿⣾⣷⢰ -⠀⠀⠀⠀⠀⠀⢀⣴⡿⢛⡥⢀⣴⣿⣿⣿⠟⠀⢹⣿⣧⠀⠀⠘⢇⠀⣀⡀⣸⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⣿⣿⣷⣿⣤⡀⠀⠀⠀⠈⢿⣿⣆⠸⣿⣿⣿⣿⣾ -⠀⠀⠀⢀⣠⠾⠋⢉⣴⣫⣶⣿⣿⡿⠋⠁⠀⠀⠀⣿⣿⡄⠀⠈⢿⡀⠈⠉⢁⡼⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣷⣧⡀⠀⠈⢻⣿⣆⠹⣿⣿⣿⣿ -⠀⠀⠀⠈⢱⣄⣾⣯⣿⣿⠟⠋⠀⠀⠀⠀⠀⣠⣼⠃⠙⢷⠀⠐⠚⠿⠖⠚⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⠛⠿⢿⣿⡏⢙⡏⠻⣿⣆⠀⠀⠻⣿⣷⣿⣿⣿⣿ -⡀⠀⠀⣠⣿⣿⣿⠟⣹⣵⣤⣤⣤⣤⣤⣤⡼⢿⡏⠀⠀⠀⠙⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⡃⠀⠀⠀⠀⢘⣿⣿⠇⠀⠹⣿⡆⠀⠀⢸⣏⣿⣿⣿⣿ -⣡⣴⣾⣻⣿⠟⣩⣾⣿⣿⣿⣿⣿⣿⣿⡏⠀⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢉⣳⠀⢤⣀⣠⠞⢉⡿⠀⠀⠀⢹⣷⠀⢀⣾⣾⣿⣿⣿⣿ -⣿⣿⢣⣿⣗⣼⣿⣿⡿⠿⢿⡟⠛⠛⠛⣷⠞⠋⠛⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣧⠀⠀⠀⠀⣠⠟⠀⠀⠀⠀⣸⠇⢀⣾⣾⣿⢿⣿⣿⣿ -⣿⣿⠠⣿⠿⣿⡁⠈⠀⠀⠀⠑⣄⣠⠞⠁⠀⠀⠀⣀⡹⠶⠤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣒⠖⠋⠁⠀⠀⠀⠀⠞⠁⣰⣿⣿⠟⢡⣿⡿⠋⠀ -⡋⠙⣸⠃⠀⠈⠻⣦⠀⢀⡴⣶⠟⠁⠀⠀⣀⡴⠚⠁⠀⠀⠀⠙⣆⠀⠀⠀⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⡿⢟⡥⣺⣿⠟⠀⠊⠀ -⠀⠀⠃⠀⠀⠀⠀⢈⡿⠋⣰⠇⠀⠀⠐⠚⠁⠀⠀⠀⠀⣠⠴⠛⠋⠓⣆⠀⠈⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣛⣻⠵⠚⢁⡴⠟⠁⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⣰⠏⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⣠⠖⠋⠀⠀⠀⠀⠀⢸⣦⠀⠈⠳⠤⠴⠖⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠊⠉⠉⠀⢀⣤⠶⠭⠄⠀⠀⠀⠀⠀⢀ -⠀⠀⠀⠀⠀⡼⠁⠀⠀⠀⠘⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⠞⠉⠈⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⠋⠁⠀⠀⠀⠀⢀⣀⣀⠐⠃ -⠀⠀⠀⠀⡼⠁⠀⠀⠀⠀⠀⡎⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠖⠋⠀⢀⠀⠀⢸⠀⠀⠀⡤⠤⠤⣤⡴⠒⠒⠒⢦⡖⠒⠲⠤⣄⣀⡀⠀⣀⣤⣾⡋⠉⠓⠶⠖⠚⠛⠉⠁⠀⠀⠀⢀ -⠀⠀⠀⡸⠁⠀⠀⠀⠀⠀⠀⡇⠀⠈⢣⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠿⣦⡞⠀⢠⡞⠀⠀⠀⠈⡇⠀⠀⠀⢸⠇⠀⠀⠀⡇⠈⠉⠙⢿⣿⣿⣿⣆⠀⠀⠀⠀⢠⠀⠀⣠⣀⣠⣿ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡇⠀⡇⠀⢸⡓⢤⡀⠀⠀⠀⠀⠀⠀⢀⡴⢻⠉⢹⣿⠇⠀⠀⠀⠀⡇⠀⠀⠀⡸⠀⠀⠀⢰⡇⠀⠀⠀⢸⣿⣿⡿⠟⠳⠤⠖⠶⠤⣤⣴⣿⣌⢿⣿ -⠀⠀⠀⠀⠀⠀⢀⠴⠋⠉⠁⡇⠀⠀⠀⠀⠇⠀⠉⠑⠶⢤⡤⠴⠞⠉⠄⣼⣠⠾⠿⠀⠀⠀⠀⠀⠃⠀⠀⠀⠃⠀⠀⠀⠸⠁⠀⠀⢰⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠦⡹ -⠠⠂⠀⠀⠀⠀⢸⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣲⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡏⠘⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⠃⠀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠁⠀⠀⠀⠀⠀⠙⠓⠤⢤⣤⣀⣀⣀⣀⣀⣠⡤⢖⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⢀⠀⠀⢀⡔⠉⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ diff --git a/components/constants/include/constants/module.h b/components/constants/include/constants/module.h index 44ca207..0a57b68 100644 --- a/components/constants/include/constants/module.h +++ b/components/constants/include/constants/module.h @@ -10,7 +10,7 @@ #include "flatbuffers_generated/RobotModule_generated.h" inline std::unordered_map MODULE_TO_NUM_CHANNELS_MAP { - {ModuleType_SPLITTER, 4}, + {ModuleType_SPLITTER, 3}, // should be 4 {ModuleType_SERVO_1, 2}, {ModuleType_DC_MOTOR, 1}, {ModuleType_SERVO_2, 2}, @@ -19,7 +19,7 @@ inline std::unordered_map MODULE_TO_NUM_CHANNELS_MAP { {ModuleType_SPEAKER, 1}, {ModuleType_IMU, 1}, {ModuleType_DISTANCE_SENSOR, 1}, - {ModuleType_SPLITTER_2, 4}, + {ModuleType_SPLITTER_2, 3}, // should be 4 {ModuleType_SPLITTER_3, 3}, {ModuleType_SPLITTER_4, 3}, {ModuleType_SPLITTER_5, 3}, diff --git a/components/dataLink/CMakeLists.txt b/components/dataLink/CMakeLists.txt index ce67ef1..2fb8c60 100644 --- a/components/dataLink/CMakeLists.txt +++ b/components/dataLink/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "DataLinkManager.cpp" "DataLinkRIP.cpp" "DataLinkScheduler.cpp" "DataLinkFrames.cpp" - PRIV_REQUIRES driver esp_event nvs_flash esp_netif rmt + PRIV_REQUIRES driver esp_event nvs_flash esp_netif rmt softUART REQUIRES esp_timer ptrQueue INCLUDE_DIRS "include") diff --git a/components/dataLink/DataLinkFrames.cpp b/components/dataLink/DataLinkFrames.cpp index 0a13edd..e9997f5 100644 --- a/components/dataLink/DataLinkFrames.cpp +++ b/components/dataLink/DataLinkFrames.cpp @@ -289,6 +289,15 @@ esp_err_t DataLinkManager::receive_rmt(uint8_t channel){ return ESP_ERR_INVALID_RESPONSE; } + // Preamble sanity check — if byte 0 is not START_OF_FRAME this buffer + // contains a merged frame, a partial capture, or line noise. Discard + // immediately rather than letting it propagate to the CRC checker. + if (data[0] != START_OF_FRAME){ + ESP_LOGW(DEBUG_LINK_TAG, "Discarding frame on ch %d: bad preamble 0x%02X (expected 0x%02X)", + channel, data[0], START_OF_FRAME); + return ESP_ERR_INVALID_RESPONSE; + } + // ---- LUT fast-path for control frames ---- // Raw wire layout for control frames: // [0] preamble @@ -301,7 +310,8 @@ esp_err_t DataLinkManager::receive_rmt(uint8_t channel){ // [12..] actual payload // [-2..-1] CRC-16 bool is_control = IS_CONTROL_FRAME(data[5]); - if (is_control && recv_len >= (size_t)(CONTROL_FRAME_OVERHEAD + CONTROL_FRAME_HASH_SIZE)){ + bool is_rip = (GET_TYPE(data[5]) == static_cast(FrameType::RIP_TABLE_CONTROL)); + if (is_control && !is_rip && recv_len >= (size_t)(CONTROL_FRAME_OVERHEAD + CONTROL_FRAME_HASH_SIZE)){ uint32_t peeked_hash = ((uint32_t)data[8] ) | ((uint32_t)data[9] << 8) | ((uint32_t)data[10] << 16) | @@ -323,20 +333,36 @@ esp_err_t DataLinkManager::receive_rmt(uint8_t channel){ // RIP control frames are handled internally – replay them too if (static_cast(GET_TYPE(cached_header.type_flag)) == FrameType::RIP_TABLE_CONTROL){ - // Re-run the RIP update using the cached message - for (size_t i = 0; i < cached_message.size() - 1; i += 2){ - uint8_t board_id = cached_message[i]; - uint8_t hops = cached_message[i + 1]; - RIPRow* entry = nullptr; + // Re-run the RIP update using the cached message (3-byte stride: board_id, hops, sum_of_hops) + for (size_t i = 0; i + 2 < cached_message.size(); i += RIP_WIRE_STRIDE){ + uint8_t board_id = cached_message[i]; + uint8_t hops = cached_message[i + 1]; + uint8_t sum_of_hops = cached_message[i + 2]; + + // Skip routes about ourselves + if (board_id == this_board_id){ + continue; + } + + RIPRow* entry = nullptr; if (rip_find_entry(board_id, &entry, true) != ESP_OK || entry == nullptr){ continue; } if (entry->valid == RIP_NEW_ROW){ - rip_add_entry(board_id, hops + 1, channel, &entry); + rip_add_entry(board_id, hops + 1, sum_of_hops, channel, &entry); } else { - rip_update_entry(hops + 1, channel, &entry); + rip_update_entry(hops + 1, sum_of_hops, channel, &entry); } } + + // If this was a discovery request, send our routing table back + if (GET_FLAG(cached_header.type_flag) == FLAG_DISCOVERY){ + esp_err_t disc_res = send_rip_frame(false, cached_header.sender_id); + if (disc_res != ESP_OK){ + ESP_LOGE(DEBUG_LINK_TAG, "Failed to send back rip table to board %d (LUT path)", cached_header.sender_id); + } + } + return ESP_OK; } @@ -407,9 +433,8 @@ esp_err_t DataLinkManager::receive_rmt(uint8_t channel){ return res; } - // Control frame fully validated – store in LUT for future replays - // Extract the hash that was embedded at data[8..11] (already validated in get_data_from_frame) - { + // Control frame fully validated – store in LUT for future replays (skip RIP frames: their payload is dynamic) + if (!is_rip){ uint32_t validated_hash = ((uint32_t)data[8] ) | ((uint32_t)data[9] << 8) | ((uint32_t)data[10] << 16) | @@ -424,10 +449,17 @@ esp_err_t DataLinkManager::receive_rmt(uint8_t channel){ if (static_cast(GET_TYPE(header.type_flag)) == FrameType::RIP_TABLE_CONTROL){ ESP_LOGI(DEBUG_LINK_TAG, "Got a RIP frame from channel %d", channel); - for (size_t i = 0; i < message_size-1; i+=2){ - uint8_t board_id = message->data()[i]; - uint8_t hops = message->data()[i+1]; - ESP_LOGI(DEBUG_LINK_TAG, "Received: board_id %d and number of hops %d on channel %d", board_id, hops, channel); + for (size_t i = 0; i + 2 < message_size; i += RIP_WIRE_STRIDE){ + uint8_t board_id = message->data()[i]; + uint8_t hops = message->data()[i + 1]; + uint8_t sum_of_hops = message->data()[i + 2]; + + // Skip routes about ourselves - we already know we're 0 hops away from ourselves + if (board_id == this_board_id){ + continue; + } + + ESP_LOGI(DEBUG_LINK_TAG, "Received: board_id %d hops %d sum_of_hops %d on channel %d", board_id, hops, sum_of_hops, channel); RIPRow* entry = nullptr; @@ -443,15 +475,14 @@ esp_err_t DataLinkManager::receive_rmt(uint8_t channel){ if (entry->valid == RIP_NEW_ROW){ //adding a new entry - rip_add_entry(board_id, hops + 1, channel, &entry); + rip_add_entry(board_id, hops + 1, sum_of_hops, channel, &entry); } else { //updating an entry - rip_update_entry(hops + 1, channel, &entry); + rip_update_entry(hops + 1, sum_of_hops, channel, &entry); } if (GET_FLAG(header.type_flag) == FLAG_DISCOVERY){ //discovery -> send routing table - // ESP_LOGI(DEBUG_LINK_TAG, "got discovery reply"); RIPRow_public row_queue = { .info = entry->info, .channel = entry->channel @@ -461,7 +492,19 @@ esp_err_t DataLinkManager::receive_rmt(uint8_t channel){ } } - if (message_size == RIP_DISCOVERY_MESSAGE_SIZE){ + + // Print the finalized RIP table after processing all received rows + ESP_LOGI(DEBUG_LINK_TAG, "--- RIP Table (after update from channel %d) ---", channel); + for (size_t i = 0; i < RIP_MAX_ROUTES; i++){ + RIPRow* row = nullptr; + if (rip_get_row(&row, i) == ESP_OK && row != nullptr){ + ESP_LOGI(DEBUG_LINK_TAG, " [%d] board_id=%d hops=%d sum_of_hops=%d channel=%d ttl=%d", + i, row->info.board_id, row->info.hops, row->info.sum_of_hops, row->channel, row->ttl); + } + } + ESP_LOGI(DEBUG_LINK_TAG, "---------------------------------------------------"); + + if (GET_FLAG(header.type_flag) == FLAG_DISCOVERY){ res = send_rip_frame(false, header.sender_id); if (res != ESP_OK){ ESP_LOGE(DEBUG_LINK_TAG, "Failed to send back rip table to board %d", header.sender_id); diff --git a/components/dataLink/DataLinkManager.cpp b/components/dataLink/DataLinkManager.cpp index bee3c2d..68d7c50 100644 --- a/components/dataLink/DataLinkManager.cpp +++ b/components/dataLink/DataLinkManager.cpp @@ -2,6 +2,7 @@ #include "BlockingQueue.h" #include "Frames.h" #include "RMTManager.h" +#include "SoftUARTManager.h" #include "esp_log.h" #include "nvs_flash.h" #include @@ -13,9 +14,15 @@ * * @param board_id Board ID of the current board. Will be written to the NVM under key "board" if not already written. */ -DataLinkManager::DataLinkManager(uint8_t board_id, uint8_t num_channels = MAX_CHANNELS){ +DataLinkManager::DataLinkManager(uint8_t board_id, uint8_t num_channels, PhysicalLayerType phy_type){ //init table for this board and set up link layer priority queue - phys_comms = std::make_unique(num_channels); + if (phy_type == PhysicalLayerType::SOFT_UART){ + phys_comms = std::make_unique(num_channels); + ESP_LOGI(DEBUG_LINK_TAG, "Using SoftUART physical layer"); + } else { + phys_comms = std::make_unique(num_channels); + ESP_LOGI(DEBUG_LINK_TAG, "Using RMT physical layer"); + } if (phys_comms == nullptr){ ESP_LOGE(DEBUG_LINK_TAG, "RMT object was not created. Link layer communications will not function."); return; diff --git a/components/dataLink/DataLinkRIP.cpp b/components/dataLink/DataLinkRIP.cpp index a0f8ee1..1e4f3f8 100644 --- a/components/dataLink/DataLinkRIP.cpp +++ b/components/dataLink/DataLinkRIP.cpp @@ -27,6 +27,7 @@ void DataLinkManager::init_rip(){ rip_table[0].info = { .board_id = this_board_id, .hops = 0, + .sum_of_hops = 0, }; rip_table[0].channel = MAX_CHANNELS + 1; rip_table[0].ttl = RIP_TTL_START; @@ -37,7 +38,7 @@ void DataLinkManager::init_rip(){ start_rip_tasks(); } -esp_err_t DataLinkManager::rip_add_entry(uint8_t board_id, uint8_t hops, uint8_t channel, RIPRow** entry){ +esp_err_t DataLinkManager::rip_add_entry(uint8_t board_id, uint8_t hops, uint8_t sum_of_hops, uint8_t channel, RIPRow** entry){ if (entry == nullptr){ return ESP_FAIL; } @@ -49,16 +50,16 @@ esp_err_t DataLinkManager::rip_add_entry(uint8_t board_id, uint8_t hops, uint8_t (*entry)->channel = channel; (*entry)->info = { .board_id = board_id, - .hops = hops + .hops = hops, + .sum_of_hops = sum_of_hops, }; (*entry)->ttl = RIP_TTL_START; (*entry)->valid = 1; - - // ESP_LOGI(DEBUG_LINK_TAG, "board_id %d now has hops %d from channel %d", (*entry)->info.board_id, (*entry)->info.hops, channel); - xSemaphoreGive((*entry)->row_sem); + rip_update_self_sum_of_hops(); + if (uxQueueMessagesWaiting(manual_broadcasts) == 0){ bool dummy = true; xQueueSend(manual_broadcasts, &dummy, 0); //new row - send broadcast @@ -67,7 +68,32 @@ esp_err_t DataLinkManager::rip_add_entry(uint8_t board_id, uint8_t hops, uint8_t return ESP_OK; } +/** + * @brief Recomputes and stores this board's own sum_of_hops (centrality score). + * Called whenever the routing table changes. No semaphores are held on entry. + */ +void DataLinkManager::rip_update_self_sum_of_hops(){ + uint32_t total = 0; + for (size_t i = 1; i < RIP_MAX_ROUTES; i++){ + if (xSemaphoreTake(rip_table[i].row_sem, pdMS_TO_TICKS(RIP_MAX_SEM_WAIT_MS)) != pdTRUE){ + continue; + } + if (rip_table[i].valid == RIP_VALID_ROW && rip_table[i].info.hops <= RIP_MAX_HOPS){ + total += rip_table[i].info.hops; + } + xSemaphoreGive(rip_table[i].row_sem); + } + + // Clamp to uint8_t max — with RIP_MAX_ROUTES=10 and RIP_MAX_HOPS=15 the max is 9*15=135, fits fine. + if (xSemaphoreTake(rip_table[0].row_sem, pdMS_TO_TICKS(RIP_MAX_SEM_WAIT_MS)) == pdTRUE){ + rip_table[0].info.sum_of_hops = (total > 255) ? 255 : static_cast(total); + xSemaphoreGive(rip_table[0].row_sem); + } +} + esp_err_t DataLinkManager::rip_reset_entry_ttl(uint8_t board_id){ + // ...existing code... + RIPRow* entry = nullptr; esp_err_t res; @@ -92,7 +118,7 @@ esp_err_t DataLinkManager::rip_reset_entry_ttl(uint8_t board_id){ return ESP_OK; } -esp_err_t DataLinkManager::rip_update_entry(uint8_t new_hop, uint8_t channel, RIPRow** entry){ +esp_err_t DataLinkManager::rip_update_entry(uint8_t new_hop, uint8_t new_sum_of_hops, uint8_t channel, RIPRow** entry){ if (entry == nullptr){ return ESP_FAIL; //board doesn't exist } @@ -102,22 +128,33 @@ esp_err_t DataLinkManager::rip_update_entry(uint8_t new_hop, uint8_t channel, RI } uint8_t old_hops = (*entry)->info.hops; + uint8_t old_sum_of_hops = (*entry)->info.sum_of_hops; + bool hops_improved = (new_hop < (*entry)->info.hops) || ((*entry)->info.hops == RIP_MAX_HOPS + 1); - if ((*entry)->info.hops >= new_hop && (*entry)->info.hops != RIP_MAX_HOPS + 1){ //no count to infinity if path is invalid + if (hops_improved){ //accept better paths and allow recovery from infinity (*entry)->info.hops = new_hop; + (*entry)->info.sum_of_hops = new_sum_of_hops; (*entry)->channel = channel; - // ESP_LOGI(DEBUG_LINK_TAG, "updated board_id %d now has hops %d from channel %d", (*entry)->info.board_id, (*entry)->info.hops, channel); + } else { + // Even if hops didn't improve, update the centrality score if it came from the same channel + if ((*entry)->channel == channel){ + (*entry)->info.sum_of_hops = new_sum_of_hops; + } } (*entry)->ttl = RIP_TTL_START; (*entry)->valid = 1; - // ESP_LOGI(DEBUG_LINK_TAG, "refreshed board_id %d ttl", (*entry)->info.board_id); + bool sum_of_hops_changed = (old_sum_of_hops != (*entry)->info.sum_of_hops); xSemaphoreGive((*entry)->row_sem); - if (uxQueueMessagesWaiting(manual_broadcasts) == 0 && old_hops > new_hop && old_hops != RIP_MAX_HOPS + 1){ - //if hops were changed, send broadcast (if there isn't already one manual broadcast request pending) + if (hops_improved || sum_of_hops_changed){ + rip_update_self_sum_of_hops(); + } + + if (uxQueueMessagesWaiting(manual_broadcasts) == 0 && (old_hops > new_hop || old_hops == RIP_MAX_HOPS + 1 || sum_of_hops_changed)){ + //if hops were changed (or recovered from infinity), or sum_of_hops changed, send broadcast bool dummy = true; xQueueSend(manual_broadcasts, &dummy, 0); } @@ -139,7 +176,7 @@ esp_err_t DataLinkManager::rip_find_entry(uint8_t board_id, RIPRow** entry, bool if (xSemaphoreTake(rip_table[i].row_sem, pdMS_TO_TICKS(RIP_MAX_SEM_WAIT_MS)) != pdTRUE){ return ESP_FAIL; } - if (rip_table[i].valid == RIP_VALID_ROW && rip_table[i].info.board_id == board_id){ + if ((rip_table[i].valid == RIP_VALID_ROW || rip_table[i].valid == RIP_NEW_ROW) && rip_table[i].info.board_id == board_id){ *entry = &rip_table[i]; xSemaphoreGive(rip_table[i].row_sem); // ESP_LOGI(DEBUG_LINK_TAG, "Found %d in table at row %d", board_id, i); @@ -198,14 +235,11 @@ esp_err_t DataLinkManager::rip_get_row(RIPRow** entry, uint8_t row_num){ return ESP_ERR_INVALID_STATE; } - if (rip_table[row_num].info.hops == RIP_MAX_HOPS + 1){ - //invalid hop, decrement counter - rip_table[row_num].ttl_flush--; - if (rip_table[row_num].ttl_flush == 0){ - rip_table[row_num].valid = RIP_INVALID_ROW; - xSemaphoreGive(rip_table[row_num].row_sem); - return ESP_FAIL; - } + if (rip_table[row_num].info.hops == RIP_MAX_HOPS + 1 && rip_table[row_num].ttl_flush == 0){ + //flush countdown has expired, invalidate the row + rip_table[row_num].valid = RIP_INVALID_ROW; + xSemaphoreGive(rip_table[row_num].row_sem); + return ESP_FAIL; } static RIPRow row_snapshots[RIP_MAX_ROUTES]; @@ -228,8 +262,7 @@ esp_err_t DataLinkManager::rip_get_row(RIPRow** entry, uint8_t row_num){ * @return esp_err_t */ esp_err_t DataLinkManager::send_rip_frame(bool broadcast, uint8_t dest_id){ - //use the control frame for the demo (as the number of rows increase, we will need to use the generic frame) - //data will be [board_id (1), hops (1), board_id (2), hops (2), ...] + // Wire format: [board_id (1), hops (1), sum_of_hops (1), ...] (RIP_WIRE_STRIDE bytes per entry) uint16_t message_idx = 0; esp_err_t res; @@ -240,7 +273,7 @@ esp_err_t DataLinkManager::send_rip_frame(bool broadcast, uint8_t dest_id){ if(broadcast){ for (size_t channel = 0; channel < num_channels; channel++){ auto rip_message = std::make_unique>(); - rip_message->resize(RIP_MAX_ROUTES * 2); + rip_message->resize(RIP_MAX_ROUTES * RIP_WIRE_STRIDE); for (size_t i = 0; i < RIP_MAX_ROUTES; i++){ res = rip_get_row(&entry, i); @@ -253,15 +286,15 @@ esp_err_t DataLinkManager::send_rip_frame(bool broadcast, uint8_t dest_id){ continue; } - // ESP_LOGI(DEBUG_LINK_TAG, "Found entry for board %d with hops %d", entry->info.board_id, entry->info.hops); - if (entry->channel == channel){ //poisoned reverse rip_message->at(message_idx++) = entry->info.board_id; rip_message->at(message_idx++) = RIP_MAX_HOPS + 1; + rip_message->at(message_idx++) = entry->info.sum_of_hops; } else { rip_message->at(message_idx++) = entry->info.board_id; rip_message->at(message_idx++) = entry->info.hops; + rip_message->at(message_idx++) = entry->info.sum_of_hops; } } @@ -299,7 +332,7 @@ esp_err_t DataLinkManager::send_rip_frame(bool broadcast, uint8_t dest_id){ } } else { auto rip_message = std::make_unique>(); - rip_message->resize(RIP_MAX_ROUTES * 2); + rip_message->resize(RIP_MAX_ROUTES * RIP_WIRE_STRIDE); for (size_t i = 0; i < RIP_MAX_ROUTES; i++){ res = rip_get_row(&entry, i); @@ -313,6 +346,7 @@ esp_err_t DataLinkManager::send_rip_frame(bool broadcast, uint8_t dest_id){ } rip_message->data()[message_idx++] = entry->info.board_id; rip_message->data()[message_idx++] = entry->info.hops; + rip_message->data()[message_idx++] = entry->info.sum_of_hops; } ESP_LOGI(DEBUG_LINK_TAG, "replying to discovery request to board %d", dest_id); res = send(dest_id, std::move(rip_message), FrameType::RIP_TABLE_CONTROL, FLAG_DISCOVERY); @@ -382,7 +416,7 @@ esp_err_t DataLinkManager::get_routing_table(RIPRow_public* table, size_t* table return ESP_FAIL; } if (rip_table[i].valid == RIP_VALID_ROW){ - table[i].info = rip_table[i].info; + table[i].info = rip_table[i].info; // copies board_id, hops, and sum_of_hops table[i].channel = rip_table[i].channel; curr_size++; } @@ -439,15 +473,20 @@ esp_err_t DataLinkManager::get_routing_table(RIPRow_public* table, size_t* table continue; } if (link_layer_obj->rip_table[i].ttl != 0){ - // link_layer_obj->rip_table[i].valid = RIP_INVALID_ROW; - // ESP_LOGI(DEBUG_LINK_TAG, "Entry %d now has ttl %d", i, link_layer_obj->rip_table[i].ttl); - // } else { link_layer_obj->rip_table[i].ttl--; if (link_layer_obj->rip_table[i].ttl == 0){ link_layer_obj->rip_table[i].info.hops = RIP_MAX_HOPS + 1; link_layer_obj->rip_table[i].ttl_flush = RIP_FLUSH_COUNT; broadcast = true; } + } else if (link_layer_obj->rip_table[i].info.hops == RIP_MAX_HOPS + 1){ + // TTL already zero and route is poisoned — count down the flush timer + if (link_layer_obj->rip_table[i].ttl_flush > 0){ + link_layer_obj->rip_table[i].ttl_flush--; + } + if (link_layer_obj->rip_table[i].ttl_flush == 0){ + link_layer_obj->rip_table[i].valid = RIP_INVALID_ROW; + } } xSemaphoreGive(link_layer_obj->rip_table[i].row_sem); diff --git a/components/dataLink/DataLinkScheduler.cpp b/components/dataLink/DataLinkScheduler.cpp index 0e024e7..a48f532 100644 --- a/components/dataLink/DataLinkScheduler.cpp +++ b/components/dataLink/DataLinkScheduler.cpp @@ -275,15 +275,11 @@ esp_err_t DataLinkManager::scheduler_send(uint8_t channel){ esp_err_t DataLinkManager::scheduler_send_rmt(uint8_t channel, SchedulerMetadata frame, uint8_t* send_data, size_t frame_size, bool wait_for_tx_done){ esp_err_t res; uint8_t channel_to_route = MAX_CHANNELS; - rmt_transmit_config_t config = { - .loop_count = 0, - .flags = { - .eot_level = 0, // typically 0 or 1, depending on your output idle level - } - }; + + // config is physical-layer specific; each IPhysicalLayer implementation + // uses its own internal configuration set at init time, so nullptr is fine. if (frame.header.receiver_id == BROADCAST_ADDR){ - // printf("Sending on channel %d\n", i); - res = phys_comms->send(send_data, frame_size, &config, channel); + res = phys_comms->send(send_data, frame_size, nullptr, channel); } else { res = route_frame(frame.header.receiver_id, &channel_to_route); @@ -291,18 +287,12 @@ esp_err_t DataLinkManager::scheduler_send_rmt(uint8_t channel, SchedulerMetadata ESP_LOGE(DEBUG_LINK_TAG, "Failed to find entry for %d", frame.header.receiver_id); return ESP_FAIL; } - // ESP_LOGI(DEBUG_LINK_TAG, "Sending frame %d on channel %d to board %d frag_info 0x%X", frame.header.seq_num, channel, frame.header.receiver_id, frame.header.frag_info); - res = phys_comms->send(send_data, frame_size, &config, channel_to_route); - // if (wait_for_tx_done){ - // phys_comms->wait_until_send_complete(channel_to_route); - // } + res = phys_comms->send(send_data, frame_size, nullptr, channel_to_route); } if (res != ESP_OK){ ESP_LOGE(DEBUG_LINK_TAG, "Failed to send message"); return ESP_FAIL; - } else{ - // ESP_LOGI(DEBUG_LINK_TAG, "Sent frame %d frag_info 0x%X", frame.header.seq_num, frame.header.frag_info); } return ESP_OK; diff --git a/components/dataLink/include/DataLinkManager.h b/components/dataLink/include/DataLinkManager.h index ac79301..8efe036 100644 --- a/components/dataLink/include/DataLinkManager.h +++ b/components/dataLink/include/DataLinkManager.h @@ -10,12 +10,20 @@ #include "freertos/semphr.h" #include "Frames.h" #include "Tables.h" -#include "RMTManager.h" +#include "IPhysicalLayer.h" #include "BlockingQueue.h" #include "BlockingPriorityQueue.h" #include #include "Scheduler.h" +/** + * @brief Selects which physical layer implementation to instantiate. + */ +enum class PhysicalLayerType : uint8_t { + RMT = 0, ///< Use the RMT-based Manchester-encoded physical layer (default) + SOFT_UART = 1, ///< Use the software-UART physical layer +}; + #define DEBUG_LINK_TAG "LinkLayer" #define CRC_POLYNOMIAL 0x1021 @@ -56,7 +64,7 @@ static const uint16_t crc16_table[256] = { */ class DataLinkManager{ public: - DataLinkManager(uint8_t board_id, uint8_t num_channels); + DataLinkManager(uint8_t board_id, uint8_t num_channels, PhysicalLayerType phy_type = PhysicalLayerType::SOFT_UART); ~DataLinkManager(); esp_err_t send(uint8_t dest_board, std::unique_ptr>&& buffer, FrameType type, uint8_t flag); esp_err_t start_receive_frames(uint8_t curr_channel); @@ -69,7 +77,7 @@ class DataLinkManager{ private: uint8_t this_board_id = 0; uint8_t num_channels = MAX_CHANNELS; - std::unique_ptr phys_comms; + std::unique_ptr phys_comms; std::unordered_map sequence_num_map; SemaphoreHandle_t sequence_num_map_mutex; @@ -93,10 +101,11 @@ class DataLinkManager{ void init_rip(); esp_err_t rip_find_entry(uint8_t board_id, RIPRow** entry, bool reserve_row); - esp_err_t rip_update_entry(uint8_t new_hop, uint8_t channel, RIPRow** entry); - esp_err_t rip_add_entry(uint8_t board_id, uint8_t hops, uint8_t channel, RIPRow** entry); + esp_err_t rip_update_entry(uint8_t new_hop, uint8_t new_sum_of_hops, uint8_t channel, RIPRow** entry); + esp_err_t rip_add_entry(uint8_t board_id, uint8_t hops, uint8_t sum_of_hops, uint8_t channel, RIPRow** entry); esp_err_t rip_reset_entry_ttl(uint8_t board_id); esp_err_t rip_get_row(RIPRow** entry, uint8_t row_num); + void rip_update_self_sum_of_hops(); //this is stored locally with metadata `ttl` // std::unordered_map rip_table; //using a hash map to store the routes to other boards - will be used as we scale up diff --git a/components/dataLink/include/Tables.h b/components/dataLink/include/Tables.h index 8545af1..7f6f85e 100644 --- a/components/dataLink/include/Tables.h +++ b/components/dataLink/include/Tables.h @@ -7,7 +7,7 @@ #define RIP_INVALID_ROW 0 #define RIP_VALID_ROW 1 #define RIP_NEW_ROW 2 -#define RIP_BROADCAST_INTERVAL 30000 //broadcast every 30 seconds (30000ms) +#define RIP_BROADCAST_INTERVAL 15000 //broadcast every 30 seconds (15000ms) // #define RIP_BROADCAST_INTERVAL 3000 //temp broadcast every 3 seconds (3000ms) #define RIP_TTL_START 180 //seconds #define RIP_MS_TO_SEC 1000 //1000 ms to 1 sec @@ -15,13 +15,15 @@ #define RIP_FLUSH_COUNT 8 //flush after 8*30 seconds = 240 seconds #define RIP_DISCOVERY_MESSAGE_SIZE 1 +#define RIP_WIRE_STRIDE 3 // bytes per entry on the wire: board_id, hops, sum_of_hops /** * @brief Routing data to a board * This struct will be sent to other boards */ typedef struct _rip_hops{ - uint8_t board_id; //ID of the destination - uint8_t hops; //hop count to `board_id` + uint8_t board_id; //ID of the destination + uint8_t hops; //hop count to `board_id` + uint8_t sum_of_hops; //sum of hops from `board_id` to all other known boards (centrality score) } RIPHop; typedef struct _rip_row{ @@ -36,7 +38,7 @@ typedef struct _rip_row{ /** * @brief Public facing RIP table row - * + * */ typedef struct _rip_public_row{ RIPHop info; diff --git a/components/rmt/RMTManager.cpp b/components/rmt/RMTManager.cpp index 8e5997d..35a0233 100644 --- a/components/rmt/RMTManager.cpp +++ b/components/rmt/RMTManager.cpp @@ -353,7 +353,8 @@ void RMTManager::reset_encoder_context(rmt_encoder_context_t* ctx){ * @param config * @return int */ -esp_err_t RMTManager::send(uint8_t* data, size_t size, rmt_transmit_config_t* config, uint8_t channel_num){ +esp_err_t RMTManager::send(uint8_t* data, size_t size, void* config_ptr, uint8_t channel_num){ + rmt_transmit_config_t* config = static_cast(config_ptr); if (channel_num >= num_channels){ ESP_LOGE(DEBUG_TAG, "send() error: invalid channel number"); return ESP_FAIL; diff --git a/components/rmt/include/IPhysicalLayer.h b/components/rmt/include/IPhysicalLayer.h new file mode 100644 index 0000000..9576c26 --- /dev/null +++ b/components/rmt/include/IPhysicalLayer.h @@ -0,0 +1,22 @@ +#ifndef IPHYSICAL_LAYER_H +#define IPHYSICAL_LAYER_H + +#include +#include +#include "esp_err.h" + +#ifndef MAX_CHANNELS +#define MAX_CHANNELS 4 +#endif + +class IPhysicalLayer { +public: + virtual ~IPhysicalLayer() = default; + + virtual esp_err_t send(uint8_t* data, size_t size, void* config, uint8_t channel_num) = 0; + virtual esp_err_t receive(uint8_t* recv_buf, size_t size, size_t* output_size, uint8_t channel_num) = 0; + virtual esp_err_t start_receiving(uint8_t channel_num) = 0; + virtual esp_err_t wait_until_send_complete(uint8_t channel_num) = 0; +}; + +#endif // IPHYSICAL_LAYER_H diff --git a/components/rmt/include/RMTManager.h b/components/rmt/include/RMTManager.h index 59a25d6..7dc3f6e 100644 --- a/components/rmt/include/RMTManager.h +++ b/components/rmt/include/RMTManager.h @@ -9,8 +9,11 @@ #include "driver/rmt_tx.h" #include "driver/rmt_rx.h" #include "soc/gpio_num.h" +#include "IPhysicalLayer.h" +#ifndef MAX_CHANNELS #define MAX_CHANNELS 4 +#endif #define RMT_SYMBOL_BLOCK_SIZE 48 #define RECEIVE_BUFFER_SIZE 1024 //this is some value (we should probably set it to some packet size that we predetermine in some custom protocol:tm:) @@ -74,12 +77,12 @@ typedef struct _rmt_channel{ * @author Justin Chow * */ -class RMTManager{ +class RMTManager : public IPhysicalLayer { public: RMTManager(uint8_t num_channels); - ~RMTManager(); - esp_err_t send(uint8_t* data, size_t size, rmt_transmit_config_t* config, uint8_t channel_num); //temp function to send some string data - esp_err_t receive(uint8_t* recv_buf, size_t size, size_t* output_size, uint8_t channel_num); + ~RMTManager() override; + esp_err_t send(uint8_t* data, size_t size, void* config, uint8_t channel_num) override; + esp_err_t receive(uint8_t* recv_buf, size_t size, size_t* output_size, uint8_t channel_num) override; static size_t encoder_callback(const void* data, size_t data_size, size_t symbols_written, size_t symbols_free, rmt_symbol_word_t* symbols, bool* done, void* arg); @@ -87,9 +90,9 @@ class RMTManager{ static bool rmt_rx_done_callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data); static bool rmt_tx_done_callback(rmt_channel_handle_t channel, const rmt_tx_done_event_data_t *edata, void *user_data); - esp_err_t start_receiving(uint8_t channel_num); + esp_err_t start_receiving(uint8_t channel_num) override; - esp_err_t wait_until_send_complete(uint8_t channel_num); + esp_err_t wait_until_send_complete(uint8_t channel_num) override; private: uint8_t num_channels; //number of channels initalized @@ -107,21 +110,21 @@ class RMTManager{ // rmt_channel_handle_t tx_chan; - const gpio_num_t tx_gpio[MAX_CHANNELS] = {GPIO_NUM_4, GPIO_NUM_5, GPIO_NUM_11, GPIO_NUM_13}; //using pins 4,5,11,13 for channels 0,1,2,3 respectively for tx + const gpio_num_t tx_gpio[MAX_CHANNELS] = {GPIO_NUM_4, GPIO_NUM_5, GPIO_NUM_11, GPIO_NUM_13}; QueueHandle_t memory_to_free; //=====================RX===================== rmt_channel_handle_t rx_chan; - const gpio_num_t rx_gpio[MAX_CHANNELS] = {GPIO_NUM_3, GPIO_NUM_6, GPIO_NUM_12, GPIO_NUM_14}; //using pins 3,6,12,14 for channels 0,1,2,3 respectively for rx + const gpio_num_t rx_gpio[MAX_CHANNELS] = {GPIO_NUM_3, GPIO_NUM_6, GPIO_NUM_12, GPIO_NUM_14}; //rx_receive_config rmt_receive_config_t receive_config = { .signal_range_min_ns = 200, .signal_range_max_ns = 200 * 1000, .flags = { - .en_partial_rx = true + .en_partial_rx = false // frames are max 121B = ~968 symbols, well within the 1024-symbol buffer } }; @@ -135,22 +138,21 @@ typedef struct _gpio_channel_pair { static const GPIO_Channel_Pair gpio_channel_pairs[MAX_CHANNELS] = { { - .tx_pin = GPIO_NUM_1, + .tx_pin = GPIO_NUM_4, + .rx_pin = GPIO_NUM_3 + }, + { + .tx_pin = GPIO_NUM_5, + .rx_pin = GPIO_NUM_6 + }, + { + .tx_pin = GPIO_NUM_11, .rx_pin = GPIO_NUM_12 }, - { - .tx_pin = GPIO_NUM_2, - .rx_pin = GPIO_NUM_13 - }, - { - .tx_pin = GPIO_NUM_3, - .rx_pin = GPIO_NUM_14 - }, { .tx_pin = GPIO_NUM_4, - .rx_pin = GPIO_NUM_15 + .rx_pin = GPIO_NUM_14 } }; //todo: use these pairs directly instead of the two arrays in the class definition above - // but ensure to update them first!!! #endif //RMT_COMMUNICATIONS diff --git a/components/rpc/CommunicationRouter.cpp b/components/rpc/CommunicationRouter.cpp index 412d289..f71e230 100644 --- a/components/rpc/CommunicationRouter.cpp +++ b/components/rpc/CommunicationRouter.cpp @@ -19,6 +19,7 @@ #define TAG "CommunicationRouter" #define MAX_RX_BUFFER_SIZE 1024 #define WIRELESS_DEQUEUE_TIMEOUT_MS 3000 +#define LEADER_ELECTION_PERIOD_MS 3000 CommunicationRouter::~CommunicationRouter() { vTaskDelete(m_router_thread); @@ -35,6 +36,16 @@ CommunicationRouter::~CommunicationRouter() { } } +[[noreturn]] void CommunicationRouter::leader_election_thread(void *args) { + const auto that = static_cast(args); + + while (true) { + that->m_last_leader_updated = std::chrono::system_clock::now(); + that->update_leader(); + vTaskDelay(pdMS_TO_TICKS(LEADER_ELECTION_PERIOD_MS)); + } +} + [[noreturn]] void CommunicationRouter::link_layer_thread(void *args) { const auto that = static_cast(args); @@ -61,21 +72,45 @@ void CommunicationRouter::update_leader() { size_t table_size = RIP_MAX_ROUTES; this->m_data_link_manager->get_routing_table(table, &table_size); - // Leader election (just get the highest id in rip) + // Compute our own sum_of_hops from our local routing table (row 0 in the + // internal table carries this, but it is also returned in the public table + // as the self-entry). We reconstruct it here directly from the peer rows. + uint32_t self_sum = 0; std::vector connected_module_ids; - uint8_t max = m_module_id; - for (int i = 0; i < table_size; i++) { - const auto id = table[i].info.board_id; - connected_module_ids.emplace_back(id); - if (id > max) { // todo: change this to be correct - max = id; + for (size_t i = 0; i < table_size; i++) { + if (table[i].info.board_id == m_module_id) continue; // skip self-row if present + connected_module_ids.emplace_back(table[i].info.board_id); + self_sum += table[i].info.hops; + } + const uint8_t self_sum_clamped = (self_sum > 255) ? 255 : static_cast(self_sum); + + // Leader election: elect the module with the lowest sum_of_hops (most central). + // Each module advertises its own sum_of_hops as the third byte of every RIP row, + // so every peer in the routing table carries the score that module computed + // locally from its own perspective — the true minimum total hop distance. + // + // Ties are broken by higher board_id for determinism. + uint8_t best_id = m_module_id; + uint8_t best_score = self_sum_clamped; + + for (size_t i = 0; i < table_size; i++) { + const auto& row = table[i]; + if (row.info.board_id == m_module_id) continue; + + const uint8_t score = row.info.sum_of_hops; + if (score == 0) continue; // a remote board advertising sum_of_hops=0 is invalid — never trust it + if (score < best_score || (score == best_score && row.info.board_id > best_id)) { + best_score = score; + best_id = row.info.board_id; } } + const uint8_t elected = best_id; + // Leader has changed, we may need to change PC connection state - if (this->m_leader != max) { - ESP_LOGI(TAG, "Leader has changed from %d to %d", this->m_leader, max); - if (max == m_module_id) { + if (this->m_leader != elected) { + ESP_LOGI(TAG, "Leader has changed from %d to %d (sum_of_hops=%d)", this->m_leader, elected, best_score); + if (elected == m_module_id) { m_pc_connection->connect(); m_lossless_server->startup(); m_lossy_server->startup(); @@ -86,7 +121,7 @@ void CommunicationRouter::update_leader() { } } - this->m_leader = max; + this->m_leader = elected; if (this->m_leader == m_module_id) { this->m_discovery_service->set_connected_boards(connected_module_ids); diff --git a/components/rpc/include/CommunicationRouter.h b/components/rpc/include/CommunicationRouter.h index 61f48b2..07f5522 100644 --- a/components/rpc/include/CommunicationRouter.h +++ b/components/rpc/include/CommunicationRouter.h @@ -50,12 +50,15 @@ public: xTaskCreate(router_thread, "router", 4096, this, 3, &this->m_router_thread); xTaskCreate(link_layer_thread, "router_rmt", 4096, this, 3, &this->m_link_layer_thread); + xTaskCreate(leader_election_thread, "router_election", 4096, this, 3, + &this->m_leader_election_thread); } ~CommunicationRouter(); [[noreturn]] static void router_thread(void *args); [[noreturn]] static void link_layer_thread(void *args); + [[noreturn]] static void leader_election_thread(void *args); int send_msg(uint8_t *buffer, size_t length) const; void update_leader(); void route(std::unique_ptr>&& buffer) const; @@ -71,6 +74,7 @@ public: private: TaskHandle_t m_router_thread = nullptr; TaskHandle_t m_link_layer_thread = nullptr; + TaskHandle_t m_leader_election_thread = nullptr; ConfigManager &m_config_manager; std::unique_ptr m_pc_connection; std::unique_ptr m_lossless_server; diff --git a/components/softUART/CMakeLists.txt b/components/softUART/CMakeLists.txt new file mode 100644 index 0000000..fddf49c --- /dev/null +++ b/components/softUART/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "SoftUARTManager.cpp" + PRIV_REQUIRES driver esp_driver_uart esp_driver_gpio + REQUIRES rmt + INCLUDE_DIRS "include") diff --git a/components/softUART/SoftUARTManager.cpp b/components/softUART/SoftUARTManager.cpp new file mode 100644 index 0000000..e932a31 --- /dev/null +++ b/components/softUART/SoftUARTManager.cpp @@ -0,0 +1,219 @@ +#include "SoftUARTManager.h" +#include "esp_log.h" +#include "driver/uart.h" +#include "driver/gpio.h" +#include + +#define TAG "SoftUART" + +SoftUARTManager::SoftUARTManager(uint8_t num_channels) { + if (num_channels == 0 || num_channels > SUART_NUM_CHANNELS) { + ESP_LOGE(TAG, "Invalid num_channels %d (must be 1-%d)", num_channels, SUART_NUM_CHANNELS); + this->num_channels = 0; + return; + } + + this->num_channels = num_channels; + + memset(hw, 0, sizeof(hw)); + memset(ch_status, SUART_CHANNEL_NOT_READY, sizeof(ch_status)); + + for (uint8_t i = 0; i < num_channels; i++) { + if (init_hw_channel(i) == ESP_OK) { + ch_status[i] = SUART_CHANNEL_READY; + } else { + ESP_LOGE(TAG, "Failed to init HW UART channel %d", i); + } + } + + ESP_LOGI(TAG, "SoftUARTManager ready: %d HW UART channel(s)", num_channels); +} + +SoftUARTManager::~SoftUARTManager() { + for (uint8_t i = 0; i < num_channels; i++) deinit_hw_channel(i); +} + +esp_err_t SoftUARTManager::init_hw_channel(uint8_t idx) { + uart_port_t port = HW_PORT[idx]; + hw[idx].port = port; + hw[idx].tx_gpio = HW_TX[idx]; + hw[idx].rx_gpio = HW_RX[idx]; + + const uart_config_t cfg = { + .baud_rate = SUART_BAUD_RATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 0, + .source_clk = UART_SCLK_DEFAULT, + }; + + esp_err_t res = uart_param_config(port, &cfg); + if (res != ESP_OK) { ESP_LOGE(TAG, "HW[%d] uart_param_config: %s", idx, esp_err_to_name(res)); return res; } + + res = uart_set_pin(port, (int)HW_TX[idx], (int)HW_RX[idx], UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + if (res != ESP_OK) { ESP_LOGE(TAG, "HW[%d] uart_set_pin: %s", idx, esp_err_to_name(res)); return res; } + + res = uart_driver_install(port, SUART_RX_BUF_SIZE * 2, SUART_RX_BUF_SIZE * 2, 0, nullptr, 0); + if (res != ESP_OK) { ESP_LOGE(TAG, "HW[%d] uart_driver_install: %s", idx, esp_err_to_name(res)); return res; } + + hw[idx].tx_done_sem = xSemaphoreCreateBinary(); + if (hw[idx].tx_done_sem == nullptr) return ESP_ERR_NO_MEM; + + hw[idx].status = SUART_CHANNEL_READY; + ESP_LOGI(TAG, "HW channel %d ready (UART%d TX=GPIO%d RX=GPIO%d)", idx, (int)port, (int)HW_TX[idx], (int)HW_RX[idx]); + return ESP_OK; +} + +void SoftUARTManager::deinit_hw_channel(uint8_t idx) { + if (hw[idx].tx_done_sem) { vSemaphoreDelete(hw[idx].tx_done_sem); hw[idx].tx_done_sem = nullptr; } + if (hw[idx].status != SUART_CHANNEL_NOT_READY) uart_driver_delete(hw[idx].port); + hw[idx].status = SUART_CHANNEL_NOT_READY; +} + +esp_err_t SoftUARTManager::send(uint8_t* data, size_t size, void* /*config*/, uint8_t channel_num) { + if (channel_num >= num_channels || data == nullptr || size == 0) return ESP_ERR_INVALID_ARG; + if (ch_status[channel_num] == SUART_CHANNEL_NOT_READY) return ESP_ERR_INVALID_STATE; + return send_hw(channel_num, data, size); +} + +esp_err_t SoftUARTManager::receive(uint8_t* recv_buf, size_t size, size_t* output_size, uint8_t channel_num) { + if (channel_num >= num_channels || recv_buf == nullptr || output_size == nullptr) return ESP_FAIL; + if (ch_status[channel_num] != SUART_CHANNEL_LISTENING) return ESP_FAIL; + return receive_hw(channel_num, recv_buf, size, output_size); +} + +esp_err_t SoftUARTManager::start_receiving(uint8_t channel_num) { + if (channel_num >= num_channels) return ESP_FAIL; + if (ch_status[channel_num] == SUART_CHANNEL_NOT_READY) return ESP_ERR_INVALID_STATE; + if (ch_status[channel_num] == SUART_CHANNEL_LISTENING) return ESP_OK; + + uart_flush_input(hw[channel_num].port); + ch_status[channel_num] = SUART_CHANNEL_LISTENING; + return ESP_OK; +} + +esp_err_t SoftUARTManager::wait_until_send_complete(uint8_t channel_num) { + if (channel_num >= num_channels) return ESP_FAIL; + + SemaphoreHandle_t sem = hw[channel_num].tx_done_sem; + if (sem == nullptr) return ESP_FAIL; + + if (xSemaphoreTake(sem, SUART_TX_DONE_WAIT_TICKS) != pdTRUE) { + ESP_LOGE(TAG, "wait_until_send_complete: timeout on channel %d", channel_num); + return ESP_FAIL; + } + + uart_wait_tx_done(hw[channel_num].port, SUART_TX_DONE_WAIT_TICKS); + return ESP_OK; +} + +esp_err_t SoftUARTManager::send_hw(uint8_t idx, uint8_t* data, size_t size) { + uart_wait_tx_done(hw[idx].port, SUART_TX_DONE_WAIT_TICKS); + int written = uart_write_bytes(hw[idx].port, reinterpret_cast(data), size); + if (written < 0 || static_cast(written) != size) { + ESP_LOGE(TAG, "HW[%d] uart_write_bytes returned %d", idx, written); + return ESP_FAIL; + } + xSemaphoreGive(hw[idx].tx_done_sem); + return ESP_OK; +} + +esp_err_t SoftUARTManager::receive_hw(uint8_t idx, uint8_t* buf, size_t size, size_t* out) { + uart_port_t port = hw[idx].port; + + // wait for at least a minimum complete frame + const size_t MIN_FRAME = 10; + size_t available = 0; + if (uart_get_buffered_data_len(port, &available) != ESP_OK || available < MIN_FRAME) { + return ESP_FAIL; + } + + //scan for the preamble byte (0xAB) + uint8_t preamble = 0; + int discard_count = 0; + while (true) { + int n = uart_read_bytes(port, &preamble, 1, pdMS_TO_TICKS(2)); + if (n < 1) return ESP_FAIL; + + if (preamble == 0xAB) break; + + discard_count++; + if (discard_count > (int)SUART_RX_BUF_SIZE) { + ESP_LOGW(TAG, "HW[%d] no preamble after %d bytes — flushing", idx, discard_count); + uart_flush_input(port); + return ESP_FAIL; + } + } + if (discard_count > 0) { + ESP_LOGD(TAG, "HW[%d] skipped %d noise byte(s) before preamble", idx, discard_count); + } + buf[0] = preamble; + + // read the remaining 7 header bytes + int peeked = uart_read_bytes(port, buf + 1, 7, pdMS_TO_TICKS(20)); + if (peeked < 7) { + ESP_LOGE(TAG, "HW[%d] timeout reading header (got %d of 7)", idx, peeked); + return ESP_FAIL; + } + + // determine frame type and total length + bool is_control = (buf[5] & 0x80) != 0; + uint16_t len_field = (uint16_t)buf[6] | ((uint16_t)buf[7] << 8); + + size_t total_frame_len; + if (is_control) { + total_frame_len = 8 + len_field + 2; + } else { + uint8_t hdr2[4]; + int n2 = uart_read_bytes(port, hdr2, 4, pdMS_TO_TICKS(20)); + if (n2 < 4) { + ESP_LOGE(TAG, "HW[%d] timeout reading generic header tail", idx); + return ESP_FAIL; + } + memcpy(buf + 8, hdr2, 4); + uint16_t data_len = (uint16_t)hdr2[2] | ((uint16_t)hdr2[3] << 8); + total_frame_len = 12 + data_len + 2; + } + + if (total_frame_len > size || total_frame_len < 10 || total_frame_len > 256) { + ESP_LOGW(TAG, "HW[%d] unreasonable frame length %d — draining", idx, (int)total_frame_len); + // Drain remaining bytes of this bad frame so the next preamble scan + // doesn't find false 0xAB matches inside the body. + size_t hdr_consumed = is_control ? 8 : 12; + size_t to_drain = 0; + if (total_frame_len > hdr_consumed && total_frame_len <= 256) { + to_drain = total_frame_len - hdr_consumed; + } else { + size_t avail = 0; + uart_get_buffered_data_len(port, &avail); + to_drain = avail; + } + if (to_drain > 0) { + uint8_t drain_buf[128]; + while (to_drain > 0) { + size_t chunk = (to_drain > sizeof(drain_buf)) ? sizeof(drain_buf) : to_drain; + int got = uart_read_bytes(port, drain_buf, chunk, pdMS_TO_TICKS(5)); + if (got <= 0) break; + to_drain -= (size_t)got; + } + } + return ESP_FAIL; + } + + // read the rest of the frame + size_t already_read = is_control ? 8 : 12; + size_t remaining = total_frame_len - already_read; + if (remaining > 0) { + int nr = uart_read_bytes(port, buf + already_read, remaining, pdMS_TO_TICKS(100)); + if (nr < (int)remaining) { + ESP_LOGE(TAG, "HW[%d] incomplete frame: got %d of %d remaining bytes", + idx, nr, (int)remaining); + return ESP_FAIL; + } + } + + *out = total_frame_len; + return ESP_OK; +} diff --git a/components/softUART/include/SoftUARTManager.h b/components/softUART/include/SoftUARTManager.h new file mode 100644 index 0000000..3abcb2e --- /dev/null +++ b/components/softUART/include/SoftUARTManager.h @@ -0,0 +1,59 @@ +#ifndef SOFT_UART_MANAGER_H +#define SOFT_UART_MANAGER_H + +#include "IPhysicalLayer.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "driver/uart.h" +#include "driver/gpio.h" +#include "soc/gpio_num.h" +#include +#include + +#define SUART_NUM_CHANNELS 3 + +#define SUART_BAUD_RATE 115200 +#define SUART_RX_BUF_SIZE 1024 +#define SUART_TX_DONE_WAIT_TICKS pdMS_TO_TICKS(5000) + +#define SUART_CHANNEL_NOT_READY 0x0 +#define SUART_CHANNEL_READY 0x1 +#define SUART_CHANNEL_LISTENING 0x2 + +typedef struct { + uart_port_t port; + gpio_num_t tx_gpio; + gpio_num_t rx_gpio; + uint8_t status; + SemaphoreHandle_t tx_done_sem; +} hw_channel_t; + +class SoftUARTManager : public IPhysicalLayer { +public: + explicit SoftUARTManager(uint8_t num_channels); + ~SoftUARTManager() override; + + esp_err_t send(uint8_t* data, size_t size, void* config, uint8_t channel_num) override; + esp_err_t receive(uint8_t* recv_buf, size_t size, size_t* output_size, uint8_t channel_num) override; + esp_err_t start_receiving(uint8_t channel_num) override; + esp_err_t wait_until_send_complete(uint8_t channel_num) override; + +private: + uint8_t num_channels; + + hw_channel_t hw[SUART_NUM_CHANNELS]; + + uint8_t ch_status[SUART_NUM_CHANNELS]; + + esp_err_t init_hw_channel(uint8_t idx); + void deinit_hw_channel(uint8_t idx); + + esp_err_t send_hw(uint8_t idx, uint8_t* data, size_t size); + esp_err_t receive_hw(uint8_t idx, uint8_t* buf, size_t size, size_t* out); + + static constexpr gpio_num_t HW_TX[SUART_NUM_CHANNELS] = { GPIO_NUM_4, GPIO_NUM_5, GPIO_NUM_11 }; + static constexpr gpio_num_t HW_RX[SUART_NUM_CHANNELS] = { GPIO_NUM_3, GPIO_NUM_6, GPIO_NUM_12 }; + static constexpr uart_port_t HW_PORT[SUART_NUM_CHANNELS] = { UART_NUM_0, UART_NUM_1, UART_NUM_2 }; +}; + +#endif // SOFT_UART_MANAGER_H diff --git a/dependencies.lock b/dependencies.lock index e515acf..e9bdf1c 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -12,10 +12,10 @@ dependencies: idf: source: type: idf - version: 5.5.2 + version: 5.4.2 direct_dependencies: - espressif/mdns - idf -manifest_hash: 03f5f8f0ee3b5b205949fa7dcdf902f4be49d846d055343c6b13f1a303516690 +manifest_hash: d6911e14b94d3fd1a768cfd7760c9d19278efb8b4c5a517908dbc036afdfb2f3 target: esp32s3 version: 2.0.0 diff --git a/main/RemoteDebugging.cpp b/main/RemoteDebugging.cpp index 178e418..3244db3 100644 --- a/main/RemoteDebugging.cpp +++ b/main/RemoteDebugging.cpp @@ -69,7 +69,6 @@ std::string RemoteDebugging::get_coredump_summary() { // Panic reason char reason[200] = {}; if (esp_core_dump_get_panic_reason(reason, sizeof(reason)) == ESP_OK) { - ESP_LOGI(TAG, "Panic reason: %s", reason); out += "Panic reason: "; out += reason; out += "\n"; @@ -88,8 +87,6 @@ std::string RemoteDebugging::get_coredump_summary() { summary->ex_info.exc_vaddr); out += line; - ESP_LOGI(TAG, "%s", line); - // Backtrace out += "Backtrace:"; for (uint32_t i = 0; i < summary->exc_bt_info.depth && i < 16; i++) { @@ -102,8 +99,6 @@ std::string RemoteDebugging::get_coredump_summary() { } out += "\n"; - ESP_LOGI(TAG, "Backtrace: %s", out); - free(summary); return out; } diff --git a/main/control/DCMotorActuator.cpp b/main/control/DCMotorActuator.cpp index c62831e..ab16d61 100644 --- a/main/control/DCMotorActuator.cpp +++ b/main/control/DCMotorActuator.cpp @@ -6,20 +6,23 @@ #include "control/DCMotorActuator.h" #include "driver/ledc.h" #include "esp_attr.h" +#include "esp_intr_alloc.h" #include "flatbuffers_generated/SensorMessage_generated.h" #include "util/number_utils.h" #include "esp_log.h" +#define TAG "DCMotor" + #define LOW_DUTY 200 #define HIGH_DUTY 1000 #define FWD_CHANNEL LEDC_CHANNEL_1 #define REV_CHANNEL LEDC_CHANNEL_0 #define DEADZONE 0.05 -#define KP 0.01 +#define KP 0.05 #define KI 0 #define KD 0.020 #define MIN_PWM_DUTY 675 -#define MAX_PWM_DUTY 1024 +#define MAX_PWM_DUTY 1023 #define TICKS_PER_ROTATION 18.0 #define GEAR_RATIO 298 @@ -58,14 +61,9 @@ DCMotorActuator::DCMotorActuator() { setup_encoder(); - this->m_pid_task = nullptr; - this->m_target_angle = 0; - this->m_integral = 0; - this->m_last_error = 0; - // Pin the PID task to Core 1 so it doesn't compete with the RMT driver, // which runs its ISR and internal tasks on Core 0. - xTaskCreatePinnedToCore(reinterpret_cast(pid_task), "pid_task", 3072, this, 1, + xTaskCreatePinnedToCore(reinterpret_cast(pid_task), "pid_task", 4096, this, 1, &this->m_pid_task, 1); } @@ -73,20 +71,16 @@ DCMotorActuator::~DCMotorActuator() { vTaskDelete(m_pid_task); } -volatile int32_t encoder_ticks = 0; -volatile int8_t direction = 0; - static void IRAM_ATTR encoder_isr_handler(void *arg) { + auto *ticks = static_cast(arg); const int a = gpio_get_level(static_cast(DC_ENCODER_A)); const int b = gpio_get_level(static_cast(DC_ENCODER_B)); // Determine direction if (a == b) { - encoder_ticks++; - direction = 1; + (*ticks)++; } else { - encoder_ticks--; - direction = -1; + (*ticks)--; } } @@ -99,8 +93,12 @@ void DCMotorActuator::setup_encoder() { io_conf.pull_up_en = GPIO_PULLUP_ENABLE; gpio_config(&io_conf); - gpio_install_isr_service(0); - gpio_isr_handler_add(static_cast(DC_ENCODER_A), encoder_isr_handler, nullptr); + esp_err_t err = gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + ESP_ERROR_CHECK(err); + } + gpio_isr_handler_add(static_cast(DC_ENCODER_A), encoder_isr_handler, + reinterpret_cast(const_cast(&m_encoder_ticks))); } void DCMotorActuator::actuate(uint8_t *cmd) { @@ -108,51 +106,67 @@ void DCMotorActuator::actuate(uint8_t *cmd) { // Will introduce latency, and means that we need to also send the size to the actuate function. const auto *angleControlCmd = Flatbuffers::AngleControlMessageBuilder::parse_angle_control_message(cmd); - this->m_target_angle = angleControlCmd->angle(); + this->m_target_angle.store(angleControlCmd->angle(), std::memory_order_relaxed); } -void DCMotorActuator::pid_task(char *args) { +void DCMotorActuator::pid_task(void *args) { const auto that = reinterpret_cast(args); while (true) { - that->m_current_angle = (encoder_ticks * 360.0) / (GEAR_RATIO * TICKS_PER_ROTATION); + that->m_current_angle = (that->m_encoder_ticks * 360.0) / (GEAR_RATIO * TICKS_PER_ROTATION); - const double error = that->m_current_angle - that->m_target_angle; + const int64_t target = that->m_target_angle.load(std::memory_order_relaxed); + const double error = that->m_current_angle - target; that->m_integral += error * KI; - const double detivative = (error - that->m_last_error) * KD; + const double derivative = (error - that->m_last_error) * KD; that->m_last_error = error; - double control = error * KP + that->m_integral + detivative; + double control = error * KP + that->m_integral + derivative; if (control > 1) { control = 1; } else if (control < -1) { control = -1; } - const auto pwm = - util::mapRange(std::abs(control), 0, 1, MIN_PWM_DUTY, MAX_PWM_DUTY); + const uint32_t pwm = static_cast( + util::mapRange(std::abs(control), 0, 1, MIN_PWM_DUTY, MAX_PWM_DUTY)); if (std::abs(control) < DEADZONE) { - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL, 0)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL)); + esp_err_t err; + err = ledc_set_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL, 0); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_set_duty failed: %s", esp_err_to_name(err)); } + err = ledc_update_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_update_duty failed: %s", esp_err_to_name(err)); } + + err = ledc_set_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL, 0); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_set_duty failed: %s", esp_err_to_name(err)); } + err = ledc_update_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_update_duty failed: %s", esp_err_to_name(err)); } - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL, 0)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL)); vTaskDelay(300 / portTICK_PERIOD_MS); continue; } + esp_err_t err; if (control > 0) { - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL, pwm)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL)); + err = ledc_set_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL, pwm); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_set_duty failed: %s", esp_err_to_name(err)); } + err = ledc_update_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_update_duty failed: %s", esp_err_to_name(err)); } - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL, 0)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL)); + err = ledc_set_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL, 0); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_set_duty failed: %s", esp_err_to_name(err)); } + err = ledc_update_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_update_duty failed: %s", esp_err_to_name(err)); } } else { - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL, pwm)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL)); + err = ledc_set_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL, pwm); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_set_duty failed: %s", esp_err_to_name(err)); } + err = ledc_update_duty(LEDC_LOW_SPEED_MODE, REV_CHANNEL); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_update_duty failed: %s", esp_err_to_name(err)); } - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL, 0)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL)); + err = ledc_set_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL, 0); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_set_duty failed: %s", esp_err_to_name(err)); } + err = ledc_update_duty(LEDC_LOW_SPEED_MODE, FWD_CHANNEL); + if (err != ESP_OK) { ESP_LOGE(TAG, "ledc_update_duty failed: %s", esp_err_to_name(err)); } } vTaskDelay(75 / portTICK_PERIOD_MS); @@ -160,7 +174,6 @@ void DCMotorActuator::pid_task(char *args) { } std::vector DCMotorActuator::get_sensor_data() { - // todo: this really needs to return a int32, should also return two sensor data items, one for target one for current return {Flatbuffers::target_angle{(int16_t)m_current_angle}, Flatbuffers::current_angle{(int16_t)m_current_angle}}; } diff --git a/main/control/Servo1Actuator.cpp b/main/control/Servo1Actuator.cpp index a4fde71..4b1c436 100644 --- a/main/control/Servo1Actuator.cpp +++ b/main/control/Servo1Actuator.cpp @@ -86,7 +86,7 @@ void Servo1Actuator::actuate(uint8_t *cmd) { const auto *angleControlCmd = Flatbuffers::AngleControlMessageBuilder::parse_angle_control_message(cmd); m_target = static_cast(angleControlCmd->angle()); - // ESP_LOGI("Servo1", "new target: %d", angleControlCmd->angle()); + ESP_LOGI("Servo1", "new target: %d", angleControlCmd->angle()); } std::vector Servo1Actuator::get_sensor_data() { diff --git a/main/include/control/DCMotorActuator.h b/main/include/control/DCMotorActuator.h index bc2178c..8ced90a 100644 --- a/main/include/control/DCMotorActuator.h +++ b/main/include/control/DCMotorActuator.h @@ -6,6 +6,7 @@ #include "IActuator.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include class DCMotorActuator final : public IActuator { public: @@ -16,14 +17,16 @@ class DCMotorActuator final : public IActuator { private: void setup_encoder(); - static void pid_task(char *args); + static void pid_task(void *args); - double m_current_angle; - int64_t m_target_angle; - TaskHandle_t m_pid_task; + volatile int32_t m_encoder_ticks{0}; - double m_integral; - double m_last_error; + double m_current_angle{0.0}; + std::atomic m_target_angle{0}; + TaskHandle_t m_pid_task{nullptr}; + + double m_integral{0.0}; + double m_last_error{0.0}; }; -#endif //SERVO1ACTUATOR_H +#endif //DCMOTORACTUATOR_H diff --git a/main/main.cpp b/main/main.cpp index 194be5c..268ae81 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -21,7 +21,6 @@ extern "C" [[noreturn]] void app_main(void) { auto& config_manager = ConfigManager::get_instance(); // NOLINT - here for easily adding temporary config config_manager.set_communication_method(CommunicationMethod::Wireless); - esp_log_set_vprintf(RemoteDebugging::custom_log_write); const auto loop_manager = std::make_unique(); diff --git a/main/main_rmt_test.cpp b/main/main_rmt_test.cpp index 7bc05da..10f236d 100644 --- a/main/main_rmt_test.cpp +++ b/main/main_rmt_test.cpp @@ -267,7 +267,7 @@ extern "C" [[noreturn]] void app_main(void) { // uint8_t iteration = 0; // const char* message = "THIS IS A TEXT MESSAGE"; - uint8_t num_channels = 4; + uint8_t num_channels = 3; std::unique_ptr obj = std::make_unique(BOARD_ID, num_channels); if (obj->ready() != ESP_OK){ diff --git a/pinout.md b/pinout.md index 54953ee..4775630 100644 --- a/pinout.md +++ b/pinout.md @@ -4,18 +4,18 @@ | ------- | ----------------------------- | | 1 | Servo PWM / DC Motor FWD PWM | | 2 | DC Motor REV PWM | -| 3 | Ch. 0 RMT RX | -| 4 | Ch. 0 RMT TX | -| 5 | Ch. 1 RMT TX | -| 6 | Ch. 1 RMT RX | +| 3 | Ch. 0 UART0 RX | +| 4 | Ch. 0 UART0 TX | +| 5 | Ch. 1 UART1 TX | +| 6 | Ch. 1 UART1 RX | | 7 | Ch. 0 90 Deg Orientation Pin | | 8 | Ch. 0 180 Deg Orientation Pin | | 9 | Ch. 0 270 Deg Orientation Pin | | 10 | Ch. 0 0 Deg Orientation Pin | -| 11 | Ch. 2 RMT TX | -| 12 | Ch. 2 RMT RX | -| 13 | Ch. 3 RMT TX | -| 14 | Ch. 3 RMT RX | +| 11 | Ch. 2 UART2 TX | +| 12 | Ch. 2 UART2 RX | +| 13 | Ch. 3 SW-UART TX | +| 14 | Ch. 3 SW-UART RX | | 15 | DC Motor Encoder A | | 16 | DC Motor Encoder B | | 17 | OLED SDA, Distance SDA | diff --git a/sdkconfig b/sdkconfig index 2812e67..18daf86 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1,7 +1,9 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.5.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.4.2 Project Configuration # +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 CONFIG_SOC_ADC_SUPPORTED=y CONFIG_SOC_UART_SUPPORTED=y CONFIG_SOC_PCNT_SUPPORTED=y @@ -9,7 +11,6 @@ CONFIG_SOC_PHY_SUPPORTED=y CONFIG_SOC_WIFI_SUPPORTED=y CONFIG_SOC_TWAI_SUPPORTED=y CONFIG_SOC_GDMA_SUPPORTED=y -CONFIG_SOC_UHCI_SUPPORTED=y CONFIG_SOC_AHB_GDMA_SUPPORTED=y CONFIG_SOC_GPTIMER_SUPPORTED=y CONFIG_SOC_LCDCAM_SUPPORTED=y @@ -95,7 +96,6 @@ CONFIG_SOC_APB_BACKUP_DMA=y CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED=y CONFIG_SOC_CACHE_FREEZE_SUPPORTED=y -CONFIG_SOC_CACHE_ACS_INVALID_STATE_ON_PANIC=y CONFIG_SOC_CPU_CORES_NUM=2 CONFIG_SOC_CPU_INTR_NUM=32 CONFIG_SOC_CPU_HAS_FPU=y @@ -124,6 +124,7 @@ CONFIG_SOC_GPIO_OUT_RANGE_MAX=48 CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x0001FFFFFC000000 CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y @@ -146,10 +147,8 @@ CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y CONFIG_SOC_I2S_SUPPORTS_PCM=y CONFIG_SOC_I2S_SUPPORTS_PDM=y CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y -CONFIG_SOC_I2S_SUPPORTS_PCM2PDM=y -CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y -CONFIG_SOC_I2S_SUPPORTS_PDM2PCM=y CONFIG_SOC_I2S_PDM_MAX_TX_LINES=2 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y CONFIG_SOC_I2S_PDM_MAX_RX_LINES=4 CONFIG_SOC_I2S_SUPPORTS_TDM=y CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y @@ -171,8 +170,6 @@ CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 CONFIG_SOC_MCPWM_SWSYNC_CAN_PROPAGATE=y CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=1 CONFIG_SOC_MMU_PERIPH_NUM=1 -CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 -CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 CONFIG_SOC_PCNT_GROUPS=1 CONFIG_SOC_PCNT_UNITS_PER_GROUP=4 CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 @@ -184,7 +181,7 @@ CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=48 CONFIG_SOC_RMT_SUPPORT_RX_PINGPONG=y CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y -CONFIG_SOC_RMT_SUPPORT_ASYNC_STOP=y +CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y CONFIG_SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP=y CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y @@ -233,7 +230,7 @@ CONFIG_SOC_SPI_SCT_SUPPORTED=y CONFIG_SOC_SPI_SCT_REG_NUM=14 CONFIG_SOC_SPI_SCT_BUFFER_NUM_MAX=y CONFIG_SOC_SPI_SCT_CONF_BITLEN_MAX=0x3FFFA -CONFIG_SOC_MEMSPI_SRC_FREQ_120M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_120M=y CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y @@ -256,18 +253,13 @@ CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 CONFIG_SOC_TOUCH_SENSOR_VERSION=2 CONFIG_SOC_TOUCH_SENSOR_NUM=15 -CONFIG_SOC_TOUCH_MIN_CHAN_ID=1 -CONFIG_SOC_TOUCH_MAX_CHAN_ID=14 -CONFIG_SOC_TOUCH_SUPPORT_BENCHMARK=y CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y CONFIG_SOC_TOUCH_SUPPORT_WATERPROOF=y CONFIG_SOC_TOUCH_SUPPORT_PROX_SENSING=y -CONFIG_SOC_TOUCH_SUPPORT_DENOISE_CHAN=y CONFIG_SOC_TOUCH_PROXIMITY_CHANNEL_NUM=3 CONFIG_SOC_TOUCH_PROXIMITY_MEAS_DONE_SUPPORTED=y CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 CONFIG_SOC_TWAI_CONTROLLER_NUM=1 -CONFIG_SOC_TWAI_MASK_FILTER_NUM=1 CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y CONFIG_SOC_TWAI_BRP_MIN=2 CONFIG_SOC_TWAI_BRP_MAX=16384 @@ -281,8 +273,6 @@ CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y CONFIG_SOC_UART_SUPPORT_APB_CLK=y CONFIG_SOC_UART_SUPPORT_RTC_CLK=y CONFIG_SOC_UART_SUPPORT_XTAL_CLK=y -CONFIG_SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE=y -CONFIG_SOC_UHCI_NUM=1 CONFIG_SOC_USB_OTG_PERIPH_NUM=1 CONFIG_SOC_SHA_DMA_MAX_BUFFER_SIZE=3968 CONFIG_SOC_SHA_SUPPORT_DMA=y @@ -325,7 +315,6 @@ CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y -CONFIG_SOC_CLK_LP_FAST_SUPPORT_XTAL_D2=y CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y CONFIG_SOC_EFUSE_DIS_DOWNLOAD_DCACHE=y CONFIG_SOC_EFUSE_HARD_DIS_JTAG=y @@ -352,7 +341,7 @@ CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND=y CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_RESUME=y CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y -CONFIG_SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE=y +CONFIG_SOC_SPI_MEM_SUPPORT_OPI_MODE=y CONFIG_SOC_SPI_MEM_SUPPORT_TIMING_TUNING=y CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y @@ -417,17 +406,6 @@ CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y CONFIG_BOOTLOADER_PROJECT_VER=1 # end of Bootloader manager -# -# Application Rollback -# -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# end of Application Rollback - -# -# Recovery Bootloader and Rollback -# -# end of Recovery Bootloader and Rollback - CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0 CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set @@ -437,8 +415,6 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # # Log # -CONFIG_BOOTLOADER_LOG_VERSION_1=y -CONFIG_BOOTLOADER_LOG_VERSION=1 # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -453,13 +429,6 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format - -# -# Settings -# -CONFIG_BOOTLOADER_LOG_MODE_TEXT_EN=y -CONFIG_BOOTLOADER_LOG_MODE_TEXT=y -# end of Settings # end of Log # @@ -476,6 +445,7 @@ CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set @@ -519,7 +489,6 @@ CONFIG_ESP_ROM_HAS_HAL_WDT=y CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y CONFIG_ESP_ROM_HAS_LAYOUT_TABLE=y CONFIG_ESP_ROM_HAS_SPI_FLASH=y -CONFIG_ESP_ROM_HAS_SPI_FLASH_MMAP=y CONFIG_ESP_ROM_HAS_ETS_PRINTF_BUG=y CONFIG_ESP_ROM_HAS_NEWLIB=y CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y @@ -533,7 +502,6 @@ CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_HAS_VERSION=y CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y -CONFIG_ESP_ROM_CONSOLE_OUTPUT_SECONDARY=y # # Boot ROM Behavior @@ -633,18 +601,6 @@ CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # Component config # -# -# !!! MINIMAL_BUILD is enabled !!! -# - -# -# Only common components and those transitively required by the main component are listed -# - -# -# If a component configuration is missing, please add it to the main component's requirements -# - # # Console Library # @@ -656,11 +612,11 @@ CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # # -# Legacy TWAI Driver Configurations +# TWAI Configuration # -# CONFIG_TWAI_SKIP_LEGACY_CONFLICT_CHECK is not set +# CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y -# end of Legacy TWAI Driver Configurations +# end of TWAI Configuration # # Legacy ADC Driver Configuration @@ -729,13 +685,6 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set # CONFIG_TEMP_SENSOR_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Temperature Sensor Driver Configurations - -# -# Legacy Touch Sensor Driver Configurations -# -# CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_TOUCH_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy Touch Sensor Driver Configurations # end of Driver Configurations # @@ -771,7 +720,7 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GPTIMER_ISR_CACHE_SAFE is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations @@ -782,7 +731,6 @@ CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set -CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM=y # end of ESP-Driver:I2C Configurations # @@ -801,10 +749,8 @@ CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM=y # # ESP-Driver:MCPWM Configurations # -CONFIG_MCPWM_ISR_HANDLER_IN_IRAM=y -# CONFIG_MCPWM_ISR_CACHE_SAFE is not set +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -CONFIG_MCPWM_OBJ_CACHE_SAFE=y # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations @@ -819,15 +765,9 @@ CONFIG_MCPWM_OBJ_CACHE_SAFE=y # # ESP-Driver:RMT Configurations # -CONFIG_RMT_ENCODER_FUNC_IN_IRAM=y -CONFIG_RMT_TX_ISR_HANDLER_IN_IRAM=y -CONFIG_RMT_RX_ISR_HANDLER_IN_IRAM=y -# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# CONFIG_RMT_TX_ISR_CACHE_SAFE is not set -# CONFIG_RMT_RX_ISR_CACHE_SAFE is not set -CONFIG_RMT_OBJ_CACHE_SAFE=y -# CONFIG_RMT_ENABLE_DEBUG_LOG is not set # CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # @@ -852,29 +792,12 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Temperature Sensor Configurations -# -# ESP-Driver:TWAI Configurations -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -# CONFIG_TWAI_IO_FUNC_IN_IRAM is not set -# CONFIG_TWAI_ISR_CACHE_SAFE is not set -# CONFIG_TWAI_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:TWAI Configurations - # # ESP-Driver:UART Configurations # # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations -# -# ESP-Driver:UHCI Configurations -# -# CONFIG_UHCI_ISR_HANDLER_IN_IRAM is not set -# CONFIG_UHCI_ISR_CACHE_SAFE is not set -# CONFIG_UHCI_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:UHCI Configurations - # # ESP-Driver:USB Serial/JTAG Configuration # @@ -957,8 +880,7 @@ CONFIG_RTC_CLK_CAL_CYCLES=1024 # # Peripheral Control # -CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM=y -CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM=y +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # end of Peripheral Control # @@ -978,28 +900,7 @@ CONFIG_XTAL_FREQ_40=y CONFIG_XTAL_FREQ=40 # end of Main XTAL Config -# -# Power Supplier -# - -# -# Brownout Detector -# -CONFIG_ESP_BROWNOUT_DET=y -CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set -CONFIG_ESP_BROWNOUT_DET_LVL=7 -CONFIG_ESP_BROWNOUT_USE_INTR=y -# end of Brownout Detector -# end of Power Supplier - CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y -CONFIG_ESP_INTR_IN_IRAM=y # end of Hardware Settings # @@ -1043,17 +944,13 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 -CONFIG_ESP_PHY_PLL_TRACK_PERIOD_MS=1000 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set # CONFIG_ESP_PHY_RECORD_USED_TIME is not set -CONFIG_ESP_PHY_IRAM_OPT=y -# CONFIG_ESP_PHY_DEBUG is not set # end of PHY # # Power Management # -CONFIG_PM_SLEEP_FUNC_IN_IRAM=y # CONFIG_PM_ENABLE is not set CONFIG_PM_SLP_IRAM_OPT=y CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y @@ -1083,7 +980,6 @@ CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_SPEED_80M is not set CONFIG_SPIRAM_SPEED_40M=y CONFIG_SPIRAM_SPEED=40 -CONFIG_SPIRAM_BOOT_HW_INIT=y CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set @@ -1105,12 +1001,6 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf -# -# ESP-ROM -# -CONFIG_ESP_ROM_PRINT_IN_IRAM=y -# end of ESP-ROM - # # ESP Security Specific # @@ -1163,7 +1053,6 @@ CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory -CONFIG_ESP_SYSTEM_IN_IRAM=y # CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set @@ -1186,18 +1075,15 @@ CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_DEFAULT is not set # CONFIG_ESP_CONSOLE_USB_CDC is not set -# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y # CONFIG_ESP_CONSOLE_UART_CUSTOM is not set # CONFIG_ESP_CONSOLE_NONE is not set -# CONFIG_ESP_CONSOLE_SECONDARY_NONE is not set -CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_CONSOLE_UART_NUM=-1 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=4 CONFIG_ESP_INT_WDT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y @@ -1211,13 +1097,28 @@ CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=7 +# end of Brownout Detector + +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y CONFIG_ESP_SYSTEM_BBPLL_RECALIB=y # end of ESP System Settings # # IPC (Inter-Processor Call) # -CONFIG_ESP_IPC_ENABLE=y CONFIG_ESP_IPC_TASK_STACK_SIZE=1280 CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y CONFIG_ESP_IPC_ISR_ENABLE=y @@ -1226,7 +1127,6 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # -CONFIG_ESP_TIMER_IN_IRAM=y # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y @@ -1269,12 +1169,10 @@ CONFIG_ESP_WIFI_IRAM_OPT=y CONFIG_ESP_WIFI_RX_IRAM_OPT=y CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y -CONFIG_ESP_WIFI_ENABLE_SAE_H2E=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 -# CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 # CONFIG_ESP_WIFI_FTM_ENABLE is not set @@ -1299,10 +1197,10 @@ CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y # # CONFIG_ESP_WIFI_WPS_STRICT is not set # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set -# CONFIG_ESP_WIFI_WPS_RECONNECT_ON_FAIL is not set # end of WPS Configuration Options # CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1401,7 +1299,6 @@ CONFIG_FREERTOS_DEBUG_OCDAWARE=y CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y CONFIG_FREERTOS_NUMBER_OF_CORES=2 -CONFIG_FREERTOS_IN_IRAM=y # end of FreeRTOS # @@ -1413,6 +1310,8 @@ CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y # CONFIG_HAL_ASSERTION_ENABLE is not set CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 CONFIG_HAL_WDT_USE_ROM_IMPL=y +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y # end of Hardware Abstraction Layer (HAL) and Low Level (LL) # @@ -1433,9 +1332,6 @@ CONFIG_HEAP_TRACING_OFF=y # # Log # -CONFIG_LOG_VERSION_1=y -# CONFIG_LOG_VERSION_2 is not set -CONFIG_LOG_VERSION=1 # # Log Level @@ -1473,15 +1369,6 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set # end of Format - -# -# Settings -# -CONFIG_LOG_MODE_TEXT_EN=y -CONFIG_LOG_MODE_TEXT=y -# end of Settings - -CONFIG_LOG_IN_IRAM=y # end of Log # @@ -1489,6 +1376,7 @@ CONFIG_LOG_IN_IRAM=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set @@ -1600,7 +1488,6 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# CONFIG_LWIP_IPV6_ND6_ROUTE_INFO_OPTION_SUPPORT is not set # CONFIG_LWIP_PPP_SUPPORT is not set # CONFIG_LWIP_SLIP_SUPPORT is not set @@ -1635,7 +1522,6 @@ CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set -# CONFIG_LWIP_USE_ESP_GETADDRINFO is not set # end of DNS CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 @@ -1656,9 +1542,6 @@ CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y # CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set # CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set -CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_NONE=y -# CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_DEFAULT is not set -# CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_CUSTOM is not set CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set @@ -1693,7 +1576,6 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -# CONFIG_MBEDTLS_SSL_KEYING_MATERIAL_EXPORT is not set CONFIG_MBEDTLS_PKCS7_C=y # end of mbedTLS v3.x related @@ -1813,23 +1695,20 @@ CONFIG_MBEDTLS_FS_IO=y # end of mbedTLS # -# LibC +# Newlib # -CONFIG_LIBC_NEWLIB=y -CONFIG_LIBC_MISC_IN_IRAM=y -CONFIG_LIBC_LOCKS_PLACE_IN_IRAM=y -CONFIG_LIBC_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_LIBC_STDOUT_LINE_ENDING_LF is not set -# CONFIG_LIBC_STDOUT_LINE_ENDING_CR is not set -# CONFIG_LIBC_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_LIBC_STDIN_LINE_ENDING_LF is not set -CONFIG_LIBC_STDIN_LINE_ENDING_CR=y -# CONFIG_LIBC_NEWLIB_NANO_FORMAT is not set -CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=y -# CONFIG_LIBC_TIME_SYSCALL_USE_RTC is not set -# CONFIG_LIBC_TIME_SYSCALL_USE_HRT is not set -# CONFIG_LIBC_TIME_SYSCALL_USE_NONE is not set -# end of LibC +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y @@ -1891,7 +1770,6 @@ CONFIG_SPI_FLASH_HPM_DC_AUTO=y CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set -CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM=y # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -1917,13 +1795,13 @@ CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 # # Auto-detect flash chips # -CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_GD_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_TH_SUPPORT_ENABLED=y +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y @@ -2008,7 +1886,6 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set # CONFIG_NO_BLOBS is not set -# CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set # CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set @@ -2016,6 +1893,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2039,8 +1917,7 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_EXTERNAL_COEX_ENABLE is not set # CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set -# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y @@ -2051,26 +1928,6 @@ CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y # CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set # CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 -CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y -CONFIG_BROWNOUT_DET=y -CONFIG_ESP32S3_BROWNOUT_DET=y -CONFIG_BROWNOUT_DET_LVL_SEL_7=y -CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y -# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set -CONFIG_BROWNOUT_DET_LVL=7 -CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 -CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 @@ -2089,13 +1946,11 @@ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=160 CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_DEFAULT is not set # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_CONSOLE_UART_NONE is not set # CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_CONSOLE_UART_NUM=-1 CONFIG_INT_WDT=y CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y @@ -2107,6 +1962,24 @@ CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32S3_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 CONFIG_IPC_TASK_STACK_SIZE=1280 CONFIG_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP32_WIFI_ENABLED=y @@ -2141,6 +2014,7 @@ CONFIG_WPA_MBEDTLS_TLS_CLIENT=y # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set # CONFIG_WPA_WPS_STRICT is not set # CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set @@ -2179,22 +2053,11 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF # CONFIG_PPP_SUPPORT is not set -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_SYSTIMER=y CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set # CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set # CONFIG_ESP32S3_TIME_SYSCALL_USE_SYSTIMER is not set # CONFIG_ESP32S3_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set # CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072